Skip to content

chore: migrate rust/receiving-icp to icp-cli#1394

Merged
marc0olo merged 12 commits into
masterfrom
chore/migrate-rust-receiving-icp-to-icp-cli
Jun 18, 2026
Merged

chore: migrate rust/receiving-icp to icp-cli#1394
marc0olo merged 12 commits into
masterfrom
chore/migrate-rust-receiving-icp-to-icp-cli

Conversation

@marc0olo

@marc0olo marc0olo commented Jun 16, 2026

Copy link
Copy Markdown
Member

Summary

Migrates rust/receiving-icp to icp-cli and showcases per-environment canister configuration via the icp.yaml environments block.

Changes

  • icp.yaml: replaces dfx.json; uses @dfinity/rust@v3.3.0. Defines three environments with per-canister environment_variables:
    • localICP_LEDGER_CANISTER_ID = ryjl3-tyaaa-aaaaa-aaaba-cai (pre-deployed by icp-cli)
    • stagingICP_LEDGER_CANISTER_ID = xafvr-biaaa-aaaai-aql5q-cai (TESTICP ledger)
    • productionICP_LEDGER_CANISTER_ID = ryjl3-tyaaa-aaaaa-aaaba-cai (mainnet ICP ledger)
  • backend/lib.rs: replaces hardcoded TESTICP principal with ic_cdk::api::env_var_value("ICP_LEDGER_CANISTER_ID") — reads the canister environment variable at runtime via the system API (the variable is a canister setting applied at deploy time, same mechanism as Runtime.envVar in Motoko); ic_cdk::export_candid!() added for Candid interface extraction
  • Cargo.toml: ic-cdk 0.18 → 0.20, ic-ledger-types 0.15 → 0.16
  • test.sh (replaces Makefile): bash script; 7 tests plus idempotent delta-based balance checks
  • README.md: environment table, deploy commands per environment
  • CI: receiving-icp.yml (renamed from receiving_icp.yml to match example dir convention) using ghcr.io/dfinity/icp-dev-env-rust:1.0.1
  • Deleted: dfx.json, old workflow

Key concept: environment-specific canister configuration

Deploying with icp deploy --environment staging targets the TESTICP ledger without any code change — icp-cli reads the environments block in icp.yaml and applies ICP_LEDGER_CANISTER_ID as a canister setting. The canister reads it at runtime via ic_cdk::api::env_var_value. This pattern applies to any per-environment constant (ledger principals, feature flags, external canister IDs).

Test plan

  • icp network start -d && icp deploy && bash test.sh passes locally
  • CI job rust-receiving_icp passes

🤖 Generated with Claude Code

marc0olo and others added 11 commits June 16, 2026 19:47
Replaces dfx.json with icp.yaml, moves Rust source to backend/, adds
Makefile with tests for account identifiers and ledger balance queries,
and adds a CI workflow using icp-dev-env-rust:1.0.0.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ml + crate bumps

Replace hardcoded TESTICP ledger principal with env!("ICP_LEDGER_CANISTER_ID")
baked at compile time by the @dfinity/rust recipe:
  local / production → ryjl3-tyaaa-aaaaa-aaaba-cai (ICP ledger)
  staging           → xafvr-biaaa-aaaai-aql5q-cai (TESTICP ledger)

icp.yaml now uses the environments block with per-environment
environment_variables under settings. Deploy with
`icp deploy --environment staging` to target TESTICP.

Also: ic-cdk 0.18 → 0.20, ic-ledger-types 0.15 → 0.16,
CI image 1.0.0 → 1.0.1.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ncipal

env!() fails at compile time when ICP_LEDGER_CANISTER_ID is not injected
by the recipe. The @dfinity/rust recipe does not yet inject environment_variables
from the icp.yaml environments.settings block into the cargo build environment
(only PUBLIC_CANISTER_ID:* vars are injected automatically).

option_env! with a hardcoded fallback ensures the build always succeeds
while still demonstrating the per-environment configuration concept in
icp.yaml. When/if the recipe gains support for injecting custom env vars,
the option_env! approach will pick them up automatically.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add ic_cdk::export_candid!() — required for candid-extractor to find
  get_candid_pointer and extract the Candid interface
- Revert to env!("ICP_LEDGER_CANISTER_ID") — icp-cli injects environment
  variables from the icp.yaml environments.settings block at build time,
  so env!() works correctly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Environment variables injected by icp-cli are read at RUNTIME via
ic_cdk::api::env_var_value, not at compile time via env!(). They are
stored as WASM metadata and retrieved when the canister executes —
the same mechanism as Runtime.envVar in Motoko.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tion

- Test 1: verify 64-char hex format (not just presence of a quote)
- Test 4: match exact Candid output (0 : nat64) instead of grepping '0'
- Test 5 (new): fund canister with 1 ICP, verify get_balance returns 100_000_000 e8s
  — this actually exercises the ledger inter-canister call
- Test 6 (new): verify get_balance_of_subaccount(0,0) also returns 100_000_000 e8s
- Test 7 (new): verify get_balance_of_subaccount(1,0) returns 0 (unfunded subaccount)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace Makefile with test.sh (bash) for Git Bash compatibility.

New tests:
- Test 8: fund subaccount(1,0) via account ID hex using
  `icp token transfer 1 "$sub1_hex"` — demonstrates that icp token
  transfer accepts ICP ledger account IDs directly as receivers
- Cross-check: verify balance via `icp token balance "$hex"` to show
  CLI and canister agree on the funded subaccount balance

Improvements:
- Test 1: grep for 64-char hex format, extract account ID for reuse
- Tests 5-7: match exact Candid output (100000000 : nat64)
- Tests use natural bash variables (no $$ / \ continuation overhead)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…summary

test.sh:
- All balance checks now delta-based (before/after funding) — idempotent
  across re-runs regardless of prior state
- Test 7: check unfunded subaccount(2,0) has 0 balance to prove independence
  (previous approach assumed (0,0) and (1,0) had different balances which
  fails after equal funding runs)
- Remove unused e8s_from_icp helper and cross-check block

README:
- Separate "Deploy and test locally" from "Deploy to staging or production"
- Describe what test.sh covers (7 tests, delta-based, idempotent)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@marc0olo marc0olo marked this pull request as ready for review June 17, 2026 16:13
@marc0olo marc0olo requested review from a team as code owners June 17, 2026 16:13

@mbjorkqvist mbjorkqvist left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks @marc0olo! Just a few minor things to point out.

Comment thread .github/workflows/receiving-icp.yml
Comment thread rust/receiving-icp/icp.yaml
Comment thread rust/receiving-icp/icp.yaml
Comment thread .github/workflows/receiving-icp.yml
- lib.rs + README: describe ICP_LEDGER_CANISTER_ID as a canister
  environment variable (a canister setting applied at deploy time via
  icp.yaml), not 'WASM metadata' — per ic_cdk::api::env_var_value docs
- Rename receiving_icp.yml → receiving-icp.yml to match example dir
  name convention (<example-dir>.yml)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@lwshang lwshang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Was the removal of the Candid file intentional?

@marc0olo

Copy link
Copy Markdown
Member Author

Was the removal of the Candid file intentional?

so far yes because it is backend only. but I also thought about it lately again. in any case the candid could be obtained from the canister directly, so I am not sure if we need to include it in the examples if it isn't required for bindings.

@marc0olo marc0olo merged commit a4de4dd into master Jun 18, 2026
6 checks passed
@marc0olo marc0olo deleted the chore/migrate-rust-receiving-icp-to-icp-cli branch June 18, 2026 14:44
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.

3 participants