# sendCalls

Requests for the wallet to sign and broadcast a batch of calls to the network.

[Read more](https://eips.ethereum.org/EIPS/eip-5792#wallet_sendcalls)

## Usage

:::code-group
```ts twoslash [example.ts]
import { parseEther } from 'viem'
import { account, walletClient } from './config'
 
const { id } = await walletClient.sendCalls({ // [!code focus:99]
  account,
  calls: [
    {
      to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
      value: parseEther('1')
    },
    {
      data: '0xdeadbeef',
      to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
    },
  ],
})
```

```ts twoslash [config.ts] filename="config.ts"
import 'viem/window'
// ---cut---
import { createWalletClient, custom } from 'viem'
import { mainnet } from 'viem/chains'

export const walletClient = createWalletClient({
  chain: mainnet,
  transport: custom(window.ethereum!),
})

export const [account] = await walletClient.getAddresses()
```
:::

Notes:

* `account` and `chain` are top level properties as all calls should be sent by the same account and chain.
* Properties of `calls` items 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_sendCalls` on EIP-5792.](https://eips.ethereum.org/EIPS/eip-5792#wallet_sendcalls)

### 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`).

[Learn more](/docs/clients/wallet#account).

:::code-group
```ts twoslash [example.ts]
import { walletClient } from './config'
 
const { id } = await walletClient.sendCalls({ // [!code focus:99]
  calls: [
    {
      to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
      value: parseEther('1')
    },
    {
      data: '0xdeadbeef',
      to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
    },
  ],
})
```

```ts [config.ts] filename="config.ts"
import 'viem/window'
import { createWalletClient, custom } from 'viem'

// Retrieve Account from an EIP-1193 Provider.
const [account] = await window.ethereum!.request({ 
  method: 'eth_requestAccounts' 
})

export const walletClient = createWalletClient({
  account,
  transport: custom(window.ethereum!)
})
```
:::

### Contract Calls

The `calls` property also accepts **Contract Calls**, and can be used via the `abi`, `functionName`, and `args` properties.

:::code-group
```ts twoslash [example.ts]
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 { id } = await walletClient.sendCalls({ // [!code focus:99]
  calls: [
    {
      to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
      value: parseEther('1')
    },
    {
      to: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
      abi,
      functionName: 'approve',
      args: [
        '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', 
        100n
      ],
    },
    {
      to: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
      abi,
      functionName: 'transferFrom',
      args: [
        '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
        '0x0000000000000000000000000000000000000000',
        100n
      ],
    },
  ],
})
```

```ts twoslash [abi.ts] filename="abi.ts"
export const wagmiAbi = [
  // ...
  {
    inputs: [],
    name: "mint",
    outputs: [],
    stateMutability: "nonpayable",
    type: "function",
  },
  // ...
] as const;
```

```ts [config.ts] filename="config.ts"
import 'viem/window'
import { createWalletClient, custom } from 'viem'

// Retrieve Account from an EIP-1193 Provider.
const [account] = await window.ethereum!.request({ 
  method: 'eth_requestAccounts' 
})

export const walletClient = createWalletClient({
  account,
  transport: custom(window.ethereum!)
})
```
:::

### 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`.

:::warning
When using `experimental_fallback` with a wallet that does not support EIP-5792,
Viem will return a custom bundle identifier (`id`). While this identifier works with Viem's [`getCallsStatus`
Action](/docs/actions/wallet/getCallsStatus), it cannot be used with the native `wallet_getCallsStatus` RPC method.
:::

:::code-group
```ts twoslash [example.ts]
import { parseEther } from 'viem'
import { account, walletClient } from './config'
 
const { id } = await walletClient.sendCalls({
  account,
  calls: [
    {
      to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
      value: parseEther('1')
    },
    {
      data: '0xdeadbeef',
      to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
    },
  ],
  experimental_fallback: true, // [!code focus]
})
```

```ts twoslash [config.ts] filename="config.ts"
import 'viem/window'
// ---cut---
import { createWalletClient, custom } from 'viem'
import { mainnet } from 'viem/chains'

export const walletClient = createWalletClient({
  chain: mainnet,
  transport: custom(window.ethereum!),
})

export const [account] = await walletClient.getAddresses()
```
:::

## Returns

`{ id: string, capabilities?: WalletCapabilities }`

The identifier can be any arbitrary string. The only requirement is that for a given session, consumers should be able to call `getCallsStatus` with this identifier to retrieve a batch call status and call receipts.

## 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](/docs/clients/wallet#json-rpc-accounts).

```ts twoslash
import { walletClient } from './config'

const { id } = await walletClient.sendCalls({
  account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', // [!code focus]
  calls: [
    {
      to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
      value: parseEther('1')
    },
    {
      data: '0xdeadbeef',
      to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
    },
  ],
})
```

### chain

