# Pay Fees in a Stablecoin

## Overview

On Tempo, you can pay transaction fees in any USD-denominated TIP-20 token using the
`feeToken` property. Tempo's Fee AMM automatically swaps your fee token to the validator's
preferred token under the hood, so your users only ever need to hold the stablecoins they
already use.

[See the Fees specification](https://docs.tempo.xyz/protocol/fees)

## Recipes

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

### Pay Fees with a Stablecoin

Pass a `feeToken` to [`sendTransactionSync`](/docs/actions/wallet/sendTransactionSync) (or any
transaction-sending action) to pay fees in that token.

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

const alphaUsd = '0x20c0000000000000000000000000000000000001'

const receipt = await client.sendTransactionSync({
  data: '0xdeadbeef',
  feeToken: alphaUsd, // [!code focus]
  to: '0xcafebabecafebabecafebabecafebabecafebabe',
})
```

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

### Validate a Fee Token

Before submitting a transaction (or saving a fee preference), you can check that a token is
usable as a fee token with [`fee.validateToken`](/tempo/actions/fee.validateToken).

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

const { address, id } = await client.fee.validateToken({
  token: '0x20c0000000000000000000000000000000000001',
})
```

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

### Set a Default Fee Token

Save an onchain default fee token for the account with
[`fee.setUserToken`](/tempo/actions/fee.setUserToken). Once set, the network uses it for the
account's transactions without you passing `feeToken` each time.

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

const { receipt } = await client.fee.setUserTokenSync({
  token: '0x20c0000000000000000000000000000000000001',
})
```

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

### Read the Default Fee Token

Read the account's current preference with
[`fee.getUserToken`](/tempo/actions/fee.getUserToken). It returns `null` if no preference is
set.

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

const token = await client.fee.getUserToken()
```

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

## Best Practices

### Choose Where to Set the Default

There are two ways to avoid passing `feeToken` on every transaction:

* **Onchain preference**: [`fee.setUserToken`](/tempo/actions/fee.setUserToken) persists the
  default on the network for the account, so it applies across clients and sessions.
* **Client-level default**: pass a `feeToken` to `createClient` to apply it to every
  transaction sent from a specific client.

```ts twoslash
import { privateKeyToAccount } from 'viem/accounts'
import { createClient } from 'viem/tempo'

export const client = createClient({
  account: privateKeyToAccount('0x...'),
  feeToken: '0x20c0000000000000000000000000000000000001', // [!code focus]
  testnet: true,
})
```

### Handle Common Errors

Fee tokens must be unpaused, USD-denominated TIP-20 tokens. If validation or submission fails,
check the error:

* `FeeTokenNotTip20Error`: the token is not a registered TIP-20 token. TIP-20 addresses use the
  `0x20c0...` prefix.
* `FeeTokenNotUsdError`: the token is a TIP-20 token, but its currency is not `USD`.
* `FeeTokenPausedError`: the token is currently paused and cannot be used for fees.

If validation passes but submission fails, ensure the account holds enough of the fee token and
that the Fee AMM has liquidity for it.

## See More

<Cards>
  <Card icon="lucide:hand-coins" title="Sponsor User Fees" description="Cover gas fees on behalf of your users for a fully gasless experience." to="/tempo/guides/sponsor-fees" />

  <Card icon="lucide:arrow-left-right" title="Provide Fee AMM Liquidity" description="Add liquidity to the Fee AMM so stablecoin fee conversions can settle." to="/tempo/guides/stablecoin-exchange/fee-amm-liquidity" />

  <Card icon="lucide:square-function" title="fee.validateToken" description="Validate that a token can be used as a Tempo fee token." to="/tempo/actions/fee.validateToken" />

  <Card icon="lucide:book-open" title="Tempo Docs: Fees" description="The full Tempo fee system and Fee AMM specification." to="https://docs.tempo.xyz/protocol/fees" />
</Cards>
