Set Up Deposit/Withdraw Wallet
Overview
The deposit/withdraw wallet is a self-custody hot wallet used for day-to-day customer operations. This wallet holds the smallest amount of funds and has no restrictive policies, allowing spenders to freely process customer deposits and withdrawals.
In the custody starter architecture, this wallet:
- Holds the smallest amount of assets (only what you need for daily operations).
- Has no policies or minimal policies for maximum operational flexibility.
- Allows spenders to withdraw freely without approval requirements.
- Receives customer deposits.
- Processes customer withdrawals.
Prerequisites
Create Deposit/Withdraw Wallet
Generate a self-custody hot wallet using BitGo Express or the SDK. You configure this wallet without restrictive policies to enable rapid customer transactions.
Endpoint: Generate Wallet
export BITGO_EXPRESS_HOST="<YOUR_LOCAL_HOST>"
export COIN="<ASSET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export ENTERPRISE="<YOUR_ENTERPRISE_ID>"
export PASSPHRASE="<YOUR_WALLET_PASSPHRASE>"
export LABEL="<YOUR_DESIRED_WALLET_NAME>"
curl -X POST \
http://$BITGO_EXPRESS_HOST/api/v2/$COIN/wallet/generate \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"enterprise": "'"$ENTERPRISE"'",
"passphrase": "'"$PASSPHRASE"'",
"label": "'"$LABEL"'",
"multisigType": "onchain",
"type": "hot"
}'const { BitGo } = require('bitgo');
const accessToken = '<YOUR_ACCESS_TOKEN>';
const bitgo = new BitGo({
accessToken: accessToken,
env: 'prod',
});
async function createDepositWithdrawWallet() {
const newWallet = await bitgo.coin('<ASSET_ID>').wallets().generateWallet({
label: 'Deposit-Withdraw Wallet - Hot',
passphrase: '<YOUR_WALLET_PASSPHRASE>',
enterprise: '<YOUR_ENTERPRISE_ID>',
multisigType: 'onchain',
type: 'hot'
});
console.log('Deposit/Withdraw Wallet Created:');
console.log('Wallet ID:', newWallet.wallet.id());
console.log('Receive Address:', newWallet.wallet.receiveAddress());
// IMPORTANT: Save the backup keychain securely
console.log('Backup Keychain (SAVE SECURELY):', newWallet.backupKeychain);
}
createDepositWithdrawWallet();Step Result
NoteThis response contains critical key material. Save the backup keychain in a secure place.
{
"wallet": {
"id": "7849948ac0623f81f74f63dbd8351d5g",
"users": [
{
"user": "62ab90e06dfda30007974f0a52a12995",
"permissions": ["admin", "spend", "view"]
}
],
"coin": "btc",
"label": "Deposit-Withdraw Wallet - Hot",
"m": 2,
"n": 3,
"keys": [
"78499487e6c77351bd3bbf04281fa8cc",
"78499487cd07fc57de18f6481baa1904",
"7849948902be620840a384c148d19980"
],
"enterprise": "62c5ae8174ac860007aff138a2d74df7",
"approvalsRequired": 1,
"isCold": false,
"type": "hot",
"multisigType": "onchain",
"receiveAddress": {
"address": "bc1p..."
}
},
"userKeychain": {
"id": "78499487e6c77351bd3bbf04281fa8cc",
"pub": "xpub661MyMwAqRbcEst4tb4F36AfvoFtAy7U9viB7zapRqNnXhPknsPwNqhxpD1CqMGSGhq3hDMKQR1Br8gGxYygoR6SGic3XdJoTEzM5v9wyFy",
"source": "user",
"encryptedPrv": "{...}"
},
"backupKeychain": {
"id": "78499487cd07fc57de18f6481baa1904",
"pub": "xpub661MyMwAqRbcEfnfBkVRk9BB1SrYaFR884ndYpmNXnci6U2wrAQCsFiD21c49Aq7EvtK6QFzDzMwmFKVqi1bTL7kmuCEJ78bFn9Rq6NyLDV",
"source": "backup",
"encryptedPrv": "{...}"
},
"bitgoKeychain": {
"id": "7849948902be620840a384c148d19980",
"pub": "xpub661MyMwAqRbcGCXsEAmctkLstGa92f5ugiD3hvCL3Wyt8BqHYGCVsL2x6PgNgJeq8Aabtz92sMzq4Ezac459QkDmxowKqoL35gNJXEJDdeo",
"source": "bitgo",
"isBitGo": true
}
}
NoteSave the wallet ID and backup keychain from the response. You need the wallet ID to configure whitelist policies with the standby wallet.
Policy Configuration
The deposit/withdraw wallet is intentionally configured with no restrictive policies to enable rapid customer transactions. Spenders can freely initiate and complete withdrawals without approval requirements.
If your use case requires some level of control, consider these optional lightweight policies:
- Velocity limit alerts: Configure notifications when withdrawal volume exceeds thresholds (without blocking transactions).
- Monitoring webhooks: Set up webhooks to track all transactions for audit purposes.
NoteAdding approval requirements to this wallet defeats the purpose of having a free-spending operational wallet. Only add policies if your compliance requirements mandate them.
Withdrawal Flow
Since this wallet has no approval policies, withdrawals can use either the simple or manual flow. Choose the appropriate tab based on your wallet type (Multisig or MPC) and preferred level of control.
The simple withdrawal flow for self-custody multisignature hot wallets enables you to build, sign, and send transactions, all in one call, using BitGo Express. The simple flow suffices for most multisignature use cases. If you require more granular control, see the Multisig Hot Manual tab.
The simple flow also supports sending to many recipients in 1 transaction, lowering the aggregate amount of blockchain fees when compared to creating multiple transactions.
1. Build, Sign, and Send Transaction
Build and sign the transaction and send it to BitGo, all in one call.
Endpoint: Send Transaction
export BITGO_EXPRESS_HOST="<YOUR_LOCAL_HOST>"
export COIN="<ASSET_ID>"
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export WALLET_PASSPHRASE="<YOUR_WALLET_PASSPHRASE>"
export ADDRESS="<DESTINATION_ADDRESS>"
export AMOUNT="<AMOUNT_IN_BASE_UNITS>"
curl -X POST \
http://$BITGO_EXPRESS_HOST/api/v2/$COIN/wallet/$WALLET_ID/sendcoins \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"address": "'"$ADDRESS"'",
"amount": "'"$AMOUNT"'",
"walletPassphrase": "'"$WALLET_PASSPHRASE"'",
"type": "transfer",
"txFormat": "psbt"
}'const tx = await wallet.send({
address: '<DESTINATION_ADDRESS>',
amount: '<AMOUNT>',
walletPassphrase: '<YOUR_WALLET_PASSPHRASE>',
txFormat: 'psbt',
type: 'transfer'
});
console.log('Transaction sent:', tx.txid);
Note: If you are building transactions for a UTXO asset in quick succession, BitGo recommends reserving unspents by passing thereservationandexpireTimeparameters. Reserving unspents avoids errors by ensuring the UTXO are not included in subsequent builds.
Step Result
BitGo uses the data you pass to build a half-signed transaction. Since this wallet has no approval policies, BitGo applies the final signature using the BitGo key and broadcasts the transaction to the blockchain immediately.
{
"transfer": {
"entries": [
{
"address": "2N1poiHTi5ur8hz5QBhNoy88bYzqrWYvBbV",
"wallet": "6553e933288be490293ae748efafeaaf",
"value": -100000,
"valueString": "-100000"
},
{
"address": "2Myx8nY8ReERqUwu9H96Lb2K4yYjs3xY8GH",
"value": 10000,
"valueString": "10000",
"isChange": false,
"isPayGo": false
},
{
"address": "tb1q5xtred89revxp789r6dmvyf74vgecczp2ch2hvhlj8anjkcepqtspu7j7d",
"wallet": "6553e933288be490293ae748efafeaaf",
"value": 331419,
"valueString": "331419",
"isChange": true,
"isPayGo": false
}
],
"id": "6553ee12d5a49ecc9baccdcbe0563448",
"coin": "tbtc4",
"wallet": "6553e933288be490293ae748efafeaaf",
"walletType": "hot",
"txid": "e7648c85edac7f9870e511b4ef95b62b1878556791bd52ac715cb2cd4b466e6f",
"state": "signed",
"type": "send"
},
"txid": "e7648c85edac7f9870e511b4ef95b62b1878556791bd52ac715cb2cd4b466e6f",
"status": "signed"
}Customer Deposits
Share the wallet receive address with customers to receive deposits. For enhanced privacy, create unique addresses for each customer or transaction.
const wallet = await bitgo.coin('<ASSET_ID>').wallets().get({ id: '<DEPOSIT_WITHDRAW_WALLET_ID>' });
// Create a new receive address
const address = await wallet.createAddress({ label: 'Customer ABC Deposit' });
console.log('New deposit address:', address.address);For more details, see Create Receive Addresses.
Next
Create Whitelists (Standby-Deposit tab)
See Also
- Custody Starter Architecture Overview
- Create Wallets
- Withdraw from Self-Custody Multisig Hot Wallet (Simple)
- Withdraw from Self-Custody Multisig Hot Wallet (Manual)
- Withdraw from Self-Custody MPC Hot Wallet (Simple)
- Withdraw from Self-Custody MPC Hot Wallet (Manual)
- Create Addresses
- API Reference: Build a Transaction
- API Reference: Create transaction request
- API Reference: Create a signature share for the transaction request
- API Reference: Get transaction requests by wallet
- API Reference: Send Half-Signed Transaction
- API Reference: Send to Many
- API Reference: Send Transaction
- API Reference: Sign MPC transaction
- API Reference: Sign Transaction
Updated 1 day ago