Withdraw - BitGo Offline Vault Multisig
Build transactions and sign offline with the OVC. See the Guide.
-
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).
-
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.
-
Using the
txHexfrom the OVC, send the half-signed transaction to BitGo. If approval is not required, BitGo applies the final signature and broadcasts to the blockchain. -
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.
// 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"'"
}'
// 1. Build Transaction
let buildParams = {
recipients: [
{
amount: `<AMOUNT_IN_BASE_UNITS>`,
address: `<DESTINATION_ADDRESS>`,
},
],
};
wallet.prebuildTransaction(buildParams).then(function (transaction) {
console.log(JSON.stringify(transaction, null, 2));
});
// 2. Sign Transaction
// Upload the unsigned transaction to the Offline Vault Console (OVC)
// 3. Send Transaction
let sendParams = {
txHex: '<HALF_SIGNED_TX_HEX_FROM_OVC>',
otp: '0000000',
};
wallet.submitTransaction(sendParams).then(function (transaction) {
console.dir(transaction);
});
// 4. Approve Transaction (Optional)
const baseCoin = bitgo.coin(initialPendingApproval.coin);
const pendingApproval = await baseCoin.pendingApprovals().get({ id: initialPendingApproval.id });
const result = await pendingApproval.approve(params);
// 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"
}