@ic-reactor/mcp 0.0.0-stage → 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/ISSUE_TEMPLATE/bug_report.yml +108 -0
- package/.github/ISSUE_TEMPLATE/config.yml +8 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +77 -0
- package/.github/actions/setup-rust-wasm/action.yml +25 -0
- package/.github/dependabot.yml +107 -0
- package/.github/workflows/auth-latest.yml +67 -0
- package/.github/workflows/b3pay-site.yml +49 -0
- package/.github/workflows/ci.yml +430 -0
- package/.github/workflows/codeql.yml +41 -0
- package/.github/workflows/dependency-review.yml +68 -0
- package/.github/workflows/docs-check.yml +98 -0
- package/.github/workflows/docs.yml +265 -0
- package/.github/workflows/e2e.yml +90 -0
- package/.github/workflows/examples-published.yml +97 -0
- package/.github/workflows/release.yml +326 -0
- package/.husky/pre-commit +12 -0
- package/.prettierignore +109 -0
- package/.prettierrc +6 -0
- package/AGENTS.md +103 -0
- package/CHANGELOG.md +3268 -0
- package/CLAUDE.md +93 -0
- package/CNAME +1 -0
- package/CODE_OF_CONDUCT.md +7 -0
- package/CONTRIBUTING.md +433 -0
- package/LICENSE +21 -0
- package/README.md +2 -2
- package/SECURITY.md +74 -0
- package/b3pay-module.json +194 -0
- package/docs/.remarkrc.json +10 -0
- package/docs/README.md +64 -0
- package/docs/astro.config.mjs +205 -0
- package/docs/favicon.svg +15 -0
- package/docs/package.json +39 -0
- package/docs/public/favicon.svg +15 -0
- package/docs/public/ic-reactor-social-card.png +0 -0
- package/docs/scripts/b3pay-static.mjs +22 -0
- package/docs/scripts/check-example-docs.mjs +214 -0
- package/docs/scripts/check-links.mjs +212 -0
- package/docs/scripts/fix-dist-links.js +125 -0
- package/docs/scripts/fix-frontmatter.js +71 -0
- package/docs/scripts/remove-redundant-h1.cjs +48 -0
- package/docs/scripts/rewrite-typedoc-links.js +110 -0
- package/docs/scripts/split-index.js +69 -0
- package/docs/src/assets/ic-reactor-hero-dark.svg +23 -0
- package/docs/src/assets/ic-reactor-hero-light.svg +23 -0
- package/docs/src/assets/ic-reactor-lockup-dark.svg +15 -0
- package/docs/src/assets/ic-reactor-lockup-light.svg +15 -0
- package/docs/src/assets/ic-reactor-mark-dark.svg +14 -0
- package/docs/src/assets/ic-reactor-mark-light.svg +14 -0
- package/docs/src/assets/layers/candid-core-layer-icon-dark.svg +4 -0
- package/docs/src/assets/layers/candid-core-layer-icon-light.svg +4 -0
- package/docs/src/assets/layers/candid-profile-layer-icon-dark.svg +4 -0
- package/docs/src/assets/layers/candid-profile-layer-icon-light.svg +4 -0
- package/docs/src/assets/layers/ic-reactor-layer-icon-dark.svg +4 -0
- package/docs/src/assets/layers/ic-reactor-layer-icon-light.svg +4 -0
- package/docs/src/components/LibraryCards.astro +172 -0
- package/docs/src/components/LibraryIcon.astro +28 -0
- package/docs/src/components/SiteTitle.astro +241 -0
- package/docs/src/content/docs/404.mdx +19 -0
- package/docs/src/content/docs/build/agent-tools.mdx +593 -0
- package/docs/src/content/docs/build/icrc1-wallet.mdx +619 -0
- package/docs/src/content/docs/build/ssr-per-user.mdx +552 -0
- package/docs/src/content/docs/examples/canister-studio.mdx +95 -0
- package/docs/src/content/docs/examples/icrc-ledger.mdx +45 -0
- package/docs/src/content/docs/examples/index.mdx +38 -0
- package/docs/src/content/docs/examples/next-ssr.mdx +73 -0
- package/docs/src/content/docs/examples/node-agent-tool.mdx +80 -0
- package/docs/src/content/docs/examples/vite-wallet.mdx +71 -0
- package/docs/src/content/docs/guides/auth.mdx +1181 -0
- package/docs/src/content/docs/guides/client.mdx +551 -0
- package/docs/src/content/docs/guides/deploy.mdx +180 -0
- package/docs/src/content/docs/guides/errors.mdx +475 -0
- package/docs/src/content/docs/guides/getting-started.mdx +620 -0
- package/docs/src/content/docs/guides/reads.mdx +586 -0
- package/docs/src/content/docs/guides/ssr.mdx +529 -0
- package/docs/src/content/docs/guides/testing.mdx +401 -0
- package/docs/src/content/docs/guides/values.mdx +261 -0
- package/docs/src/content/docs/guides/vite-plugin.mdx +690 -0
- package/docs/src/content/docs/guides/writes.mdx +572 -0
- package/docs/src/content/docs/ic-reactor/index.mdx +167 -0
- package/docs/src/content/docs/index.mdx +65 -0
- package/docs/src/content/docs/migrating-from-3.mdx +535 -0
- package/docs/src/content/docs/packages/core.mdx +186 -0
- package/docs/src/content/docs/packages/mcp.mdx +163 -0
- package/docs/src/content/docs/packages/react.mdx +207 -0
- package/docs/src/content/docs/packages/vite-plugin.mdx +73 -0
- package/docs/src/content/docs/versioning.mdx +104 -0
- package/docs/src/content.config.ts +7 -0
- package/docs/src/styles/custom.css +189 -0
- package/docs/tsconfig.typedoc.json +26 -0
- package/docs/typedoc-entry.ts +17 -0
- package/docs/typedoc.json +37 -0
- package/e2e/Cargo.lock +646 -0
- package/e2e/Cargo.toml +3 -0
- package/e2e/README.md +101 -0
- package/e2e/frontends/build.mjs +94 -0
- package/e2e/frontends/index.html +10 -0
- package/e2e/global-setup.ts +65 -0
- package/e2e/icp.yaml +38 -0
- package/e2e/package.json +40 -0
- package/e2e/setup.ts +6 -0
- package/e2e/src/actor/Cargo.toml +14 -0
- package/e2e/src/actor/hello_actor.did +10 -0
- package/e2e/src/actor/src/lib.rs +73 -0
- package/e2e/src/calls.test.ts +132 -0
- package/e2e/src/declarations/hello_actor.envelope.json +175 -0
- package/e2e/src/declarations/hello_actor.ts +15 -0
- package/e2e/src/errors.test.ts +107 -0
- package/e2e/src/frontend-headers.test.ts +253 -0
- package/e2e/src/identity.test.ts +61 -0
- package/e2e/src/react.test.tsx +59 -0
- package/e2e/src/replica.ts +70 -0
- package/e2e/src/vite-env.test.ts +108 -0
- package/e2e/test.sh +47 -0
- package/e2e/tsconfig.json +20 -0
- package/e2e/tsconfig.typecheck.json +9 -0
- package/e2e/vitest.config.ts +22 -0
- package/eslint.config.mjs +100 -0
- package/evals/PREREGISTRATION.md +1346 -0
- package/evals/README.md +756 -0
- package/evals/conditions/thin/condition.json +8 -0
- package/evals/conditions/thin/docs/candid-core-cli.README.md +90 -0
- package/evals/conditions/thin/docs/candid-core-schema.README.md +339 -0
- package/evals/conditions/thin/package.json +25 -0
- package/evals/conditions/thin/starter/src/generated/icrc1.ts +57 -0
- package/evals/conditions/thin-guide/condition.json +10 -0
- package/evals/conditions/thin-guide/docs/llms.txt +292 -0
- package/evals/conditions/v3/condition.json +9 -0
- package/evals/conditions/v3/docs/ic-reactor-core.llms.txt +232 -0
- package/evals/conditions/v3/docs/ic-reactor-react.llms.txt +280 -0
- package/evals/conditions/v3/docs/llms-full.txt +1053 -0
- package/evals/conditions/v3/package.json +26 -0
- package/evals/conditions/v3/starter/src/declarations/icrc1.did.d.ts +95 -0
- package/evals/conditions/v3/starter/src/declarations/icrc1.did.js +140 -0
- package/evals/conditions/v4/PORTING.md +384 -0
- package/evals/conditions/v4/README.md +106 -0
- package/evals/conditions/v4/condition.json +5 -0
- package/evals/conditions/v4/docs/llms.txt +323 -0
- package/evals/conditions/v4/package.json +27 -0
- package/evals/conditions/v4/starter/src/generated/icrc1.ts +78 -0
- package/evals/conditions/v4-proto/condition.json +6 -0
- package/evals/conditions/v4-proto/docs/llms.txt +291 -0
- package/evals/conditions/v4-proto/lib/SHIM-NOTES.md +20 -0
- package/evals/conditions/v4-proto/lib/package.json +27 -0
- package/evals/conditions/v4-proto/lib/src/client.ts +471 -0
- package/evals/conditions/v4-proto/lib/src/errors.ts +214 -0
- package/evals/conditions/v4-proto/lib/src/index.ts +36 -0
- package/evals/conditions/v4-proto/lib/src/principal.ts +175 -0
- package/evals/conditions/v4-proto/lib/src/service.ts +69 -0
- package/evals/conditions/v4-proto/lib/src/types.ts +174 -0
- package/evals/conditions/v4-proto/lib/test/runtime.test.ts +170 -0
- package/evals/conditions/v4-proto/lib/test/tsconfig.json +10 -0
- package/evals/conditions/v4-proto/lib/test/types.test-d.ts +145 -0
- package/evals/conditions/v4-proto/lib/test/vitest.config.mjs +8 -0
- package/evals/conditions/v4-proto/lib/tsconfig.json +17 -0
- package/evals/conditions/v4-proto/package.json +26 -0
- package/evals/conditions/v4-proto/starter/src/generated/icrc1.service.ts +19 -0
- package/evals/conditions/v4-proto/starter/src/generated/icrc1.ts +57 -0
- package/evals/drive.mjs +1221 -0
- package/evals/gate.mjs +161 -0
- package/evals/harness/aggregate.mjs +534 -0
- package/evals/harness/aggregate.test.mjs +344 -0
- package/evals/harness/assemble.mjs +216 -0
- package/evals/harness/assemble.test.mjs +143 -0
- package/evals/harness/auth.mjs +91 -0
- package/evals/harness/check-docs.mjs +157 -0
- package/evals/harness/declarations/icrc1.did.d.ts +95 -0
- package/evals/harness/declarations/icrc1.did.js +140 -0
- package/evals/harness/drive-auth.test.mjs +584 -0
- package/evals/harness/drive.test.mjs +509 -0
- package/evals/harness/fake-auth.ts +67 -0
- package/evals/harness/fake-ledger.ts +178 -0
- package/evals/harness/gate-plan.mjs +104 -0
- package/evals/harness/gate-plan.test.mjs +243 -0
- package/evals/harness/icrc1.did +88 -0
- package/evals/harness/judge.mjs +63 -0
- package/evals/harness/judge.test.mjs +81 -0
- package/evals/harness/leak-scan.mjs +1373 -0
- package/evals/harness/leak-scan.test.mjs +1300 -0
- package/evals/harness/probes/amounts.ts +14 -0
- package/evals/harness/probes/node-tool.probe.ts +48 -0
- package/evals/harness/probes/probe.mjs +149 -0
- package/evals/harness/probes/react-wallet.probe.ts +96 -0
- package/evals/harness/public/support/auth.ts +38 -0
- package/evals/harness/public/support/fake-replica.d.ts +28 -0
- package/evals/harness/public/support/fake-replica.js +434 -0
- package/evals/harness/public/support/ledger.idl.d.ts +95 -0
- package/evals/harness/public/support/ledger.idl.js +140 -0
- package/evals/harness/public/support/world.ts +179 -0
- package/evals/harness/runs.mjs +139 -0
- package/evals/harness/sandbox.mjs +88 -0
- package/evals/harness/sandbox.test.mjs +134 -0
- package/evals/harness/ship.mjs +264 -0
- package/evals/harness/ship.test.mjs +552 -0
- package/evals/harness/world.ts +291 -0
- package/evals/package.json +26 -0
- package/evals/pnpm-lock.yaml +1537 -0
- package/evals/pnpm-workspace.yaml +12 -0
- package/evals/results/2026-09-30T14-22-05-924Z/pilot.json +384 -0
- package/evals/results/2026-09-30T14-22-05-924Z/pilot.rescanned.json +404 -0
- package/evals/results/2026-09-30T14-22-05-924Z/pilot.rescanned.rescored.json +404 -0
- package/evals/results/2026-09-30T14-22-05-924Z/plan.json +240 -0
- package/evals/results/2026-09-30T14-22-05-924Z/summary.json +1800 -0
- package/evals/results/2026-09-30T14-22-05-924Z/summary.rescanned.json +1843 -0
- package/evals/results/2026-09-30T14-22-05-924Z/summary.rescanned.rescored.json +2100 -0
- package/evals/results/2026-09-30T15-48-23-343Z/pilot.json +404 -0
- package/evals/results/2026-09-30T15-48-23-343Z/pilot.rescored.json +404 -0
- package/evals/results/2026-09-30T15-48-23-343Z/plan.json +242 -0
- package/evals/results/2026-09-30T15-48-23-343Z/summary.json +1843 -0
- package/evals/results/2026-09-30T15-48-23-343Z/summary.rescored.json +2195 -0
- package/evals/results/2026-10-03-beta1-gate/pilot.json +162 -0
- package/evals/results/2026-10-03-beta1-gate/plan.json +141 -0
- package/evals/results/2026-10-03-beta1-gate/summary.json +983 -0
- package/evals/results/2026-10-05-ga-gate/contaminated-run.json +55 -0
- package/evals/results/2026-10-05-ga-gate/pilot.json +162 -0
- package/evals/results/2026-10-05-ga-gate/plan.json +457 -0
- package/evals/results/2026-10-05-ga-gate/summary.json +1037 -0
- package/evals/results/2026-10-05-ga-gate/summary.rescanned.json +1037 -0
- package/evals/results/README.md +31 -0
- package/evals/runs-pilot.log +150 -0
- package/evals/runs-pilot2.log +150 -0
- package/evals/score.mjs +256 -0
- package/evals/setup.mjs +547 -0
- package/evals/tasks/node-tool/faulty/thin-accepts-exponent/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/thin-accepts-exponent/src/index.ts +121 -0
- package/evals/tasks/node-tool/faulty/thin-anonymous-transfer/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/thin-anonymous-transfer/src/index.ts +116 -0
- package/evals/tasks/node-tool/faulty/thin-every-reject-may-have-executed/meta.json +9 -0
- package/evals/tasks/node-tool/faulty/thin-every-reject-may-have-executed/src/index.ts +118 -0
- package/evals/tasks/node-tool/faulty/thin-fetches-root-key-off-local/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/thin-fetches-root-key-off-local/src/index.ts +118 -0
- package/evals/tasks/node-tool/faulty/thin-ignores-root-key/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/thin-ignores-root-key/src/index.ts +117 -0
- package/evals/tasks/node-tool/faulty/thin-misclassifies-reject-codes/meta.json +9 -0
- package/evals/tasks/node-tool/faulty/thin-misclassifies-reject-codes/src/index.ts +119 -0
- package/evals/tasks/node-tool/faulty/thin-no-nat64-cap/meta.json +9 -0
- package/evals/tasks/node-tool/faulty/thin-no-nat64-cap/src/index.ts +118 -0
- package/evals/tasks/node-tool/faulty/thin-number-amount/meta.json +10 -0
- package/evals/tasks/node-tool/faulty/thin-number-amount/src/index.ts +117 -0
- package/evals/tasks/node-tool/faulty/thin-truncates-fraction-digits/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/thin-truncates-fraction-digits/src/index.ts +120 -0
- package/evals/tasks/node-tool/faulty/thin-unvalidated-recipient/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/thin-unvalidated-recipient/src/index.ts +118 -0
- package/evals/tasks/node-tool/faulty/v3-retry-call-errors/meta.json +11 -0
- package/evals/tasks/node-tool/faulty/v3-retry-call-errors/src/index.ts +149 -0
- package/evals/tasks/node-tool/faulty/v4-anonymous-identity-sent/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/v4-anonymous-identity-sent/src/index.ts +71 -0
- package/evals/tasks/node-tool/faulty/v4-never-may-have-executed/meta.json +9 -0
- package/evals/tasks/node-tool/faulty/v4-never-may-have-executed/src/index.ts +84 -0
- package/evals/tasks/node-tool/faulty/v4-proto-never-may-have-executed/meta.json +9 -0
- package/evals/tasks/node-tool/faulty/v4-proto-never-may-have-executed/src/index.ts +72 -0
- package/evals/tasks/node-tool/faulty/v4-proto-refuses-nat64-max/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/v4-proto-refuses-nat64-max/src/index.ts +72 -0
- package/evals/tasks/node-tool/faulty/v4-refuses-nat64-max/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/v4-refuses-nat64-max/src/index.ts +84 -0
- package/evals/tasks/node-tool/hidden/node-tool.test.ts +312 -0
- package/evals/tasks/node-tool/prompt.md +55 -0
- package/evals/tasks/node-tool/prompt.minimal.md +30 -0
- package/evals/tasks/node-tool/solutions/thin/reference/src/index.ts +118 -0
- package/evals/tasks/node-tool/solutions/thin/reference-module-scope/src/index.ts +145 -0
- package/evals/tasks/node-tool/solutions/thin-guide/reference/src/index.ts +118 -0
- package/evals/tasks/node-tool/solutions/thin-guide/reference-module-scope/src/index.ts +145 -0
- package/evals/tasks/node-tool/solutions/v3/reference/src/index.ts +140 -0
- package/evals/tasks/node-tool/solutions/v3/reference-module-scope/src/index.ts +153 -0
- package/evals/tasks/node-tool/solutions/v4/reference/src/index.ts +84 -0
- package/evals/tasks/node-tool/solutions/v4/reference-module-scope/src/index.ts +105 -0
- package/evals/tasks/node-tool/solutions/v4-proto/reference/src/index.ts +72 -0
- package/evals/tasks/node-tool/solutions/v4-proto/reference-module-scope/src/index.ts +87 -0
- package/evals/tasks/node-tool/starter/src/contract.ts +31 -0
- package/evals/tasks/node-tool/starter/src/index.ts +7 -0
- package/evals/tasks/node-tool/starter/test/smoke.test.ts +22 -0
- package/evals/tasks/node-tool/starter/tsconfig.json +17 -0
- package/evals/tasks/node-tool/task.json +63 -0
- package/evals/tasks/react-wallet/faulty/thin-accepts-exponent/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/thin-accepts-exponent/src/Wallet.tsx +216 -0
- package/evals/tasks/react-wallet/faulty/thin-anonymous-transfer/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/thin-anonymous-transfer/src/Wallet.tsx +212 -0
- package/evals/tasks/react-wallet/faulty/thin-both-auth-buttons/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/thin-both-auth-buttons/src/Wallet.tsx +210 -0
- package/evals/tasks/react-wallet/faulty/thin-constant-balance-key/meta.json +8 -0
- package/evals/tasks/react-wallet/faulty/thin-constant-balance-key/src/Wallet.tsx +213 -0
- package/evals/tasks/react-wallet/faulty/thin-no-nat64-cap/meta.json +9 -0
- package/evals/tasks/react-wallet/faulty/thin-no-nat64-cap/src/Wallet.tsx +213 -0
- package/evals/tasks/react-wallet/faulty/thin-number-balance/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/thin-number-balance/src/Wallet.tsx +213 -0
- package/evals/tasks/react-wallet/faulty/thin-transfer-as-query/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/thin-transfer-as-query/src/Wallet.tsx +254 -0
- package/evals/tasks/react-wallet/faulty/thin-truncates-fraction-digits/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/thin-truncates-fraction-digits/src/Wallet.tsx +215 -0
- package/evals/tasks/react-wallet/faulty/thin-unguarded-balance-effect/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/thin-unguarded-balance-effect/src/Wallet.tsx +214 -0
- package/evals/tasks/react-wallet/faulty/v3-http-4xx-unknown/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/v3-http-4xx-unknown/src/Wallet.tsx +224 -0
- package/evals/tasks/react-wallet/faulty/v3-mutation-retry-3/meta.json +12 -0
- package/evals/tasks/react-wallet/faulty/v3-mutation-retry-3/src/Wallet.tsx +225 -0
- package/evals/tasks/react-wallet/faulty/v3-unknown-as-error/meta.json +11 -0
- package/evals/tasks/react-wallet/faulty/v3-unknown-as-error/src/Wallet.tsx +182 -0
- package/evals/tasks/react-wallet/faulty/v4-every-reject-unknown/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/v4-every-reject-unknown/src/Wallet.tsx +160 -0
- package/evals/tasks/react-wallet/faulty/v4-keep-previous-data/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/v4-keep-previous-data/src/Wallet.tsx +166 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-every-reject-unknown/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-every-reject-unknown/src/Wallet.tsx +161 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-keep-previous-data/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-keep-previous-data/src/Wallet.tsx +163 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-retry-spread/meta.json +12 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-retry-spread/src/Wallet.tsx +162 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-status-not-idle/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-status-not-idle/src/Wallet.tsx +163 -0
- package/evals/tasks/react-wallet/faulty/v4-retry-spread/meta.json +12 -0
- package/evals/tasks/react-wallet/faulty/v4-retry-spread/src/Wallet.tsx +163 -0
- package/evals/tasks/react-wallet/faulty/v4-status-not-idle/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/v4-status-not-idle/src/Wallet.tsx +162 -0
- package/evals/tasks/react-wallet/hidden/react-wallet.test.ts +536 -0
- package/evals/tasks/react-wallet/prompt.md +88 -0
- package/evals/tasks/react-wallet/prompt.minimal.md +51 -0
- package/evals/tasks/react-wallet/solutions/thin/reference/src/Wallet.tsx +213 -0
- package/evals/tasks/react-wallet/solutions/thin/reference-module-scope/src/Wallet.tsx +227 -0
- package/evals/tasks/react-wallet/solutions/thin-guide/reference/src/Wallet.tsx +213 -0
- package/evals/tasks/react-wallet/solutions/thin-guide/reference-module-scope/src/Wallet.tsx +227 -0
- package/evals/tasks/react-wallet/solutions/v3/reference/src/Wallet.tsx +224 -0
- package/evals/tasks/react-wallet/solutions/v3/reference-module-scope/src/Wallet.tsx +230 -0
- package/evals/tasks/react-wallet/solutions/v4/reference/src/Wallet.tsx +160 -0
- package/evals/tasks/react-wallet/solutions/v4/reference-module-scope/src/Wallet.tsx +178 -0
- package/evals/tasks/react-wallet/solutions/v4-proto/reference/src/Wallet.tsx +161 -0
- package/evals/tasks/react-wallet/solutions/v4-proto/reference-module-scope/src/Wallet.tsx +161 -0
- package/evals/tasks/react-wallet/starter/src/Wallet.tsx +12 -0
- package/evals/tasks/react-wallet/starter/src/auth.ts +16 -0
- package/evals/tasks/react-wallet/starter/src/config.ts +14 -0
- package/evals/tasks/react-wallet/starter/src/ii-auth.ts +43 -0
- package/evals/tasks/react-wallet/starter/src/main.tsx +15 -0
- package/evals/tasks/react-wallet/starter/test/smoke.test.ts +34 -0
- package/evals/tasks/react-wallet/starter/tsconfig.json +18 -0
- package/evals/tasks/react-wallet/task.json +84 -0
- package/examples/canister-studio/.stackblitzrc +4 -0
- package/examples/canister-studio/README.md +183 -0
- package/examples/canister-studio/did/ckbtc_minter.did +806 -0
- package/examples/canister-studio/did/icp_ledger.did +586 -0
- package/examples/canister-studio/did/icrc1.did +88 -0
- package/examples/canister-studio/package.json +45 -0
- package/examples/canister-studio/scripts/smoke.ts +188 -0
- package/examples/canister-studio/src/calls/CacheKeyPanel.tsx +104 -0
- package/examples/canister-studio/src/calls/ConfirmWrite.tsx +265 -0
- package/examples/canister-studio/src/calls/ErrorPanel.test.tsx +113 -0
- package/examples/canister-studio/src/calls/ErrorPanel.tsx +214 -0
- package/examples/canister-studio/src/calls/MethodRunner.test.tsx +354 -0
- package/examples/canister-studio/src/calls/MethodRunner.tsx +57 -0
- package/examples/canister-studio/src/calls/ReadRunner.tsx +244 -0
- package/examples/canister-studio/src/calls/ResendPanel.tsx +165 -0
- package/examples/canister-studio/src/calls/ShareLink.tsx +59 -0
- package/examples/canister-studio/src/calls/WriteRunner.test.tsx +678 -0
- package/examples/canister-studio/src/calls/WriteRunner.tsx +670 -0
- package/examples/canister-studio/src/calls/dedupe.ts +189 -0
- package/examples/canister-studio/src/calls/error-info.ts +168 -0
- package/examples/canister-studio/src/calls/history.test.ts +284 -0
- package/examples/canister-studio/src/calls/history.ts +287 -0
- package/examples/canister-studio/src/calls/kinds.ts +68 -0
- package/examples/canister-studio/src/calls/prepare.ts +32 -0
- package/examples/canister-studio/src/calls/query-options.ts +30 -0
- package/examples/canister-studio/src/calls/read.ts +47 -0
- package/examples/canister-studio/src/calls/readback.ts +100 -0
- package/examples/canister-studio/src/calls/record.ts +123 -0
- package/examples/canister-studio/src/calls/safe-calls.test.ts +299 -0
- package/examples/canister-studio/src/calls/share.ts +46 -0
- package/examples/canister-studio/src/calls/testing/doubles.tsx +108 -0
- package/examples/canister-studio/src/calls/testing/fixtures.ts +185 -0
- package/examples/canister-studio/src/calls/useCanisterHandle.ts +35 -0
- package/examples/canister-studio/src/canisters/ckbtc_minter.envelope.json +4228 -0
- package/examples/canister-studio/src/canisters/ckbtc_minter.ts +868 -0
- package/examples/canister-studio/src/canisters/icp_ledger.envelope.json +3454 -0
- package/examples/canister-studio/src/canisters/icp_ledger.ts +584 -0
- package/examples/canister-studio/src/canisters/icrc1.envelope.json +840 -0
- package/examples/canister-studio/src/canisters/icrc1.ts +78 -0
- package/examples/canister-studio/src/components/ActionButton.tsx +32 -0
- package/examples/canister-studio/src/components/AppHeader.tsx +83 -0
- package/examples/canister-studio/src/components/AppShell.tsx +29 -0
- package/examples/canister-studio/src/components/AuthButton.tsx +79 -0
- package/examples/canister-studio/src/components/Badge.tsx +79 -0
- package/examples/canister-studio/src/components/CanisterHeader.tsx +200 -0
- package/examples/canister-studio/src/components/CanisterJump.tsx +130 -0
- package/examples/canister-studio/src/components/Card.tsx +64 -0
- package/examples/canister-studio/src/components/Code.tsx +101 -0
- package/examples/canister-studio/src/components/CopyButton.tsx +126 -0
- package/examples/canister-studio/src/components/Disclosure.tsx +34 -0
- package/examples/canister-studio/src/components/EmptyState.tsx +34 -0
- package/examples/canister-studio/src/components/MethodList.test.tsx +137 -0
- package/examples/canister-studio/src/components/MethodList.tsx +244 -0
- package/examples/canister-studio/src/components/Notice.tsx +36 -0
- package/examples/canister-studio/src/components/ProvenanceBadge.tsx +44 -0
- package/examples/canister-studio/src/components/RouteError.tsx +42 -0
- package/examples/canister-studio/src/components/SectionBoundary.tsx +76 -0
- package/examples/canister-studio/src/components/Spinner.tsx +33 -0
- package/examples/canister-studio/src/components/Tabs.tsx +96 -0
- package/examples/canister-studio/src/components/canister/CanisterLoadFailure.test.tsx +56 -0
- package/examples/canister-studio/src/components/canister/CanisterLoadFailure.tsx +165 -0
- package/examples/canister-studio/src/components/canister/CanisterNotFound.tsx +59 -0
- package/examples/canister-studio/src/components/canister/CanisterPending.tsx +33 -0
- package/examples/canister-studio/src/components/canister/MethodOverview.tsx +93 -0
- package/examples/canister-studio/src/components/canister/MethodWorkspace.test.tsx +201 -0
- package/examples/canister-studio/src/components/canister/MethodWorkspace.tsx +187 -0
- package/examples/canister-studio/src/components/canister/shared-call.test.ts +186 -0
- package/examples/canister-studio/src/components/canister/shared-call.ts +133 -0
- package/examples/canister-studio/src/components/canister/shared-link-loader.test.ts +116 -0
- package/examples/canister-studio/src/components/canister/use-canister-page.ts +44 -0
- package/examples/canister-studio/src/components/canister/workspace-key.test.ts +27 -0
- package/examples/canister-studio/src/components/canister/workspace-key.ts +36 -0
- package/examples/canister-studio/src/components/canister-id-input.ts +69 -0
- package/examples/canister-studio/src/components/canister-names.ts +11 -0
- package/examples/canister-studio/src/components/download.ts +34 -0
- package/examples/canister-studio/src/components/fallbacks.tsx +33 -0
- package/examples/canister-studio/src/components/helpers.test.ts +107 -0
- package/examples/canister-studio/src/components/history/HistoryList.tsx +284 -0
- package/examples/canister-studio/src/components/home/FeaturedLedger.tsx +149 -0
- package/examples/canister-studio/src/components/home/OpenCanister.tsx +99 -0
- package/examples/canister-studio/src/components/home/featured.test.tsx +92 -0
- package/examples/canister-studio/src/components/home/featured.ts +64 -0
- package/examples/canister-studio/src/components/interface/CandidTab.tsx +38 -0
- package/examples/canister-studio/src/components/interface/CompatReport.tsx +92 -0
- package/examples/canister-studio/src/components/interface/CompatibilityTab.tsx +190 -0
- package/examples/canister-studio/src/components/interface/ProjectTab.tsx +196 -0
- package/examples/canister-studio/src/components/interface/TypeScriptTab.tsx +114 -0
- package/examples/canister-studio/src/components/interface/tools.test.tsx +169 -0
- package/examples/canister-studio/src/components/modes.ts +31 -0
- package/examples/canister-studio/src/components/playground/MethodPicker.tsx +67 -0
- package/examples/canister-studio/src/components/playground/PlaygroundForms.tsx +112 -0
- package/examples/canister-studio/src/components/playground/PlaygroundTools.tsx +219 -0
- package/examples/canister-studio/src/components/playground/sample.ts +43 -0
- package/examples/canister-studio/src/components/playground/target.test.tsx +86 -0
- package/examples/canister-studio/src/components/primitives.test.tsx +121 -0
- package/examples/canister-studio/src/components/provenance.ts +38 -0
- package/examples/canister-studio/src/components/route-render.test.tsx +71 -0
- package/examples/canister-studio/src/components/use-task.ts +56 -0
- package/examples/canister-studio/src/components/wallet/BalancePanel.tsx +110 -0
- package/examples/canister-studio/src/components/wallet/LedgerSummary.tsx +63 -0
- package/examples/canister-studio/src/components/wallet/MinterPanel.tsx +255 -0
- package/examples/canister-studio/src/components/wallet/SendPanel.test.tsx +297 -0
- package/examples/canister-studio/src/components/wallet/SendPanel.tsx +446 -0
- package/examples/canister-studio/src/components/wallet/ledgers.test.ts +36 -0
- package/examples/canister-studio/src/components/wallet/ledgers.ts +111 -0
- package/examples/canister-studio/src/forms/JsonPanel.tsx +157 -0
- package/examples/canister-studio/src/forms/MethodForm.test.tsx +369 -0
- package/examples/canister-studio/src/forms/MethodForm.tsx +368 -0
- package/examples/canister-studio/src/forms/TypedForm.tsx +55 -0
- package/examples/canister-studio/src/forms/context.ts +62 -0
- package/examples/canister-studio/src/forms/convert.ts +131 -0
- package/examples/canister-studio/src/forms/edge.test.ts +252 -0
- package/examples/canister-studio/src/forms/engine.test.ts +358 -0
- package/examples/canister-studio/src/forms/engine.ts +1492 -0
- package/examples/canister-studio/src/forms/fields/BytesField.tsx +210 -0
- package/examples/canister-studio/src/forms/fields/Field.tsx +106 -0
- package/examples/canister-studio/src/forms/fields/FieldShell.tsx +101 -0
- package/examples/canister-studio/src/forms/fields/Group.tsx +74 -0
- package/examples/canister-studio/src/forms/fields/ListField.tsx +256 -0
- package/examples/canister-studio/src/forms/fields/Segmented.tsx +78 -0
- package/examples/canister-studio/src/forms/fields/TimestampField.tsx +108 -0
- package/examples/canister-studio/src/forms/fields/UnitsField.tsx +119 -0
- package/examples/canister-studio/src/forms/fields/composites.tsx +389 -0
- package/examples/canister-studio/src/forms/fields/leaves.tsx +350 -0
- package/examples/canister-studio/src/forms/fields.test.tsx +396 -0
- package/examples/canister-studio/src/forms/helpers.test.ts +225 -0
- package/examples/canister-studio/src/forms/hints.ts +128 -0
- package/examples/canister-studio/src/forms/json.ts +119 -0
- package/examples/canister-studio/src/forms/parsing.test.ts +217 -0
- package/examples/canister-studio/src/forms/useMethodForm.ts +251 -0
- package/examples/canister-studio/src/interface/browser.test.ts +23 -0
- package/examples/canister-studio/src/interface/browser.ts +153 -0
- package/examples/canister-studio/src/interface/cache.ts +68 -0
- package/examples/canister-studio/src/interface/cli-cache.test.ts +155 -0
- package/examples/canister-studio/src/interface/cli-cache.ts +125 -0
- package/examples/canister-studio/src/interface/compile.server.test.ts +198 -0
- package/examples/canister-studio/src/interface/compile.server.ts +262 -0
- package/examples/canister-studio/src/interface/compile.test.ts +108 -0
- package/examples/canister-studio/src/interface/compile.ts +305 -0
- package/examples/canister-studio/src/interface/docs.test.ts +75 -0
- package/examples/canister-studio/src/interface/docs.ts +100 -0
- package/examples/canister-studio/src/interface/functions.test.ts +42 -0
- package/examples/canister-studio/src/interface/functions.ts +200 -0
- package/examples/canister-studio/src/interface/live-candid.server.ts +91 -0
- package/examples/canister-studio/src/interface/live-loader.test.ts +515 -0
- package/examples/canister-studio/src/interface/live-loader.ts +364 -0
- package/examples/canister-studio/src/interface/load.test.ts +328 -0
- package/examples/canister-studio/src/interface/load.ts +249 -0
- package/examples/canister-studio/src/interface/read-candid.test.ts +185 -0
- package/examples/canister-studio/src/interface/read-candid.ts +233 -0
- package/examples/canister-studio/src/interface/server-result.ts +42 -0
- package/examples/canister-studio/src/interface/typed.ts +68 -0
- package/examples/canister-studio/src/interface/types.ts +121 -0
- package/examples/canister-studio/src/lib/format.test.ts +107 -0
- package/examples/canister-studio/src/lib/format.ts +139 -0
- package/examples/canister-studio/src/lib/hex.test.ts +43 -0
- package/examples/canister-studio/src/lib/hex.ts +33 -0
- package/examples/canister-studio/src/lib/ids.test.ts +70 -0
- package/examples/canister-studio/src/lib/ids.ts +93 -0
- package/examples/canister-studio/src/lib/reactor.test.ts +55 -0
- package/examples/canister-studio/src/lib/reactor.ts +55 -0
- package/examples/canister-studio/src/lib/registry.test.ts +74 -0
- package/examples/canister-studio/src/lib/registry.ts +238 -0
- package/examples/canister-studio/src/lib/schema.ts +148 -0
- package/examples/canister-studio/src/routeTree.gen.ts +227 -0
- package/examples/canister-studio/src/router.test.ts +290 -0
- package/examples/canister-studio/src/router.tsx +127 -0
- package/examples/canister-studio/src/routes/__root.tsx +58 -0
- package/examples/canister-studio/src/routes/canister.$canisterId.index.tsx +172 -0
- package/examples/canister-studio/src/routes/canister.$canisterId.interface.tsx +98 -0
- package/examples/canister-studio/src/routes/canister.$canisterId.tsx +91 -0
- package/examples/canister-studio/src/routes/history.tsx +55 -0
- package/examples/canister-studio/src/routes/index.tsx +169 -0
- package/examples/canister-studio/src/routes/playground.tsx +286 -0
- package/examples/canister-studio/src/routes/safety.tsx +57 -0
- package/examples/canister-studio/src/routes/wallet.tsx +213 -0
- package/examples/canister-studio/src/safety/LabTransferForm.tsx +84 -0
- package/examples/canister-studio/src/safety/RequestLog.tsx +79 -0
- package/examples/canister-studio/src/safety/SafetyLab.test.tsx +89 -0
- package/examples/canister-studio/src/safety/SafetyLab.tsx +140 -0
- package/examples/canister-studio/src/safety/ScenarioCard.tsx +262 -0
- package/examples/canister-studio/src/safety/lab-run.ts +283 -0
- package/examples/canister-studio/src/safety/mock-ledger.test.ts +99 -0
- package/examples/canister-studio/src/safety/mock-ledger.ts +263 -0
- package/examples/canister-studio/src/safety/scenarios.test.ts +157 -0
- package/examples/canister-studio/src/safety/scenarios.ts +924 -0
- package/examples/canister-studio/src/styles.css +3453 -0
- package/examples/canister-studio/src/styles.test.ts +46 -0
- package/examples/canister-studio/src/values/CallPreview.test.tsx +86 -0
- package/examples/canister-studio/src/values/CallPreview.tsx +148 -0
- package/examples/canister-studio/src/values/ErrValueView.tsx +66 -0
- package/examples/canister-studio/src/values/Inspector.tsx +133 -0
- package/examples/canister-studio/src/values/ReplyView.test.tsx +341 -0
- package/examples/canister-studio/src/values/ReplyView.tsx +164 -0
- package/examples/canister-studio/src/values/candid-text.test.ts +516 -0
- package/examples/canister-studio/src/values/candid-text.ts +479 -0
- package/examples/canister-studio/src/values/hints.ts +58 -0
- package/examples/canister-studio/src/values/json.test.ts +66 -0
- package/examples/canister-studio/src/values/json.ts +31 -0
- package/examples/canister-studio/src/values/leaves.tsx +309 -0
- package/examples/canister-studio/src/values/schema.test.ts +123 -0
- package/examples/canister-studio/src/values/schema.ts +78 -0
- package/examples/canister-studio/src/values/test-router.tsx +21 -0
- package/examples/canister-studio/src/values/tree.tsx +670 -0
- package/examples/canister-studio/src/values/use-sha256.ts +29 -0
- package/examples/canister-studio/tsconfig.json +20 -0
- package/examples/canister-studio/vite.config.ts +50 -0
- package/examples/canister-studio/vitest.config.ts +20 -0
- package/examples/icrc-ledger/.stackblitzrc +4 -0
- package/examples/icrc-ledger/README.md +100 -0
- package/examples/icrc-ledger/ckbtc_minter.did +12 -0
- package/examples/icrc-ledger/icp_ledger.did +147 -0
- package/examples/icrc-ledger/icrc1.did +88 -0
- package/examples/icrc-ledger/index.html +13 -0
- package/examples/icrc-ledger/package.json +40 -0
- package/examples/icrc-ledger/scripts/smoke.ts +151 -0
- package/examples/icrc-ledger/src/App.tsx +71 -0
- package/examples/icrc-ledger/src/ErrorPanel.tsx +105 -0
- package/examples/icrc-ledger/src/MainnetTab.tsx +450 -0
- package/examples/icrc-ledger/src/SandboxTab.test.tsx +379 -0
- package/examples/icrc-ledger/src/SandboxTab.tsx +761 -0
- package/examples/icrc-ledger/src/blocks.test.ts +247 -0
- package/examples/icrc-ledger/src/blocks.ts +140 -0
- package/examples/icrc-ledger/src/canisters/ckbtc_minter.envelope.json +96 -0
- package/examples/icrc-ledger/src/canisters/ckbtc_minter.ts +16 -0
- package/examples/icrc-ledger/src/canisters/icp_ledger.envelope.json +690 -0
- package/examples/icrc-ledger/src/canisters/icp_ledger.ts +223 -0
- package/examples/icrc-ledger/src/canisters/icrc1.envelope.json +840 -0
- package/examples/icrc-ledger/src/canisters/icrc1.ts +78 -0
- package/examples/icrc-ledger/src/format.test.ts +41 -0
- package/examples/icrc-ledger/src/format.ts +68 -0
- package/examples/icrc-ledger/src/ledger.ts +15 -0
- package/examples/icrc-ledger/src/main.tsx +10 -0
- package/examples/icrc-ledger/src/minter.ts +16 -0
- package/examples/icrc-ledger/src/sandbox.test.ts +464 -0
- package/examples/icrc-ledger/src/sandbox.ts +281 -0
- package/examples/icrc-ledger/src/styles.css +391 -0
- package/examples/icrc-ledger/src/transfer-form.test.ts +62 -0
- package/examples/icrc-ledger/src/transfer-form.ts +97 -0
- package/examples/icrc-ledger/tsconfig.json +19 -0
- package/examples/icrc-ledger/vite.config.ts +44 -0
- package/examples/icrc-ledger/vitest.config.ts +12 -0
- package/examples/next-ssr/.stackblitzrc +4 -0
- package/examples/next-ssr/README.md +112 -0
- package/examples/next-ssr/icrc1.did +88 -0
- package/examples/next-ssr/next.config.ts +10 -0
- package/examples/next-ssr/package.json +41 -0
- package/examples/next-ssr/scripts/smoke.ts +169 -0
- package/examples/next-ssr/src/app/account/CertifiedBalances.tsx +58 -0
- package/examples/next-ssr/src/app/account/account.test.tsx +165 -0
- package/examples/next-ssr/src/app/account/page.tsx +82 -0
- package/examples/next-ssr/src/app/api/balance/[ledger]/[principal]/route.ts +10 -0
- package/examples/next-ssr/src/app/globals.css +278 -0
- package/examples/next-ssr/src/app/layout.tsx +34 -0
- package/examples/next-ssr/src/app/page.tsx +46 -0
- package/examples/next-ssr/src/app/providers.browser.test.tsx +127 -0
- package/examples/next-ssr/src/app/providers.test.tsx +73 -0
- package/examples/next-ssr/src/app/providers.tsx +60 -0
- package/examples/next-ssr/src/canisters/icrc1.envelope.json +840 -0
- package/examples/next-ssr/src/canisters/icrc1.ts +78 -0
- package/examples/next-ssr/src/components/BalanceTable.tsx +43 -0
- package/examples/next-ssr/src/components/LedgerCard.test.tsx +96 -0
- package/examples/next-ssr/src/components/LedgerCard.tsx +230 -0
- package/examples/next-ssr/src/components/LedgerError.tsx +32 -0
- package/examples/next-ssr/src/components/LedgerSections.tsx +22 -0
- package/examples/next-ssr/src/components/MyBalances.test.tsx +253 -0
- package/examples/next-ssr/src/components/MyBalances.tsx +129 -0
- package/examples/next-ssr/src/components/SessionBadge.tsx +18 -0
- package/examples/next-ssr/src/components/hydration.test.tsx +259 -0
- package/examples/next-ssr/src/components/server-data.ts +10 -0
- package/examples/next-ssr/src/format.ts +46 -0
- package/examples/next-ssr/src/ledgers.ts +38 -0
- package/examples/next-ssr/src/server/balance-route.test.ts +151 -0
- package/examples/next-ssr/src/server/balance-route.ts +157 -0
- package/examples/next-ssr/src/server/error-summary.test.ts +34 -0
- package/examples/next-ssr/src/server/error-summary.ts +37 -0
- package/examples/next-ssr/src/server/parse-owner.test.ts +39 -0
- package/examples/next-ssr/src/server/parse-owner.ts +34 -0
- package/examples/next-ssr/src/server/prefetch-ledgers.test.ts +137 -0
- package/examples/next-ssr/src/server/prefetch-ledgers.ts +70 -0
- package/examples/next-ssr/src/server/read-balances.test.ts +103 -0
- package/examples/next-ssr/src/server/read-balances.ts +78 -0
- package/examples/next-ssr/src/server/request-client.rsc.test.tsx +110 -0
- package/examples/next-ssr/src/server/request-client.ts +24 -0
- package/examples/next-ssr/src/testing/mock-ledgers.ts +115 -0
- package/examples/next-ssr/src/testing/react-server-dom-turbopack.d.ts +15 -0
- package/examples/next-ssr/src/testing/setup.ts +10 -0
- package/examples/next-ssr/tsconfig.json +31 -0
- package/examples/next-ssr/vitest.config.ts +59 -0
- package/examples/node-agent-tool/.stackblitzrc +4 -0
- package/examples/node-agent-tool/README.md +165 -0
- package/examples/node-agent-tool/icp.yaml +11 -0
- package/examples/node-agent-tool/icrc1.did +88 -0
- package/examples/node-agent-tool/package.json +32 -0
- package/examples/node-agent-tool/src/canisters/icrc1.envelope.json +840 -0
- package/examples/node-agent-tool/src/canisters/icrc1.ts +78 -0
- package/examples/node-agent-tool/src/cli.test.ts +64 -0
- package/examples/node-agent-tool/src/cli.ts +23 -0
- package/examples/node-agent-tool/src/command-line.ts +159 -0
- package/examples/node-agent-tool/src/commands/balance.ts +73 -0
- package/examples/node-agent-tool/src/commands/demo.test.ts +51 -0
- package/examples/node-agent-tool/src/commands/demo.ts +359 -0
- package/examples/node-agent-tool/src/commands/info.ts +69 -0
- package/examples/node-agent-tool/src/commands/reads.test.ts +133 -0
- package/examples/node-agent-tool/src/commands/resend.test.ts +363 -0
- package/examples/node-agent-tool/src/commands/transfer.test.ts +313 -0
- package/examples/node-agent-tool/src/commands/transfer.ts +415 -0
- package/examples/node-agent-tool/src/commands/watch.test.ts +159 -0
- package/examples/node-agent-tool/src/commands/watch.ts +135 -0
- package/examples/node-agent-tool/src/commands/whoami.ts +36 -0
- package/examples/node-agent-tool/src/context.ts +20 -0
- package/examples/node-agent-tool/src/dispatch.ts +70 -0
- package/examples/node-agent-tool/src/failure.test.ts +59 -0
- package/examples/node-agent-tool/src/failure.ts +176 -0
- package/examples/node-agent-tool/src/identity.test.ts +242 -0
- package/examples/node-agent-tool/src/identity.ts +228 -0
- package/examples/node-agent-tool/src/input.ts +110 -0
- package/examples/node-agent-tool/src/ledgers.test.ts +74 -0
- package/examples/node-agent-tool/src/ledgers.ts +62 -0
- package/examples/node-agent-tool/src/mock-ledger.ts +211 -0
- package/examples/node-agent-tool/src/network.test.ts +128 -0
- package/examples/node-agent-tool/src/network.ts +101 -0
- package/examples/node-agent-tool/src/output.test.ts +208 -0
- package/examples/node-agent-tool/src/output.ts +163 -0
- package/examples/node-agent-tool/src/run.ts +73 -0
- package/examples/node-agent-tool/src/test-kit.ts +167 -0
- package/examples/node-agent-tool/tsconfig.json +18 -0
- package/examples/node-agent-tool/vitest.config.ts +8 -0
- package/examples/vite-wallet/.stackblitzrc +4 -0
- package/examples/vite-wallet/Cargo.lock +646 -0
- package/examples/vite-wallet/Cargo.toml +5 -0
- package/examples/vite-wallet/README.md +107 -0
- package/examples/vite-wallet/backend/Cargo.toml +12 -0
- package/examples/vite-wallet/backend/backend.did +37 -0
- package/examples/vite-wallet/backend/src/lib.rs +133 -0
- package/examples/vite-wallet/icp.yaml +44 -0
- package/examples/vite-wallet/index.html +13 -0
- package/examples/vite-wallet/ledger.did +54 -0
- package/examples/vite-wallet/package.json +46 -0
- package/examples/vite-wallet/public/.ic-assets.json5 +26 -0
- package/examples/vite-wallet/scripts/faucet-args.test.ts +30 -0
- package/examples/vite-wallet/scripts/faucet-args.ts +41 -0
- package/examples/vite-wallet/scripts/faucet.ts +41 -0
- package/examples/vite-wallet/src/AddressBook.test.tsx +191 -0
- package/examples/vite-wallet/src/AddressBook.tsx +147 -0
- package/examples/vite-wallet/src/App.tsx +53 -0
- package/examples/vite-wallet/src/Balance.test.tsx +57 -0
- package/examples/vite-wallet/src/Balance.tsx +58 -0
- package/examples/vite-wallet/src/EnvironmentPanel.test.tsx +83 -0
- package/examples/vite-wallet/src/EnvironmentPanel.tsx +103 -0
- package/examples/vite-wallet/src/ErrorNote.tsx +70 -0
- package/examples/vite-wallet/src/Profile.test.tsx +145 -0
- package/examples/vite-wallet/src/Profile.tsx +92 -0
- package/examples/vite-wallet/src/SendIcp.test.tsx +231 -0
- package/examples/vite-wallet/src/SendIcp.tsx +244 -0
- package/examples/vite-wallet/src/SendToContact.test.tsx +113 -0
- package/examples/vite-wallet/src/SendToContact.tsx +102 -0
- package/examples/vite-wallet/src/SignIn.test.tsx +106 -0
- package/examples/vite-wallet/src/SignIn.tsx +120 -0
- package/examples/vite-wallet/src/Wallet.test.tsx +89 -0
- package/examples/vite-wallet/src/account-switch.test.tsx +108 -0
- package/examples/vite-wallet/src/auth/dev-accounts.test.ts +113 -0
- package/examples/vite-wallet/src/auth/dev-accounts.ts +216 -0
- package/examples/vite-wallet/src/auth/local-page.test.ts +28 -0
- package/examples/vite-wallet/src/auth/local-page.ts +20 -0
- package/examples/vite-wallet/src/auth/wallet-auth.test.ts +159 -0
- package/examples/vite-wallet/src/auth/wallet-auth.ts +131 -0
- package/examples/vite-wallet/src/canisters/backend.envelope.json +275 -0
- package/examples/vite-wallet/src/canisters/backend.ts +58 -0
- package/examples/vite-wallet/src/canisters/ledger.envelope.json +451 -0
- package/examples/vite-wallet/src/canisters/ledger.ts +56 -0
- package/examples/vite-wallet/src/client.ts +45 -0
- package/examples/vite-wallet/src/main.tsx +18 -0
- package/examples/vite-wallet/src/optimistic-contacts.ts +113 -0
- package/examples/vite-wallet/src/refusal.ts +17 -0
- package/examples/vite-wallet/src/styles.css +282 -0
- package/examples/vite-wallet/src/test/test-wallet.tsx +322 -0
- package/examples/vite-wallet/src/token.ts +50 -0
- package/examples/vite-wallet/src/transfer.test.ts +178 -0
- package/examples/vite-wallet/src/transfer.ts +110 -0
- package/examples/vite-wallet/src/use-canisters.ts +49 -0
- package/examples/vite-wallet/tsconfig.json +19 -0
- package/examples/vite-wallet/vite.config.ts +47 -0
- package/examples/vite-wallet/vitest.config.ts +17 -0
- package/package.json +9 -4
- package/packages/core/.size-limit.js +47 -0
- package/packages/core/LICENSE +21 -0
- package/packages/core/README.md +84 -0
- package/packages/core/llms.txt +610 -0
- package/packages/core/package.json +89 -0
- package/packages/core/src/call.ts +961 -0
- package/packages/core/src/canister.ts +259 -0
- package/packages/core/src/client.ts +2061 -0
- package/packages/core/src/errors.ts +1079 -0
- package/packages/core/src/hydration.ts +239 -0
- package/packages/core/src/index.ts +23 -0
- package/packages/core/src/keys.ts +108 -0
- package/packages/core/src/management.ts +138 -0
- package/packages/core/src/network.ts +1020 -0
- package/packages/core/src/options.ts +1000 -0
- package/packages/core/src/runtime.ts +50 -0
- package/packages/core/src/testing/fake-replica.ts +1166 -0
- package/packages/core/src/testing/index.ts +16 -0
- package/packages/core/src/testing/test-auth.ts +340 -0
- package/packages/core/src/testing/test-client.ts +559 -0
- package/packages/core/src/types.ts +541 -0
- package/packages/core/src/units.ts +299 -0
- package/packages/core/src/version.ts +4 -0
- package/packages/core/tests/canister-helpers.ts +187 -0
- package/packages/core/tests/canister-id.test.ts +158 -0
- package/packages/core/tests/canister-unwrap.test.ts +94 -0
- package/packages/core/tests/canister.test-d.ts +406 -0
- package/packages/core/tests/canister.test.ts +1921 -0
- package/packages/core/tests/client-account-change.test.ts +131 -0
- package/packages/core/tests/client-agents.test.ts +402 -0
- package/packages/core/tests/client-auth-network.test.ts +719 -0
- package/packages/core/tests/client-disposed.test.ts +403 -0
- package/packages/core/tests/client-helpers.ts +136 -0
- package/packages/core/tests/client-hydration.test.ts +166 -0
- package/packages/core/tests/client-pinned.test.ts +626 -0
- package/packages/core/tests/client-session.test.ts +348 -0
- package/packages/core/tests/client.test-d.ts +181 -0
- package/packages/core/tests/client.test.ts +1162 -0
- package/packages/core/tests/encode.test.ts +171 -0
- package/packages/core/tests/env-canister-id.test.ts +666 -0
- package/packages/core/tests/env-cookie-copies.test.ts +182 -0
- package/packages/core/tests/error-guard.test.ts +222 -0
- package/packages/core/tests/errors.test-d.ts +280 -0
- package/packages/core/tests/errors.test.ts +1359 -0
- package/packages/core/tests/fixtures/README.md +28 -0
- package/packages/core/tests/fixtures/accounts.did +21 -0
- package/packages/core/tests/fixtures/accounts.envelope.json +367 -0
- package/packages/core/tests/fixtures/accounts.ts +26 -0
- package/packages/core/tests/fixtures/archive.did +31 -0
- package/packages/core/tests/fixtures/archive.envelope.json +259 -0
- package/packages/core/tests/fixtures/archive.ts +55 -0
- package/packages/core/tests/fixtures/icrc1.did +88 -0
- package/packages/core/tests/fixtures/icrc1.envelope.json +840 -0
- package/packages/core/tests/fixtures/icrc1.ts +78 -0
- package/packages/core/tests/fixtures/management.did +724 -0
- package/packages/core/tests/fixtures/management.envelope.json +4455 -0
- package/packages/core/tests/fixtures/management.ts +486 -0
- package/packages/core/tests/fixtures/shapes.did +33 -0
- package/packages/core/tests/fixtures/shapes.envelope.json +440 -0
- package/packages/core/tests/fixtures/shapes.ts +56 -0
- package/packages/core/tests/fixtures/skippable.did +15 -0
- package/packages/core/tests/fixtures/skippable.envelope.json +182 -0
- package/packages/core/tests/fixtures/skippable.ts +33 -0
- package/packages/core/tests/func.test.ts +154 -0
- package/packages/core/tests/identity-attributes.test.ts +214 -0
- package/packages/core/tests/keys.test.ts +289 -0
- package/packages/core/tests/management.test.ts +206 -0
- package/packages/core/tests/network-helpers.ts +121 -0
- package/packages/core/tests/network.test-d.ts +78 -0
- package/packages/core/tests/network.test.ts +1051 -0
- package/packages/core/tests/options.test.ts +1594 -0
- package/packages/core/tests/redirect-sign-in.test.ts +393 -0
- package/packages/core/tests/resend.test-d.ts +81 -0
- package/packages/core/tests/resend.test.ts +723 -0
- package/packages/core/tests/skip.test-d.ts +125 -0
- package/packages/core/tests/testing-entry.test.ts +73 -0
- package/packages/core/tests/testing-fake-replica.test.ts +1242 -0
- package/packages/core/tests/testing-test-auth.test-d.ts +84 -0
- package/packages/core/tests/testing-test-auth.test.ts +483 -0
- package/packages/core/tests/testing-test-client.test-d.ts +184 -0
- package/packages/core/tests/testing-test-client.test.ts +1272 -0
- package/packages/core/tests/time-realm.test.ts +63 -0
- package/packages/core/tests/time.test.ts +238 -0
- package/packages/core/tests/traps/README.md +39 -0
- package/packages/core/tests/traps/anonymous-write.test.ts +145 -0
- package/packages/core/tests/traps/classification-table.test.ts +256 -0
- package/packages/core/tests/traps/err-arm.test.ts +144 -0
- package/packages/core/tests/traps/fetch-spy.ts +39 -0
- package/packages/core/tests/traps/invalidation-after-write.test.ts +178 -0
- package/packages/core/tests/traps/ledger.ts +248 -0
- package/packages/core/tests/traps/root-key-off-local.test.ts +130 -0
- package/packages/core/tests/traps/stale-data-across-users.test.ts +173 -0
- package/packages/core/tests/traps/unresolved-name.test.ts +155 -0
- package/packages/core/tests/traps/update-as-query.test.ts +244 -0
- package/packages/core/tests/traps/update-not-resent.test.ts +126 -0
- package/packages/core/tests/traps/update-resent-when-never-delivered.test.ts +159 -0
- package/packages/core/tests/traps.test-d.ts +476 -0
- package/packages/core/tests/units.test-d.ts +118 -0
- package/packages/core/tests/units.test.ts +634 -0
- package/packages/core/tsconfig.json +19 -0
- package/packages/core/tsconfig.typecheck.json +16 -0
- package/packages/core/vitest.config.ts +13 -0
- package/packages/mcp/LICENSE +21 -0
- package/packages/mcp/README.md +189 -0
- package/packages/mcp/package.json +62 -0
- package/packages/mcp/src/candid/candid-text.test.ts +455 -0
- package/packages/mcp/src/candid/candid-text.ts +501 -0
- package/packages/mcp/src/candid/contract.test.ts +398 -0
- package/packages/mcp/src/candid/formats.ts +155 -0
- package/packages/mcp/src/candid/hex.ts +29 -0
- package/packages/mcp/src/candid/json-schema.test.ts +758 -0
- package/packages/mcp/src/candid/json-schema.ts +454 -0
- package/packages/mcp/src/candid/json.test.ts +1207 -0
- package/packages/mcp/src/candid/json.ts +1053 -0
- package/packages/mcp/src/candid/schema-walk.ts +189 -0
- package/packages/mcp/src/candid/type-text.test.ts +179 -0
- package/packages/mcp/src/candid/type-text.ts +238 -0
- package/packages/mcp/src/cli.ts +134 -0
- package/packages/mcp/src/identity.ts +188 -0
- package/packages/mcp/src/interface/cache.test.ts +48 -0
- package/packages/mcp/src/interface/cache.ts +68 -0
- package/packages/mcp/src/interface/cli-cache.test.ts +150 -0
- package/packages/mcp/src/interface/cli-cache.ts +122 -0
- package/packages/mcp/src/interface/compile-worker.test.ts +246 -0
- package/packages/mcp/src/interface/compile-worker.ts +290 -0
- package/packages/mcp/src/interface/compile.test.ts +155 -0
- package/packages/mcp/src/interface/compile.ts +281 -0
- package/packages/mcp/src/interface/docs.test.ts +105 -0
- package/packages/mcp/src/interface/docs.ts +86 -0
- package/packages/mcp/src/interface/fixtures/icrc1.did +88 -0
- package/packages/mcp/src/interface/hex.ts +8 -0
- package/packages/mcp/src/interface/ids.test.ts +71 -0
- package/packages/mcp/src/interface/ids.ts +87 -0
- package/packages/mcp/src/interface/loader.test.ts +804 -0
- package/packages/mcp/src/interface/loader.ts +519 -0
- package/packages/mcp/src/interface/read-candid.test.ts +300 -0
- package/packages/mcp/src/interface/read-candid.ts +259 -0
- package/packages/mcp/src/interface/types.ts +113 -0
- package/packages/mcp/src/network.ts +122 -0
- package/packages/mcp/src/options.ts +149 -0
- package/packages/mcp/src/server/approval.ts +159 -0
- package/packages/mcp/src/server/naming.ts +43 -0
- package/packages/mcp/src/server/results.ts +102 -0
- package/packages/mcp/src/server/server.ts +797 -0
- package/packages/mcp/src/server/tools.ts +116 -0
- package/packages/mcp/src/usage.ts +40 -0
- package/packages/mcp/tests/approval.test.ts +60 -0
- package/packages/mcp/tests/identity.test.ts +234 -0
- package/packages/mcp/tests/naming.test.ts +62 -0
- package/packages/mcp/tests/options.test.ts +140 -0
- package/packages/mcp/tests/server.test.ts +997 -0
- package/packages/mcp/tsconfig.json +19 -0
- package/packages/mcp/tsconfig.typecheck.json +10 -0
- package/packages/mcp/vitest.config.ts +10 -0
- package/packages/react/LICENSE +21 -0
- package/packages/react/README.md +328 -0
- package/packages/react/llms.txt +95 -0
- package/packages/react/package.json +95 -0
- package/packages/react/src/index.tsx +678 -0
- package/packages/react/tests/abandoned-render.test.tsx +816 -0
- package/packages/react/tests/auth.test.tsx +315 -0
- package/packages/react/tests/caller-keys.test.tsx +2334 -0
- package/packages/react/tests/client-time.test.ts +40 -0
- package/packages/react/tests/entry.test.ts +52 -0
- package/packages/react/tests/helpers.tsx +291 -0
- package/packages/react/tests/hydration.test.tsx +262 -0
- package/packages/react/tests/ownership.test.tsx +260 -0
- package/packages/react/tests/provider.server.test.tsx +169 -0
- package/packages/react/tests/query-client.test.tsx +107 -0
- package/packages/react/tests/strict-mode.test.tsx +288 -0
- package/packages/react/tests/suspense.test-d.tsx +357 -0
- package/packages/react/tests/two-query-cores.test.tsx +135 -0
- package/packages/react/tests/types.test-d.tsx +63 -0
- package/packages/react/tsconfig.json +23 -0
- package/packages/react/tsconfig.test.json +8 -0
- package/packages/react/tsconfig.typecheck.json +16 -0
- package/packages/react/vitest.config.ts +39 -0
- package/packages/vite-plugin/LICENSE +21 -0
- package/packages/vite-plugin/README.md +532 -0
- package/packages/vite-plugin/package.json +76 -0
- package/packages/vite-plugin/src/describe-value.test.ts +43 -0
- package/packages/vite-plugin/src/describe-value.ts +167 -0
- package/packages/vite-plugin/src/dev-environment.test.ts +747 -0
- package/packages/vite-plugin/src/dev-environment.ts +510 -0
- package/packages/vite-plugin/src/env.ts +431 -0
- package/packages/vite-plugin/src/fetch.ts +348 -0
- package/packages/vite-plugin/src/file-identity.ts +106 -0
- package/packages/vite-plugin/src/generate.ts +691 -0
- package/packages/vite-plugin/src/index.test.ts +1243 -0
- package/packages/vite-plugin/src/index.ts +2565 -0
- package/packages/vite-plugin/src/interface.ts +339 -0
- package/packages/vite-plugin/src/local-host.ts +34 -0
- package/packages/vite-plugin/src/options.ts +641 -0
- package/packages/vite-plugin/src/principal-text.test.ts +87 -0
- package/packages/vite-plugin/src/principal-text.ts +98 -0
- package/packages/vite-plugin/tests/close.test.ts +141 -0
- package/packages/vite-plugin/tests/environment-mode.test.ts +136 -0
- package/packages/vite-plugin/tests/fake-ic.ts +214 -0
- package/packages/vite-plugin/tests/fetch-sdk.test.ts +27 -0
- package/packages/vite-plugin/tests/fetch.test.ts +1196 -0
- package/packages/vite-plugin/tests/fixtures/fake-cli/bin.js +90 -0
- package/packages/vite-plugin/tests/fixtures/fake-cli/package.json +8 -0
- package/packages/vite-plugin/tests/fixtures/icrc1.did +88 -0
- package/packages/vite-plugin/tests/generation.test.ts +1036 -0
- package/packages/vite-plugin/tests/icp-command.test.ts +194 -0
- package/packages/vite-plugin/tests/icp-timeout.test.ts +83 -0
- package/packages/vite-plugin/tests/no-process-exit.test.ts +83 -0
- package/packages/vite-plugin/tests/on-generated.test.ts +323 -0
- package/packages/vite-plugin/tests/output-collision.test.ts +329 -0
- package/packages/vite-plugin/tests/package.test.ts +62 -0
- package/packages/vite-plugin/tests/project.test.ts +2993 -0
- package/packages/vite-plugin/tests/support.ts +339 -0
- package/packages/vite-plugin/tests/timeout.test.ts +107 -0
- package/packages/vite-plugin/tsconfig.json +23 -0
- package/packages/vite-plugin/tsconfig.typecheck.json +16 -0
- package/packages/vite-plugin/vitest.config.ts +9 -0
- package/pnpm-workspace.yaml +23 -0
- package/scripts/ai-context-files.js +72 -0
- package/scripts/assemble-docs-site.mjs +485 -0
- package/scripts/assemble-docs-site.test.mjs +568 -0
- package/scripts/build-examples.js +58 -0
- package/scripts/check-ai-context.js +963 -0
- package/scripts/check-ai-context.test.mjs +811 -0
- package/scripts/check-exports.mjs +767 -0
- package/scripts/check-exports.test.mjs +1136 -0
- package/scripts/check-snippets/ambient.d.ts +428 -0
- package/scripts/check-snippets/app/generated/backend.did +7 -0
- package/scripts/check-snippets/app/generated/backend.ts +15 -0
- package/scripts/check-snippets/app/generated/icrc1.did +88 -0
- package/scripts/check-snippets/app/generated/icrc1.ts +78 -0
- package/scripts/check-snippets/app/globals.ts +26 -0
- package/scripts/check-snippets/docs/guides/App.tsx +21 -0
- package/scripts/check-snippets/docs/guides/app/providers.tsx +23 -0
- package/scripts/check-snippets/docs/guides/auth-client.ts +47 -0
- package/scripts/check-snippets/docs/guides/canisters/backend.ts +3 -0
- package/scripts/check-snippets/docs/guides/canisters/icrc1.ts +3 -0
- package/scripts/check-snippets/docs/guides/components/LedgerCard.tsx +26 -0
- package/scripts/check-snippets/docs/guides/components/shell.tsx +11 -0
- package/scripts/check-snippets/docs/guides/components/sign-in-page.tsx +29 -0
- package/scripts/check-snippets/docs/guides/components/slow-section.tsx +5 -0
- package/scripts/check-snippets/docs/guides/generated/accounts.ts +95 -0
- package/scripts/check-snippets/docs/guides/generated/ckbtc_minter.ts +40 -0
- package/scripts/check-snippets/docs/guides/generated/icp_ledger.ts +267 -0
- package/scripts/check-snippets/docs/guides/ledger.ts +10 -0
- package/scripts/check-snippets/docs/guides/server/request-client.ts +8 -0
- package/scripts/check-snippets.mjs +993 -0
- package/scripts/check-snippets.test.mjs +338 -0
- package/scripts/check-stack.mjs +501 -0
- package/scripts/check-stack.test.mjs +800 -0
- package/scripts/clean-node-modules.js +67 -0
- package/scripts/example-projects.js +58 -0
- package/scripts/export-budget.mjs +145 -0
- package/scripts/faults.json +6749 -0
- package/scripts/lib/fault-workspace.mjs +210 -0
- package/scripts/lib/io.mjs +29 -0
- package/scripts/lib/io.test.mjs +38 -0
- package/scripts/lib/markdown-fences.mjs +56 -0
- package/scripts/lib/markdown-fences.test.mjs +84 -0
- package/scripts/lib/package-exports.mjs +54 -0
- package/scripts/lib/package-exports.test.mjs +66 -0
- package/scripts/lib/release-pr-steps.mjs +47 -0
- package/scripts/release-tag.mjs +95 -0
- package/scripts/release-tag.test.mjs +278 -0
- package/scripts/release-workflow.test.mjs +98 -0
- package/scripts/release.js +167 -0
- package/scripts/release.test.mjs +347 -0
- package/scripts/removed-v3-names.js +125 -0
- package/scripts/size-app/.size-limit.js +90 -0
- package/scripts/size-app/core.js +3 -0
- package/scripts/size-app/package.json +24 -0
- package/scripts/size-app/react.js +4 -0
- package/scripts/size-app.test.mjs +73 -0
- package/scripts/sync-ai-context-versions.js +102 -0
- package/scripts/sync-example-versions.js +151 -0
- package/scripts/test-examples-published.mjs +1585 -0
- package/scripts/test-examples-published.test.mjs +1586 -0
- package/scripts/traps/any-method-vars-not-a-list.json +5 -0
- package/scripts/traps/canister-method-unknown.json +5 -0
- package/scripts/traps/client-says-who-calls-once.json +5 -0
- package/scripts/traps/client-says-who-calls.json +5 -0
- package/scripts/traps/err-only-on-canister-err.json +14 -0
- package/scripts/traps/format-units-refuses-missing-value.json +5 -0
- package/scripts/traps/format-units-refuses-number.json +5 -0
- package/scripts/traps/format-units-unknown-option.json +5 -0
- package/scripts/traps/guard-err-is-the-methods.json +5 -0
- package/scripts/traps/guard-false-keeps-every-kind.json +5 -0
- package/scripts/traps/internals-not-exported.json +9 -0
- package/scripts/traps/network-refuses-unknown-name.json +5 -0
- package/scripts/traps/never-err-has-no-type.json +5 -0
- package/scripts/traps/options-method-unknown.json +5 -0
- package/scripts/traps/options-vars-wrong-type.json +5 -0
- package/scripts/traps/parse-units-refuses-number.json +5 -0
- package/scripts/traps/parse-units-unknown-option.json +5 -0
- package/scripts/traps/principal-is-not-plain-text.json +14 -0
- package/scripts/traps/query-options-refuses-oneway.json +5 -0
- package/scripts/traps/query-options-refuses-update.json +5 -0
- package/scripts/traps/refuse-next-unknown-option.json +5 -0
- package/scripts/traps/resend-key-reads-the-methods-arg.json +5 -0
- package/scripts/traps/resend-states-its-dedupe-key.json +5 -0
- package/scripts/traps/suspense-refuses-argument-skip.json +5 -0
- package/scripts/traps/suspense-refuses-skippable-read.json +5 -0
- package/scripts/traps/suspense-refuses-vars-skip-fits.json +5 -0
- package/scripts/traps/test-handler-method-unknown.json +5 -0
- package/scripts/traps/test-handler-nat-is-bigint.json +5 -0
- package/scripts/traps/test-handler-takes-the-domain-value.json +5 -0
- package/scripts/traps/vars-of-two-arguments-are-the-tuple.json +5 -0
- package/scripts/typecheck-examples.js +122 -0
- package/scripts/verify-faults.mjs +375 -0
- package/scripts/verify-faults.test.mjs +402 -0
- package/scripts/verify-package-artifacts.mjs +590 -0
- package/scripts/verify-peer-floors.js +399 -0
- package/scripts/verify-peer-floors.test.mjs +422 -0
- package/scripts/verify-test-fails-rules.mjs +104 -0
- package/scripts/verify-test-fails-rules.test.mjs +215 -0
- package/scripts/verify-test-fails.js +371 -0
- package/scripts/verify-traps.mjs +505 -0
- package/scripts/verify-traps.test.mjs +521 -0
- package/scripts/verify-typescript-floor.js +239 -0
- package/skill-packages/ic-reactor/SKILL.md +103 -0
- package/stack.json +8 -0
- package/tsconfig.base.json +23 -0
- package/tsconfig.json +8 -0
|
@@ -0,0 +1,620 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Getting started"
|
|
3
|
+
description: "Install ic-reactor 4, generate a module from a .did file with Meant's CLI or the Vite plugin, and make a first read and write"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
import { Aside } from "@astrojs/starlight/components"
|
|
7
|
+
|
|
8
|
+
This page takes an app from nothing to a first read and a first write. It uses
|
|
9
|
+
the ICRC-1 ledger interface (`icrc1.did`) and the ICP ledger on mainnet.
|
|
10
|
+
|
|
11
|
+
`icrc1.did` is the file of the same name in the repository's
|
|
12
|
+
[`examples/icrc-ledger`](https://github.com/B3Pay/ic-reactor/tree/main/examples/icrc-ledger)
|
|
13
|
+
directory. Copy it to your project's root once step 0 has made the project.
|
|
14
|
+
To work with another canister,
|
|
15
|
+
save its interface from the canister itself (see
|
|
16
|
+
[Get a canister's .did](#get-a-canisters-did) below). The generator names a
|
|
17
|
+
module after its file, so a saved `icp_ledger.did` gives
|
|
18
|
+
`./generated/icp_ledger`, not the `./generated/icrc1` this page imports.
|
|
19
|
+
|
|
20
|
+
## 0. Create the project
|
|
21
|
+
|
|
22
|
+
Start in an empty directory. For a React app, make it with Vite's `react-ts`
|
|
23
|
+
template, which steps 5 and 6 assume:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
npm create vite@latest my-app -- --template react-ts --no-interactive
|
|
27
|
+
cd my-app
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
For Node only (steps 1 to 4), make a package that is an ES module:
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
mkdir my-app && cd my-app
|
|
34
|
+
npm init -y
|
|
35
|
+
npm pkg set type=module
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Both give a `package.json` with `"type": "module"`. That matters:
|
|
39
|
+
`@ic-reactor/core` and `@ic-reactor/react` are ES modules only, and the
|
|
40
|
+
scripts on this page use top-level `await`, which `npx tsx` refuses in a
|
|
41
|
+
CommonJS package with "Top-level await is currently not supported with the
|
|
42
|
+
'cjs' output format". `npm install` in an empty directory writes no `"type"`,
|
|
43
|
+
and `npm init -y` writes none (npm 10) or `"commonjs"` (npm 11); both fail.
|
|
44
|
+
See [ES modules only](#es-modules-only) below.
|
|
45
|
+
|
|
46
|
+
## 1. Install
|
|
47
|
+
|
|
48
|
+
The core packages and the runtime they sit on:
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
npm install @ic-reactor/core @icp-sdk/core @tanstack/query-core
|
|
52
|
+
npm install --save-exact @meantjs/schema@0.6.0
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
For React, add the provider and TanStack's React bindings. For Internet
|
|
56
|
+
Identity sign-in, add `@icp-sdk/auth`:
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
npm install @ic-reactor/react @tanstack/react-query
|
|
60
|
+
npm install @icp-sdk/auth
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Install `@tanstack/query-core` at the exact version your
|
|
64
|
+
`@tanstack/react-query` depends on (`npm view @tanstack/react-query@<version>
|
|
65
|
+
dependencies`), and check that `npm ls @tanstack/query-core` shows one copy.
|
|
66
|
+
With two copies, `client.queryOptions()` throws a `TypeError` for the hooks'
|
|
67
|
+
`skipToken`, and `ReactorProvider` throws in development.
|
|
68
|
+
|
|
69
|
+
The generator is a development tool:
|
|
70
|
+
|
|
71
|
+
```sh
|
|
72
|
+
npm install --save-dev --save-exact @meantjs/cli@0.5.1
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`@meantjs/schema` and `@meantjs/cli` are installed exactly
|
|
76
|
+
(`--save-exact`) because the generated module imports the schema runtime, and
|
|
77
|
+
the CLI has to pair with that runtime. `@ic-reactor/core` lists the schema
|
|
78
|
+
version it needs in its `peerDependencies`; `@ic-reactor/vite-plugin` lists the
|
|
79
|
+
CLI version. Install the CLI at the version above: without a version, npm
|
|
80
|
+
installs the newest CLI, and when that one pairs with another schema, npm stops
|
|
81
|
+
with `ERESOLVE`.
|
|
82
|
+
|
|
83
|
+
## 2. Generate the module
|
|
84
|
+
|
|
85
|
+
Everything the client knows about a canister comes from a module that
|
|
86
|
+
`meant gen` writes from the canister's `.did` file. With `icrc1.did` in the
|
|
87
|
+
project's root:
|
|
88
|
+
|
|
89
|
+
```sh
|
|
90
|
+
npx @meantjs/cli gen icrc1.did -o src/generated
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The module is named after the `.did` file: this writes `src/generated/icrc1.ts`
|
|
94
|
+
and, beside it, `src/generated/icrc1.envelope.json`. Do not edit either. The
|
|
95
|
+
module exports a TypeScript type and a schema for each Candid type, the
|
|
96
|
+
service schema `actor`, and `type Actor`, which types each method as its call
|
|
97
|
+
signature, `(arg0: ...) => Promise<...>`, marked with its mode
|
|
98
|
+
(`& $.WithMode<"query">`).
|
|
99
|
+
|
|
100
|
+
Several files can be generated at once:
|
|
101
|
+
`npx @meantjs/cli gen a.did b.did -o src/canisters`.
|
|
102
|
+
|
|
103
|
+
In CI, add `--check`. It writes nothing and exits 1 when the files on disk
|
|
104
|
+
differ from what the generator would write:
|
|
105
|
+
|
|
106
|
+
```sh
|
|
107
|
+
npx @meantjs/cli gen icrc1.did -o src/generated --check
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Or generate with the Vite plugin
|
|
111
|
+
|
|
112
|
+
In a Vite app, the plugin runs the same generator when `vite dev` or
|
|
113
|
+
`vite build` starts, and again when the `.did` file changes. Set `outDir` to
|
|
114
|
+
`src/generated` to match the imports on this page (without it the plugin
|
|
115
|
+
writes to `src/canisters`):
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
// vite.config.ts
|
|
119
|
+
import { icReactor } from "@ic-reactor/vite-plugin"
|
|
120
|
+
import { defineConfig } from "vite"
|
|
121
|
+
|
|
122
|
+
export default defineConfig({
|
|
123
|
+
plugins: [
|
|
124
|
+
icReactor({
|
|
125
|
+
canisters: {
|
|
126
|
+
icrc1: { didFile: "icrc1.did", outDir: "src/generated" },
|
|
127
|
+
},
|
|
128
|
+
}),
|
|
129
|
+
],
|
|
130
|
+
})
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The plugin also sets up a local environment. See
|
|
134
|
+
[The Vite plugin](/v4/guides/vite-plugin/).
|
|
135
|
+
|
|
136
|
+
Commit `icrc1.did` and the generated module. Vite's `react-ts` template builds
|
|
137
|
+
with `tsc -b && vite build`, so TypeScript checks `src/` before the plugin has
|
|
138
|
+
generated anything, and a fresh clone without the module fails its first
|
|
139
|
+
build. If you would rather not commit the module, run
|
|
140
|
+
`npx @meantjs/cli gen icrc1.did -o src/generated` before `tsc -b`, for
|
|
141
|
+
example in a `prebuild` script.
|
|
142
|
+
|
|
143
|
+
An app that only talks to mainnet has no local network for the plugin to
|
|
144
|
+
find, and `vite dev` says "Could not detect the local IC environment". Set
|
|
145
|
+
`injectEnvironment: false` in `icReactor({ ... })` to skip that detection.
|
|
146
|
+
|
|
147
|
+
### Get a canister's .did
|
|
148
|
+
|
|
149
|
+
Every canister on the Internet Computer can publish its Candid interface as
|
|
150
|
+
`candid:service` metadata. In a Vite app, give the canister's entry its
|
|
151
|
+
`canisterId`: when `didFile` is not on disk, `vite dev` or `vite build` reads
|
|
152
|
+
the metadata from certified state, writes it to `didFile`, and generates the
|
|
153
|
+
module from it.
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
// vite.config.ts
|
|
157
|
+
import { icReactor } from "@ic-reactor/vite-plugin"
|
|
158
|
+
import { defineConfig } from "vite"
|
|
159
|
+
|
|
160
|
+
export default defineConfig({
|
|
161
|
+
plugins: [
|
|
162
|
+
icReactor({
|
|
163
|
+
canisters: {
|
|
164
|
+
icp_ledger: {
|
|
165
|
+
didFile: "icp_ledger.did", // written when missing: commit it
|
|
166
|
+
canisterId: "ryjl3-tyaaa-aaaaa-aaaba-cai",
|
|
167
|
+
network: "ic", // the default
|
|
168
|
+
outDir: "src/generated",
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
injectEnvironment: false,
|
|
172
|
+
}),
|
|
173
|
+
],
|
|
174
|
+
})
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Commit the file it writes. Once `didFile` is on disk, a build reads it and
|
|
178
|
+
makes no network request, so builds stay reproducible and work offline. To
|
|
179
|
+
fetch it again, run `IC_REACTOR_FETCH=icp_ledger npx vite build` (names
|
|
180
|
+
separated by commas, or `all`). The plugin needs `@icp-sdk/core` for the
|
|
181
|
+
fetch, which the install above has already added. See
|
|
182
|
+
[The Vite plugin](/v4/guides/vite-plugin/#fetch-a-did-from-a-live-canister).
|
|
183
|
+
To keep only the methods the app calls, list them in `methods`, and the plugin
|
|
184
|
+
writes the [projection](/v4/guides/vite-plugin/#only-the-methods-the-app-calls)
|
|
185
|
+
of the interface to them.
|
|
186
|
+
|
|
187
|
+
Without Vite, this script reads the same metadata and saves it to a file:
|
|
188
|
+
|
|
189
|
+
{/* prettier-ignore */}
|
|
190
|
+
```ts
|
|
191
|
+
// scripts/fetch-did.ts: save a live canister's Candid interface from certified
|
|
192
|
+
// state. readState checks the subnet's signature against the IC root key, and
|
|
193
|
+
// throws when the replica cannot be reached or refuses the read.
|
|
194
|
+
// usage: npx tsx scripts/fetch-did.ts <canister-id> [out.did]
|
|
195
|
+
import { HttpAgent, StatePaths } from "@icp-sdk/core/agent"
|
|
196
|
+
import { Principal } from "@icp-sdk/core/principal"
|
|
197
|
+
import { writeFile } from "node:fs/promises"
|
|
198
|
+
|
|
199
|
+
const [id, out = `${id}.did`] = process.argv.slice(2)
|
|
200
|
+
if (!id) throw new Error("usage: fetch-did <canister-id> [out.did]")
|
|
201
|
+
|
|
202
|
+
const canisterId = Principal.fromText(id)
|
|
203
|
+
const agent = await HttpAgent.create({ host: "https://icp-api.io" })
|
|
204
|
+
const path = StatePaths.canisterCandid(canisterId)
|
|
205
|
+
const { values } = await agent.readState({ canisterId }, { paths: [path] })
|
|
206
|
+
const did = values.get(path)
|
|
207
|
+
if (did === null) throw new Error(`${id} has no candid:service metadata`)
|
|
208
|
+
|
|
209
|
+
await writeFile(out, did)
|
|
210
|
+
console.log(`wrote ${out}: ${did.length} bytes of certified candid:service from ${id}`)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
```sh
|
|
214
|
+
npx tsx scripts/fetch-did.ts ryjl3-tyaaa-aaaaa-aaaba-cai icp_ledger.did
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
That saves the ICP ledger's full interface, which is not `icrc1.did`, and
|
|
218
|
+
`npx @meantjs/cli gen icp_ledger.did -o src/generated` names its module
|
|
219
|
+
`icp_ledger`: import from `./generated/icp_ledger` in place of this page's
|
|
220
|
+
`./generated/icrc1`.
|
|
221
|
+
|
|
222
|
+
With [icp-cli](https://github.com/dfinity/icp-cli) installed,
|
|
223
|
+
`icp canister metadata <canister-id> candid:service -n ic > icp_ledger.did`
|
|
224
|
+
reads the same metadata. A canister that keeps its metadata private, or
|
|
225
|
+
publishes none, has no interface to fetch: ask its developers for the `.did`.
|
|
226
|
+
|
|
227
|
+
## 3. Set up a client and a canister
|
|
228
|
+
|
|
229
|
+
```ts
|
|
230
|
+
// src/ledger.ts
|
|
231
|
+
import { createClient } from "@ic-reactor/core"
|
|
232
|
+
import { actor, type Actor } from "./generated/icrc1"
|
|
233
|
+
|
|
234
|
+
export const client = createClient({ network: "ic", identity: "anonymous" })
|
|
235
|
+
export const ledger = client.canister<Actor>(actor, {
|
|
236
|
+
id: "ryjl3-tyaaa-aaaaa-aaaba-cai",
|
|
237
|
+
})
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
`createClient` does no work until it is used. `identity: "anonymous"` is a
|
|
241
|
+
client that only reads: it refuses every update before sending anything.
|
|
242
|
+
`client.canister()` returns an object with one async method per Candid method.
|
|
243
|
+
It returns the same object each time, so it is safe to call in a render.
|
|
244
|
+
|
|
245
|
+
Read [The client](/v4/guides/client/) for the other networks and for signing
|
|
246
|
+
users in.
|
|
247
|
+
|
|
248
|
+
## 4. A first read, outside React
|
|
249
|
+
|
|
250
|
+
Call the methods directly:
|
|
251
|
+
|
|
252
|
+
```ts
|
|
253
|
+
// src/read.ts
|
|
254
|
+
import { formatUnits } from "@ic-reactor/core"
|
|
255
|
+
import { ledger } from "./ledger"
|
|
256
|
+
|
|
257
|
+
const decimals = await ledger.icrc1_decimals() // 8
|
|
258
|
+
const fee = await ledger.icrc1_fee() // 10000n: a bigint, never a number
|
|
259
|
+
|
|
260
|
+
console.log(formatUnits(fee, decimals)) // "0.0001"
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Run it with `npx tsx src/read.ts`. Plain `node src/read.ts` fails: Node
|
|
264
|
+
resolves an import such as `./ledger` only with its file extension, which a
|
|
265
|
+
bundler's imports leave out.
|
|
266
|
+
|
|
267
|
+
The imports on this page are written for a bundler, or for TypeScript's
|
|
268
|
+
`moduleResolution: "bundler"`. Under `moduleResolution: "nodenext"` (a Node
|
|
269
|
+
project compiled by `tsc`), TypeScript wants the extension of the file it
|
|
270
|
+
compiles to (error TS2835), so write `./generated/icrc1.js` and
|
|
271
|
+
`./ledger.js`:
|
|
272
|
+
|
|
273
|
+
```ts nocheck
|
|
274
|
+
// src/ledger.ts, under "moduleResolution": "nodenext"
|
|
275
|
+
import { actor, type Actor } from "./generated/icrc1.js"
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Amounts are `bigint` in base units. `formatUnits` turns one into text, and
|
|
279
|
+
`parseUnits` goes the other way. See [Values and units](/v4/guides/values/).
|
|
280
|
+
|
|
281
|
+
A direct call never touches a cache. To read through the client's cache outside
|
|
282
|
+
React, use `client.queryClient.fetchQuery(client.queryOptions(...))`; see
|
|
283
|
+
[Reads](/v4/guides/reads/).
|
|
284
|
+
|
|
285
|
+
## 5. A first read, in React
|
|
286
|
+
|
|
287
|
+
Put a `ReactorProvider` around the tree. Its `client` prop is a factory: the
|
|
288
|
+
provider calls it once and owns the client it creates, disposing it when the
|
|
289
|
+
provider unmounts.
|
|
290
|
+
|
|
291
|
+
```tsx
|
|
292
|
+
// src/App.tsx
|
|
293
|
+
import { createClient } from "@ic-reactor/core"
|
|
294
|
+
import { ReactorProvider, useClient } from "@ic-reactor/react"
|
|
295
|
+
import { useQuery } from "@tanstack/react-query"
|
|
296
|
+
import { actor, type Actor } from "./generated/icrc1"
|
|
297
|
+
|
|
298
|
+
export function App() {
|
|
299
|
+
return (
|
|
300
|
+
<ReactorProvider
|
|
301
|
+
client={() => createClient({ network: "ic", identity: "anonymous" })}
|
|
302
|
+
>
|
|
303
|
+
<Fee />
|
|
304
|
+
</ReactorProvider>
|
|
305
|
+
)
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function Fee() {
|
|
309
|
+
const client = useClient()
|
|
310
|
+
const ledger = client.canister<Actor>(actor, {
|
|
311
|
+
id: "ryjl3-tyaaa-aaaaa-aaaba-cai",
|
|
312
|
+
})
|
|
313
|
+
const fee = useQuery(client.queryOptions(ledger, "icrc1_fee"))
|
|
314
|
+
|
|
315
|
+
if (fee.isPending) return <p>Loading</p>
|
|
316
|
+
if (fee.isError) return <p>{fee.error.message}</p>
|
|
317
|
+
return <p>Fee: {fee.data.toString()} base units</p>
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
This file exports a named `App`. Vite's `react-ts` template imports a default
|
|
322
|
+
one in `src/main.tsx`, so change that import to
|
|
323
|
+
`import { App } from "./App"`.
|
|
324
|
+
|
|
325
|
+
`useQuery` is TanStack Query's own hook. `client.queryOptions(ledger, method,
|
|
326
|
+
arg)` gives it the key, the function and the retry rule. Build the options in
|
|
327
|
+
render, from the `useClient()` of that render.
|
|
328
|
+
|
|
329
|
+
`fee.error` is a `ReactorError`. See
|
|
330
|
+
[Errors and mayHaveExecuted](/v4/guides/errors/).
|
|
331
|
+
|
|
332
|
+
## 6. A first write
|
|
333
|
+
|
|
334
|
+
A write needs a signed-in caller. Give the client an `auth` factory instead of
|
|
335
|
+
an `identity`: users then sign in and out, and the client calls as whoever is
|
|
336
|
+
signed in. The factory runs once, in a browser only.
|
|
337
|
+
|
|
338
|
+
```tsx
|
|
339
|
+
// src/App.tsx
|
|
340
|
+
import { createClient } from "@ic-reactor/core"
|
|
341
|
+
import { ReactorProvider, useAuth, useClient } from "@ic-reactor/react"
|
|
342
|
+
import { AuthClient } from "@icp-sdk/auth/client"
|
|
343
|
+
import { principal } from "@meantjs/schema"
|
|
344
|
+
import { useMutation } from "@tanstack/react-query"
|
|
345
|
+
import { useState } from "react"
|
|
346
|
+
import { actor, type Actor } from "./generated/icrc1"
|
|
347
|
+
|
|
348
|
+
export function App() {
|
|
349
|
+
return (
|
|
350
|
+
<ReactorProvider
|
|
351
|
+
client={() =>
|
|
352
|
+
createClient({
|
|
353
|
+
network: "ic",
|
|
354
|
+
auth: (network) => new AuthClient(network),
|
|
355
|
+
})
|
|
356
|
+
}
|
|
357
|
+
>
|
|
358
|
+
<Send />
|
|
359
|
+
</ReactorProvider>
|
|
360
|
+
)
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
function Send() {
|
|
364
|
+
const client = useClient()
|
|
365
|
+
const { status, principal: caller, signIn } = useAuth()
|
|
366
|
+
const [signInError, setSignInError] = useState<string>()
|
|
367
|
+
const ledger = client.canister<Actor>(actor, {
|
|
368
|
+
id: "ryjl3-tyaaa-aaaaa-aaaba-cai",
|
|
369
|
+
})
|
|
370
|
+
const transfer = useMutation(client.mutationOptions(ledger, "icrc1_transfer"))
|
|
371
|
+
|
|
372
|
+
if (status !== "signed-in")
|
|
373
|
+
return (
|
|
374
|
+
<>
|
|
375
|
+
<button
|
|
376
|
+
onClick={() =>
|
|
377
|
+
// signIn() rejects when the sign-in fails or the user closes it.
|
|
378
|
+
signIn().catch((error: unknown) => setSignInError(String(error)))
|
|
379
|
+
}
|
|
380
|
+
>
|
|
381
|
+
Sign in
|
|
382
|
+
</button>
|
|
383
|
+
{signInError && <p>{signInError}</p>}
|
|
384
|
+
</>
|
|
385
|
+
)
|
|
386
|
+
return (
|
|
387
|
+
<>
|
|
388
|
+
<button
|
|
389
|
+
disabled={transfer.isPending}
|
|
390
|
+
onClick={() =>
|
|
391
|
+
// 1 e8s to the signed-in principal itself. The ledger still
|
|
392
|
+
// charges its fee.
|
|
393
|
+
transfer.mutate({
|
|
394
|
+
to: { owner: principal(caller), subaccount: null },
|
|
395
|
+
amount: 1n,
|
|
396
|
+
fee: null,
|
|
397
|
+
memo: null,
|
|
398
|
+
from_subaccount: null,
|
|
399
|
+
created_at_time: null,
|
|
400
|
+
})
|
|
401
|
+
}
|
|
402
|
+
>
|
|
403
|
+
Send 1 e8s to yourself
|
|
404
|
+
</button>
|
|
405
|
+
{transfer.error && (
|
|
406
|
+
<p>
|
|
407
|
+
{transfer.error.mayHaveExecuted
|
|
408
|
+
? "Unknown outcome: check the balance before sending again"
|
|
409
|
+
: transfer.error.message}
|
|
410
|
+
</p>
|
|
411
|
+
)}
|
|
412
|
+
</>
|
|
413
|
+
)
|
|
414
|
+
}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
Three things in this snippet matter:
|
|
418
|
+
|
|
419
|
+
- `icrc1_transfer` returns `variant { Ok : nat; Err : TransferError }`. The
|
|
420
|
+
mutation resolves with the `Ok` value, and an `Err` rejects as a
|
|
421
|
+
`ReactorError` of kind `"canister_err"` with the `Err` value in `err`.
|
|
422
|
+
- A failed write either certainly had no effect, or may have executed.
|
|
423
|
+
`error.mayHaveExecuted` says which. When it is `true`, do not send the
|
|
424
|
+
transfer again blindly: read the balance first.
|
|
425
|
+
- There is no `retry` on the mutation, and there must not be one. The client
|
|
426
|
+
itself re-sends an update, at most twice, only after a failure that proves
|
|
427
|
+
the canister never got it.
|
|
428
|
+
|
|
429
|
+
After the write, the client invalidates the ledger's reads, so a mounted
|
|
430
|
+
balance refetches by itself. See [Writes](/v4/guides/writes/).
|
|
431
|
+
|
|
432
|
+
<Aside type="caution">
|
|
433
|
+
This sends a real transfer on mainnet if the signed-in user holds ICP. Try
|
|
434
|
+
writes on a local replica or with the test client first. See
|
|
435
|
+
[Testing](/v4/guides/testing/).
|
|
436
|
+
</Aside>
|
|
437
|
+
|
|
438
|
+
## Keep the IC stack out of the first load
|
|
439
|
+
|
|
440
|
+
The `App` of step 6 imports the client, `AuthClient` and the generated module.
|
|
441
|
+
`src/main.tsx` imports `App`, so a Vite build puts all of them in the one chunk
|
|
442
|
+
the page loads before it shows anything. `React.lazy` moves them out of that
|
|
443
|
+
chunk, into chunks the page loads asynchronously, with no change to `App.tsx`
|
|
444
|
+
and no option of this library:
|
|
445
|
+
|
|
446
|
+
```tsx
|
|
447
|
+
// src/main.tsx
|
|
448
|
+
import { lazy, StrictMode, Suspense } from "react"
|
|
449
|
+
import { createRoot } from "react-dom/client"
|
|
450
|
+
|
|
451
|
+
// App builds the client (ReactorProvider, createClient, AuthClient) and
|
|
452
|
+
// imports the generated module: all of it loads with this import. The
|
|
453
|
+
// boundary below waits for this import only: the boundaries for reads and
|
|
454
|
+
// lazy routes go inside App, below its ReactorProvider.
|
|
455
|
+
const App = lazy(() => import("./App").then((m) => ({ default: m.App })))
|
|
456
|
+
|
|
457
|
+
createRoot(document.getElementById("root")!).render(
|
|
458
|
+
<StrictMode>
|
|
459
|
+
<Suspense fallback={<p>Loading…</p>}>
|
|
460
|
+
<App />
|
|
461
|
+
</Suspense>
|
|
462
|
+
</StrictMode>
|
|
463
|
+
)
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
It holds only while `main.tsx`, and every module it imports statically,
|
|
467
|
+
imports nothing from `@ic-reactor/*`, `@icp-sdk/*` or the generated module.
|
|
468
|
+
One static import of any of them puts it back in the first chunk. The
|
|
469
|
+
`ReactorProvider` is inside `App`, so every `useClient()` and `useAuth()` is
|
|
470
|
+
too.
|
|
471
|
+
|
|
472
|
+
Measured on the [Vite wallet](/v4/examples/vite-wallet/) with Vite 8.3.0,
|
|
473
|
+
minified JavaScript (its 3.28 kB of CSS loads first either way). For the lazy
|
|
474
|
+
build its `main.tsx` was changed as above, with its dev accounts, which import
|
|
475
|
+
`@icp-sdk/core`, loaded in the same lazy import:
|
|
476
|
+
|
|
477
|
+
| `vite build` of the wallet | First chunk | Loaded asynchronously |
|
|
478
|
+
| -------------------------- | ------------------------- | ------------------------- |
|
|
479
|
+
| as it is | 622.46 kB, 193.56 kB gzip | nothing |
|
|
480
|
+
| with `React.lazy` | 222.30 kB, 69.90 kB gzip | 401.79 kB, 126.21 kB gzip |
|
|
481
|
+
|
|
482
|
+
The first load is React, React DOM and the fallback. The rest is the client,
|
|
483
|
+
the agent with its certificate check, `AuthClient` and the wallet's own code,
|
|
484
|
+
in three chunks the browser fetches together once the first one runs. React
|
|
485
|
+
starts that import while it renders `<App />`, so a fast or cached import can
|
|
486
|
+
arrive before the fallback is ever painted: what moves is the first chunk's
|
|
487
|
+
size, not a guarantee that the rest loads after the first paint. Every
|
|
488
|
+
chunk is under 222 kB, so the build stays under Vite's 500 kB chunk warning,
|
|
489
|
+
which the wallet otherwise raises to 700 kB.
|
|
490
|
+
|
|
491
|
+
### Suspense boundaries go below the provider
|
|
492
|
+
|
|
493
|
+
The boundary in `main.tsx` sits above the `ReactorProvider`. When something
|
|
494
|
+
below the provider suspends before the provider's first commit, and no
|
|
495
|
+
boundary sits between them, React throws that render away, the provider's
|
|
496
|
+
state with it, and the next attempt calls the factory again:
|
|
497
|
+
|
|
498
|
+
- A `useSuspenseQuery` read there never ends. Each attempt gets a new client
|
|
499
|
+
and an empty cache, sends the read again and suspends again, so the page
|
|
500
|
+
stays on the `main.tsx` fallback.
|
|
501
|
+
- A lazily loaded route there renders once its chunk arrives, but every
|
|
502
|
+
attempt before that builds a client of its own.
|
|
503
|
+
|
|
504
|
+
So put a `Suspense` boundary inside `App`, below the provider, around every
|
|
505
|
+
component that reads with `useSuspenseQuery` (see
|
|
506
|
+
[Reads](/v4/guides/reads/#suspense)) and every lazy route. React can still
|
|
507
|
+
start the provider over a few times before it commits: for a moment after it
|
|
508
|
+
last showed a fallback (300 ms in React 19), it holds back a new one, and it
|
|
509
|
+
starts again when a read finishes in that time. Each client it throws away has
|
|
510
|
+
already sent the read. The provider disposes such a client only as a best
|
|
511
|
+
effort, when the runtime has `FinalizationRegistry` and the garbage collector
|
|
512
|
+
runs its finalizer, which JavaScript does not guarantee. When the
|
|
513
|
+
first screen reads with `useSuspenseQuery`, build the client once, at the top
|
|
514
|
+
level of the lazy module, and hand it to the provider, so every attempt gets
|
|
515
|
+
the same client and cache and the read is sent once:
|
|
516
|
+
|
|
517
|
+
```tsx
|
|
518
|
+
// src/App.tsx, when the first screen suspends
|
|
519
|
+
import { createClient } from "@ic-reactor/core"
|
|
520
|
+
import { ReactorProvider, useClient } from "@ic-reactor/react"
|
|
521
|
+
import { AuthClient } from "@icp-sdk/auth/client"
|
|
522
|
+
import { useSuspenseQuery } from "@tanstack/react-query"
|
|
523
|
+
import { Suspense } from "react"
|
|
524
|
+
import { actor, type Actor } from "./generated/icrc1"
|
|
525
|
+
|
|
526
|
+
// Built once, when the lazy chunk runs, and never disposed: the provider
|
|
527
|
+
// disposes only a client its own factory created.
|
|
528
|
+
const appClient = createClient({
|
|
529
|
+
network: "ic",
|
|
530
|
+
auth: (network) => new AuthClient(network),
|
|
531
|
+
})
|
|
532
|
+
|
|
533
|
+
export function App() {
|
|
534
|
+
return (
|
|
535
|
+
<ReactorProvider client={() => appClient}>
|
|
536
|
+
<Suspense fallback={<p>Loading the fee…</p>}>
|
|
537
|
+
<Fee />
|
|
538
|
+
</Suspense>
|
|
539
|
+
</ReactorProvider>
|
|
540
|
+
)
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
function Fee() {
|
|
544
|
+
const client = useClient()
|
|
545
|
+
const ledger = client.canister<Actor>(actor, {
|
|
546
|
+
id: "ryjl3-tyaaa-aaaaa-aaaba-cai",
|
|
547
|
+
})
|
|
548
|
+
const fee = useSuspenseQuery(client.queryOptions(ledger, "icrc1_fee"))
|
|
549
|
+
return <p>Fee: {fee.data.toString()} base units</p>
|
|
550
|
+
}
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
That suits a browser-only app whose root is never unmounted. A module that
|
|
554
|
+
also runs on a server keeps the factory: a module-scope client there is shared
|
|
555
|
+
by every request. See
|
|
556
|
+
[The client](/v4/guides/client/#one-client-per-tab-one-per-request).
|
|
557
|
+
|
|
558
|
+
### What a route guard sees
|
|
559
|
+
|
|
560
|
+
`AuthState.status` is one of `"anonymous"`, `"signed-in"`, `"expired"` and
|
|
561
|
+
`"signed-in-elsewhere"`, and it keeps those four: there is no member for "not
|
|
562
|
+
loaded yet". With the pattern above:
|
|
563
|
+
|
|
564
|
+
- **While the chunk loads**, React shows the `Suspense` fallback and renders
|
|
565
|
+
nothing below it. There is no client and no auth yet, and no status to
|
|
566
|
+
read: `useAuth()` throws outside a `ReactorProvider`. Put the guard, and the
|
|
567
|
+
routes it guards, inside `App`, below the provider, and let the fallback
|
|
568
|
+
stand for "not known yet". A `Suspense` boundary of the guard's own, around
|
|
569
|
+
the lazy routes it renders, goes there too, below the provider. Code that
|
|
570
|
+
runs before the chunk arrives, such as a router loader in `main.tsx`, must
|
|
571
|
+
not redirect on sign-in: it cannot know.
|
|
572
|
+
- **On the first render inside `App`**, the provider builds the client, and
|
|
573
|
+
the first `useAuth()` or `useClient()` builds the auth and reads its state.
|
|
574
|
+
`AuthClient` of `@icp-sdk/auth` 10 reads its stored session synchronously
|
|
575
|
+
when it is built, so a returning user is `"signed-in"` on that first render,
|
|
576
|
+
never `"anonymous"` first. The status falls to `"anonymous"` later only if
|
|
577
|
+
the stored session turns out unusable, as on any sign-out.
|
|
578
|
+
- **An `AuthLike` of your own** that learns its session asynchronously says
|
|
579
|
+
`signed-out`, so `"anonymous"`, until it knows. The status cannot tell that
|
|
580
|
+
apart from a signed-out user, so a guard over such an auth renders nothing,
|
|
581
|
+
or a fallback, until the auth's own signal says it is ready, and only then
|
|
582
|
+
redirects on `"anonymous"`.
|
|
583
|
+
|
|
584
|
+
A page that hydrates server HTML is another case: `useAuth()` is `"anonymous"`
|
|
585
|
+
during the hydrating render whatever the session. See
|
|
586
|
+
[SSR and hydration](/v4/guides/ssr/).
|
|
587
|
+
|
|
588
|
+
## ES modules only
|
|
589
|
+
|
|
590
|
+
`@ic-reactor/core` and `@ic-reactor/react` are ES modules only, with no
|
|
591
|
+
CommonJS build (the Vite plugin ships both). Use them from a package with
|
|
592
|
+
`"type": "module"`, or through a bundler (Vite, Next.js, webpack, esbuild),
|
|
593
|
+
which handles either.
|
|
594
|
+
|
|
595
|
+
From CommonJS:
|
|
596
|
+
|
|
597
|
+
- Plain Node can `require()` them from Node 20.19 (on Node 20) or 22.12 on.
|
|
598
|
+
An `import()` works in a CommonJS module Node runs as written; TypeScript
|
|
599
|
+
compiled with `module: "commonjs"` turns it into a `require()`.
|
|
600
|
+
- A TypeScript runner or build that compiles your own files to CommonJS can
|
|
601
|
+
fail on a dependency instead: `npx tsx` in a package without
|
|
602
|
+
`"type": "module"` stops with `ERR_PACKAGE_PATH_NOT_EXPORTED` naming a
|
|
603
|
+
subpath of `@icp-sdk/core`. Set `"type": "module"` (or name the file
|
|
604
|
+
`.mts`).
|
|
605
|
+
|
|
606
|
+
## Next
|
|
607
|
+
|
|
608
|
+
- [Build an ICRC-1 wallet](/v4/build/icrc1-wallet/): sign-in, a balance and
|
|
609
|
+
a transfer that is never paid twice, in one app with a test.
|
|
610
|
+
- [The client](/v4/guides/client/): networks, `identity` and `auth`, disposal,
|
|
611
|
+
one client per request on a server.
|
|
612
|
+
- [Reads](/v4/guides/reads/) and [Writes](/v4/guides/writes/): the rules behind
|
|
613
|
+
`queryOptions` and `mutationOptions`.
|
|
614
|
+
- [Errors and mayHaveExecuted](/v4/guides/errors/): what to do for each kind of
|
|
615
|
+
failure.
|
|
616
|
+
- [Auth](/v4/guides/auth/): signing in and out, and what happens to reads when
|
|
617
|
+
the caller changes.
|
|
618
|
+
- [Deploy to a frontend canister](/v4/guides/deploy/): the security headers to
|
|
619
|
+
serve the built app with.
|
|
620
|
+
- [Examples](/v4/examples/): five apps to read and run.
|