Skip to main content

Processing Withdrawals

This guide covers best practices for building a secure, scalable withdrawal flow — from transaction creation to on-chain confirmation.

Overview

The withdrawal flow:

  1. Create a transaction with the destination address, amount, and asset
  2. Approval pipeline — transaction goes through quorum-based approval (if configured)
  3. MPC signing — cosigners produce the signature
  4. Broadcast — signed transaction is submitted to the blockchain
  5. Confirmation — track until mined

Basic Withdrawal

curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"orderId": "c3d4e5f6-a7b8-4c9d-0e1f-2a3b4c5d6e7f",
"vaultId": "kR7mNpX2wQvL9sYhBjD4eT",
"addressId": "nP6qR8sT0uV2wXyZaBcDeF",
"destination": "0x742d35Cc6634C0532925a3b8...",
"network": "ethereum-mainnet",
"asset": "c60_t0xdac17f958d2ee523a2206206994597c13d831ec7",
"amount": "500.00",
"feePriority": "medium"
}' \
https://api.carabaas.com/api/v1/transactions

Idempotency

The orderId field ensures idempotency. Submitting the same orderId twice returns the existing transaction instead of creating a duplicate — critical for preventing double-spends.

Approval Pipeline

For vaults with quorum configured, transactions enter approval-pending state:

  1. Transaction is created → approval-pending
  2. Approvers are notified (via webhook or polling)
  3. Each approver signs the transaction payload with their RSA key
  4. Once the quorum threshold is met → transaction proceeds to signing
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"approval": "base64_encoded_signature",
"keyId": "approver-key-id"
}' \
https://api.carabaas.com/api/v1/transactions/{txId}/approve

See Approval Workflow for full implementation details.

Monitoring Withdrawals

Subscribe to the outgoing webhook stream:

curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/withdrawals",
"streams": ["outgoing"]
}' \
https://api.carabaas.com/api/v1/subscriptions/{vaultId}

Transaction State Notifications

EventMeaningAction
approval-pendingWaiting for approvalsNotify approvers
approvedOne approval receivedTrack quorum progress
requestedSubmitted to MPC signingWait for signature
signedMPC signature completedWait for broadcast
submittedBroadcast to blockchainTrack confirmations
minedConfirmed on blockchainMark as complete
warningInsufficient balance — retrying for 72hReplenish source address
cancelledCancelled (e.g., balance timeout)Notify customer
rolledbackRolled back after submissionInvestigate and retry

Fee Management

Fee Priority

PriorityDescription
lowLower fee, slower confirmation
mediumBalanced fee and speed
highHigher fee, faster confirmation

Transaction Replacement (RBF)

If a transaction is stuck due to low fees, replace it:

curl -X PATCH \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "feePriority": "high" }' \
https://api.carabaas.com/api/v1/transactions/{txId}/replace

Insufficient Balance Handling

If the source address has insufficient funds at signing time:

  1. The platform sends a warning webhook notification with reasonCode: "insufficient_balance"
  2. The platform waits up to 72 hours for the balance to be replenished
  3. If funds arrive within that window, the transaction proceeds automatically
  4. Otherwise, it is cancelled with a cancelled notification
tip

Monitor warning notifications and set up alerts to replenish source addresses proactively.

Transaction Simulation

Preview a transaction before committing:

curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"vaultId": "kR7mNpX2wQvL9sYhBjD4eT",
"destination": "0x742d35Cc...",
"network": "ethereum-mainnet",
"asset": "c1",
"amount": "1.0"
}' \
https://api.carabaas.com/api/v1/transactions/simulate

Withdrawal Vault Patterns

PatternDescription
Single withdrawal vaultSimple setup for low-volume operations
Hot / cold splitHot vault for daily operations, cold vault for reserves
Per-departmentSeparate vaults for operations, finance, risk

Address Validation

Always validate destination addresses before creating transactions:

curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"network": "ethereum-mainnet",
"address": "0x742d35Cc..."
}' \
https://api.carabaas.com/api/v1/addresses/canonicalize

Address Book Whitelisting

For additional security, maintain a whitelist of approved destination addresses:

curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"items": [{
"address": "0x742d35Cc...",
"network": "ethereum-mainnet",
"name": "Supplier Wallet"
}]
}' \
https://api.carabaas.com/api/v1/addressbooks

See Also