Recover Advanced Wallet

Overview

Recovery operations for advanced wallets enable you to recover assets using your user and backup keys stored in your key management service (KMS) or hardware security module (HSM). The Advanced Wallet Manager (AWM) and Master BitGo Express (MBE) work together to build and sign recovery transactions without requiring the BitGo key.

This guide covers recovery for an advanced wallet with balance only in the base address. BitGo supports recovery operations for assets held in either multisignature and multi-party computation (MPC) wallets.

Prerequisites

1. Configure Recovery Mode

Set the environment variable RECOVERY_MODE=true for both the Advanced Wallet Manager and Master BitGo Express services.

# In your docker-compose.yml file
services:
  advanced-wallet-manager:
    environment:
      # ... other environment variables ...
      - RECOVERY_MODE=true

  master-bitgo-express:
    environment:
      # ... other environment variables ...
      - RECOVERY_MODE=true

Step Result

The AWM and MBE services can now start in recovery mode.

2. Start Services

# Start both services in background
docker-compose up -d

# Check the logs to verify recovery mode is enabled
docker-compose logs

Step Result

Creating network "advanced-wallets_my-internal-network" with driver "bridge"
Creating network "advanced-wallets_my-public-network" with driver "bridge"
Creating advanced-wallet-manager ... done
Creating master-bitgo-express    ... done

advanced-wallet-manager | 2025-01-26 10:30:15:0015 info: Advanced Wallet Manager starting...
advanced-wallet-manager | 2025-01-26 10:30:15:0015 info: Base URI: http://localhost:3080
advanced-wallet-manager | 2025-01-26 10:30:15:0015 info: Port: 3080
advanced-wallet-manager | 2025-01-26 10:30:15:0015 info: Recovery Mode: true

master-bitgo-express    | 2025-01-26 10:30:16:0016 info: Master Express server starting...
master-bitgo-express    | 2025-01-26 10:30:16:0016 info: Base URI: http://localhost:3081
master-bitgo-express    | 2025-01-26 10:30:16:0016 info: Port: 3081
master-bitgo-express    | 2025-01-26 10:30:16:0016 info: Recovery Mode: true

3. Recover Assets

Recoveries vary by asset type and signature scheme. See the following examples.

Endpoint: Advanced Wallets - Recover Assets

export IP_OR_HOSTNAME="<YOUR_SERVER_IP_OR_HOSTNAME>"
export COIN="<ASSET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export COMMON_KEYCHAIN="<COMMON_KEYCHAIN>"
export RECOVERY_ADDRESS="<DESTINATION_ADDRESS>"
export API_KEY="<BLOCKCHAIN_EXPLORER_API_KEY>"

curl -X POST \
  http://$IP_OR_HOSTNAME/api/v1/$COIN/advancedwallet/recovery \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "isTssRecovery": true,
    "tssRecoveryParams": {
      "commonKeychain": "'"$COMMON_KEYCHAIN"'"
    },
    "recoveryDestinationAddress": "'"$RECOVERY_ADDRESS"'",
    "apiKey": "'"$API_KEY"'"
  }'
export IP_OR_HOSTNAME="<YOUR_SERVER_IP_OR_HOSTNAME>"
export COIN="<ASSET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export COMMON_KEYCHAIN="<COMMON_KEYCHAIN>"
export RECOVERY_ADDRESS="<DESTINATION_ADDRESS>"
export API_KEY="<BLOCKCHAIN_EXPLORER_API_KEY>"
export TOKEN_CONTRACT="<TOKEN_CONTRACT_ADDRESS>"
export ATA_ADDRESS="<ASSOCIATED_TOKEN_ACCOUNT>"
export RECOVERY_ATA="<RECOVERY_DESTINATION_ATA>"
export PROGRAM_ID="<TOKEN_PROGRAM_ID>"

