Skip to content

feat(ckdoge-minter): support ICRC-21 consent messages#10140

Open
Dfinity-Bjoern wants to merge 2 commits intomasterfrom
claude/inspiring-neumann-b9d915
Open

feat(ckdoge-minter): support ICRC-21 consent messages#10140
Dfinity-Bjoern wants to merge 2 commits intomasterfrom
claude/inspiring-neumann-b9d915

Conversation

@Dfinity-Bjoern
Copy link
Copy Markdown
Contributor

Summary

Implements the ICRC-21 Canister Call Consent Message standard on the ckDOGE minter so that ICRC-21-aware wallets can display a human-readable description of retrieve_doge_with_approval calls before the user signs.

Both display variants from the standard are supported:

  • GenericDisplay — a Markdown message intended for software wallets with a full screen.
  • FieldsDisplay — a list of (label, Value) fields tailored for hardware wallets (e.g. Ledger Nano S+).

Also adds an icrc10_supported_standards query that advertises ICRC-10 and ICRC-21.

This mirrors the ckBTC minter implementation from #10093, with the PR-review learnings applied up front rather than as follow-ups.

Implementation

  • New module rs/dogecoin/ckdoge/minter/src/updates/icrc21.rs holds the consent-message construction and icrc10_supported_standards.
  • main.rs exposes the two new endpoints (icrc21_canister_call_consent_message as update, icrc10_supported_standards as query).
  • ckdoge_minter.did declares the ICRC-10 / ICRC-21 types and methods.
  • The handler enforces the standard's argument-size limit (reusing MAX_CONSENT_MESSAGE_ARG_SIZE_BYTES from icrc-ledger-types) and returns Icrc21Error::UnsupportedCanisterCall for unknown methods or undecodable args.
  • Scope: only retrieve_doge_with_approval produces a consent message; the legacy retrieve_doge flow intentionally returns UnsupportedCanisterCall.
  • Network-aware token symbols: Mainnet ⇒ ckDOGE/DOGE, Regtest ⇒ ckTESTDOGE/TESTDOGE, threaded through the GenericDisplay Markdown, the FieldsDisplay intent, the TokenAmount symbol, and the address label.
  • No canister-side pagination: long values (Dogecoin address, subaccount hex) are emitted as a single Value::Text per the ICRC-21 spec; wallets handle pagination (cf. the Ledger ICP app).
  • Markdown-injection defence: the destination address is parsed via DogecoinAddress::parse before any interpolation. Bad addresses (including newlines/backticks/# payloads or addresses from the wrong network) are rejected with a generic error and never echoed back.
  • ICRC-10 / ICRC-21 URLs point at the canonical dfinity/ICRC repo.

Test plan

  • 11 new unit tests in updates::tests::icrc21 covering: argument-size limit, unsupported method (incl. explicit retrieve_doge), decode failures, GenericDisplay output (with and without subaccount), FieldsDisplay output (with and without subaccount), regtest token symbols (both display variants), and Markdown-injection / wrong-network address rejection. Tests live in updates/tests.rs (separate from prod code).
  • New test_icrc21_endpoints_smoke integration test in tests/tests.rs installs a mainnet minter via Setup::new(Network::Mainnet) and exercises the full Candid path end-to-end: icrc10_supported_standards advertises both standards with the canonical URL; icrc21_canister_call_consent_message returns the expected GenericDisplay markdown and FieldsDisplay structured message; unsupported methods (including retrieve_doge) are rejected.
  • cargo clippy --all-features -p ic-ckdoge-minter -p ic-ckdoge-minter-test-utils clean with the workspace lint set.
  • bazel test //rs/dogecoin/ckdoge/minter:unit_tests //rs/dogecoin/ckdoge/minter:ckdoge_candid_api_tests //rs/dogecoin/ckdoge/minter:ckdoge_minter_replay_events_tests all pass (the candid API test verifies the .did matches the canister).
  • bazel test //rs/dogecoin/ckdoge/minter:integration_tests (Linux x86_64 only — runs in CI; contains the smoke test).
  • Try the FieldsDisplay output on an actual Ledger Nano S+ once a ckDOGE app is available.

🤖 Generated with Claude Code

Implements the ICRC-21 Canister Call Consent Message standard on the
ckDOGE minter so that ICRC-21-aware wallets can display a human-readable
description of `retrieve_doge_with_approval` calls before the user
signs. Mirrors the ckBTC minter implementation from #10093, with the
PR-review learnings applied up front:

- Token symbols depend on the configured Dogecoin network (Mainnet =>
  ckDOGE/DOGE, Regtest => ckTESTDOGE/TESTDOGE) and are threaded through
  both the GenericDisplay Markdown and FieldsDisplay fields.
- `retrieve_doge_with_approval` is the only supported method; the
  legacy `retrieve_doge` flow intentionally returns
  UnsupportedCanisterCall.
- Long values (Dogecoin address, subaccount hex) are emitted as a
  single `Value::Text` per the ICRC-21 spec — wallets are responsible
  for paginating, no canister-side chunking.
- The destination address is parsed via `DogecoinAddress::parse` before
  any interpolation, blocking Markdown-injection payloads (newlines,
  backticks, `#`) and rejecting addresses from the wrong network.
- Reuses `MAX_CONSENT_MESSAGE_ARG_SIZE_BYTES` from icrc-ledger-types.
- ICRC-10 / ICRC-21 URLs point at the canonical dfinity/ICRC repo.
- ICRC-21 unit tests live in `updates/tests.rs` (separate from prod
  code), and a smoke integration test exercises the endpoints
  end-to-end through Candid.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the feat label May 8, 2026
@Dfinity-Bjoern Dfinity-Bjoern marked this pull request as ready for review May 8, 2026 11:05
@Dfinity-Bjoern Dfinity-Bjoern requested a review from a team as a code owner May 8, 2026 11:05
@github-actions github-actions Bot added the @defi label May 8, 2026
@Dfinity-Bjoern Dfinity-Bjoern requested a review from Copilot May 8, 2026 11:07
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds ICRC-21 “canister call consent messages” support to the ckDOGE minter so ICRC-21-aware wallets can preview a human-readable description of retrieve_doge_with_approval before signing, and advertises ICRC-10/ICRC-21 support via icrc10_supported_standards.

Changes:

  • Implemented ICRC-21 consent message generation (GenericDisplay Markdown + FieldsDisplay fields) for retrieve_doge_with_approval, including network-aware symbols (Mainnet vs Regtest) and address validation.
  • Exposed new canister endpoints: icrc21_canister_call_consent_message (update) and icrc10_supported_standards (query), and updated the .did accordingly.
  • Added unit + integration smoke tests and updated test utilities to exercise the new endpoints.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.

Show a summary per file
File Description
rs/dogecoin/ckdoge/test_utils/src/minter.rs Adds helper wrappers to call/decode the new ICRC-10/ICRC-21 endpoints in PocketIC-based tests.
rs/dogecoin/ckdoge/minter/tests/tests.rs Adds an integration smoke test covering supported-standards advertising, both display variants, and unsupported-method behavior.
rs/dogecoin/ckdoge/minter/src/updates/tests.rs Adds unit tests for argument-size limits, decode failures, both display variants (with/without subaccount), network-aware symbols, and invalid-address rejection.
rs/dogecoin/ckdoge/minter/src/updates/mod.rs Exposes the new icrc21 updates module.
rs/dogecoin/ckdoge/minter/src/updates/icrc21.rs Implements ICRC-21 consent message construction + ICRC-10 supported-standards list for ckDOGE.
rs/dogecoin/ckdoge/minter/src/main.rs Exposes the two new canister endpoints wired to the updates::icrc21 module.
rs/dogecoin/ckdoge/minter/ckdoge_minter.did Adds ICRC-10/ICRC-21 types and endpoint declarations to the public Candid interface.
rs/dogecoin/ckdoge/minter/BUILD.bazel Adds the needed icrc-ledger-types dependency for the canister build target.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

The qualified `candid::Encode!(...)` form doesn't resolve through the
re-export chain on the Linux toolchain — both Cargo Lint Linux and
Bazel Test All fail with:

  error: cannot find macro `Encode` in this scope
    = note: this error originates in the macro `candid::Encode`

Switch to the standard `use candid::Encode;` + bare `Encode!(...)` form
that the rest of the codebase uses. No behaviour change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.

@Dfinity-Bjoern Dfinity-Bjoern marked this pull request as ready for review May 8, 2026 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants