Skip to main content

Getting Started

Relay pre-signed Solana transactions via the Relayer API. The relayer appends the fee-payer signature before broadcasting.
For EVM workflows, see EVM Getting Started.

Overview

  • Build and sign a Solana transaction (base64 wire format) with your authority key; leave the fee-payer slot empty.
  • POST the signed transaction under the solana payload alongside callback and timestamp.
  • The relayer signs as fee-payer, submits to the selected cluster, and posts callbacks to your URL.

Request Format

  • solana: object containing your pre-signed transaction and metadata.
    • txBase64: base64-encoded wire transaction signed by the authority.
  • callback: { url } for execution updates.
  • timestamp: unix epoch ms for replay protection.

Authentication and Callbacks

  • Each API request must include an ed25519 public client key and a signature generated by the corresponding private key.
  • Share the public key with Upside to whitelist the client; rotate it periodically.
  • Callbacks include X-Callback-Sig-B64, a base64-encoded ed25519 signature of the canonicalized callback body.
  • Verify callbacks using the public key from GET /api/v1/callback_pk.

Example Request

Build a transaction with your Solana SDK of choice, then sign and send the API request:

import { createReqSignature } from './createReqSignature'
import { sign } from 'tweetnacl'

const requestBody = {
solana: {
txBase64: 'BASE64_WIRE_TX_WITH_AUTHORITY_SIGNATURE',
},
callback: { url: 'https://example.org/tx-updates/1/receive' },
timestamp: Date.now(),
}

const keyPair = sign.keyPair.fromSecretKey(
Buffer.from('ED_25519_SECRET_IN_BASE64', 'base64'),
)
const signature = createReqSignature(requestBody, keyPair.secretKey)
const sigB64 = Buffer.from(signature).toString('base64')
const pkB64 = Buffer.from(keyPair.publicKey).toString('base64')

const resp = await fetch('https://relayer.upside.gg/api/v1/relay_meta_tx', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Request-Pk-B64': pkB64,
'X-Request-Sig-B64': sigB64,
},
body: JSON.stringify(requestBody),
})

if (resp.status !== 201) {
throw new Error(`Failed to submit meta tx: ${await resp.text()}`)
}