Documentation Index
Fetch the complete documentation index at: https://docs.polygon.technology/llms.txt
Use this file to discover all available pages before exploring further.
The following examples are demonstrations of integrations and should not be
used in production. In production, store sensitive information such as API keys
and private keys in a secrets manager or vault.
This guide covers native USDC on Polygon PoS. Native USDC behaves like any
other ERC-20 token: you can read balances, approve spenders, and transfer
tokens directly onchain.
For cross-chain USDC transfers using Circle’s CCTP, see
USDC Gateway Integration.
| Approach | Description | When to use |
|---|
| Native USDC | Standard ERC-20 contract directly on Polygon PoS | When you only need payments within Polygon |
| Gateway USDC | Circle’s cross-chain system that moves USDC between blockchains (CCTP) | When your users need to send or receive USDC across chains |
Example: Read Balance and Transfer
The following example uses viem to check the USDC balance
and send 1 USDC on Polygon.
// pnpm add viem
import { createPublicClient, createWalletClient, http, parseUnits } from "viem";
import { polygon } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";
// Native USDC contract on Polygon PoS (not bridged USDC.e)
const USDC = "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359";
const erc20 = [
{ type: "function", name: "decimals", stateMutability: "view", inputs: [], outputs: [{ type: "uint8" }] },
{ type: "function", name: "balanceOf", stateMutability: "view", inputs: [{ type: "address" }], outputs: [{ type: "uint256" }] },
{ type: "function", name: "transfer", stateMutability: "nonpayable", inputs: [{ type: "address" }, { type: "uint256" }], outputs: [{ type: "bool" }] },
];
const account = privateKeyToAccount(process.env.PRIV_KEY as `0x${string}`);
const rpc = http(process.env.POLYGON_RPC_URL);
const pub = createPublicClient({ chain: polygon, transport: rpc });
const wallet = createWalletClient({ chain: polygon, transport: rpc, account });
async function main() {
const me = account.address;
const decimals = await pub.readContract({ address: USDC, abi: erc20, functionName: "decimals" });
const bal = await pub.readContract({ address: USDC, abi: erc20, functionName: "balanceOf", args: [me] });
console.log("Balance:", Number(bal) / 10 ** Number(decimals), "USDC");
// Send 1 USDC
const amount = parseUnits("1", Number(decimals));
const hash = await wallet.writeContract({ address: USDC, abi: erc20, functionName: "transfer", args: ["0xRecipient...", amount] });
console.log("tx:", hash);
}
main();