wallet_sendCalls
Broadcast bundle of calls to the network.
Authentication Required: Yes
Request
await jaw.provider.request({
method: 'wallet_sendCalls',
params: [{
calls: [
{
to: '0xContractA...',
value: '0x0',
data: '0x...',
},
{
to: '0xContractB...',
value: '0x0',
data: '0x...',
},
],
}],
});Parameters
| Name | Type | Required | Description |
|---|---|---|---|
calls | array | Yes | Array of call objects |
calls[].to | 0x${string} | Yes | Recipient address |
calls[].value | 0x${string} | No | Value in wei (hex), default "0x0" |
calls[].data | 0x${string} | No | Call data (hex), default "0x" |
chainId | 0x${string} | No | Target chain ID (defaults to connected chain) |
capabilities | object | No | Additional capabilities (see below) |
Capabilities
| Name | Type | Description |
|---|---|---|
capabilities.permissions | object | Permission capability for delegated execution |
capabilities.permissions.id | 0x${string} | ID of the permission to use for execution |
Response
Returns a batch call identifier.
Example
{
"id": "0x123abc..."
}Behavior
- All calls succeed atomically or all fail together
- Uses currently connected chain if
chainIdnot specified - Returns batch ID immediately for status tracking
- Background task monitors completion
- Gas is sponsored by paymaster if configured
- Users offered native ERC-20 paymaster option for gas fees (no configuration needed)
Errors
| Code | Description |
|---|---|
| 4001 | User rejected the request |
| 4100 | Unauthorized (not authenticated) |
| -32602 | Invalid params |
Example
Transfer Multiple ERC-20 Tokens
import { encodeFunctionData } from 'viem';
const transferAbi = [{
name: 'transfer',
type: 'function',
inputs: [
{ name: 'to', type: 'address' },
{ name: 'amount', type: 'uint256' },
],
}];
const account = '0x1234...';
const recipient = '0x5678...';
// Encode both transfers
const usdcTransfer = encodeFunctionData({
abi: transferAbi,
functionName: 'transfer',
args: [recipient, 1000000n],
});
const uniTransfer = encodeFunctionData({
abi: transferAbi,
functionName: 'transfer',
args: [recipient, 1000000000000000000n],
});
// Send both transfers atomically
const result = await jaw.provider.request({
method: 'wallet_sendCalls',
params: [{
calls: [
{
to: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
data: usdcTransfer,
},
{
to: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
data: uniTransfer,
},
],
}],
});
console.log('Batch ID:', result.id);Check Status
// Get status of the batch
const status = await jaw.provider.request({
method: 'wallet_getCallsStatus',
params: [result.id],
});
console.log('Status:', status.status);Execute with Permission (Delegated Execution)
When a permission has been granted via wallet_grantPermissions, you can execute calls using that permission. This allows the spender to execute transactions on behalf of the account within the permission's constraints.
import { encodeFunctionData } from 'viem';
// First, get the permission ID from a previous wallet_grantPermissions call
const permissionId = '0x1234...'; // The permission ID returned from grantPermissions
const transferData = encodeFunctionData({
abi: erc20Abi,
functionName: 'transfer',
args: ['0x5678...', 1000000n],
});
// Execute the transfer using the permission
const result = await jaw.provider.request({
method: 'wallet_sendCalls',
params: [{
calls: [
{
to: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
data: transferData,
},
],
capabilities: {
permissions: {
id: permissionId,
},
},
}],
});
console.log('Batch ID:', result.id);When using the permissions capability:
- The calls are executed through the JustaPermissionManager contract
- The permission's call and spend limits are enforced
- The spender must have been granted appropriate permissions for the calls being made
Related Methods
- wallet_getCallsStatus - Get batch status
- wallet_showCallsStatus - Show status UI
- wallet_grantPermissions - Grant permissions for delegated execution