curl -X POST \
  http://$IP_OR_HOSTNAME/api/v1/$COIN/advancedwallet/recovery \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "isTssRecovery": true,
    "tssRecoveryParams": {
      "commonKeychain": "'"$COMMON_KEYCHAIN"'"
    },
    "recoveryDestinationAddress": "'"$RECOVERY_ADDRESS"'",
    "apiKey": "'"$API_KEY"'",
    "coinSpecificParams": {
      "solanaRecoveryOptions": {
        "tokenContractAddress": "'"$TOKEN_CONTRACT"'",
        "closeAtaAddress": "'"$ATA_ADDRESS"'",
        "recoveryDestinationAtaAddress": "'"$RECOVERY_ATA"'",
        "programId": "'"$PROGRAM_ID"'"
      }
    }
  }'
export IP_OR_HOSTNAME="<YOUR_SERVER_IP_OR_HOSTNAME>"
export COIN="<ASSET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export COMMON_KEYCHAIN="<COMMON_KEYCHAIN>"
export WALLET_CONTRACT="<WALLET_CONTRACT_ADDRESS>"
export RECOVERY_ADDRESS="<DESTINATION_ADDRESS>"
export BITGO_DESTINATION="<BITGO_DESTINATION_ADDRESS>"
export API_KEY="<BLOCKCHAIN_EXPLORER_API_KEY>"

curl -X POST \
  http://$IP_OR_HOSTNAME/api/v1/$COIN/advancedwallet/recovery \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "isTssRecovery": true,
    "tssRecoveryParams": {
      "commonKeychain": "'"$COMMON_KEYCHAIN"'"
    },
    "recoveryDestinationAddress": "'"$RECOVERY_ADDRESS"'",
    "coinSpecificParams": {
      "ecdsaEthLikeRecoverySpecificParams": {
        "walletContractAddress": "'"$WALLET_CONTRACT"'",
        "bitgoDestinationAddress": "'"$BITGO_DESTINATION"'",
        "apiKey": "'"$API_KEY"'"
      }
    }
  }'
export IP_OR_HOSTNAME="<YOUR_SERVER_IP_OR_HOSTNAME>"
export COIN="<ASSET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export COMMON_KEYCHAIN="<COMMON_KEYCHAIN>"
export RECOVERY_ADDRESS="<DESTINATION_ADDRESS>"
export ROOT_ADDRESS="<WALLET_ROOT_ADDRESS>"

curl -X POST \
  http://$IP_OR_HOSTNAME/api/v1/$COIN/advancedwallet/recovery \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "isTssRecovery": true,
    "tssRecoveryParams": {
      "commonKeychain": "'"$COMMON_KEYCHAIN"'"
    },
    "recoveryDestinationAddress": "'"$RECOVERY_ADDRESS"'",
    "coinSpecificParams": {
      "ecdsaCosmosLikeRecoverySpecificParams": {
        "rootAddress": "'"$ROOT_ADDRESS"'"
      }
    }
  }'
export IP_OR_HOSTNAME="<YOUR_SERVER_IP_OR_HOSTNAME>"
export COIN="<ASSET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export USER_PUB="<USER_PUBLIC_KEY>"
export BACKUP_PUB="<BACKUP_PUBLIC_KEY>"
export BITGO_PUB="<BITGO_PUBLIC_KEY>"
export RECOVERY_ADDRESS="<DESTINATION_ADDRESS>"
export API_KEY="<BLOCKCHAIN_EXPLORER_API_KEY>"
export FEE_RATE="<FEE_RATE_IN_SATS_PER_BYTE>"

curl -X POST \
  http://$IP_OR_HOSTNAME/api/v1/$COIN/advancedwallet/recovery \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "isTssRecovery": false,
    "multiSigRecoveryParams": {
      "userPub": "'"$USER_PUB"'",
      "backupPub": "'"$BACKUP_PUB"'",
      "bitgoPub": "'"$BITGO_PUB"'"
    },
    "recoveryDestinationAddress": "'"$RECOVERY_ADDRESS"'",
    "apiKey": "'"$API_KEY"'",
    "coinSpecificParams": {
      "utxoRecoveryOptions": {
        "feeRate": '"$FEE_RATE"',
        "scan": 20
      }
    }
  }'
export IP_OR_HOSTNAME="<YOUR_SERVER_IP_OR_HOSTNAME>"
export COIN="<ASSET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export USER_PUB="<USER_PUBLIC_KEY>"
export BACKUP_PUB="<BACKUP_PUBLIC_KEY>"
export WALLET_CONTRACT="<WALLET_CONTRACT_ADDRESS>"
export RECOVERY_ADDRESS="<DESTINATION_ADDRESS>"
export API_KEY="<BLOCKCHAIN_EXPLORER_API_KEY>"

