WDK logoWDK documentation
SolanaGasless SolanaGuides

Send Transactions

Quote, sign, and send paymaster-funded Solana transactions.

This guide explains how to send native SOL, sign without broadcasting, quote paymaster fees, and use prebuilt transaction messages.

Use BigInt values for token and lamport amounts to avoid precision loss.

Send Native SOL

Use sendTransaction({ to, value }) to send native SOL through the configured paymaster:

Send SOL through the paymaster
const result = await account.sendTransaction({
  to: 'Recipient1111111111111111111111111111111',
  value: 1000000n
})

console.log('Transaction hash:', result.hash)
console.log('Paymaster fee:', result.fee)

The returned fee is denominated in the configured paymaster token's base units, not lamports.

Quote Before Sending

Use quoteSendTransaction() to get the paymaster fee before submitting:

Quote SOL send
const quote = await account.quoteSendTransaction({
  to: 'Recipient1111111111111111111111111111111',
  value: 1000000n
})

console.log('Paymaster fee estimate:', quote.fee)

Set a Transaction Fee Cap

Set transactionMaxFee in the wallet config or as a per-call override to cancel sendTransaction() or signTransaction() when the paymaster fee is higher than your cap:

Send with a transaction fee cap
const result = await account.sendTransaction({
  to: 'Recipient1111111111111111111111111111111',
  value: 1000000n
}, {
  transactionMaxFee: 500000n
})

quoteSendTransaction() returns the estimated fee without enforcing transactionMaxFee.

Sign Without Broadcasting

Use signTransaction() when another process will inspect or submit the fully signed transaction:

Sign paymaster-funded transaction
const signedTransaction = await account.signTransaction({
  to: 'Recipient1111111111111111111111111111111',
  value: 1000000n
}, {
  transactionMaxFee: 500000n
})

console.log('Signed transaction:', signedTransaction)

The module signs with the owner account, asks the paymaster to sign, and returns a fully signed Solana transaction. It does not broadcast from signTransaction().

Use a TransactionMessage

Pass a prebuilt TransactionMessage when your app needs custom instructions.

Quote and send a TransactionMessage
const quote = await account.quoteSendTransaction(transactionMessage)
console.log('Paymaster fee estimate:', quote.fee)

const result = await account.sendTransaction(transactionMessage)
console.log('Transaction hash:', result.hash)

If the message already includes a recent blockhash or durable nonce lifetime, the module preserves it. If it does not, the module fetches the latest blockhash.

If a prebuilt message sets feePayer, it must equal paymasterAddress. The module sets the fee payer to the paymaster address before asking the paymaster for fee instructions.

Read a Transaction Receipt

Use getTransactionReceipt(hash) to check whether a submitted transaction has been included in a block:

Read transaction receipt
const receipt = await account.getTransactionReceipt(result.hash)

if (receipt === null) {
  console.log('Transaction is not included in a block yet.')
} else {
  console.log('Transaction receipt:', receipt)
}

The method returns null while the transaction is still pending.

Override Paymaster Token

You can override the paymaster token for one quote, sign, or send call:

Override fee token for one send
const result = await account.sendTransaction({
  to: 'Recipient1111111111111111111111111111111',
  value: 1000000n
}, {
  paymasterToken: {
    address: 'AlternateFeeMint11111111111111111111111111'
  }
})

Next Steps

To transfer SPL tokens instead of native SOL, see Transfer SPL Tokens.

On this page