* **Type:** [`Chain`](/docs/glossary/types#chain)
* **Default:** `walletClient.chain`

The target chain to broadcast the calls.

```ts twoslash
import { mainnet } from 'viem/chains'
import { walletClient } from './config'

const { id } = await walletClient.sendCalls({
  chain: mainnet, // [!code focus]
  calls: [
    {
      to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
      value: parseEther('1')
    },
    {
      data: '0xdeadbeef',
      to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
    },
  ],
})
```

### calls

* **Type:** `Call[]`

An array of calls to be signed and broadcasted.

```ts twoslash
import { mainnet } from 'viem/chains'
import { walletClient } from './config'

const { id } = await walletClient.sendCalls({
  chain: mainnet,
  calls: [ // [!code focus]
    { // [!code focus]
      to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', // [!code focus]
      value: parseEther('1') // [!code focus]
    }, // [!code focus]
    { // [!code focus]
      data: '0xdeadbeef', // [!code focus]
      to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', // [!code focus]
    }, // [!code focus]
  ], // [!code focus]
})
```

#### calls.data

* **Type:** `Hex`

Calldata to broadcast (typically a contract function selector with encoded arguments, or contract deployment bytecode).

```ts twoslash
import { mainnet } from 'viem/chains'
import { walletClient } from './config'

const { id } = await walletClient.sendCalls({
  chain: mainnet,
  calls: [ 
    { 
      to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', 
      value: parseEther('1') 
    }, 
    { 
      data: '0xdeadbeef', // [!code focus]
      to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
    },
  ],
})
```

When calling functions on contracts, it may be more convenient to pass in a [Contract Call](#contract-calls), providing the `abi`, `functionName`, and `args` properties which will then be encoded into the appropriate `calls.data`.

```ts twoslash
import { parseAbi } from 'viem'
import { walletClient } from './config'

const abi = parseAbi([
  'function approve(address, uint256) returns (bool)',
])
 
const { id } = await walletClient.sendCalls({
  calls: [
    {
      to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
      value: parseEther('1')
    },
    {
      to: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
      abi, // [!code focus:6]
      functionName: 'approve',
      args: [
        '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', 
        100n
      ],
    }
  ],
})
```

#### calls.to

* **Type:** `Address`

Recipient address of the call.

```ts twoslash
import { mainnet } from 'viem/chains'
import { walletClient } from './config'

const { id } = await walletClient.sendCalls({
  chain: mainnet,
  calls: [ 
    { 
      to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', // [!code focus]
      value: parseEther('1') 
    }, 
    { 
      data: '0xdeadbeef', 
      to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', // [!code focus]
    },
  ],
})
```

#### calls.value

* **Type:** `Address`

Value to send with the call.

```ts twoslash
import { mainnet } from 'viem/chains'
import { walletClient } from './config'

const { id } = await walletClient.sendCalls({
  chain: mainnet,
  calls: [ 
    { 
      to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', 
      value: parseEther('1') // [!code focus]
    }, 
    { 
      data: '0xdeadbeef', 
      to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
    },
  ],
})
```

#### calls.dataSuffix

* **Type:** Hex

Data to append to the end of the calldata. Useful for adding a "domain" tag.

```ts twoslash [example.ts]
import { parseAbi } from 'viem'
import { walletClient } from './config'

const abi = parseAbi([
  'function approve(address, uint256) returns (bool)',
])
 // ---cut---
const { id } = await walletClient.sendCalls({
  calls: [
    {
      to: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
      abi,
      functionName: 'approve',
      args: [
        '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', 
        100n
      ],
      dataSuffix: '0xdeadbeef' // [!code focus]
    }
  ],
})
```

### capabilities

* **Type:** `WalletCapabilities`

Capability metadata for the calls (e.g. specifying a paymaster).

```ts twoslash
import { walletClient } from './config'

const { id } = await walletClient.sendCalls({
  calls: [
    {
      to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
      value: parseEther('1')
    },
    {
      data: '0xdeadbeef',
      to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
    },
  ],
  capabilities: { // [!code focus]
    paymasterService: { // [!code focus]
      url: 'https://...' // [!code focus]
    } // [!code focus]
  } // [!code focus]
})
```

### forceAtomic

* **Type:** `boolean`
* **Default:** `false`

Force the calls to be executed atomically. [See more](https://eips.ethereum.org/EIPS/eip-5792#call-execution-atomicity)

```ts twoslash
import { walletClient } from './config'

const { id } = await walletClient.sendCalls({
  calls: [
    {
      to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
      value: parseEther('1')
    },
    {
      data: '0xdeadbeef',
      to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
    },
  ],
  forceAtomic: true, // [!code focus]
})
```

### id

* **Type:** `string`

Attribute the call batch with an identifier.

```ts twoslash
import { walletClient } from './config'

const { id } = await walletClient.sendCalls({
  calls: [
    {
      to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
      value: parseEther('1')
    },
    {
      data: '0xdeadbeef',
      to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
    },
  ],
  id: '<my-batch-id>', // [!code focus]
})
```
