> **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.

# Transfer Tokens \[token.transfer]

Transfers an ERC-20 token, waits for the transaction receipt, and returns the decoded `Transfer`
event. When `from` is provided, the action uses `transferFrom`.

## Usage

Use `transferSync` to transfer tokens and wait for the decoded `Transfer` event.

:::code-group
```ts twoslash [example.ts]
import { client } from './viem.config'

const { from, to, value, receipt } = await client.token.transferSync({
  amount: 500000000n,
  to: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
  token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
})
// @log: { from: '0x…', to: '0x7099…', value: 500000000n, decimals: 6, formatted: '500', receipt: { … } }
```

```ts twoslash [viem.config.ts] filename="viem.config.ts"
import { Account, Client, http, walletActions } from 'viem'
import { mainnet } from 'viem/chains'
import { usdc } from 'viem/tokens'

export const client = Client.create({
  account: Account.fromPrivateKey('0x…'),
  chain: mainnet,
  tokens: [usdc],
  transport: http(),
}).extend(walletActions())
```
:::

### Asynchronous Usage

Use `transfer` when the transaction hash is needed immediately and receipt tracking happens
elsewhere.

:::code-group
```ts twoslash [example.ts]
import { client } from './viem.config'

const hash = await client.token.transfer({
  amount: 500000000n,
  to: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
  token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
})
// @log: "0x4ca7ee652d57678f26e887c19671f76c1aff..."
```

```ts twoslash [viem.config.ts] filename="viem.config.ts"
import { Account, Client, http, walletActions } from 'viem'
import { mainnet } from 'viem/chains'
import { usdc } from 'viem/tokens'

export const client = Client.create({
  account: Account.fromPrivateKey('0x…'),
  chain: mainnet,
  tokens: [usdc],
  transport: http(),
}).extend(walletActions())
```
:::

### Standalone Action

Call `Actions.token.transferSync` directly by passing the Client as the first argument. Use
`Actions.token.transfer` for the asynchronous variant.

:::code-group
```ts twoslash [example.ts]
import { Actions } from 'viem'
import { client } from './viem.config'

const { from, to, value, receipt } = await Actions.token.transferSync(client, {
  amount: 500000000n,
  to: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
  token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
})
// @log: { from: '0x…', to: '0x7099…', value: 500000000n, decimals: 6, formatted: '500', receipt: { … } }
```

```ts twoslash [viem.config.ts] filename="viem.config.ts"
import { Account, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { usdc } from 'viem/tokens'

export const client = Client.create({
  account: Account.fromPrivateKey('0x…'),
  chain: mainnet,
  tokens: [usdc],
  transport: http(),
})
```
:::

## Recipes

### Transfer a Formatted Amount

Declare the token on the Client to select it by symbol. Viem uses the declared decimals to convert
the formatted amount to base units.

:::code-group
```ts twoslash [example.ts]
import { client } from './viem.config'

const hash = await client.token.transfer({
  amount: { formatted: '500' }, // [!code focus]
  to: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
  token: 'usdc', // [!code focus]
})
// @log: "0x4ca7ee652d57678f26e887c19671f76c1aff..."
```

```ts twoslash [viem.config.ts] filename="viem.config.ts"
import { Account, Client, http, walletActions } from 'viem'
import { mainnet } from 'viem/chains'
import { usdc } from 'viem/tokens'

export const client = Client.create({
  account: Account.fromPrivateKey('0x…'),
  chain: mainnet,
  tokens: [usdc],
  transport: http(),
}).extend(walletActions())
```
:::

### Transfer from Another Account

Pass `from` when the caller has an allowance to transfer tokens for another account. Viem calls
the token's `transferFrom` function.

:::code-group
```ts twoslash [example.ts]
import { client } from './viem.config'

const hash = await client.token.transfer({
  amount: { formatted: '500' },
  from: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', // [!code focus]
  to: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
  token: 'usdc',
})
// @log: "0x4ca7ee652d57678f26e887c19671f76c1aff..."
```

```ts twoslash [viem.config.ts] filename="viem.config.ts"
import { Account, Client, http, walletActions } from 'viem'
import { mainnet } from 'viem/chains'
import { usdc } from 'viem/tokens'

export const client = Client.create({
  account: Account.fromPrivateKey('0x…'),
  chain: mainnet,
  tokens: [usdc],
  transport: http(),
}).extend(walletActions())
```
:::

## Return Value

### Synchronous

`{ from, to, value, decimals?, formatted?, receipt }`

The decoded `Transfer` event args, transaction receipt, and formatted amount when the token's
decimals are known.

### Asynchronous

`Hex`

The transaction hash.

## Parameters

### account

* **Type:** `Account | Address`
* **Default:** `client.account`

The account that sends the transaction.

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

