Enable Bulk ERC20 Withdrawals - JavaScript

Approve the batcher smart contract to enable bulk ERC20 token withdrawals using the BitGo JavaScript SDK. Includes flows for Custody MPC, Custody Multisig, Self-Custody MPC (Hot and Cold), and Self-Custody Multisig (Hot and Cold) wallets. See the Guide.

  1. Before approving tokens, you can check if your wallet has already approved the batcher contract using the REST API (see the cURL cookbook). The large number shown in the response (2^256-1) is the maximum approval amount (unlimited).

    Approving the batcher smart contract is a one-time operation, but each token requires a separate approval in each wallet.

    Prerequisites: Complete Get Started, Create Wallets, and Deposit Assets (you must have the ERC20 token in the wallet).

    API Reference

  2. Build an approval transaction for the ERC20 token to authorize the batcher smart contract to transfer tokens on your behalf. The SDK method depends on your wallet type:

    • Custody MPC: Use sendMany with isTss: true and type: 'tokenApproval'.
    • Custody Multisig: Use sendMany with type: 'tokenApproval' (no isTss flag).
    • Self-Custody MPC: Use sendMany with isTss: true, type: 'tokenApproval', walletPassphrase, and feeOptions.
    • BitGo Offline Vault MPC: Use sendMany with isTss: true, type: 'tokenApproval', and feeOptions (no passphrase — sign offline).
    • Self-Custody Multisig: Use buildErc20TokenApproval with tokenName and walletPassphrase to build, sign, and send in one operation.
    • BitGo Offline Vault Multisig: Use buildErc20TokenApproval to get the unsigned transaction, sign offline using the OVC, then send the half-signed transaction with sendTransaction.

    Transactions for approving the batcher smart contract follow the transaction flow of the wallet type, and must receive all required signatures and approvals before broadcasting to the blockchain. Once you sign and broadcast your approval transaction, you can Bulk Withdraw ERC20 Tokens.

    API Reference

// 1. (Optional) Check Token Allowance
// Use the REST API for this step (see cURL cookbook)

// 2. Approve Batcher Smart Contract
async function approveToken() {
  const walletInstance = await bitgo
    .coin('opeth')
    .wallets()
    .get({ id: '<YOUR_WALLET_ID>' });

  // For custodial MPC wallets, use sendMany with type: 'tokenApproval'
  const result = await walletInstance.sendMany({
    isTss: true,
    type: 'tokenApproval',
    tokenName: 'opeth:usdc'
  });

  return result;
}
Response
// 1. (Optional) Check Token Allowance Response
{
  "allowance": "115792089237316195423570985008687907853269984665640564039457584007913129639935"
}

// Approve Batcher Smart Contract Response (applies to all wallet types)
{
  "pendingApproval": {
    "id": "63727a81cdbc820007b27caa7b76016d",
    "coin": "eth",
    "wallet": "63726fde0a3c94000758f2790536041d",
    "state": "pendingFinalApproval",
    "scope": "wallet",
    "info": {
      "type": "transactionRequest",
      "transactionRequest": {
        "coinSpecific": {
          "eth": {
            "eip1559": {
              "maxPriorityFeePerGas": 1500000000,
              "maxFeePerGas": 133302263906
            },
            "recipients": [
              {
                "amount": "0",
                "address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
                "data": "0x095ea7b3000000000000000000000000..."
              }
            ]
          }
        }
      }
    }
  }
}