Accelerate Transactions
Overview
During periods of high transaction volume, transactions with lower fees might get stuck waiting for confirmation in the mempool. If this happens, you can accelerate the transaction by creating a new transaction with a higher fee. The new transaction replaces the original in the mempool and has a higher probability of being mined more quickly, since miners and validators are economically incentivized.
Transaction acceleration differs between UTXO and account-based assets.
You can subscribe to the stuckTx wallet webhook to receive notifications when a transaction becomes stuck. For more information, see Create Wallet Webhooks.
Recipes
Need just the steps? Expand a recipe below to get started:
Account-Based
UTXO
Ethereum, and other EVM blockchains, allow for only one transaction per nonce from a single address. A nonce is a sequential counter for transactions sent from an account. Therefore, you can accelerate a stuck transaction by rebroadcasting the same transaction with the same nonce but with a higher fee.
Prerequisites
- Get Started
- Initiate a withdrawal (see Withdraw Overview).
Build Acceleration Transaction
Endpoints:
export COIN="<ASSET_ID>"
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export NONCE="<NONCE_OF_STUCK_TRANSACTION>"
export MAX_FEE_PER_GAS="<HIGHER_MAX_FEE_PER_GAS>"
export MAX_PRIORITY_FEE_PER_GASE="<HIGHER_MAX_PRIORITY_FEE_PER_GAS>"
curl -X POST \
https://app.bitgo-test.com/api/v2/$COIN/wallet/$WALLET_ID/tx/initiate \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"type": "acceleration",
"nonce": "'"$NONCE"'",
"eip1559": {
"maxFeePerGas": "'"$MAX_FEE_PER_GAS"'",
"maxPriorityFeePerGas": "'"$MAX_PRIORITY_FEE_PER_GASE"'"
},
"recipients": [...] # Use the exact recipients array from the original transaction
}'export WALLET_ID="<WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export MAX_FEE_PER_GAS="<HIGHER_MAX_FEE_PER_GAS>"
export MAX_PRIORITY_FEE_PER_GASE="<HIGHER_MAX_PRIORITY_FEE_PER_GAS>"
export NONCE="<NONCE_OF_STUCK_TRANSACTION>"
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": {
"feeOptions": {
"gasLimit": 0,
"maxFeePerGas": "'"$MAX_FEE_PER_GAS"'",
"maxPriorityFeePerGas": "'"$MAX_PRIORITY_FEE_PER_GASE"'"
},
"intentType": "acceleration",
"txid": "string",
"sequenceId": "string",
"nonce": "'"$NONCE"'",
"hopParams": {
"gasPriceMax": 0,
"paymentId": "string",
"userReqSig": "string"
},
"receiveAddress": "string",
"senderAddressIndex": 0
},
"videoApprovers": [
"585951a5df8380e0e3063e9f",
"585951a5df8380e0e304a553"
],
"apiVersion": "lite",
"preview": false
}'export WALLET_ID="<WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export MAX_FEE_PER_GAS="<HIGHER_MAX_FEE_PER_GAS>"
export MAX_PRIORITY_FEE_PER_GASE="<HIGHER_MAX_PRIORITY_FEE_PER_GAS>"
export NONCE="<NONCE_OF_STUCK_TRANSACTION>"
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": {
"feeOptions": {
"gasLimit": 0,
"maxFeePerGas": "'"$MAX_FEE_PER_GAS"'",
"maxPriorityFeePerGas": "'"$MAX_PRIORITY_FEE_PER_GASE"'"
},
"intentType": "acceleration",
"txid": "string",
"sequenceId": "string",
"nonce": "'"$NONCE"'",
"hopParams": {
"gasPriceMax": 0,
"paymentId": "string",
"userReqSig": "string"
},
"receiveAddress": "string",
"senderAddressIndex": 0
},
"videoApprovers": [
"585951a5df8380e0e3063e9f",
"585951a5df8380e0e304a553"
],
"apiVersion": "lite",
"preview": false
}'export COIN="<ASSET_ID>"
export WALLET_ID="<WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export NONCE="<NONCE_OF_STUCK_TRANSACTION>"
export MAX_FEE_PER_GAS="<HIGHER_MAX_FEE_PER_GAS>"
export MAX_PRIORITY_FEE_PER_GASE="<HIGHER_MAX_PRIORITY_FEE_PER_GAS>"
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 '{
"type": "acceleration",
"nonce": "'"$NONCE"'",
"eip1559": {
"maxPriorityFeePerGas": "'"$MAX_FEE_PER_GAS"'",
"maxPriorityFeePerGas": "'"$MAX_PRIORITY_FEE_PER_GASE"'"
},
"recipients": [...], # Use the exact recipients array from the original transaction
}'Step Result
{
"txRequestId": "string",
"version": 0,
"latest": true,
"walletId": "string",
"walletType": "cold",
"enterpriseId": "string",
"state": "initialized",
"date": {},
"createdDate": {},
"userId": "string",
"initiatedBy": "string",
"updatedBy": "string",
"intent": {
"feeOptions": {
"unit": "baseUnit",
"formula": "fixed",
"feeType": "base",
"gasLimit": 0,
"gasPrice": 0
},
"intentType": "acceleration",
"txid": "string",
"sequenceId": "string",
"comment": "string",
"nonce": "string",
"hopParams": {
"gasPriceMax": 0,
"paymentId": "string",
"userReqSig": "string"
},
"receiveAddress": "string",
"senderAddressIndex": 0
},
"intents": [
{
"intentType": "stake",
"sequenceId": "abc123",
"comment": "string",
"nonce": "string",
"memo": "string",
"stakingRequestId": "string",
"poolKeyHash": "string"
}
],
"pendingApprovalId": "string",
"isCanceled": true,
"unsignedTxs": [
{
"serializedTxHex": "string",
"signableHex": "string",
"derivationPath": "string",
"feeInfo": {
"feeString": "string",
"fee": 0
},
"coinSpecific": {},
"parsedTx": {
"minerFee": "string",
"spendAmount": "string",
"spendAmounts": [
{
"coinName": "string",
"amountString": "string"
}
],
"payGoFee": "string",
"outputs": [
{
"address": "string",
"isPayGo": true,
"value": 0,
"wallet": "string",
"walletV1": "string",
"baseAddress": "string",
"enterprise": "string",
"valueString": "string",
"data": "string",
"change": true,
"coinName": "string"
}
],
"inputs": [
{
"derivationIndex": 0,
"value": 0,
"address": "string",
"valueString": "string",
"chain": 0,
"index": 0
}
],
"type": "string",
"memo": "string"
}
}
],
"signatureShares": [
{
"from": "user",
"to": "user",
"share": "string"
}
],
"commitmentShares": [
{
"from": "user",
"to": "user",
"share": "string",
"type": "commitment"
}
],
"txHashes": [
"string"
]
}You have two options to accelerate a stuck UTXO transaction:
- Replace-By-Fee (RBF) - RBF transactions include a higher fee and replace the lower-fee stuck transaction. To learn more, see the concept topic, Replace-By-Fee (RBF).
- Child-Pays-For-Parent (CPFP) - CPFP transactions utilize a stuck transaction output of a lower-fee parent transaction to create a higher-fee child transaction. The parent transaction must be confirmed before the child transaction. Therefore, miners are likely to included both in the same block.
Note: BitGo recommends accelerating using RBF, and by default, enables RBF for all transactions created in the BitGo web application.
Prerequisites
- Get Started
- To accelerate using RBF, ensure your initial transaction was built with
isReplaceableByFeeset totrue. To learn more, see Withdraw Overview.
Build Acceleration Transaction
Endpoint: Accelerate Transaction
export COIN="<ASSET_ID>"
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export TRANSACTION_ID="<STUCK_TX_ID>"
export FEE_MULTIPLIER="<FEE_MULTIPLIER>"
curl -X POST \
"http://$BITGO_EXPRESS_HOST/api/v2/$COIN/wallet/$WALLET_ID/acceleratetx" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"rbfTxIds": ["'"$TRANSACTION_ID"'"],
"feeMultiplier": "'"$FEE_MULTIPLIER"'"
}'export COIN="<ASSET_ID>"
export WALLET_ID="<YOUR_WALLET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export TRANSACTION_ID="<STUCK_TX_ID>"
export FEE_RATE="<FEE_RATE>"
export MAX_FEE="<MAX_FEE>"
curl -X POST \
"http://$BITGO_EXPRESS_HOST/api/v2/$COIN/wallet/$WALLET_ID/acceleratetx" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"cpfpTxIds": ["'"$TRANSACTION_ID"'"],
"cpfpFeeRate": "'"$FEE_RATE"'",
"maxFee": "'"$MAX_FEE"'"
}'Step Result
{
"transfer": {
"coin": "btc",
"id": "59cd72485007a239fb00282ed480da1f",
"wallet": "59cd72485007a239fb00282ed480da1f",
"enterprise": "59cd72485007a239fb00282ed480da1f",
"txid": "b8a828b98dbf32d9fd1875cbace9640ceb8c82626716b4a64203fdc79bb46d26",
"txidType": "transactionHash",
"height": 0,
"heightId": "string",
"date": "2019-08-24T14:15:22Z",
"confirmations": 0,
"type": "send",
"value": 0,
"valueString": "2000000",
"intendedValueString": "2000000",
"baseValue": 0,
"baseValueString": "2000000",
"baseValueWithoutFees": 0,
"baseValueWithoutFeesString": "2000000",
"feeString": "string",
"payGoFee": 0,
"payGoFeeString": "string",
"usd": 0,
"usdRate": 0,
"state": "confirmed",
"tags": [
"59cd72485007a239fb00282ed480da1f"
],
"history": [
{
"date": "2019-08-24T14:15:22Z",
"user": "59cd72485007a239fb00282ed480da1f",
"action": "created",
"comment": "string"
}
],
"comment": "string",
"vSize": 0,
"coinSpecific": {},
"sequenceId": "string",
"entries": [
{
"address": "2NAUwNgXaoFj2VVnSEvNLGuez8CfdU2UCMZ",
"wallet": "string",
"value": 0,
"valueString": "string",
"isChange": true,
"isPayGo": true,
"token": "omg",
"label": "string",
"failed": true
}
],
"usersNotified": true,
"label": "string",
"replaces": [
"string"
],
"replacedBy": [
"string"
]
},
"txid": "string",
"tx": "string",
"status": "signed"
}Next
Acceleration transactions follow the transaction flow of their wallet type, and must receive all required signatures and approvals before before broadcasting to the blockchain. To learn more, see Withdraw Overview
After receiving all required signatures and approvals, BitGo broadcasts the transaction to the blockchain. You can view your completed transaction in BitGo or on a blockchain explorer. For UTXO assets, the blockchain explorer may also identify the transaction with an RBF or CPFP flag. Once your accelerated transaction is confirmed on chain, BitGo updates the status of the original transaction to Replaced.
See Also
Updated 3 months ago