Manage ERC20 Approvals

This tutorial will guide you through the process of managing ERC20 token approvals using the Blockdaemon DeFi API's Account API. We'll cover how to get, modify, and delete token approvals using the defi-api-examples tool.

Prerequisites

  • Node.js (v21.5.0 recommended) and npm (v10.2.4 or later)
  • nvm for node version management (recommended)
  • Blockdaemon DeFi API credentials
  • Basic understanding of TypeScript and async/await

Setup

  1. Setup the development environment, as defined here https://docs.blockdaemon.com/reference/set-up-the-development-environment

Get approvals

To get information about existing token approvals, use the get-approvals script:

npx ts-node src/main/scripts/get-approvals.ts

The script uses the following TypeScript code:

[...]
  const getApprovalRequest: GetTokenApprovalRequest = {
    chainID: "eip155:1", // Ethereum mainnet
    accountAddress: process.env.SENDER_ADDRESS,
    tokenAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC on Ethereum
    spenderAddress: "0x2222222222222222222222222222222222222222", // Example spender address
  };

  try {
    const approval = await accountAPI.getTokenApproval(getApprovalRequest);
    logger.info("Got approval:", JSON.stringify(approval, null, 2));
    return approval;
    
   [...]

Create or Modify Token Approvals

To create or modify a token approval, you'll need to use the sign-and-broadcast-transaction script in combination with the approval modification code. Here's an example of how to modify an approval:

import { ModifyTokenApprovalRequest, AccountApi } from "@blockdaemon/blockdaemon-defi-api-typescript-fetch";
import { log, apiConfig, OPTIMISM_RPC, optimismWallet } from "../utils/common";
import { signAndBroadcastTransaction } from "../endpoints/wallet";

const logger = log.getLogger("modify-token-approval");

async function modifyTokenApproval() {
  const accountAPI = new AccountApi(apiConfig);

  const modifyApprovalRequest: ModifyTokenApprovalRequest = {
    tokenApprovalModification: {
      chainID: "eip155:10", // Optimism
      accountAddress: process.env.SENDER_ADDRESS,
      tokenAddress: "0x0b2c639c533813f4aa9d7837caf62653d097ff85", // USDC on Optimism
      spenderAddress: "0x2222222222222222222222222222222222222222", // Example spender address
      toApprovedAmount: "1000000", // 1 USDC (6 decimals)
    },
  };

  try {
    const approval = await accountAPI.modifyTokenApproval(modifyApprovalRequest);
    logger.info("Got approval transaction payload");
    logger.debug(JSON.stringify(approval, null, 2));

    const approvalPayload = approval.transactionRequest.data;
    const approvalGasLimit = approval.transactionRequest.gasLimit;

    const result = await signAndBroadcastTransaction(
      approvalPayload,
      approval.transactionRequest.to,
      "0",
      approvalGasLimit,
      optimismWallet.privateKey,
      OPTIMISM_RPC
    );

    logger.info("Approval transaction sent:", result.transactionHash);
    return result.transactionHash;
  } catch (error) {
    logger.error("Failed to modify token approval:", error);
    throw error;
  }
}

modifyTokenApproval();

You may see an example of doing these operations on do-swapscript, where an approval is created and disseminated.

To do this with a cURL command, you may try:

curl -X POST 'https://svc.blockdaemon.com/defi/approvals' -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" -d '{ "tokenApprovalModification": { "chainID": "YOUR_FROM_CHAIN", "accountAddress": "YOUR_FROM_ADDRESS", "tokenAddress": "YOUR_FROM_TOKEN", "spenderAddress": "YOUR_APPROVAL_ADDRESS", "toApprovedAmount": "YOUR_FROM_AMOUNT" } }'

A concrete example is here:

curl -X POST 'https://svc.blockdaemon.com/defi/approvals' -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" -d '{ "tokenApprovalModification": { "chainID": "eip155:10", "accountAddress": "0xf271AAFC62634e6Dc9A276ac0f6145C4fDbE2Ced", "tokenAddress": "0xda10009cbd5d07dd0cecc66161fc93d7c9000da1", "spenderAddress": "0xB0D502E938ed5f4df2E681fE6E419ff29631d62b", "toApprovedAmount": "1000000000000000000" } }'

Deleting Token Approvals

To delete a token approval, you can set the approved amount to zero using the modify approval function:

const deleteApprovalRequest: ModifyTokenApprovalRequest = {
    tokenApprovalModification: {
      chainID: "eip155:10", // Optimism
      accountAddress: process.env.SENDER_ADDRESS,
      tokenAddress: "0x0b2c639c533813f4aa9d7837caf62653d097ff85", // USDC on Optimism
      spenderAddress: "0x2222222222222222222222222222222222222222", // Example spender address
      toApprovedAmount: "0", // Set to zero to delete the approval
    },
  };

  try {
    const approval = await accountAPI.modifyTokenApproval(deleteApprovalRequest);