Skip to main content
In this example, we’ll show how to send a transaction on Tempo. Since Tempo has no native token, all transactions pay fees in TIP-20 stablecoins.
import { FC, useState } from 'react';
import { useDynamicContext } from '@dynamic-labs/sdk-react-core';
import { isTempoWallet } from '@dynamic-labs/tempo';
import { encodeFunctionData, erc20Abi, Hex } from 'viem';

const SendTransactionButton: FC = () => {
  const { primaryWallet } = useDynamicContext();
  const [txHash, setTxHash] = useState<string | null>(null);

  const onSendTransaction = async () => {
    if (!primaryWallet || !isTempoWallet(primaryWallet)) {
      throw new Error('Tempo wallet not found');
    }

    const publicClient = await primaryWallet.getPublicClient();
    const walletClient = await primaryWallet.getWalletClient();

    const fromAddress = primaryWallet.address as Hex;
    const toAddress = '0x...' as Hex; // recipient address
    const tokenAddress = '0x...' as Hex; // TIP-20 token to transfer
    const feeTokenAddress = '0x...' as Hex; // TIP-20 token for gas fees
    const amount = BigInt(1000000); // amount in base units

    // Encode the transfer call
    const callData = encodeFunctionData({
      abi: erc20Abi,
      functionName: 'transfer',
      args: [toAddress, amount],
    });

    // Get nonce
    const nonce = await publicClient.getTransactionCount({
      address: fromAddress,
    });

    // Estimate gas with 30% buffer
    const gasEstimate = await publicClient.estimateGas({
      account: fromAddress,
      data: callData,
      to: tokenAddress,
    });
    const gas = (gasEstimate * BigInt(130)) / BigInt(100);

    // Get gas price
    const gasPrice = await publicClient.getGasPrice();

    // Build Tempo transaction with fee token
    const tempoTx = {
      calls: [
        {
          data: callData,
          to: tokenAddress,
          value: BigInt(0),
        },
      ],
      chainId: await publicClient.getChainId(),
      gas,
      maxFeePerGas: gasPrice,
      maxPriorityFeePerGas: gasPrice / BigInt(10),
      nonce,
      feeToken: feeTokenAddress,
    };

    // Sign and send the transaction
    const hash = await walletClient.sendTransaction(tempoTx);
    setTxHash(hash);

    console.log('Transaction hash:', hash);
  };

  return (
    <div>
      <button onClick={onSendTransaction}>Send Transaction</button>
      {txHash && <p>Transaction: {txHash}</p>}
    </div>
  );
};

Transaction Parameters

ParameterTypeRequiredDescription
callsArrayYesArray of call objects with to, data, and value
chainIdnumberYesThe Tempo chain ID (4217 for mainnet, 42431 for testnet)
gasbigintYesGas limit for the transaction
maxFeePerGasbigintYesMaximum fee per gas unit
maxPriorityFeePerGasbigintYesMaximum priority fee per gas unit
noncenumberYesTransaction nonce
feeTokenHexNoTIP-20 token address to pay gas fees (defaults to network stablecoin)