Skip to main content
This tutorial guides you through interacting with smart contracts deployed on Arc Testnet. You’ll learn how to execute contract functions like minting tokens, transferring assets, and performing contract-specific operations for ERC-20, ERC-721, ERC-1155, and Airdrop contracts.

Prerequisites

To complete this tutorial, you need:
  1. Node.js v22+ installed
  2. Deployed contract on Arc - Complete the Deploy contracts tutorial first
  3. Contract address - The address of your deployed contract
  4. Funded wallet - Dev-controlled wallet with testnet USDC for gas fees
  5. API credentials - Your API key and Entity Secret from the Developer Console
This tutorial assumes you have a contract already deployed on Arc Testnet with a funded dev-controlled wallet. If you don’t, follow the Deploy contracts tutorial first.

Interact with ERC-20 contracts

ERC-20 tokens support standard fungible token operations. You’ll learn to mint new tokens and transfer them between addresses.

Mint tokens

Use the mintTo function to mint tokens. The wallet must have MINTER_ROLE.
import { initiateDeveloperControlledWalletsClient } from "@circle-fin/developer-controlled-wallets";

const circleDeveloperSdk = initiateDeveloperControlledWalletsClient({
  apiKey: process.env.CIRCLE_API_KEY,
  entitySecret: process.env.CIRCLE_ENTITY_SECRET,
});

const mintResponse =
  await circleDeveloperSdk.createContractExecutionTransaction({
    walletId: process.env.WALLET_ID,
    abiFunctionSignature: "mintTo(address,uint256)",
    abiParameters: [
      process.env.WALLET_ADDRESS,
      "1000000000000000000", // 1 token with 18 decimals
    ],
    contractAddress: process.env.CONTRACT_ADDRESS,
    fee: {
      type: "level",
      config: {
        feeLevel: "MEDIUM",
      },
    },
  });
Response:
{
  "data": {
    "id": "601a0815-f749-41d8-b193-22cadd2a8977",
    "state": "INITIATED"
  }
}
Token decimals: ERC-20 tokens typically use 18 decimals. To mint 1 token, use 1000000000000000000 (1 × 10^18).

Transfer tokens

Use the transfer function to send tokens to another address.
const transferResponse =
  await circleDeveloperSdk.createContractExecutionTransaction({
    walletId: process.env.WALLET_ID,
    abiFunctionSignature: "transfer(address,uint256)",
    abiParameters: [
      process.env.RECIPIENT_WALLET_ADDRESS,
      "1000000000000000000", // 1 token with 18 decimals
    ],
    contractAddress: process.env.CONTRACT_ADDRESS,
    fee: {
      type: "level",
      config: {
        feeLevel: "MEDIUM",
      },
    },
  });
Response:
{
  "data": {
    "id": "601a0815-f749-41d8-b193-22cadd2a8977",
    "state": "INITIATED"
  }
}

Complete script

Here’s the complete script combining mint and transfer operations:
import { initiateDeveloperControlledWalletsClient } from "@circle-fin/developer-controlled-wallets";

const circleDeveloperSdk = initiateDeveloperControlledWalletsClient({
  apiKey: process.env.CIRCLE_API_KEY,
  entitySecret: process.env.CIRCLE_ENTITY_SECRET,
});

async function main() {
  // Mint tokens
  const mintResponse =
    await circleDeveloperSdk.createContractExecutionTransaction({
      walletId: process.env.WALLET_ID,
      abiFunctionSignature: "mintTo(address,uint256)",
      abiParameters: [
        process.env.WALLET_ADDRESS,
        "1000000000000000000", // 1 token with 18 decimals
      ],
      contractAddress: process.env.CONTRACT_ADDRESS,
      fee: {
        type: "level",
        config: {
          feeLevel: "MEDIUM",
        },
      },
    });

  console.log("Mint transaction:", mintResponse.data?.id);

  // Transfer tokens
  const transferResponse =
    await circleDeveloperSdk.createContractExecutionTransaction({
      walletId: process.env.WALLET_ID,
      abiFunctionSignature: "transfer(address,uint256)",
      abiParameters: [
        process.env.RECIPIENT_WALLET_ADDRESS,
        "1000000000000000000", // 1 token with 18 decimals
      ],
      contractAddress: process.env.CONTRACT_ADDRESS,
      fee: {
        type: "level",
        config: {
          feeLevel: "MEDIUM",
        },
      },
    });

  console.log("Transfer transaction:", transferResponse.data?.id);
}

main();
Run the script:
npx tsx --env-file=.env interact-erc20.ts

Check transaction status

After executing a contract function, check the transaction status using GET /transactions/{id}:
const transactionResponse = await circleDeveloperSdk.getTransaction({
  id: "<TRANSACTION_ID>",
});
Response:
{
  "data": {
    "transaction": {
      "id": "601a0815-f749-41d8-b193-22cadd2a8977",
      "blockchain": "ARC-TESTNET",
      "state": "COMPLETE",
      "txHash": "0xb9e8774147fe086e5864828457f2bf3f8f25a356f6df4c920a677bfd3c3e9ac7"
    }
  }
}
View your transaction on the Arc Testnet Explorer by searching for the txHash.

Summary

After completing this tutorial, you’ve learned how to:
  • Execute contract functions using the Circle SDKs
  • Mint and transfer tokens for your deployed contracts
  • Check transaction status and retrieve transaction details
  • Perform contract-specific operations based on token type