Send Transactions
Send native tokens on EVM chains with EIP-1559 or legacy gas settings.
This guide explains how to send EVM transactions with EIP-1559 gas parameters, send legacy gas transactions, deploy contracts, sign without broadcasting, estimate fees, cap transaction fees, use dynamic fee rates, and wait for finality.
BigInt Usage: Always use BigInt (the n suffix) for monetary values to avoid precision loss with large numbers.
Send with EIP-1559 Gas Parameters
You can use account.sendTransaction() to send an EIP-1559 transaction. EIP-1559 transactions provide more predictable gas fees and faster inclusion times.
const result = await account.sendTransaction({
to: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
value: 1000000000000000000n, // 1 ETH in wei
maxFeePerGas: 30000000000,
maxPriorityFeePerGas: 2000000000
})
console.log('Transaction hash:', result.hash)
console.log('Transaction fee:', result.fee, 'wei')Send with Legacy Gas Parameters
You can also use account.sendTransaction() with legacy gas settings for chains that do not support EIP-1559.
const legacyResult = await account.sendTransaction({
to: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
value: 1000000000000000000n,
gasPrice: 20000000000n,
gasLimit: 21000
})
console.log('Transaction hash:', legacyResult.hash)Deploy a Contract
For contract-creation transactions, omit to or pass to: null and provide the deployment bytecode in data.
const result = await account.sendTransaction({
to: null,
value: 0n,
data: contractBytecode,
maxFeePerGas: 30000000000n,
maxPriorityFeePerGas: 2000000000n
})
console.log('Deployment transaction:', result.hash)Sign Without Broadcasting
Use account.signTransaction() when you need a signed raw transaction but want to submit it through a separate relay, service, or review flow.
const signedTransaction = await account.signTransaction({
to: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
value: 1000000000000000000n,
chainId: 1,
maxFeePerGas: 30000000000n,
maxPriorityFeePerGas: 2000000000n
})
console.log('Signed transaction:', signedTransaction)signTransaction() returns the signed transaction payload and does not broadcast it. In 1.0.0-beta.17, do not pass that serialized payload back to sendTransaction(): the send path does not broadcast the supplied bytes and can populate a different transaction. Submit signed raw transactions through a separate relay or provider. Use sendTransaction() with an EvmTransaction object when WDK should populate, sign, broadcast, and return the transaction hash.
Estimate Transaction Fees
Use account.quoteSendTransaction() to get a fee estimate before sending.
const quote = await account.quoteSendTransaction({
to: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
value: 1000000000000000000n
})
console.log('Estimated fee:', quote.fee, 'wei')Cap Transaction Fees
Set transactionMaxFee when you create the wallet to stop native sendTransaction() calls and provider-backed signTransaction() calls if the estimated fee exceeds your limit. Offline signing without a provider cannot estimate fees, so the fee-cap check does not run there.
const wallet = new WalletManagerEvm(seedPhrase, {
provider: 'https://eth.drpc.org',
transactionMaxFee: 100000000000000n
})Use Dynamic Fee Rates
Retrieve current fee rates using wallet.getFeeRates() and apply them to your transaction.
const feeRates = await wallet.getFeeRates()
console.log('Normal fee rate:', feeRates.normal, 'wei')
console.log('Fast fee rate:', feeRates.fast, 'wei')
const result = await account.sendTransaction({
to: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
value: 1000000000000000000n,
data: '0x',
gasLimit: 21000,
maxFeePerGas: feeRates.fast,
maxPriorityFeePerGas: 2000000000n
})
console.log('Transaction sent:', result.hash)
console.log('Fee paid:', result.fee, 'wei')Gas Estimation: The maxFeePerGas and maxPriorityFeePerGas fields enable EIP-1559 transactions, ensuring more predictable gas fees and faster inclusion times.
Wait for Finality
Use the hash returned by sendTransaction() with waitForTransaction():
const result = await account.sendTransaction({
to: recipient,
value: 1000000000000000n
})
const receipt = await account.waitForTransaction(result.hash, {
target: 'final'
})
if (receipt.finality === 'dropped') {
console.log('The sender nonce was consumed by another transaction')
} else if (receipt.success === false) {
console.log('The transaction was included but reverted')
}The EVM default timeout is 120 seconds and the polling interval is four seconds. A node that does not implement the finalized block tag can report confirmed but cannot advance the receipt to final; use a bounded timeout appropriate for that provider. A finality target indicates settlement level, not execution success, so inspect success.
getTransactionReceipt() remains available for the native ethers receipt but is deprecated in favor of getTransaction().
Next Steps
To transfer ERC-20 tokens instead of native tokens, see Transfer ERC-20 Tokens.