curl -X POST \
  http://$IP_OR_HOSTNAME/api/v1/$COIN/advancedwallet/recovery \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "isTssRecovery": false,
    "multiSigRecoveryParams": {
      "userPub": "'"$USER_PUB"'",
      "backupPub": "'"$BACKUP_PUB"'",
      "walletContractAddress": "'"$WALLET_CONTRACT"'"
    },
    "recoveryDestinationAddress": "'"$RECOVERY_ADDRESS"'",
    "apiKey": "'"$API_KEY"'",
    "coinSpecificParams": {
      "evmRecoveryOptions": {
        "gasLimit": 500000,
        "eip1559": {
          "maxFeePerGas": 50000000000,
          "maxPriorityFeePerGas": 2000000000
        },
        "replayProtectionOptions": {
          "chain": 1,
          "hardfork": "london"
        }
      }
    }
  }'

Step Result

The AWM and MBE complete the recovery by executing the following

  1. MBE validates your request parameters and uses the BitGo SDK to build an unsigned recovery transaction.
  2. MBE sends the unsigned transaction to AWM.
  3. AWM retrieves the private keys from KMS using the provided public keys or common keychain.
  4. AWM signs the transaction with both the user and backup keys.
  5. AWM returns the signed transaction to MBE.
  6. MBE returns the signed transaction to you, ready for broadcast.
{
  "txHex": "0x02f8b38201a48459682f008459682f0e8303d09094a2c8e69f90f5e16b6f9e4e3c6c9a9e5f7a3b4d6580b844a9059cbb0000000000000000000000001234567890123456789012345678901234567890000000000000000000000000000000000000000000000000000000000000000ac001a0d5e7b0f2f4e3c6d9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6a05a04b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1"
}
{
  "txHex": "01000000000101edd7a5d948a6c79f273ce686a6a8f2e96ed8c2583b5e77b866aa2a1b3426fbed0100000000ffffffff02102700000000000017a914192f23283c2a9e6c5d11562db0eb5d4eb47f460287b9bc2c000000000017a9145c139b242ab3701f321d2399d3a11b028b3b361e870247304402206ac9477fece38d96688c6c3719cb27396c0563ead0567457e7e884b406b6da8802201992d1cfa1b55a67ce8acb482e9957812487d2555f5f54fb0286ecd3095d78e4012103c92564575197c4d6e3d9792280e7548b3ba52a432101c62de2186c4e2fa7fc580000000000"
}

4. Broadcast the Recovery Transaction

Once you have the signed transaction hex, you can broadcast it to the network using a blockchain explorer or node. This process varies by blockchain.

Using Blockchain Explorer

For Bitcoin and other UTXO networks, you can use services such as:

For Ethereum and EVM-compatible networks, you can use services such as:

Using Command Line

# Uses bitcoin-cli
bitcoin-cli sendrawtransaction "<TX_HEX>"
# Uses curl with Ethereum node
curl -X POST \
  https://mainnet.infura.io/v3/YOUR_PROJECT_ID \
  -H 'Content-Type: application/json' \
  -d '{
    "jsonrpc": "2.0",
    "method": "eth_sendRawTransaction",
    "params": ["<TX_HEX>"],
    "id": 1
  }'
# Uses Solana CLI
solana send-transaction <TX_HEX> --url <CLUSTER_URL>

Step Result

Once broadcast, you receive a transaction ID that you can use to track the recovery transaction on a blockchain explorer. For example:

{
  "result": "8747673834d6c71560a2816963585718567419020dc58151d2f7e1ed8c57de14"
}

Next Steps

After successfully broadcasting your recovery transaction:

  1. Monitor the transaction status on a blockchain explorer using the transaction ID.
  2. Wait for sufficient blockchain confirmations (BitGo recommends 6+ for Bitcoin and 12+ for Ethereum).
  3. Verify the recovered funds arrive at the destination address.
  4. Update your wallet configuration and key management procedures as needed.

See Also