Create Whitelists

Overview

You can enhance security for a wallet by whitelisting crypto addresses and wallets. Whitelisting creates a wallet policy. Wallet policies dictate what actions trigger when a withdrawal initiates to a non-whitelisted address or wallet. For example, you can configure a wallet policy to automatically deny transactions to non-whitelisted addresses or require approval from an admin to proceed. Wallet policies are specific to individual wallets.

When you update a wallet policy, BitGo sends an email notification to all wallet users. However, BitGo doesn't send an email notification when you initially create a wallet policy. For your security, new wallet-policy rules lock after 48 hours and can only be unlocked by BitGo support. Wallet policies are different than enterprise policies. To learn more about enterprise policies, see Policies Overview.

Note: Wallet-policies apply only to transactions that involve the BitGo key. Transactions that use the user key and the backup key bypass wallet policies. For more details about transacting with the backup key, see Set Up Wallet Recovery Wizard.

Prerequisites

Steps

1. Create Wallet Policy

Endpoint: Add wallet-policy rule

export COIN="<ASSET_ID>"
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export ID="<NAME_OF_WHITELIST>"
export ITEM="<ADDRESS_TO_WHITELIST>"

curl -X POST \
  "https://app.bitgo-test.com/api/v2/$COIN/wallet/$WALLET_ID/policy/rule" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
  "coin": "'"$COIN"'",
  "id": "'"$ID"'",
  "type": "advancedWhitelist",
  "condition": {
    "add": {
      "type": "address",
      "item": "'"$ITEM"'"
    }
  },
  "action": {
    "type": "deny" # this configures what happens to transactions to non-whitelisted addresses
  }
}'
const BitGoJS = require('bitgo');
const bitgo = new BitGoJS.BitGo({ env: 'test' });
const promise = require('bluebird');

// Set your access token here
const accessToken = '<YOUR_ACCESS_TOKEN>';
// Set your coin of choice here
const coin = '<COIN>';
// Set your wallet ID here
const walletId ='<YOUR_WALLET_ID>';

promise.coroutine(function *() {
  bitgo.authenticateWithAccessToken({ accessToken });

  const wallet = yield bitgo.coin(coin).wallets().get({ id: walletId });

  console.log(`Setting new whitelist policy on wallet ${wallet.label()}`);
  const policy = {
              action: {
              type: 'getApproval'
    },
    condition: {
              add: {
              item: '<ADDRESS_TO_WHITELIST>',
              type: 'address',
              metaData: {
                label: "Recipient Wallet"
              }
            },
    },
    id: '<NAME_OF_WHITELIST>',
    type: 'advancedWhitelist'
  };

  const result = yield wallet.createPolicyRule(policy);
  console.dir(result);
})();

Step Result

If creating the whitelist doesn't require approval, it's now in effect.

