Build stablecoin-first dapps on Tempo (TIP-20 payments, memos, fee tokens, sponsorship, batching, TIP-403 compliance, and stablecoin DEX).
Production-ready patterns and code snippets for building on Tempo, an EVM chain optimized for stablecoin payments where transaction fees are paid in USD-denominated TIP-20 tokens (no native gas token).
cast rpc tempo_fundAddress <YOUR_ADDRESS> --rpc-url https://rpc.testnet.tempo.xyz
Faucet commonly funds (addresses may vary by network config):
BALANCE / SELFBALANCE return 0CALLVALUE returns 0eth_getBalance is the native gas token balance and may display weird values.balanceOf() instead.fee_token (Tempo Transactions) or rely on fee token preferences.Tip: If you’re using legacy EVM transactions to call a non–TIP-20 contract, the fee token may fall back to pathUSD. Prefer Tempo Transactions if you control submission.
import { parseUnits, pad, stringToHex } from "viem"
import { client } from "./viem.config"
const invoiceId = pad(stringToHex("INV-12345"), { size: 32 })
const { receipt } = await client.token.transferSync({
amount: parseUnits("100", 6), // common USD stablecoin decimals
to: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb",
token: "0x20c0000000000000000000000000000000000001", // AlphaUSD (example)
memo: invoiceId,
})
console.log(receipt)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface ITIP20 {
function transfer(address to, uint256 amount) external returns (bool);
function transferWithMemo(address to, uint256 amount, bytes32 memo) external;
}
contract PaymentSender {
ITIP20 public immutable token;
constructor(address tip20) {
token = ITIP20(tip20);
}
function sendPayment(address recipient, uint256 amount) external {
require(token.transfer(recipient, amount), "transfer failed");
}
function sendPaymentWithMemo(address recipient, uint256 amount, bytes32 invoiceId) external {
token.transferWithMemo(recipient, amount, invoiceId);
}
}
import { encodeFunctionData, parseUnits } from "viem"
import { Abis } from "tempo.ts/viem"
import { client } from "./viem.config"
const tokenABI = Abis.tip20
const token = "0x20c0000000000000000000000000000000000001" // AlphaUSD example
const calls = [
{
to: token,
data: encodeFunctionData({
abi: tokenABI,
functionName: "transfer",
args: ["0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb", parseUnits("100", 6)],
}),
},
{
to: token,
data: encodeFunctionData({
abi: tokenABI,
functionName: "transfer",
args: ["0x70997970C51812dc3A010C7d01b50e0d17dc79C8", parseUnits("50", 6)],
}),
},
]
const hash = await client.sendTransaction({ calls })
console.log(hash)
// Pseudocode-style (see tempo-go SDK docs for full imports)
tx := transaction.NewDefault(42429)
// User signs transaction intent first
transaction.SignTransaction(tx, userSigner)
// A separate fee payer selects fee token and signs to sponsor
transaction.AddFeePayerSignature(tx, feePayerSigner)
client.SendTransaction(tx)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface ITIP20 {}
interface ITIP20Factory {
function createToken(
string memory name,
string memory symbol,
string memory currency,
ITIP20 quoteToken,
address admin
) external returns (address token);
}
contract IssueStablecoin {
address public constant TIP20_FACTORY = 0x20fc000000000000000000000000000000000000;
address public constant PATH_USD = 0x20c0000000000000000000000000000000000000;
function createUSDToken(string memory name, string memory symbol) external returns (address) {
return ITIP20Factory(TIP20_FACTORY).createToken(
name,
symbol,
"USD",
ITIP20(PATH_USD),
msg.sender
);
}
}
getMetadata / decimals()).tempo.ts (viem / wagmi actions)github.com/tempoxyz/tempo-go