> ## Documentation Index
> Fetch the complete documentation index at: https://www.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Tempo

> Add the Tempo chain extension, read Tempo state with a viem PublicClient, and send TIP-20 stablecoin transfers

[Tempo](https://tempo.xyz) is EVM compatible but has no native token: every transfer moves a TIP-20 stablecoin, and fees are paid in TIP-20 tokens too. Tempo therefore gets its own extension and its own network registry, separate from the EVM extensions on [Adding EVM Extensions](/docs/javascript/reference/evm/adding-evm-extensions).

## Installation

```bash theme={"system"}
npm install @dynamic-labs-sdk/evm
```

## Add the extension

`addTempoExtension` registers Tempo's network provider builder. Register it at module level next to your client, and enable Tempo in the [Dynamic dashboard](https://app.dynamic.xyz/dashboard/chains-and-networks).

```typescript theme={"system"}
import { createDynamicClient } from '@dynamic-labs-sdk/client';
import { addTempoExtension } from '@dynamic-labs-sdk/evm/tempo';

const dynamicClient = createDynamicClient({
  ...
});

addTempoExtension();
```

Tempo wallet accounts have `chain: 'TEMPO'`, so use `isTempoWalletAccount` rather than the EVM guard to pick them out of a user's accounts:

```typescript theme={"system"}
import { getWalletAccounts } from '@dynamic-labs-sdk/client';
import { isTempoWalletAccount } from '@dynamic-labs-sdk/evm/tempo';

const getTempoWalletAccounts = () => getWalletAccounts().filter(isTempoWalletAccount);
```

## Read chain state

`getTempoPublicClient` resolves the active Tempo network from the Tempo registry and returns a [viem PublicClient](https://viem.sh/docs/clients/public) pointed at it.

```typescript theme={"system"}
import { getTempoPublicClient } from '@dynamic-labs-sdk/evm/tempo';
import type { TempoWalletAccount } from '@dynamic-labs-sdk/evm/tempo';

const getTempoBlockNumber = async (walletAccount: TempoWalletAccount) => {
  const publicClient = await getTempoPublicClient({ walletAccount });

  return publicClient.getBlockNumber();
};
```

## Send a TIP-20 transfer

`sendTip20Transaction` transfers a TIP-20 token with a viem WalletClient created from the Tempo wallet account. `tokenAddress` is required, and `decimals` defaults to `18`, so pass the token's own decimals for tokens such as 6 decimal stablecoins. `amount` is the human-readable amount, not the smallest unit.

<Tabs>
  <Tab title="JavaScript">
    ```typescript theme={"system"}
    import { sendTip20Transaction } from '@dynamic-labs-sdk/evm/tempo';
    import type { TempoWalletAccount } from '@dynamic-labs-sdk/evm/tempo';
    import { createWalletClientForWalletAccount } from '@dynamic-labs-sdk/evm/viem';

    const sendStablecoin = async (walletAccount: TempoWalletAccount) => {
      const walletClient = await createWalletClientForWalletAccount({ walletAccount });

      return sendTip20Transaction({
        amount: '1.5',
        decimals: 6,
        to: '0xRecipientAddress...',
        tokenAddress: '0xTip20TokenAddress...',
        walletClient,
      });
    };
    ```
  </Tab>

  <Tab title="React">
    ```tsx theme={"system"}
    import { sendTip20Transaction } from '@dynamic-labs-sdk/evm/tempo';
    import { isTempoWalletAccount } from '@dynamic-labs-sdk/evm/tempo';
    import { createWalletClientForWalletAccount } from '@dynamic-labs-sdk/evm/viem';
    import { useGetWalletAccounts } from '@dynamic-labs-sdk/react-hooks';

    function SendStablecoinButton() {
      const { data: walletAccounts = [] } = useGetWalletAccounts();
      const walletAccount = walletAccounts.find(isTempoWalletAccount);

      const handleSend = async () => {
        if (!walletAccount) return;

        const walletClient = await createWalletClientForWalletAccount({ walletAccount });

        const hash = await sendTip20Transaction({
          amount: '1.5',
          decimals: 6,
          to: '0xRecipientAddress...',
          tokenAddress: '0xTip20TokenAddress...',
          walletClient,
        });

        console.log('Transfer sent:', hash);
      };

      return (
        <button disabled={!walletAccount} onClick={handleSend}>
          Send 1.5 TIP-20
        </button>
      );
    }
    ```
  </Tab>
</Tabs>

<Warning>
  There is no native token on Tempo, so a value transfer without `tokenAddress` cannot succeed. `sendTip20Transaction` throws `TempoNativeTokenError` when `tokenAddress` is empty.
</Warning>

## Recognize Tempo networks

`isTempoChainId` tells you whether a chain ID belongs to Tempo, which is useful when your app routes a network ID to chain-specific behavior. `TEMPO_CHAIN_IDS` holds the same list if you need to enumerate it.

```typescript theme={"system"}
import { TEMPO_CHAIN_IDS, isTempoChainId } from '@dynamic-labs-sdk/evm/tempo';

const supportsNativeValueTransfers = (networkId: number) => !isTempoChainId(networkId);

console.log('Tempo networks:', TEMPO_CHAIN_IDS);
```

`isTempoNetworkProvider` narrows a network provider to a `TempoNetworkProvider`, and `isTempoWalletProvider` does the same for wallet providers.
