githubEdit

CBTC Minting and Burning

👥 Audience: App Developers and Infrastructure Integrators building minting or redemption flows into their applications.

⚠️ API Disclaimer: CBTC APIs are subject to change. There is no formal versioning policy today. Breaking changes are communicated via #cbtc-ecosystem and the site changelog. All code examples require Engineering validation before production use.


Overview: The Full BTC to CBTC Lifecycle

This guide covers the complete lifecycle of converting Bitcoin to CBTC and back: minting (BTC to CBTC on Canton) and burning (CBTC back to BTC). For a quick end-to-end walkthrough, see the CBTC Quick Start. This guide goes deeper into each step, covering edge cases, error handling, and recovery patterns for production integrations.

Key facts:

  • Exchange rate: 1 BTC = 1 CBTC, always

  • Confirmations required: 6 Bitcoin block confirmations (~60 minutes)

  • Processing time: Additional 60–120 seconds after confirmations for Attestor verification

  • Wallet requirement: Taproot-compatible Bitcoin wallet (P2TR addresses)

  • Minimum amount: 0.001 BTC


How to Mint CBTC: Deposit Bitcoin and Receive Wrapped BTC on Canton

How It Works

Step-by-Step

Step 1: Authenticate

Obtain a JWT token from your OIDC provider (Keycloak is officially supported). See the Authentication Guide for setup details.

Step 2: Create a Deposit Account

A Deposit Account is required before you can generate deposit addresses.

Using cbtc-lib (Rust):

Using Canton API (curl):

You can fetch the CBTCDepositAccountRules from an attestor’s /app/get-account-contract-rules endpoint

⚠️ Coming soon: This endpoint will require a Credential as an additional argument. Monitor #cbtc-ecosystem for the update.

Step 3: Generate a Bitcoin Deposit Address

Each deposit address is unique to your account and is a standard Taproot (P2TR) address.

Using cbtc-lib (Rust):

Step 4: Send Bitcoin

Send the exact amount of BTC you want to mint as CBTC to the generated Taproot address from your Bitcoin wallet.

Step 5: Wait for Confirmations

The Attestor network automatically monitors the Bitcoin network. Once your transaction reaches 6 confirmations (~60 minutes), it transitions to the processing state.

You can poll for deposit status:

Using cbtc-lib (Rust):

Step 6: Attestor Verification

This step is fully automated. The Attestor network:

  1. Independently verifies the Bitcoin transaction has 6+ confirmations

  2. Each Attestor submits a ConfirmDepositAction to the Canton governance module

  3. Once the required threshold of confirmations is reached, the Coordinator executes the mint No action is required from your application during this step.

Step 7: CBTC Available

Your CBTC is minted and available in your Canton party. Check your balance:

Using cbtc-lib (Rust):


How to Burn CBTC: Redeem Wrapped Bitcoin for Native BTC

How It Works

Step-by-Step

Step 1: Initiate a Burn

First, create a WithdrawAccount with your destination BTC address. The destination address is stored on the WithdrawAccount and can be updated later. Then submit the withdrawal against that account.

Using cbtc-lib (Rust):

Step 2: Attestor Verification and Signing

The Attestor network:

  1. Verifies the burn request on Canton

  2. Constructs the Bitcoin withdrawal transaction

  3. Coordinates FROST threshold signing across Attestors

  4. Once the signing threshold is met, broadcasts the signed transaction to the Bitcoin network This step is fully automated. No action required.

Step 3: Bitcoin Delivery

After the signed transaction is broadcast, wait for 6 Bitcoin confirmations. Your BTC will arrive at the specified destination address.


Error Handling and Recovery Patterns for CBTC Integrations

🔧 Error handling is critical for production integrations. The CBTC system includes built-in resilience, but your application should handle these scenarios gracefully.

Failed Broadcast

The system includes automatic retry logic. If a Bitcoin transaction fails to broadcast initially, the Coordinator detects the failure during subsequent periodic checks (every 60–120 seconds) and rebroadcasts using stored transaction data.

What your app should do: Monitor withdrawal status. If status remains in broadcasting for more than 10 minutes, log an alert for investigation.

Insufficient Confirmations

If a deposit stalls below 6 confirmations (e.g., due to Bitcoin network congestion), the system simply waits. There is no timeout.

What your app should do: Display the current confirmation count to the user. Consider showing an estimated time based on current Bitcoin block times.

Idempotency

Each withdrawal generates a unique transaction ID that prevents accidental double-spending, even if network issues cause retry attempts. The system is designed to be idempotent.

What your app should do: Store the withdrawal request ID and use it for status checks rather than initiating duplicate requests.

Attestor Timeout

If governance approval is delayed (e.g., some Attestors are temporarily offline), the system continues to collect approvals. As long as the threshold can eventually be met, the operation will complete.

What your app should do: If a mint or burn is pending for more than 2 hours, escalate to BitSafe support.

Partial Failure

If some Attestors approve but the threshold is not reached (e.g., too many Attestors offline simultaneously), the operation will remain pending until the threshold is met or the situation is resolved.

What your app should do: Alert your operations team. Contact BitSafe engineering via #cbtc-ecosystem or [email protected]envelope.


CBTC UTXO Management: Consolidation and Best Practices

⚠️ Important for high-volume integrations. Each CBTC transfer creates UTXOs. Canton recommends a maximum of 10 UTXOs per party. Exceeding this causes increased load and fees on your node.

The cbtc-lib Rust library provides functions for managing UTXOs:

Best practices:

  • Monitor UTXO count per party and consolidate proactively

  • Batch transfers where possible to minimise UTXO creation

  • If creating many parties, use the Ledger API directly (not wallet UI/API) — see Canton docsarrow-up-right


Escalation Path

Situation
Action

Mint pending > 2 hours

Check Bitcoin confirmations first. If 6+ confirmations reached, contact BitSafe

Burn pending > 2 hours

Contact BitSafe engineering

Unexpected error from API

Retry with exponential backoff. If persistent, contact BitSafe

UTXO-related issues

Use cbtc-lib consolidation functions. If unresolved, contact BitSafe

Support channels:


Last updated