> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://v3.viem.sh/api/mcp` to find what you need.

# Overriding Actions

## Overview

Actions attached through [`.extend()`](/docs/clients/create#extending-a-client) can intercept nested
calls that core Actions make.

For example, [`Actions.contract.write`](/docs/actions/wallet/contract/write) uses the
[Client](/docs/clients)
[`transaction.send`](/docs/actions/wallet/transaction/send) action when attached. Otherwise, it uses
[`Actions.transaction.send`](/docs/actions/wallet/transaction/send).

This resolution is performed by [`Actions.getAction`](#actionsgetaction), which is also available for library authors composing their own actions.

```ts twoslash
import { Account, Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({
  account: Account.fromPrivateKey('0x…'),
  chain: mainnet,
  transport: http(),
}).extend((client) => ({
  transaction: {
    send: (options: Actions.transaction.send.Options<typeof mainnet>) =>
      Actions.transaction.send(client, { ...options, nonce: 69 }),
  },
}))

// Dispatches its transaction through the `transaction.send` override.
const hash = await Actions.contract.write(client, {
  abi: Abi.from(['function mint()']),
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  functionName: 'mint',
})
```

Core Actions consult overrides at
[`transaction.send`](/docs/actions/wallet/transaction/send),
[`transaction.sendSync`](/docs/actions/wallet/transaction/send),
[`transaction.prepare`](/docs/actions/public/transaction/prepare),
[`transaction.estimateGas`](/docs/actions/public/transaction/estimateGas), and
[`call`](/docs/actions/public/call).

:::note
Actions attached by `.extend()` capture the Client at that point. Earlier extensions cannot access
overrides attached by a later extension.

Attach overrides before decorators.
:::

## Recipes

These recipes assume you have [set up a Client](/docs/clients/create).

### Intercept Nested Sends

Attach a `transaction.send` action to route every dispatched transaction through custom logic,
including transactions sent internally by
[`Actions.contract.write`](/docs/actions/wallet/contract/write),
[`Actions.contract.deploy`](/docs/actions/wallet/contract/deploy), and token actions.

```ts twoslash
import { Account, Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'

const client = Client.create({
  account: Account.fromPrivateKey('0x…'),
  chain: mainnet,
  transport: http(),
}).extend((client) => ({ // [!code focus]
  transaction: { // [!code focus]
    send: (options: Actions.transaction.send.Options<typeof mainnet>) => { // [!code focus]
      // Custom dispatch logic, such as routing through a relayer. // [!code focus]
      return Actions.transaction.send(client, options) // [!code focus]
    }, // [!code focus]
  }, // [!code focus]
})) // [!code focus]
```

### Resolve Overrides in Custom Actions

Library actions can resolve a Client's overrides the same way core Actions do. `getAction` returns the attached action when present, or the standalone action bound to the Client.

```ts twoslash
import { Actions, type Client } from 'viem'
import type { Hex } from 'viem/utils'

export async function sendAndAudit(
  client: Client.Client,
  options: Actions.transaction.send.Options,
): Promise<Hex.Hex> {
  const send = Actions.getAction( // [!code focus]
    client, // [!code focus]
    Actions.transaction.send, // [!code focus]
    'transaction.send', // [!code focus]
  ) // [!code focus]
  const hash = await send(options)
  console.log('sent', hash)
  return hash
}
```

## `Actions.getAction`

Retrieves the action attached to the Client at `path`, falling back to the standalone action `fn` bound to the Client.

### Usage

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'

const client = Client.create({ chain: mainnet, transport: http() })

const send = Actions.getAction(
  client,
  Actions.transaction.send,
  'transaction.send',
)
```

### Parameters

#### client

* **Type:** `Client.Client`

Client to resolve the action against.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
// ---cut---
const client = Client.create({ chain: mainnet, transport: http() })

const send = Actions.getAction(
  client, // [!code focus]
  Actions.transaction.send,
  'transaction.send',
)
```

#### fn

* **Type:** `(client: Client.Client, options: options) => returnType`

Standalone action to fall back to when no action is attached at `path`.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
const client = Client.create({ chain: mainnet, transport: http() })
// ---cut---
const send = Actions.getAction(
  client,
  Actions.transaction.send, // [!code focus]
  'transaction.send',
)
```

#### path

* **Type:** `string`

The action's dot-notation path on the Client, such as `'transaction.send'`.

Pass the path explicitly because Actions use nested Client namespaces, and minifiers can change
function names.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
const client = Client.create({ chain: mainnet, transport: http() })
// ---cut---
const send = Actions.getAction(
  client,
  Actions.transaction.send,
  'transaction.send', // [!code focus]
)
```

### Return Value

`(options: options) => returnType`

The Client-attached action at `path`, or `fn` bound to the Client.
