Skip to content

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

Merged
marc0olo merged 1 commit into
masterfrom
motoko-icp_transfer-actor-id-alias
Aug 4, 2026
Merged

refactor(motoko/icp_transfer): call the ICP ledger via canister: import + --actor-id-alias#1455
marc0olo merged 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.

SituationMechanismExample
id fixed & universal (same everywhere)--actor-id-aliasicp_transfer (this PR)
id varies per environment, injected at deploy--actor-env-aliasparallel_calls, pub-sub, ic-pos, evm_block_explorer, llm_chatbot
id chosen at runtime / many targetsgenerated 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) <noreply@anthropic.com>

CopilotAI 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.

FileDescription
motoko/icp_transfer/README.mdDocuments the canister:icp_ledger + --actor-id-alias approach and how to refresh the ledger .did.
motoko/icp_transfer/mops.tomlAdds --actor-id-alias icp_ledger ryjl3-tyaaa-aaaaa-aaaba-cai candid/icp_ledger.did to moc args.
motoko/icp_transfer/candid/icp_ledger.didIntroduces the official ICP ledger Candid interface used for typed imports.
motoko/icp_transfer/backend/app.moReplaces 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.

@marc0olo
marc0olo merged commit f624495 into masterAug 4, 2026
8 checks passed
@marc0olo
marc0olo deleted the motoko-icp_transfer-actor-id-alias branch August 4, 2026 13:31
Sign up for freeto 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.

3 participants

@marc0olo@mbjorkqvist