Set Up EVM Keyring

Overview

The Ethereum Virtual Machine (EVM) keyring system enables you to create unified wallets and addresses across multiple EVM-compatible blockchains using a single set of cryptographic keys (user, backup, and BitGo). The base address of the wallet and the derived receive addresses are all cryptographically identical on every supported EVM blockchain.

EVM keyrings use a reference model for creating linked wallets and addresses. A reference wallet is the foundational MPC wallet that acts as the cryptographic source for all other wallets linked in the EVM keyring. The keys to the reference wallet are the source keys that you use across all linked wallets. In addition, all linked addresses match their reference addresses.

Use Cases

The main use cases for EVM keyrings are:

  • Cross-Chain Recovery - If you accidentally send assets to the wrong EVM blockchain, you can recover them by linking the receiving wallets and addresses to your EVM keyring. Once linked, the stuck assets automatically flush to a wallet on the correct EVM blockchain.
  • Unified Identity - You can have the same addresses across all supported EVM chains.
  • Simplified Management - Manage only a single set of keys (user, backup, and BitGo) for wallets across multiple EVM blockchains.

Creating a unified identity and simplifying your key management are proactive measures you can take to utilize EVM keyrings. In contrast, cross-chain recoveries are reactive measures that you only have to take if a transaction accidentally sends assets to the wrong blockchain.

Prerequisites

1. Select Reference Wallet

Choose an existing EVM wallet to serve as your reference wallet.

Endpoints:

  • cURL (List Wallets)
  • cURL (List Wallets by Coin)
1 2 3 4 5 6 export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>" curl -X GET \ https://app.bitgo-test.com/api/v2/wallets \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $ACCESS_TOKEN"

Step Result

Select the wallet you want to use as the reference wallet and save the wallet id.

  • JSON, (List Wallets)
  • JSON (List Wallets by Coin)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 { "wallets": [ { "id": "63bd84ea4512c10007ce54a47743f93d", "users": [ { "user": "62ab90e06dfda30007974f0a52a12995", "permissions": ["admin", "view", "spend"] } ], "coin": "hteth", "label": "My Ethereum Testnet Wallet", "m": 2, "n": 3, "keys": [ "63bd84ea4b81a4000748b540f63580d9", "63bd84ea77fe2100070aef91ce0e2b47", "62c5ae7f74ac860007aff0cb9bcf93a6" ], "keySignatures": { "backupPub": "20c89b7e0da32c8e3060b548d47e309f0cb8629a4563a564996421fd57c60a3aa751f4d265551520bf92e1e4328f5584456c815b9a46ea5180c655032757524764", "bitgoPub": "2087ffd8dfad9b53cf1fe1ccf563cff90899424743d761ec6b727122e7493cb0a946424eeb3edac624270542035239b66757d608c8885ff0830f47a7d3e5598163" }, "enterprise": "62c5ae8174ac860007aff138a2d74df7" ... } ] }

Once you have a reference wallet ID, you can link wallets to the EVM keyring by creating wallets on other blockchains. Pass the wallet id of the reference wallet in the evmKeyRingReferenceWalletId field.

Repeat this step for each EVM-compatible blockchain you want to add to your keyring.

Endpoint: Generate Wallet

  • cURL
  • JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 export BITGO_EXPRESS_HOST="<YOUR_LOCAL_HOST>" export COIN="<ASSET_ID>" export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>" export LABEL="<YOUR_WALLET_NAME>" export REFERENCE_WALLET_ID="<YOUR_REFERENCE_WALLET_ID>" curl -X POST \ http://$BITGO_EXPRESS_HOST/api/v2/$COIN/wallet/generate \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -d '{ "label": "'"$LABEL"'", # (Optional) If absent, uses the label of the reference wallet "evmKeyRingReferenceWalletId": "'"$REFERENCE_WALLET_ID"'", ... }'

Step Result

