Withdraw from Wallet - Self-Managed MPC Hot (Advanced)
Overview
You withdraw from self-managed MPC hot wallets by submitting transaction-request details to BitGo. BitGo uses the data you pass to construct an unsigned transaction that wallet co-signers can sign and wallet admins can approve. Once the transaction is half signed and approved, you send it to BitGo for final signing and broadcasting to the blockchain.
If you don't need this level of granular control for your withdrawals, see the integration guide for the simple flow.
Prerequisites
- Get Started
- Create Wallets
- Create Wallet Whitelists
- Set Up External-Signer Mode (Optional)
- Deposit assets into your wallet
1. Request Transaction
Request the transaction by specifying the transaction details and sending them to BitGo.
Endpoint: Create transaction request
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
export WALLET_ID="<WALLET_ID>" export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>" curl -X POST \ https://app.bitgo-test.com/api/v2/wallet/$WALLET_ID/txrequests \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -d '{ "idempotencyKey": "string", "intent": { "intentType": "payment", "sequenceId": "abc123", "comment": "string", "nonce": "string", "recipients": [ { "address": { "address": "string", "options": {} }, "amount": { "value": "100", "symbol": "gteth" }, "data": "string" } ] }, "apiVersion": "full", "preview": false }'
Step Result
BitGo uses the data you pass to build an unsigned transaction.
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
{ "txRequestId": "string", "version": 0, "latest": true, "walletId": "string", "walletType": "cold", "enterpriseId": "string", "state": "initialized", "date": "2018-05-05T19:46:22.019Z", "userId": "string", "intent": { "nonce": "string", "memo": "string", "intentType": "claim", "sequenceId": "abc123", "comment": "string", "stakingRequestId": "string", "stakingAddress": "string", "amount": { "value": "100", "symbol": "usdc" } }, "pendingApprovalId": "string", "transactions": [ { "state": "initialized", "unsignedTx": { "serializedTxHex": "string", "signableHex": "string", "derivationPath": "string", "feeInfo": { "feeString": "string", "fee": 0 } }, "signatureShares": [ { "from": "user", "to": "user", "share": "string" } ], "txHash": "string" } ] }
2. Sign Transaction
Endpoint: Sign MPC transaction
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
export BITGO_EXPRESS_HOST="<YOUR_LOCAL_HOST>" export COIN="<ASSET_ID>" export WALLET_ID="<YOUR_WALLET_ID>" export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>" export TX_REQUEST_ID="<TX_REQUEST_ID>" curl -X POST \ http://$BITGO_EXPRESS_HOST:3080/api/v2/$COIN/wallet/$WALLET_ID/signtxtss \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -d '{ "txRequestId": "'"$TX_REQUEST_ID"'", "prv": "string, # Either pass just your `prv` or pass your `walletPassphrase`, `keychain`, and `encryptedPrv` "walletPassphrase": "string", "keychain": { "encryptedPrv": "string" } }'
Step Result
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
{ "txRequestId": "string", "version": 0, "latest": true, "walletId": "string", "walletType": "cold", "enterpriseId": "string", "state": "initialized", "date": "2018-05-05T19:46:22.019Z", "userId": "string", "intent": { "nonce": "string", "memo": "string", "intentType": "claim", "sequenceId": "abc123", "comment": "string", "stakingRequestId": "string", "stakingAddress": "string", "amount": { "value": "100", "symbol": "usdc" } }, "intents": [ { "nonce": "string", "memo": "string", "intentType": "claim", "sequenceId": "abc123", "comment": "string", "stakingRequestId": "string", "stakingAddress": "string", "amount": { "value": "100", "symbol": "usdc" } } ], "pendingApprovalId": "string", "unsignedTxs": [ { "serializedTxHex": "string", "signableHex": "string", "derivationPath": "string", "feeInfo": { "feeString": "string", "fee": 0 } } ], "signatureShares": [ { "from": "user", "to": "user", "share": "string" } ], "txHashes": [ "string" ] }
3. Approve Transaction
Note: You can't approve your own transactions - another admin must approve them.
Endpoint: Update Pending Approval
1 2 3 4 5 6 7 8 9 10 11 12
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"'" }'
Step Result
Once approved, BitGo rebuilds the half-signed transaction, applying the most up-to-date fees.
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
{ "id": "65529448bd87efe59c3b0156ddfce867", "coin": "tbtc", "wallet": "654ec786c07fe8dc0dcfe03916ec5bb0", "enterprise": "62c5ae8174ac860007aff138a2d74df7", "creator": "62ab90e06dfda30007974f0a52a12995", "createDate": "2023-11-13T21:25:28.022Z", "info": { "type": "transactionRequest", "transactionRequest": { "requestedAmount": "10000", "fee": 20451, "sourceWallet": "654ec786c07fe8dc0dcfe03916ec5bb0", "policyUniqueId": "654ec786c07fe8dc0dcfe03f", "recipients": [ { "address": "2N1UvKhtSHLUa9YomSH7n9YMFCkMG2pbmsQ", "amount": "10000", "_id": "65529448bd87efe59c3b0158" } ], "coinSpecific": { "tbtc": { "txHex": "010000000001010e4d3af014f9efe311062965d561b67f78a1759e7016605cd506ddd7041762d50000000023220020510ded26d712922bbb61bc68ef6766f836a03527820cbdc8b1551914eb467dafffffffff02102700000000000017a9145a581567fd2a630e61e34a696ab3bb887972886d87ad0f010000000000225120850d0ab466d15cb1565dd528d4d9709f3e46f41d41fe6d94aa01378e626983990500483045022100db45a8d94ee2144f7e29baa855d94a2bf0120707a7ab2fc93734ed94af972c460220558d00b91275aafc7805dfaaf9ab796adbe9f4e66dc467f7eb93b790671a323201000069522103c10ac628c880629ed0fd2a0563a898f4882baca45e15668a4d3064cf1ea379882103e56f84be4460080618ef869bb7b07096880760f748ba23efab533c2359f923bd21020ae81372264b5eac5c9dc7fe0b9a32bad00771c3a2c71f6e2c971823c3182ed653ae00000000" } }, "validTransaction": "010000000001010e4d3af014f9efe311062965d561b67f78a1759e7016605cd506ddd7041762d50000000023220020510ded26d712922bbb61bc68ef6766f836a03527820cbdc8b1551914eb467dafffffffff02102700000000000017a9145a581567fd2a630e61e34a696ab3bb887972886d87ad0f010000000000225120850d0ab466d15cb1565dd528d4d9709f3e46f41d41fe6d94aa01378e626983990400483045022100db45a8d94ee2144f7e29baa855d94a2bf0120707a7ab2fc93734ed94af972c460220558d00b91275aafc7805dfaaf9ab796adbe9f4e66dc467f7eb93b790671a323201473044022049e20c0073f42c9636408efc6c833ebf0e1a8ef13e8cb818dde2f4e2af7f7b7f022000cb3a321d65605b9d51d7f87e34306169607646c8d54a44011b021eff3dbe500169522103c10ac628c880629ed0fd2a0563a898f4882baca45e15668a4d3064cf1ea379882103e56f84be4460080618ef869bb7b07096880760f748ba23efab533c2359f923bd21020ae81372264b5eac5c9dc7fe0b9a32bad00771c3a2c71f6e2c971823c3182ed653ae00000000", "validTransactionHash": "5ea8d2b93997ed9fa3597a2f3113817c8216f573a0278c2533bb5db50fdb0dff" } }, "state": "approved", "scope": "wallet", "userIds": [ "62ab90e06dfda30007974f0a52a12995", "621d08a634ad8a0007fcddffd7c429cc" ], "approvalsRequired": 1, "singleRunResults": [ { "ruleId": "Custodial Enterprise Transaction ID Verification", "triggered": false, "_id": "65529448bd87efe59c3b0157" } ], "resolvers": [ { "user": "621d08a634ad8a0007fcddffd7c429cc", "date": "2023-11-13T21:44:27.794Z", "resolutionType": "pending" } ] }
4. Send Transaction
Using the txRequestId
returned in the prior steps, send the half-signed transaction to BitGo.
Endpoint: Send a Half-Signed Transaction
1 2 3 4 5 6 7 8 9 10 11
export COIN="<ASSET_ID>" export WALLET_ID="<YOUR_WALLET_ID>" export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>" 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 '{ "txRequestId": "string" }'
Step Result
BitGo applies the final signature using the BitGo key and broadcasts the transaction to the blockchain.
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
{ "transfer": { "entries": [ { "address": "2NAVwU9KtPyE4h3RyHkhbLgQQvrc4EuSXD3", // sender address "wallet": "654ec786c07fe8dc0dcfe03916ec5bb0", "value": -100000, "valueString": "-100000" }, { "address": "2Mw241n14gJx2PcK2kijidZ2BPGeJBdwp1A", // receiver address "value": 10000, "valueString": "10000", "isChange": false, "isPayGo": false }, { "address": "tb1pq9m0lqjg4lfa0rj9wzjjjumk3l6vecndt8wla5756ktre6h6fexqg7z0vq", // change address that collects the UTXO "wallet": "654ec786c07fe8dc0dcfe03916ec5bb0", "value": 70013, "valueString": "70013", "isChange": true, "isPayGo": false } ], "id": "65528cde229f765c57a8f4d1eb762908", "coin": "tbtc", "wallet": "654ec786c07fe8dc0dcfe03916ec5bb0", "walletType": "hot", "enterprise": "62c5ae8174ac860007aff138a2d74df7", "txid": "c68916ddc1672ec62c474ef0839ec479ad9b2dabc2249177ce6be6247f81dfe7", "txidType": "transactionHash", "height": 999999999, "heightId": "999999999-65528cde229f765c57a8f4d1eb762908", "date": "2023-11-13T20:53:51.445Z", "type": "send", "value": -29987, "valueString": "-29987", "intendedValueString": "-29987", "baseValue": -10000, "baseValueString": "-10000", "baseValueWithoutFees": -10000, "baseValueWithoutFeesString": "-10000", "feeString": "19987", "payGoFee": 0, "payGoFeeString": "0", "usd": -11.0275843085, "usdRate": 36774.55, "state": "signed", "instant": false, "isReward": false, "isFee": false, "tags": [ "654ec786c07fe8dc0dcfe03916ec5bb0", "62c5ae8174ac860007aff138a2d74df7" ], "history": [ { "date": "2023-11-13T20:53:51.444Z", "action": "signed" }, { "date": "2023-11-13T20:53:50.646Z", "user": "62ab90e06dfda30007974f0a52a12995", "action": "created" } ], "signedDate": "2023-11-13T20:53:51.444Z", "vSize": 225, "metadata": [], "signedTime": "2023-11-13T20:53:51.444Z", "createdTime": "2023-11-13T20:53:50.646Z" }, "txid": "c68916ddc1672ec62c474ef0839ec479ad9b2dabc2249177ce6be6247f81dfe7", "tx": "01000000000101c76ddd01e185e12e995c6f4f36bd440867296d3f224751d73432d465be93478100000000232200204fe0358ee98bef039832fa3a4dc96cb4b265448f3d89c4a05a997a3481f3da6effffffff02102700000000000017a9142962c500562c9db56434702a629ff08fcbd5add0877d110100000000002251200176ff8248afd3d78e4570a52973768ff4cce26d59ddfed3d4d5963ceafa4e4c0400483045022100c4db3db14398d5cc4c9a2a3e4a8fa4fa3b8960ad80eb840e51e182f7561cf6c102207a6410e68aaf7327a1daed83838a39b96e37e22783d879a838640035b6059bcc0147304402205888b2863bb8fc296ed51374db2d03c7fdc746fd0d6c5ceebbe2246bb76b67840220730c8b8395285767ef1049c40cd6cbdecfb5ecfefd795ac2053b28b7a6b0790f0169522103a4c6a0aa167ef75fcf4a96c53b2dd20aee3afa19d1bc2ec4354328ae87c0976621022e4d77a9d0fecafc7ad4f9cfd9144082cf146b27de945ba26d22f26438c5784b2103ee2fef2c21d48bbd0d3813c71269fca6e1bff51e676b1f0131aa29afceb08f8853ae00000000", "status": "signed" }
Next
You can view your completed withdrawal in BitGo or on a blockchain explorer.