WDK logoWDK documentation

Send Transactions

Send gasless transactions and estimate fees.

This guide explains how to send a gasless transaction, estimate fees, cap transaction fees, reuse a recent quote, and use a custom paymaster token.

Send a Gasless Transaction

You can send a transaction with gas fees paid in the paymaster token using account.sendTransaction():

Send Gasless Transaction
const result = await account.sendTransaction({
  to: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  value: 1000000000000000n // 0.001 ETH in wei
})
console.log('Transaction hash:', result.hash)
console.log('Fee paid in paymaster token:', result.fee)

ERC-4337 transactions are gasless for the end user. Gas fees are paid through the configured paymaster using the specified paymaster token (e.g., USD₮).

Estimate Fees

You can estimate the fee for a transaction without broadcasting it using account.quoteSendTransaction():

Estimate Fee
const quote = await account.quoteSendTransaction({
  to: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  value: 1000000000000000n
})
console.log('Estimated fee:', quote.fee)

Cap Transaction Fees

Set transactionMaxFee to reject non-sponsored sendTransaction() and signTransaction() operations when the estimated UserOperation fee is above your cap. Use transferMaxFee separately for token transfers.

Cap sendTransaction fees
const result = await account.sendTransaction({
  to: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  value: 1000000000000000n
}, {
  transactionMaxFee: 100000
})

transactionMaxFee applies to Paymaster Token and Native Coins modes. Sponsored operations return a zero fee to the caller and do not use this cap.

Reuse a Recent Quote

Quotes are cached for up to 2 minutes. If you call sendTransaction() with the same transaction during that window, the account checks the current on-chain nonce before reusing the cached UserOperation. If the nonce has moved, it builds a fresh quote before sending.

Quote Then Send
const tx = {
  to: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  value: 1000000000000000n
}

const quote = await account.quoteSendTransaction(tx)
console.log('Estimated fee:', quote.fee)

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

Send Rapid Transactions

When you call sendTransaction() or transfer() rapidly from the same account instance, the wallet reserves local nonces so concurrent UserOperations use sequential nonces. If submission fails before bundler acceptance, the reserved nonce is released. If the failure is ambiguous, such as a transport error after submission, the wallet keeps the nonce reserved to avoid accidental reuse.

The wallet reads the on-chain nonce before reserving locally. If that read does not complete within 30 seconds, the operation fails instead of guessing the next nonce.

Send with Custom Paymaster Token

You can override the default paymaster token for a specific transaction by passing a config object to account.sendTransaction():

Custom Paymaster Token
const result = await account.sendTransaction({
  to: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
  value: 1000000000000000n
}, {
  paymasterToken: {
    address: '0x68749665FF8D2d112Fa859AA293F07A622782F38' // XAUT
  }
})

Next Steps

Learn how to transfer ERC-20 tokens.

On this page