***

## description: Restrict which accounts can send or receive a TIP-20 token with a transfer policy.

# Configure Transfer Policies

## Overview

A transfer policy gates who may send or receive a TIP-20 token using a TIP-403 policy. You create a
whitelist or blacklist policy, attach it to your token, and update its members as your compliance
needs change. Transfers that violate the policy revert, and blocked funds can be recovered by an
authorized account.

[See the Policy Registry specification](https://docs.tempo.xyz/protocol/tip403/overview)

## Recipes

These recipes assume you have [set up a Tempo client](/tempo).

### Create a Policy

Create a TIP-403 policy with [`policy.createSync`](/tempo/actions/policy.create). A `whitelist` only
allows the listed addresses, while a `blacklist` allows everyone except the listed addresses.

:::code-group

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

const { policyId } = await client.policy.createSync({
  admin: client.account.address,
  addresses: ['0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb'],
  type: 'whitelist',
})
```

```ts twoslash [viem.config.ts] filename="viem.config.ts"
// [!include ~/snippets/tempo/viem.config.ts:setup]
```

:::

### Attach a Policy to a Token

Set the active transfer policy for your token with
[`token.changeTransferPolicySync`](/tempo/actions/token.changeTransferPolicy). The caller must hold
the role that administers transfer policy on the token.

:::code-group

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

const { receipt } = await client.token.changeTransferPolicySync({
  policyId: 1n,
  token: '0x20c0000000000000000000000000000000000000',
})
```

```ts twoslash [viem.config.ts] filename="viem.config.ts"
// [!include ~/snippets/tempo/viem.config.ts:setup]
```

:::

### Update Policy Members

Add or remove addresses with [`policy.modifyWhitelistSync`](/tempo/actions/policy.modifyWhitelist)
for whitelists, or [`policy.modifyBlacklistSync`](/tempo/actions/policy.modifyBlacklist) for
blacklists. Changes apply to every token referencing the policy.

:::code-group

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

const { receipt } = await client.policy.modifyWhitelistSync({
  address: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb',
  allowed: true,
  policyId: 1n,
})
```

```ts twoslash [viem.config.ts] filename="viem.config.ts"
// [!include ~/snippets/tempo/viem.config.ts:setup]
```

:::

### Check Authorization

Read a policy's metadata with [`policy.getData`](/tempo/actions/policy.getData), and check whether a
specific account is allowed by it with [`policy.isAuthorized`](/tempo/actions/policy.isAuthorized).

:::code-group

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

const isAuthorized = await client.policy.isAuthorized({
  policyId: 1n,
  user: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb',
})
```

```ts twoslash [viem.config.ts] filename="viem.config.ts"
// [!include ~/snippets/tempo/viem.config.ts:setup]
```

:::

## Best Practices

### Reuse a Policy Across Tokens

A single TIP-403 policy can back many tokens. Maintain one shared allowlist and reference it from each
token so compliance rules stay consistent and are updated in one place.

### Set a Policy Admin You Control

The policy admin is the only account that can change its members. Set it to a secured account or
multisig so you can keep the policy current without exposing a single hot key.

### Stage Policy Changes Before Attaching

Create and populate a policy first, verify membership with `policy.isAuthorized`, then attach it with
`token.changeTransferPolicy`. This avoids blocking legitimate transfers while the policy is still
being configured.

## See More

<Cards>
  <Card icon="lucide:arrow-left-right" title="Transfer Tokens" description="Move balances once your transfer policy is set." to="/tempo/guides/transfer-tokens" />

  <Card icon="lucide:shield-check" title="Receive Policies" description="Control which senders and tokens your account accepts." to="/tempo/guides/receive-policies" />

  <Card icon="lucide:square-function" title="token.changeTransferPolicy" description="Set the active transfer policy for a token." to="/tempo/actions/token.changeTransferPolicy" />

  <Card icon="lucide:book-open" title="Tempo Docs: Policy Registry" description="How TIP-403 policies gate transfers." to="https://docs.tempo.xyz/protocol/tip403/overview" />
</Cards>
