Skip to content

refactor(motoko/icp_transfer): call the ICP ledger via canister: import + --actor-id-alias - #1455

Open
marc0olo wants to merge 1 commit into
masterfrom
motoko-icp_transfer-actor-id-alias
Open

refactor(motoko/icp_transfer): call the ICP ledger via canister: import + --actor-id-alias#1455
marc0olo wants to merge 1 commit into
masterfrom
motoko-icp_transfer-actor-id-alias

Conversation

@marc0olo

Copy link
Copy Markdown
Member

What

Replaces icp_transfer's hand-written ICP ledger actor type (and the hardcoded actor("ryjl3-…") reference) with a typed canister:icp_ledger import bound by moc's --actor-id-alias. All ledger types now come from the ledger's official Candid interface — nothing is hand-declared.

This completes the inter-canister-call taxonomy across the Motoko examples: each moc mechanism matched to the situation it's actually for.

Why --actor-id-alias here

The ICP ledger lives at the same, fixed, well-known principal (ryjl3-tyaaa-aaaaa-aaaba-cai) on both mainnet and the local development network (the managed local network provisions it at the canonical id — that's why test.sh can use icp token transfer/balance). When the target id is fixed and universal, binding it at compile time is the simplest correct choice.

Situation Mechanism Example
id fixed & universal (same everywhere) --actor-id-alias icp_transfer (this PR)
id varies per environment, injected at deploy --actor-env-alias parallel_calls, pub-sub, ic-pos, evm_block_explorer, llm_chatbot
id chosen at runtime / many targets generated bindings + actor(id) icrc2-swap

Using --actor-env-alias here would mean adding icp.yaml env injection to carry an id that never varies — moving parts for no benefit. Generated bindings would be for the runtime/many-targets case. --actor-id-alias keeps the constant id in one place (the mops.toml flag) and needs no runtime resolution — while still dropping every hand-written ledger type.

Changes

  • candid/icp_ledger.did — the ledger's official interface, taken from the ledger-suite-icp-2025-08-29 release (ledger.did).
  • mops.toml--actor-id-alias icp_ledger ryjl3-tyaaa-aaaaa-aaaba-cai candid/icp_ledger.did (plus the repeated global flags).
  • backend/app.moimport IcpLedger "canister:icp_ledger"; types are now IcpLedger.Tokens / IcpLedger.TransferArgs / etc.; removed the hand-written Tokens/SubAccount/BlockIndex/AccountIdentifier/LedgerTransferArgs/TransferError/TransferResult and the actor("ryjl3-…") line.
  • README — new "Calling the ICP ledger" section explaining the mechanism and how to refresh the .did.

icp_transfer is backend-only (no committed backend.did), so there's no frontend-bindings impact.

Testing

icp deploy && bash test.shall 3 tests pass: toAccountIdHex matches icp identity account-id, and both transferToPrincipal and transferToAccountId perform real ICP transfers through the imported ledger with correct balance deltas (−1 ICP sender, +99_990_000 e8s recipient). Build is clean (no warnings).

🤖 Generated with Claude Code

…rt + --actor-id-alias

Replace the hand-written ICP ledger actor type (and the hardcoded
`actor("ryjl3-…")` reference) with a typed `canister:icp_ledger` import bound
by moc's `--actor-id-alias`. All ledger types now come from the ledger's
official Candid interface — nothing is hand-declared.

Why `--actor-id-alias` (and not `--actor-env-alias` or generated bindings):
the ICP ledger lives at the *same, fixed, well-known* principal
(ryjl3-tyaaa-aaaaa-aaaba-cai) on both mainnet and the local development
network. When the target id is fixed and universal, binding it at compile time
is the simplest correct choice — no per-environment env-var injection needed
(that's what `--actor-env-alias` is for), and no runtime `actor(id)`
construction (that's for targets chosen at runtime).

- candid/icp_ledger.did — the ledger's official interface, from the
  ledger-suite-icp-2025-08-29 release (`ledger.did`).
- mops.toml — `--actor-id-alias icp_ledger ryjl3-tyaaa-aaaaa-aaaba-cai candid/icp_ledger.did`.
- backend/app.mo — `import IcpLedger "canister:icp_ledger"`; types are now
  `IcpLedger.Tokens` / `IcpLedger.TransferArgs` / …; removed the hand-written
  Tokens/SubAccount/BlockIndex/AccountIdentifier/LedgerTransferArgs/TransferError/
  TransferResult and the `actor("ryjl3-…")` line.

Verified end-to-end: `icp deploy && bash test.sh` — all 3 tests pass (real ICP
transfers via the imported ledger, with correct balance deltas).

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@marc0olo
marc0olo requested a review from a team as a code owner July 28, 2026 20:04
@marc0olo
marc0olo requested a review from Copilot July 28, 2026 20:04

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors the Motoko icp_transfer example to call the ICP ledger via a typed canister:icp_ledger import, with the ledger principal bound at compile time using moc --actor-id-alias. This removes hand-written ledger types and the hardcoded actor("ryjl3-...") reference, aligning the example with the repository’s typed inter-canister call patterns.

Changes:

  • Adds the official ICP ledger Candid interface (candid/icp_ledger.did) and uses it as the single source of truth for ledger request/response types.
  • Updates mops.toml to bind canister:icp_ledger to the fixed ledger principal via --actor-id-alias.
  • Refactors the backend to use IcpLedger.* types and IcpLedger.transfer(...), removing all locally-declared ledger types/actor wiring, and documents the mechanism in the README.

Reviewed changes

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

File Description
motoko/icp_transfer/README.md Documents the canister:icp_ledger + --actor-id-alias approach and how to refresh the ledger .did.
motoko/icp_transfer/mops.toml Adds --actor-id-alias icp_ledger ryjl3-tyaaa-aaaaa-aaaba-cai candid/icp_ledger.did to moc args.
motoko/icp_transfer/candid/icp_ledger.did Introduces the official ICP ledger Candid interface used for typed imports.
motoko/icp_transfer/backend/app.mo Replaces hand-written ledger types and hardcoded actor with typed canister:icp_ledger import + official Candid types.

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants