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:
- Create a transaction with the destination address, amount, and asset
- Approval pipeline — transaction goes through quorum-based approval (if configured)
- MPC signing — cosigners produce the signature
- Broadcast — signed transaction is submitted to the blockchain
- 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:
- Transaction is created →
approval-pending - Approvers are notified (via webhook or polling)
- Each approver signs the transaction payload with their RSA key
- 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
| Event | Meaning | Action |
|---|---|---|
approval-pending | Waiting for approvals | Notify approvers |
approved | One approval received | Track quorum progress |
requested | Submitted to MPC signing | Wait for signature |
signed | MPC signature completed | Wait for broadcast |
submitted | Broadcast to blockchain | Track confirmations |
mined | Confirmed on blockchain | Mark as complete |
warning | Insufficient balance — retrying for 72h | Replenish source address |
cancelled | Cancelled (e.g., balance timeout) | Notify customer |
rolledback | Rolled back after submission | Investigate and retry |
Fee Management
Fee Priority
| Priority | Description |
|---|---|
low | Lower fee, slower confirmation |
medium | Balanced fee and speed |
high | Higher 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:
- The platform sends a
warningwebhook notification withreasonCode: "insufficient_balance" - The platform waits up to 72 hours for the balance to be replenished
- If funds arrive within that window, the transaction proceeds automatically
- Otherwise, it is cancelled with a
cancellednotification
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
| Pattern | Description |
|---|---|
| Single withdrawal vault | Simple setup for low-volume operations |
| Hot / cold split | Hot vault for daily operations, cold vault for reserves |
| Per-department | Separate 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