ZeroCopyZeroCopy
Sending

Tips

Choose a tip amount and add a SOL transfer to a live tip account.

Each submission must meet your key's tip requirement. Add a SOL transfer to the transaction, or use a declared tip if support has enabled it for your key.

All tip amounts are in lamports. One SOL is 1,000,000,000 lamports.

Live accounts

Call getTipAccounts or getBundleTipAccounts and choose any returned address. Both methods return the same live set.

Do not hard-code the addresses. Refresh a cached list before using it and after a missing_tip response whose found is lower than you expected. If the list is empty, wait and try again; submissions return not_ready with waiting_for: tip_vaults.

What counts

Add a top-level System Program Transfer to a live tip account. The recipient must be a static account key, not an address loaded through a lookup table.

CPI transfers and transferWithSeed do not count. Multiple qualifying transfers add together, including across a bundle's members.

The tip transfers only if the transaction executes successfully. Solana network fees are separate and can still be charged when execution fails.

Minimum tip

The minimum is set per key. Its default is 1,000,000 lamports (0.001 SOL), but your key may differ. The minimum field of a missing_tip response is authoritative; found is the amount SWQoS counted inside your transaction or bundle.

An in-transaction tip at or above the key minimum pays for the submission, and any declared tip value is ignored. If the in-transaction amount is below the minimum, a declaration must meet the minimum on its own; the two amounts are not added. Avoid a partial transfer plus a declaration unless you intend to make both payments.

Engine minimums

Bundles must also meet the minimum for an available block engine. A single transaction can still use direct leader delivery when it is not eligible for engine delivery.

Tip floor

Use getTipFloor or GET /tip_floor to see regional landed-tip percentiles in lamports. They are observations, not a required tip or a prediction. Your key's minimum still applies. Query a hosted region; the local agent does not serve the floor.

Add a transfer with Kit

This tip-only example discovers a live account, reads a blockhash from your Solana read RPC, signs a transfer, and submits it. In your application, append your other instructions before signing. TIP_LAMPORTS is the amount you choose, at least your key's minimum.

tip-and-send.ts
import { readFile } from 'node:fs/promises'
import { getTransferSolInstruction } from '@solana-program/system'
import {
  address,
  appendTransactionMessageInstructions,
  createKeyPairSignerFromBytes,
  createSolanaRpc,
  createTransactionMessage,
  getBase64EncodedWireTransaction,
  pipe,
  setTransactionMessageFeePayerSigner,
  setTransactionMessageLifetimeUsingBlockhash,
  signTransactionMessageWithSigners,
} from '@solana/kit'
import { call, required } from './swqos.ts'

const readRpc = createSolanaRpc(required('SOLANA_RPC_URL'))
const payer = await createKeyPairSignerFromBytes(
  new Uint8Array(JSON.parse(await readFile(required('KEYPAIR_FILE'), 'utf8'))),
)
const [tipAccount] = await call<string[]>('getTipAccounts')
if (!tipAccount) throw new Error('no live tip account; retry shortly')
const { value: lifetime } = await readRpc.getLatestBlockhash({ commitment: 'confirmed' }).send()
const message = pipe(
  createTransactionMessage({ version: 0 }),
  (m) => setTransactionMessageFeePayerSigner(payer, m),
  (m) => setTransactionMessageLifetimeUsingBlockhash(lifetime, m),
  (m) =>
    appendTransactionMessageInstructions(
      [
        getTransferSolInstruction({
          source: payer,
          destination: address(tipAccount),
          amount: BigInt(required('TIP_LAMPORTS')),
        }),
      ],
      m,
    ),
)
const transaction = await signTransactionMessageWithSigners(message)
const signature = await call<string>('sendTransaction', [
  getBase64EncodedWireTransaction(transaction),
  { encoding: 'base64', skipPreflight: true },
])
console.log(signature)

KEYPAIR_FILE names a Solana CLI keypair JSON file. The client helper preserves structured refusals. After acceptance, confirm the signature using readRpc.

On this page