const client = Client.create({ chain: mainnet, transport: http() })
// ---cut---
const hash = await Actions.token.transfer(client, {
  account: Account.fromPrivateKey('0x…'), // [!code focus]
  amount: 500000000n,
  to: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
  token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
})
```

### amount

* **Type:** `bigint | { decimals?: number; formatted: string }`

The amount to transfer, in base units (`bigint`) or as a formatted helper. When `formatted` is given, `decimals` is taken from the helper, the declared token, or fetched.

```ts twoslash
// @noErrors
import { Client, http, walletActions } from 'viem'
import { mainnet } from 'viem/chains'
import { usdc } from 'viem/tokens'

const client = Client.create({
  chain: mainnet,
  tokens: [usdc],
  transport: http(),
}).extend(walletActions())
// ---cut---
const hash = await client.token.transfer({
  amount: { formatted: '500' }, // [!code focus]
  to: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
  token: 'usdc',
})
```

#### decimals

* **Type:** `number`

Token decimals used to parse a formatted `amount`. When omitted, decimals are taken from a declared token, or fetched from the contract.

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

const client = Client.create({ chain: mainnet, transport: http() })
// ---cut---
const hash = await Actions.token.transfer(client, {
  amount: { decimals: 6, formatted: '500' }, // [!code focus]
  to: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
  token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
})
```

### chain

* **Type:** `Chain | null`
* **Default:** `client.chain`

The target chain. Pass `null` to skip the current-chain assertion.

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

const client = Client.create({ chain: mainnet, transport: http() })
// ---cut---
const hash = await Actions.token.transfer(client, {
  amount: 500000000n,
  chain: mainnet, // [!code focus]
  to: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
  token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
})
```

### from

* **Type:** `Address`

The account to transfer tokens from, using an allowance via `transferFrom`. When omitted, tokens are transferred from the caller.

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

const client = Client.create({ chain: mainnet, transport: http() })
// ---cut---
const hash = await Actions.token.transfer(client, {
  amount: 500000000n,
  from: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', // [!code focus]
  to: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
  token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
})
```

### gas

* **Type:** `bigint | Hex`

The gas limit for the transaction.

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

const client = Client.create({ chain: mainnet, transport: http() })
// ---cut---
const hash = await Actions.token.transfer(client, {
  amount: 500000000n,
  gas: 50_000n, // [!code focus]
  to: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
  token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
})
```

### maxFeePerGas

* **Type:** `bigint | number | Hex`

The maximum total fee per gas.

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

const client = Client.create({ chain: mainnet, transport: http() })
// ---cut---
const hash = await Actions.token.transfer(client, {
  amount: 500000000n,
  maxFeePerGas: 30_000_000_000n, // [!code focus]
  to: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
  token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
})
```

### maxPriorityFeePerGas

* **Type:** `bigint | number | Hex`

The maximum priority fee per gas.

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

const client = Client.create({ chain: mainnet, transport: http() })
// ---cut---
const hash = await Actions.token.transfer(client, {
  amount: 500000000n,
  maxPriorityFeePerGas: 1_000_000_000n, // [!code focus]
  to: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
  token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
})
```

### nonce

* **Type:** `bigint | Hex`

The transaction nonce.

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

const client = Client.create({ chain: mainnet, transport: http() })
// ---cut---
const hash = await Actions.token.transfer(client, {
  amount: 500000000n,
  nonce: 12n, // [!code focus]
  to: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
  token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
})
```

### throwOnReceiptRevert

* **Type:** `boolean`
* **Default:** `true`

Whether `transferSync` throws if the transaction receipt indicates a revert.

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

const client = Client.create({ chain: mainnet, transport: http() })
// ---cut---
const result = await Actions.token.transferSync(client, {
  amount: 500000000n,
  throwOnReceiptRevert: false, // [!code focus]
  to: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
  token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
})
```

### to

* **Type:** `Address`

The recipient of the tokens.

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

const client = Client.create({ chain: mainnet, transport: http() })
// ---cut---
const hash = await Actions.token.transfer(client, {
  amount: 500000000n,
  to: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8', // [!code focus]
  token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
})
```

### token

* **Type:** `Address | string`

The token to transfer: a contract `address`, or a symbol declared on the client's [`tokens`](/docs/clients/create) array.

```ts twoslash
// @noErrors
import { Client, http, walletActions } from 'viem'
import { mainnet } from 'viem/chains'
import { usdc } from 'viem/tokens'

const client = Client.create({
  chain: mainnet,
  tokens: [usdc],
  transport: http(),
}).extend(walletActions())
// ---cut---
const hash = await client.token.transfer({
  amount: 500000000n,
  to: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
  token: 'usdc', // [!code focus]
})
```

## Errors

| Error | Description |
| --- | --- |
| `Account.NotFoundError` | No `account` was provided and the client has no account. |
| `ContractError.ContractFunctionExecutionError` | The `transfer`/`transferFrom` call could not be executed. |