{
  "id": "66e9f4bb549f6c3957f8977fe3ed6ab4",
  "users": [
    {
      "user": "62ab90e06dfda30007974f0a52a12995",
      "permissions": ["admin", "spend", "view"]
    }
  ],
  "coin": "tbtc4",
  "label": "Policy Wallet 2",
  "m": 2,
  "n": 3,
  "keys": [
    "66e9f4ac6bfc0956265268311208afd7",
    "66e9f4ac9231837dc9c945a6c4a725d0",
    "66e9f4adbfe06bac12b54a93d22b6dfc"
  ],
  "keySignatures": {},
  "enterprise": "62c5ae8174ac860007aff138a2d74df7",
  "bitgoOrg": "BitGo Trust",
  "tags": [
    "66e9f4bb549f6c3957f8977fe3ed6ab4",
    "62c5ae8174ac860007aff138a2d74df7"
  ],
  "disableTransactionNotifications": false,
  "freeze": {},
  "deleted": false,
  "approvalsRequired": 1,
  "isCold": false,
  "coinSpecific": {},
  "admin": {
    "policy": {
      "date": "2024-09-18T22:05:21.220Z",
      "id": "66e9f4bb549f6c3957f897824915d45f",
      "label": "default",
      "rules": [
        {
          "id": "My First Wallet Policy for a Whitelist",
          "lockDate": "2025-09-18T22:05:21.219Z",
          "coin": "tbtc4",
          "type": "advancedWhitelist",
          "action": { "type": "deny", "userIds": [] },
          "condition": {
            "entries": [
              {
                "item": "2N6CWMMYXdufJyBa16KNorHs8AakXcqyHhf",
                "type": "address"
              }
            ]
          }
        }
      ],
      "version": 5,
      "latest": true
    }
  },
  "clientFlags": [],
  "walletFlags": [],
  "allowBackupKeySigning": false,
  "recoverable": true,
  "startDate": "2024-09-17T21:29:31.000Z",
  "type": "hot",
  "buildDefaults": {},
  "customChangeKeySignatures": {},
  "hasLargeNumberOfAddresses": false,
  "multisigType": "onchain",
  "hasReceiveTransferPolicy": false,
  "config": {},
  "balance": 0,
  "balanceString": "0",
  "rbfBalance": 0,
  "rbfBalanceString": "0",
  "confirmedBalance": 0,
  "confirmedBalanceString": "0",
  "spendableBalance": 0,
  "spendableBalanceString": "0",
  "unspentCount": 0,
  "receiveAddress": {
    "id": "66e9f4bc549f6c3957f897a441904bff",
    "address": "tb1pv2jfqgu2py8unuwrgraegqqw3ds022lvx2f29hg2av504l4rtjhqld35ns",
    "chain": 40,
    "index": 1,
    "coin": "tbtc4",
    "wallet": "66e9f4bb549f6c3957f8977fe3ed6ab4",
    "coinSpecific": {}
  },
  "pendingApprovals": []
}
{
  "pendingApproval": {
    "id": "66edb22fbef3fef723292c7b14ae01f3", # admin who approves the wallet policy needs this ID
    "coin": "tbtc4",
    "wallet": "66e9aba320e050e4334b23285bfe3b2e",
    "wallets": [],
    "enterprise": "62c5ae8174ac860007aff138a2d74df7",
    "bitgoOrg": "BitGo Trust",
    "creator": "62ab90e06dfda30007974f0a52a12995",
    "createDate": "2024-09-20T17:34:39.157Z",
    "info": {
      "type": "policyRuleRequest",
      "policyRuleRequest": {
        "action": "create",
        "update": {
          "id": "My First Wallet Policy for a Whitelist",
          "type": "advancedWhitelist",
          "action": { "type": "deny", "userIds": [] },
          "condition": {
            "add": {
              "type": "address",
              "item": "2N6CWMMYXdufJyBa16KNorHs8AakXcqyHhf"
            }
          },
          "coin": "tbtc4"
        }
      }
    },
    "approvers": [],
    "state": "pending",
    "scope": "wallet",
    "userIds": [
      "62ab90e06dfda30007974f0a52a12995",
      "627ff9325a5c1b0007c05a40d15e1522"
    ],
    "approvalsRequired": 1,
    "singleRunResults": [],
    "resolvers": [],
    "actions": [],
    "resolutionOrder": []
  }
}

2. Approve Whitelist (Optional)

Note: If your new wallet policy requires approval, another admin must approve it.

Endpoint: Update Pending Approval

export APPROVAL_ID="<APPROVAL_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export OTP="<YOUR_OTP>"

curl -X PUT \
  https://app.bitgo-test.com/api/v2/pendingApprovals/$APPROVAL_ID \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "state": "approved",
    "otp": "'"$OTP"'"
  }'
const baseCoin = this.bitgoSDK.coin(initialPendingApproval.coin);
const pendingApproval = await baseCoin.pendingApprovals().get({ id: initialPendingApproval.id });
const result = await pendingApproval.approve(params);

Step Result

Your wallet policy is approved and your whitelist is now in effect.

{
  "id": "66edb22fbef3fef723292c7b14ae01f3",
  "coin": "tbtc4",
  "wallet": "66e9aba320e050e4334b23285bfe3b2e",
  "wallets": [],
  "enterprise": "62c5ae8174ac860007aff138a2d74df7",
  "bitgoOrg": "BitGo Trust",
  "creator": "62ab90e06dfda30007974f0a52a12995",
  "createDate": "2024-09-20T17:34:39.157Z",
  "approvedDate": "2024-09-20T17:37:57.246Z",
  "info": {
    "type": "policyRuleRequest",
    "policyRuleRequest": {
      "action": "create",
      "update": {
        "id": "My First Wallet Policy for a Whitelist",
        "type": "advancedWhitelist",
        "action": { "type": "deny", "userIds": [] },
        "condition": {
          "add": {
            "type": "address",
            "item": "2N6CWMMYXdufJyBa16KNorHs8AakXcqyHhf"
          }
        },
        "coin": "tbtc4"
      }
    }
  },
  "approvers": [],
  "state": "approved",
  "scope": "wallet",
  "userIds": [
    "62ab90e06dfda30007974f0a52a12995",
    "627ff9325a5c1b0007c05a40d15e1522"
  ],
  "approvalsRequired": 1,
  "singleRunResults": [],
  "resolvers": [
    {
      "user": "627ff9325a5c1b0007c05a40d15e1522",
      "date": "2024-09-20T17:37:55.612Z",
      "resolutionType": "pending",
      "resolutionAction": "approve"
    }
  ],
  "actions": [],
  "resolutionOrder": []
}

Next

You can view whitelists and wallet policies using the Get Wallet by Coin and ID endpoint.

See Also

API Reference: Add Wallet-Policy Rule