sendCallsSync
Requests for the wallet to sign and broadcast a batch of calls to the network, and waits for the calls to be included in a block.
Usage
import { parseEther } from 'viem'
import { account, walletClient } from './config'
const status = await walletClient.sendCallsSync({
account,
calls: [
{
to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
value: parseEther('1')
},
{
data: '0xdeadbeef',
to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
},
],
})Notes:
accountandchainare top level properties as all calls should be sent by the same account and chain.- Properties of
callsitems are only those shared by all transaction types (e.g.data,to,value). The Wallet should handle other required properties like gas & fees. - Read
wallet_sendCallson EIP-5792.
Account Hoisting
If you do not wish to pass an account to every sendCalls, you can also hoist the Account on the Wallet Client (see config.ts).
import { walletClient } from './config'
const status = await walletClient.sendCallsSync({
calls: [
{
to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
value: parseEther('1')
},
{
data: '0xdeadbeef',
to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
},
],
})Contract Calls
The calls property also accepts Contract Calls, and can be used via the abi, functionName, and args properties.
import { parseAbi } from 'viem'
import { walletClient } from './config'
const abi = parseAbi([
'function approve(address, uint256) returns (bool)',
'function transferFrom(address, address, uint256) returns (bool)',
])
const status = await walletClient.sendCallsSync({
calls: [
{
to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
value: parseEther('1')
},
{
to: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi,
functionName: 'approve',
args: [
'0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
100n
],
},
{
to: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi,
functionName: 'transferFrom',
args: [
'0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
'0x0000000000000000000000000000000000000000',
100n
],
},
],
})Compatibility Fallback
If the Wallet does not support EIP-5792 and wallet_sendCalls, passing the experimental_fallback
flag to sendCalls will allow Viem to fall back to executing the calls sequentially
via eth_sendTransaction.
import { parseEther } from 'viem'
import { account, walletClient } from './config'
const status = await walletClient.sendCallsSync({
account,
calls: [
{
to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
value: parseEther('1')
},
{
data: '0xdeadbeef',
to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
},
],
experimental_fallback: true,
})Returns
WalletGetCallsStatusReturnType
Status of the calls.
Parameters
account
- Type:
Account | Address | null
The Account to sign & broadcast the call from. If set to null, it is assumed that the wallet will handle filling the sender of the calls.
Accepts a JSON-RPC Account.
import { walletClient } from './config'
const status = await walletClient.sendCallsSync({
account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
calls: [
{
to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
value: parseEther('1')
},
{
data: '0xdeadbeef',
to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
},
],
})chain
- Type:
Chain - Default:
walletClient.chain
The target chain to broadcast the calls.
import { mainnet } from 'viem/chains'
import { walletClient } from './config'
const status = await walletClient.sendCallsSync({
chain: mainnet,
calls: [
{
to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
value: parseEther('1')
},
{
data: '0xdeadbeef',
to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
},
],
})calls
- Type:
Call[]
An array of calls to be signed and broadcasted.
import { mainnet } from 'viem/chains'
import { walletClient } from './config'
const status = await walletClient.sendCallsSync({
chain: mainnet,
calls: [
{
to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
value: parseEther('1')
},
{
data: '0xdeadbeef',
to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
},
],
})calls.data
- Type:
Hex
Calldata to broadcast (typically a contract function selector with encoded arguments, or contract deployment bytecode).
import { mainnet } from 'viem/chains'
import { walletClient } from './config'
const status = await walletClient.sendCallsSync({
chain: mainnet,
calls: [
{
to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
value: parseEther('1')
},
{
data: '0xdeadbeef',
to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
},
],
})When calling functions on contracts, it may be more convenient to pass in a Contract Call, providing the the abi, functionName, and args properties which will then be encoded into the appropriate calls.data.
import { parseAbi } from 'viem'
import { walletClient } from './config'
const abi = parseAbi([
'function approve(address, uint256) returns (bool)',
])
const status = await walletClient.sendCallsSync({
calls: [
{
to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
value: parseEther('1')
},
{
to: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi,
functionName: 'approve',
args: [
'0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
100n
],
}
],
})calls.to
- Type:
Address
Recipient address of the call.
import { mainnet } from 'viem/chains'
import { walletClient } from './config'
const status = await walletClient.sendCallsSync({
chain: mainnet,
calls: [
{
to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
value: parseEther('1')
},
{
data: '0xdeadbeef',
to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
},
],
})calls.value
- Type:
Address
Value to send with the call.
import { mainnet } from 'viem/chains'
import { walletClient } from './config'
const status = await walletClient.sendCallsSync({
chain: mainnet,
calls: [
{
to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
value: parseEther('1')
},
{
data: '0xdeadbeef',
to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
},
],
})calls.dataSuffix
- Type: Hex
Data to append to the end of the calldata. Useful for adding a "domain" tag.
const status = await walletClient.sendCallsSync({
calls: [
{
to: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi,
functionName: 'approve',
args: [
'0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
100n
],
dataSuffix: '0xdeadbeef'
}
],
})capabilities
- Type:
WalletCapabilities
Capability metadata for the calls (e.g. specifying a paymaster).
import { walletClient } from './config'
const status = await walletClient.sendCallsSync({
calls: [
{
to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
value: parseEther('1')
},
{
data: '0xdeadbeef',
to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
},
],
capabilities: {
paymasterService: {
url: 'https://...'
}
}
})forceAtomic
- Type:
boolean - Default:
false
Force the calls to be executed atomically. See more
import { walletClient } from './config'
const status = await walletClient.sendCallsSync({
calls: [
{
to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
value: parseEther('1')
},
{
data: '0xdeadbeef',
to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
},
],
forceAtomic: true,
})id
- Type:
string
Attribute the call batch with an identifier.
import { walletClient } from './config'
const status = await walletClient.sendCallsSync({
calls: [
{
to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
value: parseEther('1')
},
{
data: '0xdeadbeef',
to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
},
],
id: '<my-batch-id>',
})pollingInterval (optional)
- Type:
number - Default:
walletClient.pollingInterval
The polling interval to poll for the calls status.
import { walletClient } from './config'
const status = await walletClient.sendCallsSync({
calls: [
{
to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
value: parseEther('1')
},
{
data: '0xdeadbeef',
to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
},
],
pollingInterval: 1_000,
})timeout (optional)
- Type:
number - Default:
chain.blockTime * 3
The timeout to wait for the calls status.
import { walletClient } from './config'
const status = await walletClient.sendCallsSync({
calls: [
{
to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
value: parseEther('1')
},
],
timeout: 20_000,
})