Withdraw - BitGo Offline Vault Multisig

Build transactions and sign offline with the OVC. See the Guide.

  1. Build the transaction by specifying transaction details and sending them to BitGo. BitGo constructs an unsigned transaction. Save this JSON file to an SD card for transfer to the Offline Vault Console (OVC).

    API Reference

  2. Upload the unsigned transaction to the OVC and sign it there with your private key. The OVC is an air-gapped signing solution for cold wallets.

  3. Using the txHex from the OVC, send the half-signed transaction to BitGo. If approval is not required, BitGo applies the final signature and broadcasts to the blockchain.

    API Reference

  4. If your withdrawal requires approval, another admin must approve it — you cannot approve your own transactions. Once approved, BitGo rebuilds the transaction with current fees, applies the final signature, and broadcasts to the blockchain.

    API Reference

// 1. Build Transaction
export COIN="<ASSET_ID>"
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export ADDRESS="<DESTINATION_ADDRESS>"
export AMOUNT="<AMOUNT_IN_BASE_UNITS>"

curl -X POST \
  https://app.bitgo-test.com/api/v2/$COIN/wallet/$WALLET_ID/tx/build \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "recipients": [
      {
        "amount": "'"$AMOUNT"'",
        "address": "'"$ADDRESS"'"
      }
    ]
  }'
// 2. Sign Transaction
// Upload the unsigned transaction to the Offline Vault Console (OVC) and sign there
// 3. Send Transaction
curl -X POST \
  https://app.bitgo-test.com/api/v2/$COIN/wallet/$WALLET_ID/tx/send \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "halfSigned": {
      "txHex": "<HALF_SIGNED_TX_HEX_FROM_OVC>"
    }
  }'
// 4. Approve Transaction (Optional)
export APPROVAL_ID="<APPROVAL_ID>"
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"'"
  }'
Response
// 1. Build Transaction Response
{
  "txHex": "01000000010e4d3af014f9efe311062965d561b67f78a1759e...",
  "txInfo": {
    "nP2SHInputs": 0,
    "nSegwitInputs": 1,
    "nOutputs": 2,
    "unspents": [{ "chain": 10, "index": 5, "value": 100000 }],
    "changeAddresses": ["tb1ps5xs4drx69wtz4ja655dfktsnulydaqag8lxm992qymcucnfswvspwdwxq"]
  },
  "feeInfo": {
    "size": 226,
    "fee": 20451,
    "feeRate": 90491
  },
  "coin": "tbtc4"
}

// 3. Send Transaction Response (approval not required)
{
  "transfer": {
    "id": "65528cde229f765c57a8f4d1eb762908",
    "coin": "tbtc4",
    "txid": "c68916ddc1672ec62c474ef0839ec479ad9b2dabc2249177ce6be6247f81dfe7",
    "state": "signed",
    "type": "send"
  },
  "txid": "c68916ddc1672ec62c474ef0839ec479ad9b2dabc2249177ce6be6247f81dfe7",
  "status": "signed"
}

// 4. Approve Transaction Response
{
  "id": "65529448bd87efe59c3b0156ddfce867",
  "state": "approved"
}