diff --git a/docs/guides/chain-fusion/bitcoin.mdx b/docs/guides/chain-fusion/bitcoin.mdx index 16eac75f..0f692992 100644 --- a/docs/guides/chain-fusion/bitcoin.mdx +++ b/docs/guides/chain-fusion/bitcoin.mdx @@ -12,7 +12,7 @@ ICP provides a protocol-level integration with the Bitcoin network. Canisters ca There are two approaches to working with Bitcoin on ICP: - **ckBTC (chain-key Bitcoin)**: a 1:1 BTC-backed token native to ICP. Transfers settle in 1-2 seconds with a 10 satoshi fee. Best for most applications that need to accept, hold, or transfer Bitcoin value. -- **Direct Bitcoin API**: call the management canister to read UTXOs, get balances, and submit raw Bitcoin transactions. Best for advanced use cases that need full control over Bitcoin transactions (custom scripts, Ordinals, Runes, BRC-20). +- **Direct Bitcoin API**: call the Bitcoin canister to read UTXOs, get balances, and submit raw Bitcoin transactions. Best for advanced use cases that need full control over Bitcoin transactions (custom scripts, Ordinals, Runes, BRC-20). This guide covers both approaches. @@ -34,19 +34,25 @@ ckBTC is the recommended path for most developers. The ckBTC minter canister hol ```plantuml actor User participant "ckBTC Minter" as Minter +participant "Bitcoin Checker" as KYT +participant "ckBTC Ledger" as Ledger participant "Bitcoin Network" as BTC -User -> Minter: get_btc_address(account) +User -> Minter: get_btc_address(owner, subaccount) Minter --> User: btc_address User -> BTC: send BTC to btc_address -User -> Minter: update_balance(account) -Minter --> User: ckBTC minted to ICRC-1 account +note right of BTC: 4 confirmations required +User -> Minter: update_balance(owner, subaccount) +Minter -> KYT: check UTXO +KYT --> Minter: ok +Minter -> Ledger: mint ckBTC (amount - kyt_fee) +Minter --> User: MintedUtxos ``` -1. Call `get_btc_address` on the minter with the user's principal and subaccount. This returns a unique Bitcoin address controlled by the minter. -2. The user sends BTC to that address using any Bitcoin wallet. -3. Wait for Bitcoin confirmations (the minter requires confirmations before minting). -4. Call `update_balance` on the minter with the same principal and subaccount. The minter checks for new UTXOs and mints equivalent ckBTC to the user's ICRC-1 account. +1. Call `get_btc_address` on the minter with the user's principal and subaccount. This returns a unique Bitcoin address controlled by the minter via threshold ECDSA. +2. Send BTC to that address from any Bitcoin wallet. +3. Wait for 4 Bitcoin confirmations (mainnet). The minter will not process UTXOs until the required number of confirmations is reached. +4. Call `update_balance` on the minter. The minter checks for new UTXOs, runs a KYT (Know-Your-Transaction) compliance check via the Bitcoin Checker canister, and mints ckBTC to the user's ICRC-1 account. A KYT fee of 100 satoshis is deducted per UTXO. UTXOs that fail the KYT check are quarantined and not minted. @@ -243,15 +249,20 @@ async fn transfer(to: Principal, amount: Nat) -> Result { actor User participant "ckBTC Ledger" as Ledger participant "ckBTC Minter" as Minter +participant "Bitcoin Checker" as KYT participant "Bitcoin Network" as BTC User -> Ledger: icrc2_approve(spender=minter, amount) User -> Minter: retrieve_btc_with_approval(btc_address, amount) +Minter -> KYT: check destination address +KYT --> Minter: ok Minter -> Ledger: icrc2_transfer_from(user, minter, amount) -Minter -> BTC: send BTC to btc_address +Minter --> User: block_index +note right of Minter: processed asynchronously +Minter -> BTC: submit signed transaction ``` -Withdrawal is a two-step process: approve the minter to spend your ckBTC, then call `retrieve_btc_with_approval`. The minimum withdrawal is 50,000 satoshis (0.0005 BTC). +Withdrawal is a two-step process: approve the minter to spend your ckBTC, then call `retrieve_btc_with_approval`. Before burning ckBTC, the minter runs a KYT check on the destination Bitcoin address. The Bitcoin transaction is submitted asynchronously — the minter batches pending requests to optimize miner fees. Track status with `retrieve_btc_status_v2(block_index)`. The minimum withdrawal is 50,000 satoshis (0.0005 BTC). @@ -493,7 +504,7 @@ For a complete working example with all type definitions and error handling, see ## Direct Bitcoin API -For use cases that require full control over Bitcoin transactions (custom scripts, Ordinals, Runes, BRC-20), you can call the Bitcoin API directly through the management canister. This involves generating addresses with threshold ECDSA or Schnorr signatures, building raw transactions, and submitting them to the Bitcoin network. +For use cases that require full control over Bitcoin transactions (custom scripts, Ordinals, Runes, BRC-20), you can call the Bitcoin canister directly. This involves generating addresses with threshold ECDSA or Schnorr signatures, building raw transactions, and submitting them to the Bitcoin network. ### Bitcoin API canister IDs @@ -1165,7 +1176,7 @@ docker stop bitcoind && docker rm bitcoind - [Chain-key cryptography](../../concepts/chain-key-cryptography.md): learn how threshold ECDSA and Schnorr signatures work - [Chain-key tokens](../digital-assets/chain-key-tokens.md): explore ckBTC, ckETH, and other chain-key tokens - [Ethereum integration](ethereum.md): apply similar patterns for Ethereum -- [Management canister reference](../../reference/management-canister.md): full API reference for `bitcoin_get_utxos`, `sign_with_ecdsa`, and other management canister methods +- [Management canister reference](../../reference/management-canister.md): full API reference for `sign_with_ecdsa`, `sign_with_schnorr`, and other management canister methods (note: the `bitcoin_*` methods in the management canister are deprecated; use the Bitcoin canister directly) - [Bitcoin canister API specification](https://github.com/dfinity/bitcoin-canister/blob/master/INTERFACE_SPECIFICATION.md): detailed API documentation - [Bitcoin integration (Learn Hub)](https://learn.internetcomputer.org/hc/en-us/articles/34211154520084): protocol-level details of how ICP connects to Bitcoin diff --git a/docs/guides/chain-fusion/dogecoin.md b/docs/guides/chain-fusion/dogecoin.md index 125789f6..df73100d 100644 --- a/docs/guides/chain-fusion/dogecoin.md +++ b/docs/guides/chain-fusion/dogecoin.md @@ -14,7 +14,7 @@ ICP canisters can interact directly with the Dogecoin network without bridges or - **Dogecoin canister**: a system canister controlled by the NNS that exposes an API for querying Dogecoin network state (UTXOs, balances, block information) and submitting signed transactions. - **Threshold ECDSA**: canisters request threshold ECDSA signatures from the management canister to sign Dogecoin transactions. The private key is never reconstructed; it exists only as secret shares distributed across subnet nodes. -This is the same model as the [Bitcoin integration](bitcoin.md), using a UTXO-based transaction model and secp256k1 ECDSA signatures. The main difference is that Dogecoin transactions are submitted through the Dogecoin canister rather than the Bitcoin management canister API. +This is the same model as the [Bitcoin integration](bitcoin.md), using a UTXO-based transaction model and secp256k1 ECDSA signatures. The main difference is that Dogecoin transactions are submitted through the Dogecoin canister rather than the Bitcoin canister. ## How it works @@ -118,7 +118,7 @@ For a complete, working implementation covering all steps (including deriving a The [Bitcoin integration guide](bitcoin.md) covers the same conceptual steps with complete inline code. Because Dogecoin is a fork of Bitcoin and shares the same UTXO model and secp256k1 ECDSA signatures, the patterns translate directly with these differences: -- Use the Dogecoin canister for UTXO queries and transaction submission (not the management canister's `bitcoin_*` API) +- Use the Dogecoin canister for UTXO queries and transaction submission (not the Bitcoin canister's `bitcoin_*` API) - Use Dogecoin's P2PKH address format (mainnet addresses start with `D`) - Dogecoin uses koinus instead of satoshis (1 DOGE = 100,000,000 koinus) - Dogecoin uses a different fee rate: use `dogecoin_get_current_fee_percentiles` to get current rates @@ -131,13 +131,13 @@ The key differences in implementation: | | Bitcoin | Dogecoin | |---|---|---| -| API | Management canister (`bitcoin_*` methods) | Dogecoin canister | +| API | Bitcoin canister (`bitcoin_*` methods) | Dogecoin canister | | Chain-key token | ckBTC | ckDOGE | | Address prefix | `1`, `3`, `bc1` (mainnet) | `D` (mainnet) | | Unit | satoshi | koinu | | Status | Stable | Beta | -Developers familiar with the Bitcoin integration will find the Dogecoin integration conceptually identical. The primary practical difference is calling the Dogecoin canister rather than the management canister's Bitcoin API. +Developers familiar with the Bitcoin integration will find the Dogecoin integration conceptually identical. The primary practical difference is calling the Dogecoin canister rather than the Bitcoin canister. ## NNS governance diff --git a/docs/guides/digital-assets/chain-key-tokens.mdx b/docs/guides/digital-assets/chain-key-tokens.mdx index 7715cdd7..24279aa6 100644 --- a/docs/guides/digital-assets/chain-key-tokens.mdx +++ b/docs/guides/digital-assets/chain-key-tokens.mdx @@ -34,7 +34,7 @@ The deposit flow has two steps: 1. **Get a deposit address**: call `get_btc_address` on the ckBTC minter with the owner principal and an optional subaccount. The minter returns a unique Bitcoin address. 2. **Mint ckBTC**: after BTC is sent to that address, call `update_balance` on the minter. The minter checks for new UTXOs and mints ckBTC to the corresponding ICRC-1 account. -The minter requires a minimum number of Bitcoin confirmations before minting (currently 6 on mainnet). `update_balance` returns `NoNewUtxos` if confirmations have not yet been reached: your app should poll or prompt the user to wait. +The minter requires a minimum number of Bitcoin confirmations before minting (currently 4 on mainnet). `update_balance` returns `NoNewUtxos` if confirmations have not yet been reached: your app should poll or prompt the user to wait. diff --git a/plugins/remark-plantuml.mjs b/plugins/remark-plantuml.mjs index e75013a1..ec53894f 100644 --- a/plugins/remark-plantuml.mjs +++ b/plugins/remark-plantuml.mjs @@ -26,15 +26,15 @@ skinparam defaultFontSize 13 skinparam defaultFontColor #1a1714 skinparam sequenceArrowThickness 1.5 skinparam sequenceArrowColor #cc5a2b -skinparam SequenceLifeLineBorderColor #e5ddcf +skinparam SequenceLifeLineBorderColor #6b6660 skinparam ParticipantBackgroundColor #fdfaf3 -skinparam ParticipantBorderColor #e5ddcf +skinparam ParticipantBorderColor #6b6660 skinparam ParticipantFontColor #1a1714 skinparam ActorBackgroundColor #fdfaf3 -skinparam ActorBorderColor #e5ddcf +skinparam ActorBorderColor #6b6660 skinparam ActorFontColor #1a1714 skinparam NoteBackgroundColor #f2d7c7 -skinparam NoteBorderColor #e5ddcf +skinparam NoteBorderColor #6b6660 skinparam NoteFontColor #1a1714 `; @@ -53,7 +53,7 @@ export default function remarkPlantUML() { const url = toUrl(node.value); parent.children[index] = { type: "html", - value: `PlantUML diagram`, + value: `
PlantUML diagram
`, }; }); }; diff --git a/src/styles/custom.css b/src/styles/custom.css index f00a160f..f886470a 100644 --- a/src/styles/custom.css +++ b/src/styles/custom.css @@ -307,6 +307,28 @@ h1, h2, h3, h4, h5, h6 { color: var(--sl-color-white); } +/* ── PlantUML diagrams ────────────────────────────────────── */ + +.plantuml-diagram { + display: block; + margin: 1.5rem 0; + background: var(--icp-bg-elev); + border-radius: 6px; + padding: 1.5rem; + text-align: center; +} + +.plantuml-diagram img { + max-width: 100%; + height: auto; + display: block; + margin: 0 auto; +} + +[data-theme='dark'] .plantuml-diagram img { + filter: invert(1) hue-rotate(180deg); +} + /* ── Agent signaling ──────────────────────────────────────── */ /* Visually hidden but present in DOM for HTML-to-markdown converters.