<!-- tempo-docs-context -->
> Source: [/docs/guide/issuance/use-for-fees](https://tempo.xyz/developers/docs/guide/issuance/use-for-fees.md)
> Section: [Tempo EVM](https://tempo.xyz/developers/docs/development.md). Build on Tempo EVM: wallets and keys, transactions and fees, TIP-20 Tokens, contracts, exchange, network details, nodes, protocol specifications, and changelog.
> [Documentation index](https://tempo.xyz/developers/llms.txt) · [Docs skill](https://tempo.xyz/developers/SKILL.md)

> Tempo MCP: Use `search`, `find_pages`, `read_page`, and `code` at `https://mcp.tempo.xyz` for Tempo and related documentation.
> If an indexed page is missing or reflects an older site, read this site’s [documentation index](https://tempo.xyz/developers/llms.txt) and Markdown pages directly.

# Use your stablecoin for fees

Provide fee-pool liquidity so users can pay transaction fees in your USD-denominated TIP-20 token. The examples use Moderato testnet; see [transaction fees](https://tempo.xyz/developers/docs/protocol/fees) for eligibility and conversion rules.

## Fee-token stablecoin demo

**Interactive demo: Use Your Stablecoin for Fees**

1. Connect
2. Add funds
3. Create or load token
4. Grant token roles
5. Mint token
6. Mint fee AMM liquidity
7. Pay with issued token

Source: [tempoxyz/examples/tree/main/examples/issuance](https://github.com/tempoxyz/examples/tree/main/examples/issuance)

## Fee-token stablecoin setup steps

::::steps
### Create your fee-token stablecoin

First, create and mint your stablecoin by following the [Create a Stablecoin](https://tempo.xyz/developers/docs/guide/issuance/create-a-stablecoin) guide.

### Add Fee AMM liquidity

Before users can pay fees with your token, you need to provide liquidity in the Fee AMM between your token and a liquid quote token, or directly against validator payout tokens where you want explicit direct-route coverage.

To determine which validator tokens are needed, sample recent blocks and query `validatorTokens(block.miner)` on the FeeManager contract. An unset preference resolves to pathUSD. Preferences can change; do not assume all validators accept the same payout token.

Add liquidity to your token's fee pool with the [backend Viem client](https://tempo.xyz/developers/docs/guide/payments/send-a-payment#send-from-your-backend). Set `TEMPO_TOKEN` to the token you issued on Moderato:

:::code-group
```ts [add-fee-liquidity.ts]
import { getAddress, parseUnits } from 'viem'
import { client } from './viem.config'

const token = process.env.TEMPO_TOKEN
if (!token) throw new Error('Set TEMPO_TOKEN to your issued token address')
const validatorToken = '0x20c0000000000000000000000000000000000001'

const { receipt } = await client.amm.mintSync({
  feeToken: validatorToken,
  to: client.account.address,
  userTokenAddress: getAddress(token),
  validatorTokenAddress: validatorToken,
  validatorTokenAmount: parseUnits('100', 6),
})

console.log(receipt.transactionHash)
```

```solidity [Solidity]
IFeeAMM feeAmm = IFeeAMM(TIP_FEE_AMM_ADDRESS);
address yourToken = 0x20c0000000000000000000000000000000000004; // Your issued token
address validatorToken = 0x20c0000000000000000000000000000000000001; // AlphaUSD

// Add 100 AlphaUSD of liquidity to the fee pool
feeAmm.mint(
  yourToken,
  validatorToken,
  100_000_000, // 100 tokens (6 decimals)
  address(this)
);
```
:::

You can also check your token's fee pool liquidity at any time:

:::code-group
```ts [check-fee-liquidity.ts]
import { getAddress } from 'viem'
import { client } from './viem.config'

const token = process.env.TEMPO_TOKEN
if (!token) throw new Error('Set TEMPO_TOKEN to your issued token address')

const pool = await client.amm.getPool({
  userToken: getAddress(token),
  validatorToken: '0x20c0000000000000000000000000000000000001',
})

console.log('Has validator-token liquidity:', pool.reserveValidatorToken > 0n)
```

```solidity [Solidity]
IFeeAMM feeAmm = IFeeAMM(TIP_FEE_AMM_ADDRESS);
address yourToken = 0x20c0000000000000000000000000000000000004; // Your issued token
address validatorToken = 0x20c0000000000000000000000000000000000001; // AlphaUSD

// Get pool reserves
IFeeAMM.Pool memory pool = feeAmm.getPool(yourToken, validatorToken);

// Check if there's sufficient liquidity
require(pool.reserveValidatorToken > 0, "No liquidity available for fee conversion");
```
:::

If the pool has no liquidity (`reserveValidatorToken == 0`), you'll need to add liquidity to the fee pool before users can pay fees with your token. See [Manage fee liquidity](https://tempo.xyz/developers/docs/guide/stablecoin-dex/managing-fee-liquidity) for adding and rebalancing reserves.

### Send a payment using your stablecoin as the fee token

Your users can send payments using your issued stablecoin as the fee token:

:::code-group
```tsx twoslash [PayWithIssuedToken.tsx]
import React from 'react'
import { Hooks } from 'wagmi/tempo'
import { useConnection } from 'wagmi'
import { parseUnits, toHex, isAddress } from 'viem'

// @noErrors
export function PayWithIssuedToken() {
  const { address } = useConnection()
  const [recipient, setRecipient] = React.useState<string>('')
  const [memo, setMemo] = React.useState<string>('')

  const feeToken = '0x...' // Your issued token address
  const paymentToken = '0x20c0000000000000000000000000000000000001' // AlphaUSD

  const { data: paymentBalance, refetch: paymentBalanceRefetch } = // [!code hl]
    Hooks.token.useGetBalance({ // [!code hl]
      account: address, // [!code hl]
      token: paymentToken, // [!code hl]
    }) // [!code hl]

  const { data: feeTokenBalance, refetch: feeTokenBalanceRefetch } = // [!code hl]
    Hooks.token.useGetBalance({ // [!code hl]
      account: address, // [!code hl]
      token: feeToken, // [!code hl]
    }) // [!code hl]

  const sendPayment = Hooks.token.useTransferSync({ // [!code hl]
    mutation: { // [!code hl]
      onSettled() { // [!code hl]
        paymentBalanceRefetch() // [!code hl]
        feeTokenBalanceRefetch() // [!code hl]
      }, // [!code hl]
    }, // [!code hl]
  }) // [!code hl]

  const isValidRecipient = recipient && isAddress(recipient)

  const handleTransfer = () => { // [!code hl]
    if (!isValidRecipient) return // [!code hl]
    sendPayment.mutate({ // [!code hl]
      amount: parseUnits('100', 6), // [!code hl]
      to: recipient as `0x${string}`, // [!code hl]
      token: paymentToken, // [!code hl]
      memo: memo ? toHex(memo, { size: 32 }) : undefined, // [!code hl]
      feeToken, // Pay fees with your issued token // [!code hl]
    }) // [!code hl]
  } // [!code hl]

  return (
    <>
      <div>
        <label>Recipient address</label>
        <input
          type="text"
          value={recipient}
          onChange={(e) => setRecipient(e.target.value)}
          placeholder="0x..."
        />
      </div>
      <div>
        <label>Memo (optional)</label>
        <input
          type="text"
          value={memo}
          onChange={(e) => setMemo(e.target.value)}
          placeholder="INV-12345"
        />
      </div>
      <button // [!code hl]
        disabled={!address || !isValidRecipient || sendPayment.isPending} // [!code hl]
        onClick={handleTransfer} // [!code hl]
        type="button" // [!code hl]
      > {/* [!code hl] */}
      {sendPayment.isPending ? 'Sending...' : 'Send'} {/* [!code hl] */}
      </button> {/* [!code hl] */}
    </>
  )
}
```

```tsx twoslash [config.ts] filename="config.ts"
// @noErrors
import { tempoModerato } from 'viem/chains'
import { createConfig, http } from 'wagmi'
import { tempoWallet } from 'wagmi/connectors'

export const config = createConfig({
  connectors: [tempoWallet()],
  chains: [tempoModerato],
  multiInjectedProviderDiscovery: false,
  transports: {
    [tempoModerato.id]: http(),
  },
})
```
:::

Users can set your stablecoin as their default fee token at the account level, or specify it for individual transactions. Learn more about [how users pay fees in different stablecoins](https://tempo.xyz/developers/docs/guide/payments/pay-fees-in-any-stablecoin).
::::

## How stablecoin fee payments work

Users can [choose a fee token](https://tempo.xyz/developers/docs/guide/payments/pay-fees-in-any-stablecoin) for a transaction or set an account default. The Fee AMM converts the fee when the selected token differs from the validator's preferred token. This conversion does not change the token or amount sent to the payment recipient.

<span id="benefits-of-stablecoin-fee-tokens" />

See the [fee-token selection rules](https://tempo.xyz/developers/docs/protocol/fees/spec-fee#fee-token-preferences) for the full preference order.

## Stablecoin fee-token best practices

### Monitor pool liquidity

Regularly check your token's fee pool reserves to ensure users can consistently pay fees with your stablecoin. Low liquidity can prevent transactions from being processed.

### Maintain adequate reserves

Keep sufficient validator token reserves in your fee pool to handle expected transaction volume. Consider your user base size and typical transaction frequency when determining reserve levels.

As fees accrue in your token, the pool will run low on validator tokens and need to be rebalanced. Use [`rebalanceSwap`](https://tempo.xyz/developers/docs/guide/stablecoin-dex/managing-fee-liquidity#rebalance-pools) to replenish validator token reserves when they become depleted.

### Test before launch

Before promoting fee payments with your token, thoroughly test the flow on testnet:

1. Add liquidity to the fee pool
2. Verify users can set your token as their fee preference
3. Execute test transactions with various gas costs
4. Monitor that fee conversions work correctly

## Next steps for stablecoin fee tokens

* [Manage Your Stablecoin](https://tempo.xyz/developers/docs/guide/issuance/manage-stablecoin) — Manage roles, supply caps, and transfer policies
* [Managing Fee Liquidity](https://tempo.xyz/developers/docs/guide/stablecoin-dex/managing-fee-liquidity) — Add and remove liquidity to enable fee conversions
* [Fee Tokens](https://tempo.xyz/developers/docs/protocol/fees/spec-fee) — Complete fee token specification
