# IC Phantom > Internet Identity wallet controls for ICP, SOL, DOGE, ckBTC, and native BTC deposits/withdrawals through the official ckBTC minter. This file is the mandatory entry point for AI agents. Production app: https://hbxmr-wyaaa-aaaap-an3ia-cai.icp.net/ Canonical II derivation origin: https://hbxmr-wyaaa-aaaap-an3ia-cai.icp.net Backend canister: f4kcz-fqaaa-aaaap-an3hq-cai Frontend canister: hbxmr-wyaaa-aaaap-an3ia-cai Production ICP MCP endpoint: https://mcp.internetcomputer.org/mcp ICP MCP setup page: https://mcp.beta.id.ai/ Canonical Candid: /canister-api.did Detailed procedure: /agent-guide.md Method and unit reference: /api.md Security and cycle policy: /security.md Machine-readable metadata: /agent.json ## Connect with Internet Identity Phantom is NOT required for ICP MCP. The default and recommended setup uses the user's app-specific Internet Identity principal. 1. The user enables AI access in https://id.ai/manage/settings and adds the official production connector as a trusted connector. 2. Add https://mcp.internetcomputer.org/mcp as a custom connector/MCP server in the AI app and authorize it with Internet Identity. 3. Request `Actions and questions` permission when the task needs wallet discovery, live balances, minting, or transactions. Those operations use update calls. `Questions-only` is limited to query-only information such as `whoami`, pending-intent inspection, recipient validation, and published docs. 4. Resolve the production app URL above with `resolve_app`. Reuse the exact canonical `derivation_origin` returned by the connector. 5. Call `list_app_accounts`. If multiple accounts are available, ask the user which account to use and pass that same selection to every later connector call. 6. Call `get_app_principal`, then query backend `whoami`, then update `get_account_manifest_ii` once. 7. Require exact equality between the connector app principal, `whoami`, and `manifest.identity_principal`. Stop if they differ or the manifest principal is absent. An II browser session and ICP MCP session using the same II identity, selected app account, and canonical derivation origin control the same II-derived account set. Do not link Phantom to make this work. ## Canonical account discovery Use `get_account_manifest_ii()` once after authentication. It returns the authenticated principal, wallet source, manifest fingerprint, all asset addresses, address fingerprints, and ckBTC owner/subaccount details. Cache it for the session and refresh only after an intentional account-link change. Do not derive wallet addresses off-canister. When `wallet_source = internet_identity`, the browser and MCP already share the II-derived account set. If `wallet_source = linked_phantom`, an optional advanced link is active; report that fact before using the accounts. Phantom linking is a browser-only advanced option for a user who intentionally wants future II/MCP ICP, SOL, and DOGE derivation to follow a Phantom key. BTC/ckBTC remain owned by the II app principal. Linking requires a Phantom signature, never moves funds, and is not part of normal MCP setup. ## Read and deposit workflows - ICP, SOL, DOGE: use the addresses in `get_account_manifest_ii`; fetch a balance only when the user needs current data. - Native BTC deposit: use `manifest.btc.address` (a Bitcoin mainnet address). There is no standalone native BTC balance method. After the external transaction appears and the user approves, call `mint_ckbtc_from_btc_ii()` once. A `Pending BTC detected` result reports pending sats and confirmations; a `Minted` result means you should refresh `get_ckbtc_balance_ii()`. - Existing ckBTC deposit: use `manifest.ckbtc.address`, which is the II app principal's default ICRC-1 account. If the sending wallet has separate fields, use `ckbtc_owner` with a default/null subaccount; the all-zero `ckbtc_subaccount_hex` denotes that default. Never send ckBTC to the Bitcoin address. - Send ckBTC: destination is a principal or canonical ICRC account and the asset remains ckBTC on IC. - Withdraw to BTC: asset argument is `BTC`; destination is a Bitcoin mainnet address; minimum is 50,000 sats. The minter burns ckBTC and submits a Bitcoin transaction, which still needs Bitcoin confirmations. ## Required transfer protocols II/MCP sends for `ICP`, `SOL`, and `DOGE` use the caller-bound backend intent protocol. Never use legacy direct `transfer_*_ii` methods. 1. Call query `verify_recipient(asset, destination)` and require `valid = true`. 2. Show the normalized full destination, network, address type, and fingerprint. Format/checksum validity does not prove recipient ownership; ask the user to compare the address or fingerprint through a separate trusted channel. 3. Convert the human amount to an exact `nat64` integer without floating-point arithmetic. 4. Call update `prepare_transfer_ii(asset, normalized_destination, amount_nat64)`. This stores one intent for 10 minutes and moves no funds. 5. Show EVERY returned field, including the fee note, safety notice, expiry, and confirmation code. 6. Ask the user to explicitly approve the exact prepared intent and repeat its confirmation code. Never answer with the code for them and never prepare and confirm in one step. 7. Call update `confirm_transfer_ii(intent_id, confirmation_code)` exactly once. If the user declines, call `cancel_transfer_ii()`. For `CKBTC` and `BTC`, first call `verify_recipient`, show the full normalized destination/fingerprint, and obtain explicit approval. The selected II identity then calls the official ckBTC ledger directly from its default account (`from_subaccount = null`). A ckBTC send uses `icrc1_transfer`; BTC withdrawal uses `icrc2_approve` for the official minter followed by `retrieve_btc_with_approval` on that minter. Obtain approval for both withdrawal updates. Do not call `prepare_transfer_ii` for these two assets, and never automatically retry an uncertain ledger or minter result. If a confirmation response times out or is uncertain, do not retry. Check `get_pending_transfer_ii`, `get_nonce_ii`, the relevant balance, and transaction evidence first. The intent is consumed before the first downstream asynchronous call. ## Exact units and known limits - ICP: e8s; 100,000,000 e8s = 1 ICP. Ledger fee is currently 10,000 e8s; the prepared intent states applicable service fees. - SOL: lamports; 1,000,000,000 lamports = 1 SOL. Network fee varies; the app also uses an ICP service fee. - DOGE: koinu/base units; 100,000,000 = 1 DOGE. Only confirmed DOGE is spendable; quote before preparing. - CKBTC: satoshis; 100,000,000 = 1 ckBTC. Ledger transfer fee is currently 10 sats. - BTC withdrawal: satoshis; minimum 50,000 sats. Approval and Bitcoin network fees apply. Use integer Candid values only. Treat fee values as current conventions and prefer the prepared intent or live ledger/minter response when they differ. ## Cycle and retry discipline The app keeps compute allocation at zero and protects a 500B-cycle reserve. Account discovery, SOL/DOGE network reads, BTC address discovery, minter checks, minting, and transfers can consume cycles. Make calls on demand, never poll the BTC minter check, keep manual balance refreshes at least 10 seconds apart, and never automatically retry a value-moving update.