Withdraw On Chain from Lightning Wallet
Overview
You can withdraw bitcoin from your Lightning wallet to an on-chain address on the main Bitcoin blockchain. This process uses a specific Lightning Express endpoint to make the on-chain withdrawal.
Prerequisites
1. Build, Authenticate, and Send Transaction
Use BitGo Express to build, authenticate, and broadcast an on-chain bitcoin transaction all in one call.
Endpoint: Lightning - Onchain Withdrawal
export BITGO_EXPRESS_HOST="<YOUR_LOCALHOST>"
export COIN="tlntbc"
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export WALLET_PASSPHRASE="<YOUR_WALLET_PASSPHRASE>"
export DESTINATION_ADDRESS="<DESTINATION_ADDRESS>"
export AMOUNT_SAT="<AMOUNT_IN_SATS>"
export SATSPERVBYTE="<FEE_RATE_IN_SATS_PER_VBYTE>"
export NUM_BLOCKS="<NUMBER_OF_BLOCKS_FOR_CONFIRMATION>"
curl -X POST \
http://$BITGO_EXPRESS_HOST/api/v2/$COIN/wallet/$WALLET_ID/lightning/withdraw \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"passphrase": "'"$WALLET_PASSPHRASE"'", # Wallet passphrase
"recipients": [ # Array of recipients for the withdrawal
{
"amount": "'"$AMOUNT_SAT"'", # Amount to send in satoshis
"address": "'"$DESTINATION_ADDRESS"'" # Destination Bitcoin address
}
],
"satsPerVbyte": "'"$SATSPERVBYTE"'" # Fee rate in satoshis per virtual byte
"numBlocks": "'"$NUM_BLOCKS"'" # Target number of blocks for confirmation, used for fee estimation
"sequenceId": string, # Custom identifier for tracking the payment
"comment": string # Additional note or comment for internal reference
}'
const { BitGo } = require('bitgo');
const { getLightningWallet } = require('@bitgo/abstract-lightning');
const accessToken = '<YOUR_ACCESS_TOKEN>';
// Initialize the SDK
const bitgo = new BitGo({
accessToken: accessToken,
env: 'test',
customRootURI: 'https://app.bitgo-test.com',
});
// Enter your Lightning wallet
const walletId = '<YOUR_WALLET_ID>'
const existingWallet = await bitgo.coin('tlnbtc').wallets().get({ id: walletId });
const lightningWallet = getLightningWallet(existingWallet);
const onchainWithdrawal = await lightningWallet.withdrawOnchain({
recipients: [
{
amount: 'amount to be sent in satoshis',
address: 'destination address'
}
],
satsPerVbyte: 'fee rate in satoshis per virtual byte',
passphrase: 'your wallet passphrase',
});
console.dir(onchainWithdrawal);
Step Result
If your on-chain withdrawal doesn't require approval, BitGo publishes the transaction to the blockchain. If you Create Policy Rules to require approvals on withdrawals, the transaction remains in a pending-approval status until a wallet admin approves it.
{
"txRequestId": string, // Unique identifier for the transaction request
"txRequestState": delivered, // State of the transaction request
"withdrawStatus": {
"status": delivered, // Withdrawal status
"txid": string, // transaction ID of the on-chain transaction
"failureReason": string // Reason for failure if withdrawal failed
},
"transfer": {
"id": string,
"coin": string,
"wallet": string,
"walletType": string,
"enterprise": string,
"organization": string,
"txid": string,
"state": string, // initialized, unconfirmed, confirmed
"type": string, // send, receive
"value": number // millisatoshis
"valueString": string, // millisatoshis
"coinSpecific": {
"isOffchain": false,
"invoice": string
},
}
}
2. Approve Transaction (Optional)
Note: If you configure an approval requirement for withdrawals, you can't approve your own transactions - another admin must approve them.
Endpoint: Update Pending Approval
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"'"
}'
const baseCoin = this.bitgoSDK.coin(initialPendingApproval.coin);
const pendingApproval = await baseCoin.pendingApprovals().get({ id: initialPendingApproval.id });
const result = await pendingApproval.approve(params);
Step Result
Once approved, BitGo submits the transaction to a Lightning Network Daemon (LND) for broadcasting to the Bitcoin blockchain.
{
"id": "655686880765186f0b3e9e88e1bdd0f4",
"coin": "tbtc4",
"wallet": "6553e933288be490293ae748efafeaaf",
"enterprise": "62c5ae8174ac860007aff138a2d74df7",
"creator": "62ab90e06dfda30007974f0a52a12995",
"createDate": "2023-11-16T21:15:52.703Z",
"info": {
"type": "transactionRequest",
"transactionRequest": {
"requestedAmount": "10000",
"fee": 45242,
"sourceWallet": "6553e933288be490293ae748efafeaaf",
"policyUniqueId": "6553e933288be490293ae753",
"recipients": [
{
"address": "2N3sBpM1RnWRMXnEVoUWnM7xtYzL756JE2Q",
"amount": "10000",
"_id": "655686880765186f0b3e9e8a"
}
],
"buildParams": {
"recipients": [
{
"address": "2N3sBpM1RnWRMXnEVoUWnM7xtYzL756JE2Q",
"amount": "10000"
}
],
"changeAddressType": [
"p2trMusig2",
"p2wsh",
"p2shP2wsh",
"p2sh",
"p2tr"
],
"txFormat": "psbt"
},
"coinSpecific": {
"tbtc4": {
"txHex": "01000000000101eac5e7d68acfc2349672fb99094e79c2006e5fd663475c8f1eb6f29095970b740100000000ffffffff02102700000000000017a914747e6b7f5db53794b0fc01d95878e0f9b6db96738746c1020000000000220020efb9deaabeab5d62cecc363f24cd6deafcdd14d93d8734f7f01ed3953e732a640500483045022100cd6c221e4cefbb51aa82087d86e7d089b2473eb21ae809dba89eb9f13c4caf19022000f3b7f1b7fec2dc49cbfce35baa69ca37ab9ee8e51c779cde5b98a653f3e142010000695221029bde55661e4f359cf9ca2d1846c235e752f760ed6d65e2018f821253e78b3c722103f2b4a813ab79e4fb46edf3a6a87fb154a85b45810158e949f41a3fce3c9bf574210399a6d766f6d3a3843f8479446ee766b5745dc15c24d1db5149214d27987bd29453ae00000000"
}
},
"validTransaction": "01000000000101eac5e7d68acfc2349672fb99094e79c2006e5fd663475c8f1eb6f29095970b740100000000ffffffff02102700000000000017a914747e6b7f5db53794b0fc01d95878e0f9b6db96738746c1020000000000220020efb9deaabeab5d62cecc363f24cd6deafcdd14d93d8734f7f01ed3953e732a640400483045022100cd6c221e4cefbb51aa82087d86e7d089b2473eb21ae809dba89eb9f13c4caf19022000f3b7f1b7fec2dc49cbfce35baa69ca37ab9ee8e51c779cde5b98a653f3e14201473044022002b246c43722fec49858caf6b0605a0d01a6b6c13c964b84bf272604fd3951780220324ee44ba3ce8febb154c317e688a5f6ed410ad8e2bd77c5678bf1f7f3eb45f601695221029bde55661e4f359cf9ca2d1846c235e752f760ed6d65e2018f821253e78b3c722103f2b4a813ab79e4fb46edf3a6a87fb154a85b45810158e949f41a3fce3c9bf574210399a6d766f6d3a3843f8479446ee766b5745dc15c24d1db5149214d27987bd29453ae00000000",
"validTransactionHash": "ff40ccd5c8ba75ffdce27d8584b6e8ee625cb3f71f7cbb6d072a445a97c2c8c3"
}
},
"state": "approved",
"scope": "wallet",
"userIds": [
"62ab90e06dfda30007974f0a52a12995",
"627ff9325a5c1b0007c05a40d15e1522"
],
"approvalsRequired": 1,
"singleRunResults": [
{
"ruleId": "Custody Enterprise Transaction ID Verification",
"triggered": false,
"_id": "655686880765186f0b3e9e89"
}
],
"resolvers": [
{
"user": "627ff9325a5c1b0007c05a40d15e1522",
"date": "2023-11-16T21:33:24.644Z",
"resolutionType": "pending"
}
]
}
{
"id": "65568eda6c1568b87f40a6131d4fbc89",
"coin": "tbtc4",
"wallet": "6553e933288be490293ae748efafeaaf",
"enterprise": "62c5ae8174ac860007aff138a2d74df7",
"creator": "62ab90e06dfda30007974f0a52a12995",
"createDate": "2023-11-16T21:51:22.221Z",
"info": {
"type": "transactionRequest",
"transactionRequest": {
"requestedAmount": "20000",
"fee": 51622,
"sourceWallet": "6553e933288be490293ae748efafeaaf",
"policyUniqueId": "6553e933288be490293ae753",
"recipients": [
{
"address": "2MzCZbQ2pcHKBPzhpdeaKBgu52YtqdDv6Le",
"amount": "10000",
"_id": "65568eda6c1568b87f40a615"
},
{
"address": "2NDi4jr1DjqpWBU6FJRqq5uaiWihwXJAWSU",
"amount": "10000",
"_id": "65568eda6c1568b87f40a616"
}
],
"buildParams": {
"recipients": [
{
"address": "2MzCZbQ2pcHKBPzhpdeaKBgu52YtqdDv6Le",
"amount": "10000"
},
{
"address": "2NDi4jr1DjqpWBU6FJRqq5uaiWihwXJAWSU",
"amount": "10000"
}
],
"changeAddressType": [
"p2trMusig2",
"p2wsh",
"p2shP2wsh",
"p2sh",
"p2tr"
],
"txFormat": "psbt"
},
"coinSpecific": {
"tbtc4": {
"txHex": "01000000000101c3c8c2975a442a076dbb7c1ff7b35c62eee8b684857de2dcff75bac8d5cc40ff0100000000ffffffff03102700000000000017a9144c47ff958d212988eb5e0407ede223d66d8fdbab87102700000000000017a914e07606a95924b156375a9b3929c2ae63db20e3bd8780a90100000000002200209cb3a333ddbdb7496ad4c7ee8f339ac2e3dfb648e3dfec4b0635b0e5541102610500483045022100883f2c5a762a307380723cad5d536329b45aa2a67ee5c53940551c926902929002203cba824bc6fc01ba6510131b47137dc7b292d96938c89c7e12b891ca039781f601000069522102b2c328f03cb3b1a513adaae92226dfbaeabfdf053ba5057b1922a327798261a22102c0e4a38730d48b220547abe8d6676c9a432245c7c968b5e8e9609a7837c773b021025e180472019c87bc2cdef9e1bc787369e9e5fd6212c5f01549bb96c155e8cdbd53ae00000000"
}
},
"validTransaction": "01000000000101c3c8c2975a442a076dbb7c1ff7b35c62eee8b684857de2dcff75bac8d5cc40ff0100000000ffffffff03102700000000000017a9144c47ff958d212988eb5e0407ede223d66d8fdbab87102700000000000017a914e07606a95924b156375a9b3929c2ae63db20e3bd8780a90100000000002200209cb3a333ddbdb7496ad4c7ee8f339ac2e3dfb648e3dfec4b0635b0e5541102610400483045022100883f2c5a762a307380723cad5d536329b45aa2a67ee5c53940551c926902929002203cba824bc6fc01ba6510131b47137dc7b292d96938c89c7e12b891ca039781f60147304402203c309e14eda12d133d7885deddbf95b15878fc69758bd81bb3b3fbaf1088c8dc02201286da4e0ffde355d399b6659feb2d30db28f26586e0de9d3f8f9a6fb701ac330169522102b2c328f03cb3b1a513adaae92226dfbaeabfdf053ba5057b1922a327798261a22102c0e4a38730d48b220547abe8d6676c9a432245c7c968b5e8e9609a7837c773b021025e180472019c87bc2cdef9e1bc787369e9e5fd6212c5f01549bb96c155e8cdbd53ae00000000",
"validTransactionHash": "4929b91960acdf2d18076ac6151d0aff96b4f4834f9f78eaf40e78ce05f5c0a4"
}
},
"state": "approved",
"scope": "wallet",
"userIds": [
"62ab90e06dfda30007974f0a52a12995",
"627ff9325a5c1b0007c05a40d15e1522"
],
"approvalsRequired": 1,
"singleRunResults": [
{
"ruleId": "Custody Enterprise Transaction ID Verification",
"triggered": false,
"_id": "65568eda6c1568b87f40a614"
}
],
"resolvers": [
{
"user": "627ff9325a5c1b0007c05a40d15e1522",
"date": "2023-11-16T21:56:45.511Z",
"resolutionType": "pending"
}
]
}
Next
You can view your completed on-chain withdrawal in BitGo or on a blockchain explorer.
See Also
Updated 1 day ago