Your new EVM wallets have the same base address as the reference wallet, enabling cross-chain operations.

  • JSON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 { "id": "68c3f553f62546c8e364ad785896b81f", "users": [ { "user": "5cae3130f8f4561d51dfcbfdaafba9b9", "permissions": [ "admin", "spend", "view" ] } ], "coin": "tpolygon", "label": "POLYGON EVM MPC W1", "m": 2, "n": 3, "keys": [ "689a571fc2a2ca9dc5fb114f8708be32", "689a571f3a7b477d8dff80535499dc61", "689a571ec4e260bc28136c2f66666c2b" ], "keySignatures": {}, "enterprise": "65a66817a7f6736078ab85afed6033d3", "organization": "65a66818a7f6736078ab864f0042ff3d", "bitgoOrg": "BitGo Trust", "tags": [ "68c3f553f62546c8e364ad785896b81f", "65a66817a7f6736078ab85afed6033d3" ], "disableTransactionNotifications": false, "freeze": {}, "deleted": false, "approvalsRequired": 1, "isCold": false, "coinSpecific": { "deployedInBlock": false, "lastChainIndex": { "0": -1, "1": -1 }, "baseAddress": "0x67000269cdddf7e3220d9e81b0b2aa54ccc4b008", "feeAddress": "0xff45beb151901ef6cde8166fa025d595905f7e39", "pendingChainInitialization": false, "pendingEcdsaTssInitialization": false, "creationFailure": [], "gasPriceTier": "fast", "tokenFlushThresholds": {}, "lowPriorityFeeAddress": "0xff45beb151901ef6cde8166fa025d595905f7e39", "salt": "0xf", "walletVersion": 5, "pendingDeployment": false, "deployForwardersManually": false, "flushForwardersManually": false, "enableMMI": false, "enableNFT": false, "sendManyTokens": [] }, "admin": { "policy": { "date": "2025-09-12T10:26:27.263Z", "id": "68c3f553f62546c8e364ad89bcc3e662", "label": "default", "rules": [], "version": 0, "latest": true } }, "clientFlags": [], "walletFlags": [], "allowBackupKeySigning": false, "evmKeyRingevmKeyRingReferenceWalletId": "689a575960b27cc44f82733b8a26cf1d", "recoverable": true, "startDate": "2025-09-12T10:26:27.000Z", "type": "hot", "buildDefaults": {}, "customChangeKeySignatures": {}, "hasLargeNumberOfAddresses": false, "multisigType": "tss", "multisigTypeVersion": "MPCv2", "hasReceiveTransferPolicy": false, "creator": "5cae3130f8f4561d51dfcbfdaafba9b9", "walletFullyCreated": true, "config": {}, "balanceString": "0", "confirmedBalanceString": "0", "spendableBalanceString": "0", "lockedBalanceString": "0", "stakedBalanceString": "0", "receiveAddress": { "id": "68c3f553f62546c8e364ad93a8811c8e", "address": "0x67000269cdddf7e3220d9e81b0b2aa54ccc4b008", "chain": 0, "index": 0, "coin": "tpolygon", "wallet": "68c3f553f62546c8e364ad785896b81f", "coinSpecific": { "nonce": -1, "txCount": 0, "pendingChainInitialization": false, "creationFailure": [], "pendingDeployment": false, "forwarderVersion": 4, "isTss": true, "isNonceLocked": false, "updateTime": "2025-09-12T10:26:27.394Z" } }, "pendingApprovals": [] }

Once you have wallets in the EVM keyring that share the same base address, you can create linked addresses. Use a reference address from any existing wallet in your keyring to create an identical address in a linked wallet on different blockchain.

Note the following address initialization differences:

  • Reference Address - The smart contract deploys only upon receiving the first transaction.
  • EVM Keyring Address - The smart contract deploys upon creation, enabling immediate cross-chain recovery.
  • cURL
  • JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 export COIN="<ASSET_ID>" export WALLET_ID="<YOUR_WALLET_ID>" export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>" export REFERENCE_ADDRESS="<YOUR_REFERENCE_ADDRESS>" curl -X POST \ "https://app.bitgo.com/api/v2/$COIN/wallet/$WALLET_ID/address" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "evmKeyRingReferenceAddress": "'"$REFERENCE_ADDRESS"'" }'

Step Result

Your new address is the same as the reference address, enabling cross-chain operations.

  • JSON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 { "id": "68c42570b9c05fcdd3f0c53b5261259f", "address": "0x9eaa84c52cd8649395c62b3ac982f00ad317df2b", "chain": 0, "index": 3, "coin": "tpolygon", "lastNonce": 0, "wallet": "68c3fd5e9384c89efe35dda0eefc8402", "needsConsolidation": false, "coinSpecific": { "nonce": -1, "updateTime": "2025-09-12T13:51:44.694Z", "txCount": 0, "pendingChainInitialization": true, "creationFailure": [], "salt": "0x3", "pendingDeployment": false, "forwarderVersion": 4 }, "addressType": "p2sh", "keychains": [ { "id": "68c3fd5bc20920edd2ceec194611dc7b", "source": "user", "type": "tss", "commonKeychain": "02f22ee8420903c0f57fca647c9c08da9e3ba48cebe43a0c4df8673369830d67dd5fe5ab4557e8447ebab88db4e9b56099549303ea14005dc9f78358986d987c85", "encryptedPrv": "..." }, { "id": "68c3fd5c74f8b62d58168c51addb8e87", "source": "backup", "type": "tss", "commonKeychain": "02f22ee8420903c0f57fca647c9c08da9e3ba48cebe43a0c4df8673369830d67dd5fe5ab4557e8447ebab88db4e9b56099549303ea14005dc9f78358986d987c85", "encryptedPrv": "..." }, { "id": "68c3fd5be4dbc6d15a832b89d62ff1f6", "source": "bitgo", "type": "tss", "commonKeychain": "02f22ee8420903c0f57fca647c9c08da9e3ba48cebe43a0c4df8673369830d67dd5fe5ab4557e8447ebab88db4e9b56099549303ea14005dc9f78358986d987c85", "isBitGo": true, "isTrust": false, "hsmType": "institutional" } ], "baseAddress": "0xaf34750bcf93ccbb22569c06af40558dfcd3e717", "format": undefined }

4. Fund Gas Tank

The gas tank address is automatically inherited from the reference wallet and is therefore the same across all blockchains in your EVM keyring. Fund your gas tank with the native assets of each blockchain in your keyring. During a cross-chain recovery, the gas tank pays for the deployment of a forwarder smart contract using the native asset of the target blockchain.

To learn more, see Fund Gas Tanks.

Next Steps

Any address in your EVM keyring is set up for automatic cross-chain recovery. If you have assets that were sent to an EVM wallet on the wrong blockchain, or if you receive future transactions as such, BitGo automatically:

  • Deploys the forwarder contract for the address on the target EVM network.
  • Automatically syncs the balance.
  • Makes the previously stuck assets available in your target EVM wallet, fully recovered and accessible for withdrawal.

See Also