@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,292 @@
|
|
|
1
|
+
# candid-core + TanStack Query on the Internet Computer
|
|
2
|
+
|
|
3
|
+
> How to call Internet Computer canisters with a module generated from the
|
|
4
|
+
> canister's `.did` by `candid-core-cli gen`, `@candid-core/schema`'s
|
|
5
|
+
> `createActor` over `@icp-sdk/core`'s `HttpAgent`, and TanStack Query used
|
|
6
|
+
> directly. There is no framework in between: this guide is the set of rules
|
|
7
|
+
> that framework would otherwise enforce. The `@candid-core/schema` and
|
|
8
|
+
> `@candid-core/cli` READMEs next to this file are the API reference.
|
|
9
|
+
|
|
10
|
+
## Imports
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { AnonymousIdentity, HttpAgent, type Identity } from "@icp-sdk/core/agent"
|
|
14
|
+
import { Principal } from "@icp-sdk/core/principal"
|
|
15
|
+
import { ActorError, createActor } from "@candid-core/schema/actor"
|
|
16
|
+
import { httpTransport } from "@candid-core/schema/transport-icp"
|
|
17
|
+
import { actor, type Actor } from "./generated/icrc1" // the generated module
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The generated module (`src/generated/icrc1.ts`) exports one type and one
|
|
21
|
+
schema per Candid type, the service schema `actor`, and `type Actor`: one
|
|
22
|
+
async function per method, with its argument and result types. Do not edit
|
|
23
|
+
it.
|
|
24
|
+
|
|
25
|
+
## Setup
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
const agent = HttpAgent.createSync({ host, identity, rootKey, shouldFetchRootKey })
|
|
29
|
+
const ledger = createActor<Actor>(actor, "ryjl3-tyaaa-aaaaa-aaaba-cai", httpTransport({ agent }))
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`host` and the root key:
|
|
33
|
+
|
|
34
|
+
- mainnet — `host: "https://icp-api.io"`; no `rootKey`, no fetching.
|
|
35
|
+
- a local replica — `host: "http://127.0.0.1:4943"` (or yours). Pass
|
|
36
|
+
`rootKey` when you have it, and then never fetch one; without it,
|
|
37
|
+
`shouldFetchRootKey: true` fetches it from the replica. Fetch only when the
|
|
38
|
+
host is local (`localhost`, `127.0.0.1`, `[::1]`), never from any other
|
|
39
|
+
host.
|
|
40
|
+
|
|
41
|
+
The identity:
|
|
42
|
+
|
|
43
|
+
- a fixed `Identity` (scripts, servers, tests); omit it for anonymous.
|
|
44
|
+
- a sign-in source — anything with `getIdentity(): Identity` (the anonymous
|
|
45
|
+
identity while signed out), `isAuthenticated(): boolean` and
|
|
46
|
+
`subscribe(listener): () => void` (called on every sign-in, sign-out and
|
|
47
|
+
principal switch). Read it at the moment you act.
|
|
48
|
+
|
|
49
|
+
Who is calling, and may they write:
|
|
50
|
+
|
|
51
|
+
| Question | Answer |
|
|
52
|
+
| ---------------------- | ----------------------------------------------------------------------- |
|
|
53
|
+
| the caller's principal | `identity.getPrincipal().toText()` (`"2vxsx-fae"`, anonymous, when signed out) |
|
|
54
|
+
| may a write be sent | `auth.isAuthenticated() && !identity.getPrincipal().isAnonymous()` |
|
|
55
|
+
| when did it change | `auth.subscribe(fn)` |
|
|
56
|
+
|
|
57
|
+
Build one agent (and one actor) per identity, and never change an agent's
|
|
58
|
+
identity afterwards (no `replaceIdentity`). A call made as Alice then always
|
|
59
|
+
goes out through Alice's agent, however the sign-in state changes while it
|
|
60
|
+
is in flight.
|
|
61
|
+
|
|
62
|
+
In React, re-render on identity changes with `useSyncExternalStore`, and key
|
|
63
|
+
the agent on the identity:
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
const identity = useSyncExternalStore(auth.subscribe, auth.getIdentity)
|
|
67
|
+
const signedIn = auth.isAuthenticated() && !identity.getPrincipal().isAnonymous()
|
|
68
|
+
const ledger = useMemo(() => makeLedger(identity), [identity])
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Build agents and actors once per identity (module scope, or `useState` /
|
|
72
|
+
`useMemo`), not on every render.
|
|
73
|
+
|
|
74
|
+
## Values
|
|
75
|
+
|
|
76
|
+
The actor takes and returns the generated module's types:
|
|
77
|
+
|
|
78
|
+
| Candid | Value |
|
|
79
|
+
| ---------------------------- | --------------------------------------------------- |
|
|
80
|
+
| `nat`, `int`, `nat64`, `int64` | `bigint` (never `number`) |
|
|
81
|
+
| `nat8`..`nat32`, `int8`..`int32`, floats | `number` |
|
|
82
|
+
| `text` | `string` |
|
|
83
|
+
| `bool` | `boolean` |
|
|
84
|
+
| `principal` | in: `Principal.fromText(text)`; out: an object with only `toText()` |
|
|
85
|
+
| `blob` / `vec nat8` | `Uint8Array` |
|
|
86
|
+
| `opt T` | `T \| null` (the property is always present) |
|
|
87
|
+
| `vec T` | `T[]` |
|
|
88
|
+
| `record { a : T }` | `{ a: T }` — every field present |
|
|
89
|
+
| `variant { A : T; B }` | `{ tag: "A"; value: T } \| { tag: "B" }` |
|
|
90
|
+
|
|
91
|
+
Make principals from user input with `Principal.fromText(text)`, which throws
|
|
92
|
+
for invalid text; catch it and refuse the input. A principal in a reply is not
|
|
93
|
+
a `Principal` instance: call `.toText()` on it.
|
|
94
|
+
|
|
95
|
+
Arguments are positional, as in `type Actor`: `ledger.method(arg)`; a method
|
|
96
|
+
with no arguments takes none.
|
|
97
|
+
|
|
98
|
+
### Results
|
|
99
|
+
|
|
100
|
+
Replies come back whole. A method whose result is `variant { Ok : T; Err : E }`
|
|
101
|
+
resolves with `{ tag: "Ok", value }` or `{ tag: "Err", value }`; nothing
|
|
102
|
+
throws for `Err`. Switch on the tag (or use `unwrapResult` from
|
|
103
|
+
`@candid-core/schema/validate`).
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
// icrc1_transfer : (TransferArg) -> (variant { Ok : nat; Err : TransferError })
|
|
107
|
+
const result = await ledger.icrc1_transfer(arg)
|
|
108
|
+
if (result.tag === "Ok") {
|
|
109
|
+
const blockIndex: bigint = result.value
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Reads
|
|
114
|
+
|
|
115
|
+
Query methods go through `useQuery` (or `queryClient.fetchQuery`):
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
import { skipToken, useQuery } from "@tanstack/react-query"
|
|
119
|
+
|
|
120
|
+
const caller = identity.getPrincipal().toText()
|
|
121
|
+
const profile = useQuery({
|
|
122
|
+
queryKey: ["ic", host, caller, BACKEND_ID, "get_profile", userId],
|
|
123
|
+
queryFn: userId ? () => backend.get_profile(Principal.fromText(userId)) : skipToken,
|
|
124
|
+
})
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
`skipToken` is TanStack Query's; pass it instead of a function while the
|
|
128
|
+
arguments do not exist yet.
|
|
129
|
+
|
|
130
|
+
Key every read by
|
|
131
|
+
`["ic", network, callerPrincipal, canisterId, method, ...args]`, with args as
|
|
132
|
+
text (`principal.toText()`, `bigint.toString()`): TanStack Query hashes keys
|
|
133
|
+
with `JSON.stringify`, which throws on a `bigint`. Because the caller is in
|
|
134
|
+
the key, one principal's cached answer is never served to another: after a
|
|
135
|
+
sign-in, sign-out or switch, the new caller's key has no data until it loads,
|
|
136
|
+
and `data` is `undefined` meanwhile. Keep it that way: options that carry data
|
|
137
|
+
from one key to the next (`placeholderData: keepPreviousData`, `initialData`
|
|
138
|
+
from another key) would show the previous principal's data.
|
|
139
|
+
|
|
140
|
+
Reads may keep TanStack Query's default retries: a query changes nothing. Add
|
|
141
|
+
ordinary options as you need them (`staleTime`, `select`).
|
|
142
|
+
|
|
143
|
+
`Principal.fromText` throws while you build the key if the text is not a
|
|
144
|
+
principal; validate input before it reaches a query.
|
|
145
|
+
|
|
146
|
+
## Writes
|
|
147
|
+
|
|
148
|
+
Update methods go through `useMutation`, or are called directly:
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
const transfer = useMutation({
|
|
152
|
+
mutationFn: (arg: TransferArg) => ledger.icrc1_transfer(arg),
|
|
153
|
+
onSettled: (_data, error) => {
|
|
154
|
+
// after a success, and after a failure that may have executed
|
|
155
|
+
if (!error || mayHaveExecuted(error)) {
|
|
156
|
+
return queryClient.invalidateQueries({ queryKey: ["ic", host] })
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
})
|
|
160
|
+
if (signedIn) transfer.mutate(arg)
|
|
161
|
+
|
|
162
|
+
await ledger.icrc1_transfer(arg) // direct call, outside React
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
- Invalidate the reads a write can change (for every caller) after a success,
|
|
166
|
+
and also after a failure that may have executed, because the write may have
|
|
167
|
+
happened. Nothing else is needed to show fresh data after an unknown outcome.
|
|
168
|
+
- Do not retry a write. Mutations retry nothing by default; keep it that way.
|
|
169
|
+
If you must, re-send only after a failure that proves the canister never
|
|
170
|
+
received the request (see Errors: reject code 2, or an HTTP 4xx other than
|
|
171
|
+
408); any other failure is final.
|
|
172
|
+
- A write is sent as whoever is signed in when it runs. If nobody is (or the
|
|
173
|
+
identity is anonymous), refuse it before calling anything.
|
|
174
|
+
- Call update methods only from `useMutation` or directly, never from
|
|
175
|
+
`useQuery`; call query methods from `useQuery` or directly.
|
|
176
|
+
|
|
177
|
+
## Errors
|
|
178
|
+
|
|
179
|
+
The actor throws `ActorError` for a codec failure and passes `@icp-sdk/core`'s
|
|
180
|
+
agent errors through untouched. A failed write either certainly had no
|
|
181
|
+
effect, or may have executed:
|
|
182
|
+
|
|
183
|
+
| What was thrown | Meaning | May have executed |
|
|
184
|
+
| ---------------------------------------------------------------------- | -------------------------------------------------------------------- | ---------------------- |
|
|
185
|
+
| `ActorError`, message starting `encode` | the arguments could not be encoded; nothing was sent | no |
|
|
186
|
+
| your own refusal (not signed in, invalid input) | nothing was sent | no |
|
|
187
|
+
| agent error, `code.name === "HttpErrorCode"`, `code.status` 4xx but not 408 | the replica or boundary refused the request | no |
|
|
188
|
+
| agent error with `code.rejectCode` 1, 2 or 3 | the IC rejected the call before any canister code ran (2 is transient) | no |
|
|
189
|
+
| agent error with `code.rejectCode` 4 or 5 | the canister's own code rejected (4) or trapped (5); it may have committed state first | yes (for a write) |
|
|
190
|
+
| any other agent error (`kind` `"Transport"`, `"Protocol"`, `"Trust"`, `"Unknown"`: network drop, timeout, 5xx, 408) | a write went out and no trustworthy answer came back | yes |
|
|
191
|
+
| `ActorError`, message starting `decode` | a reply arrived but did not decode as the result type | yes (for a write) |
|
|
192
|
+
| an `Err` reply (not thrown) | the canister returned `Err` | no |
|
|
193
|
+
|
|
194
|
+
Read agent errors structurally — `kind`, `code.name`, `code.rejectCode`,
|
|
195
|
+
`code.status` — so an error from another copy of the agent classifies the
|
|
196
|
+
same way:
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
function mayHaveExecuted(error: unknown): boolean {
|
|
200
|
+
if (error instanceof ActorError) return !error.message.startsWith("encode")
|
|
201
|
+
const code = (error as { code?: { name?: unknown; rejectCode?: unknown; status?: unknown } })?.code
|
|
202
|
+
if (typeof code?.rejectCode === "number") return code.rejectCode > 3
|
|
203
|
+
if (code?.name === "HttpErrorCode" && typeof code.status === "number") {
|
|
204
|
+
return !(code.status >= 400 && code.status < 500 && code.status !== 408)
|
|
205
|
+
}
|
|
206
|
+
return true
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
For a query, `httpTransport` throws a plain `Error` naming the reject code in
|
|
211
|
+
its message; a query changes nothing, so it never "may have executed".
|
|
212
|
+
|
|
213
|
+
## Outside React
|
|
214
|
+
|
|
215
|
+
```ts
|
|
216
|
+
import { QueryClient } from "@tanstack/query-core"
|
|
217
|
+
|
|
218
|
+
const queryClient = new QueryClient()
|
|
219
|
+
const key = ["ic", host, caller, LEDGER_ID, "icrc1_balance_of", owner.toText()]
|
|
220
|
+
const balance = await queryClient.fetchQuery({ queryKey: key, queryFn: () => ledger.icrc1_balance_of(account) })
|
|
221
|
+
await queryClient.invalidateQueries({ queryKey: ["ic", host] })
|
|
222
|
+
const fresh = await ledger.icrc1_balance_of(account) // no cache at all
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Direct calls never touch a cache; use them in scripts and services that must
|
|
226
|
+
always see current state.
|
|
227
|
+
|
|
228
|
+
## Example
|
|
229
|
+
|
|
230
|
+
```tsx
|
|
231
|
+
import { useMemo, useState, useSyncExternalStore } from "react"
|
|
232
|
+
import { QueryClient, QueryClientProvider, skipToken, useMutation, useQuery, useQueryClient } from "@tanstack/react-query"
|
|
233
|
+
import { HttpAgent, type Identity } from "@icp-sdk/core/agent"
|
|
234
|
+
import { createActor } from "@candid-core/schema/actor"
|
|
235
|
+
import { httpTransport } from "@candid-core/schema/transport-icp"
|
|
236
|
+
import { actor, type Actor } from "./generated/backend"
|
|
237
|
+
|
|
238
|
+
const HOST = "https://icp-api.io"
|
|
239
|
+
const makeBackend = (identity: Identity) =>
|
|
240
|
+
createActor<Actor>(actor, BACKEND_ID, httpTransport({ agent: HttpAgent.createSync({ host: HOST, identity }) }))
|
|
241
|
+
|
|
242
|
+
export function App({ auth }: { auth: AuthLike }) {
|
|
243
|
+
const [queryClient] = useState(() => new QueryClient())
|
|
244
|
+
return (
|
|
245
|
+
<QueryClientProvider client={queryClient}>
|
|
246
|
+
<Profile auth={auth} />
|
|
247
|
+
</QueryClientProvider>
|
|
248
|
+
)
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function Profile({ auth }: { auth: AuthLike }) {
|
|
252
|
+
const queryClient = useQueryClient()
|
|
253
|
+
const identity = useSyncExternalStore(auth.subscribe, auth.getIdentity)
|
|
254
|
+
const me = identity.getPrincipal()
|
|
255
|
+
const signedIn = auth.isAuthenticated() && !me.isAnonymous()
|
|
256
|
+
const backend = useMemo(() => makeBackend(identity), [identity])
|
|
257
|
+
const profile = useQuery({
|
|
258
|
+
queryKey: ["ic", HOST, me.toText(), BACKEND_ID, "get_profile", me.toText()],
|
|
259
|
+
queryFn: signedIn ? () => backend.get_profile(me) : skipToken,
|
|
260
|
+
})
|
|
261
|
+
const rename = useMutation({
|
|
262
|
+
mutationFn: (name: string) => backend.set_name(me, name),
|
|
263
|
+
onSettled: (_d, error) =>
|
|
264
|
+
!error || mayHaveExecuted(error) ? queryClient.invalidateQueries({ queryKey: ["ic", HOST] }) : undefined,
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
if (!signedIn) return <p>Sign in</p>
|
|
268
|
+
if (profile.data === undefined) return <p>Loading…</p>
|
|
269
|
+
return (
|
|
270
|
+
<>
|
|
271
|
+
<p>{profile.data.name}</p>
|
|
272
|
+
<button disabled={rename.isPending} onClick={() => rename.mutate("Ada")}>Rename</button>
|
|
273
|
+
{rename.error && <p>{mayHaveExecuted(rename.error) ? "Unknown outcome" : rename.error.message}</p>}
|
|
274
|
+
</>
|
|
275
|
+
)
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## Do not
|
|
280
|
+
|
|
281
|
+
- Pass principal text where a principal is expected: use
|
|
282
|
+
`Principal.fromText(text)`.
|
|
283
|
+
- Convert `bigint` values to `number`, or put a `bigint` in a query key.
|
|
284
|
+
- Add `retry` to a write, or call a write from `useQuery`: TanStack Query may
|
|
285
|
+
run a query's function again whenever it refetches, and every run of an
|
|
286
|
+
update executes again.
|
|
287
|
+
- Leave the caller out of a key, or carry data across keys
|
|
288
|
+
(`keepPreviousData`, cross-key `initialData`).
|
|
289
|
+
- Build agents or actors inside render without `useMemo`/`useState`, or
|
|
290
|
+
change an agent's identity once built.
|
|
291
|
+
- Send a write while nobody is signed in, or as the anonymous identity.
|
|
292
|
+
- Treat every failed write as "not executed": classify it as above.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "v3",
|
|
3
|
+
"library": "Available library: IC Reactor 3.13.0 as published — `@ic-reactor/core`, and `@ic-reactor/react` for React (it re-exports core) — on `@icp-sdk/core`, `@icp-sdk/auth` and TanStack Query. The ledger's Candid declarations (`idlFactory`, `_SERVICE`) are in `src/declarations/`. Its documentation is in `docs/`; read it before you start.",
|
|
4
|
+
"docs": [
|
|
5
|
+
"docs/llms-full.txt",
|
|
6
|
+
"docs/ic-reactor-core.llms.txt",
|
|
7
|
+
"docs/ic-reactor-react.llms.txt"
|
|
8
|
+
]
|
|
9
|
+
}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# @ic-reactor/core
|
|
2
|
+
|
|
3
|
+
> Framework-agnostic runtime for calling Internet Computer canisters with
|
|
4
|
+
> typed methods, TanStack Query caching, typed errors and exact token amounts.
|
|
5
|
+
> No React: React apps install `@ic-reactor/react`, which re-exports all of this.
|
|
6
|
+
|
|
7
|
+
Applies to `@ic-reactor/core` 3.13.0.
|
|
8
|
+
|
|
9
|
+
Read this file from `node_modules/@ic-reactor/core/llms.txt` when writing code
|
|
10
|
+
against the installed version. The complete guide for every package is
|
|
11
|
+
https://ic-reactor.b3pay.net/llms-full.txt, and behaviour changes are in
|
|
12
|
+
https://github.com/B3Pay/ic-reactor/blob/main/CHANGELOG.md.
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm add @ic-reactor/core @icp-sdk/core @tanstack/query-core
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Setup and Usage
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import {
|
|
24
|
+
ClientManager,
|
|
25
|
+
Reactor,
|
|
26
|
+
isCanisterError,
|
|
27
|
+
reactorRetry,
|
|
28
|
+
} from "@ic-reactor/core"
|
|
29
|
+
import { QueryClient } from "@tanstack/query-core"
|
|
30
|
+
import { canisterId, idlFactory, type _SERVICE } from "./declarations/backend"
|
|
31
|
+
|
|
32
|
+
const clientManager = new ClientManager({
|
|
33
|
+
queryClient: new QueryClient({
|
|
34
|
+
defaultOptions: { queries: { retry: reactorRetry } },
|
|
35
|
+
}),
|
|
36
|
+
agentOptions: { host: "https://ic0.app" },
|
|
37
|
+
})
|
|
38
|
+
const backend = new Reactor<_SERVICE>({
|
|
39
|
+
clientManager,
|
|
40
|
+
idlFactory,
|
|
41
|
+
name: "backend",
|
|
42
|
+
canisterId,
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
// A cached, deduplicated read
|
|
46
|
+
export const getProfile = (id: string) =>
|
|
47
|
+
backend.fetchQuery({ functionName: "get_profile", args: [id] })
|
|
48
|
+
|
|
49
|
+
// An update resolves with the Ok value and throws a CanisterError for Err
|
|
50
|
+
export async function rename(name: string) {
|
|
51
|
+
try {
|
|
52
|
+
const profile = await backend.callMethod({
|
|
53
|
+
functionName: "update_profile",
|
|
54
|
+
args: [{ name }],
|
|
55
|
+
})
|
|
56
|
+
await backend.invalidateQueries({ functionName: "get_profile" })
|
|
57
|
+
return profile
|
|
58
|
+
} catch (error) {
|
|
59
|
+
if (isCanisterError(error)) return `Refused: ${error.code}` // "NotFound"
|
|
60
|
+
throw error // CallError: network, agent, certificate or trap
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## When to Use What
|
|
66
|
+
|
|
67
|
+
| Need | Use |
|
|
68
|
+
| -------------------------------------------- | -------------------------------------------------------------------------- |
|
|
69
|
+
| Raw Candid values (`bigint`, `Principal`) | `new Reactor<_SERVICE>({ clientManager, idlFactory, name, canisterId })` |
|
|
70
|
+
| Strings for display and forms, validators | `new DisplayReactor<_SERVICE>(...)` (adds zod) |
|
|
71
|
+
| A cached, deduplicated read | `reactor.fetchQuery({ functionName, args })` |
|
|
72
|
+
| An update, or a read that skips the cache | `reactor.callMethod({ functionName, args })` |
|
|
73
|
+
| Read or refresh the cache | `reactor.getQueryData(...)`, `await reactor.invalidateQueries(...)` |
|
|
74
|
+
| Another canister with the same interface | `reactor.forCanister(canisterId)` |
|
|
75
|
+
| One agent and cache for several canisters | one `ClientManager`, passed to every reactor |
|
|
76
|
+
| Act as an identity | `clientManager.updateAgent(identity)` |
|
|
77
|
+
| Your own `queryClient.fetchQuery` of a query | wrap it in `clientManager.fetchAcrossIdentitySwitch(() => ...)` |
|
|
78
|
+
| Show or read token amounts | `formatTokenAmount`, `parseTokenAmount` |
|
|
79
|
+
| Validate typed principal text | `isPrincipalText(text.trim())` |
|
|
80
|
+
| Tests | `installFakeReplica`, `createTestCanister` from `@ic-reactor/core/testing` |
|
|
81
|
+
| React | `@ic-reactor/react` instead |
|
|
82
|
+
|
|
83
|
+
## Reactors and Values
|
|
84
|
+
|
|
85
|
+
- Pass the service type (`new Reactor<_SERVICE>(...)`). Without it every
|
|
86
|
+
argument and result is `any` (`unknown` on a `DisplayReactor`).
|
|
87
|
+
- A `Result` is unwrapped: `callMethod` and `fetchQuery` resolve with the `Ok`
|
|
88
|
+
value and throw a `CanisterError` for an `Err`.
|
|
89
|
+
- `DisplayReactor` maps `nat`/`int`/`nat64`/`int64` to `string`, `principal`
|
|
90
|
+
to text, `blob` to hex, `opt T` to `T | undefined` and a variant to
|
|
91
|
+
`{ _type: "A", A: value }` (`{ _type: "A" }` for a case without a value:
|
|
92
|
+
switch on `_type`). `fromZodSchema(schema, { async: true })` builds
|
|
93
|
+
an async validator, which runs only in `validate()` and
|
|
94
|
+
`callMethodWithValidation()`.
|
|
95
|
+
- Floats display as numbers, and `NaN`, `±Infinity` and `-0` are sent back as
|
|
96
|
+
read; JSON writes `NaN`/`±Infinity` as `null` and `-0` as `0`.
|
|
97
|
+
- `vec record { text; T }` displays as an object: a repeated key keeps its last
|
|
98
|
+
value. Use `Reactor` where repeated keys or their order matter.
|
|
99
|
+
- `reactor.forCanister(canisterId)` returns a memoized sibling of the same
|
|
100
|
+
class on the same `ClientManager`, with the same interface and validators,
|
|
101
|
+
whose calls and keys use its own canister.
|
|
102
|
+
- Types: `ReactorArgsOf<typeof r, "method">`, `ReactorDataOf<...>`,
|
|
103
|
+
`ReactorErrorOf<...>`, `ServiceOf<typeof r>`, `TransformOf<typeof r>`.
|
|
104
|
+
|
|
105
|
+
## Cache and Identity
|
|
106
|
+
|
|
107
|
+
- Query keys start with the canister id and the method name; build one with
|
|
108
|
+
`reactor.generateQueryKey(...)`, never by hand.
|
|
109
|
+
- `invalidateQueries` returns TanStack Query's `Promise<void>`: `await` it to
|
|
110
|
+
wait for the active matches to refetch (a failed refetch does not reject
|
|
111
|
+
it), or prefix a call you do not wait for with `void`.
|
|
112
|
+
- A sign-in or sign-out (`updateAgent` with another principal) cancels the
|
|
113
|
+
fetches in flight of every canister the manager has a reactor for, removes
|
|
114
|
+
their unobserved cache entries and refetches the rest; a renewed delegation
|
|
115
|
+
for the same principal keeps the cache.
|
|
116
|
+
`fetchQuery` then fetches again as the new principal instead of rejecting,
|
|
117
|
+
and after three switches in a row rejects with a `CallError`.
|
|
118
|
+
|
|
119
|
+
## Token Amounts and Principals
|
|
120
|
+
|
|
121
|
+
- Ledger amounts are base units: a `bigint` from `Reactor`, integer text from
|
|
122
|
+
`DisplayReactor`. Never use `Number`, `parseFloat`, `Math.pow` or `toFixed`:
|
|
123
|
+
`Math.floor(Number("0.29") * 10 ** 8)` is 28999999.
|
|
124
|
+
- `formatTokenAmount(value, decimals, options?)` takes the value and
|
|
125
|
+
`icrc1_decimals` as returned. Options: `maxFractionDigits` (truncates unless
|
|
126
|
+
`roundingMode: "halfExpand"`), `minFractionDigits`, `trimTrailingZeros`,
|
|
127
|
+
`locale`, `useGrouping`. Without `locale` it writes plain text (`"1234.5"`).
|
|
128
|
+
- `parseTokenAmount(text, decimals)` returns a `bigint`; it throws a
|
|
129
|
+
`TypeError` for text that is not digits with one `.`, and a `RangeError` for
|
|
130
|
+
more fraction digits than the token has or a negative amount
|
|
131
|
+
(`{ allowNegative: true }` for an `int`). Send `amount.toString()` to a
|
|
132
|
+
`DisplayReactor`.
|
|
133
|
+
- `isPrincipalText(text.trim())` accepts canonical principal text of at most
|
|
134
|
+
29 bytes and never throws. A `DisplayReactor` takes the text; a `Reactor`
|
|
135
|
+
takes `Principal.fromText(text)`.
|
|
136
|
+
- `jsonToString(value)` prints a raw value: bigints as digits, principals as
|
|
137
|
+
text, blobs as hex.
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
import { formatTokenAmount, parseTokenAmount } from "@ic-reactor/core"
|
|
141
|
+
import { ledger } from "./ledger" // a DisplayReactor of an ICRC-1 ledger
|
|
142
|
+
|
|
143
|
+
export async function send(owner: string, input: string, decimals: number) {
|
|
144
|
+
const amount = parseTokenAmount(input, decimals) // "0.29", 8 -> 29000000n
|
|
145
|
+
await ledger.callMethod({
|
|
146
|
+
functionName: "icrc1_transfer",
|
|
147
|
+
args: [{ to: { owner }, amount: amount.toString() }], // display form
|
|
148
|
+
})
|
|
149
|
+
}
|
|
150
|
+
export const show = (balance: string, decimals: number) =>
|
|
151
|
+
formatTokenAmount(balance, decimals, { maxFractionDigits: 4 }) // "1.2345"
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Errors and Retries
|
|
155
|
+
|
|
156
|
+
- `CanisterError`: the canister returned `Err`. Read the value on `.err` and
|
|
157
|
+
the variant (or API `code`) on `.code`; `.details` is the API payload's
|
|
158
|
+
`details` as decoded.
|
|
159
|
+
- `CallError`: network, agent, certificate, a trap, or a validator that threw
|
|
160
|
+
(its error is the `cause`).
|
|
161
|
+
- `ValidationError`: a `DisplayReactor` validator refused the arguments.
|
|
162
|
+
- Use `isCanisterError`, `isCallError` and `isValidationError`; they also
|
|
163
|
+
recognise errors from another copy of the package.
|
|
164
|
+
- `reactorRetry` retries transport, certificate, HTTP 5xx/408/429 and
|
|
165
|
+
`SysTransient`/`SysUnknown` failures up to 3 times, never a
|
|
166
|
+
`CanisterError`, a `ValidationError`, an encode/decode failure or another
|
|
167
|
+
HTTP 4xx. Set it as `defaultOptions.queries.retry` on a `QueryClient` you
|
|
168
|
+
create.
|
|
169
|
+
- `reactorRetry` and `reactorUpdateRetry` retry only in a browser: where there
|
|
170
|
+
is no `window` (Node, server rendering, a web worker) they return `false`,
|
|
171
|
+
as TanStack Query retries nothing on a server by default. The agent still
|
|
172
|
+
resends a failed HTTP request itself. For query retries in a Node script,
|
|
173
|
+
pass the predicate:
|
|
174
|
+
`retry: (count, error) => count < 3 && isRetryableReactorError(error)`.
|
|
175
|
+
- Each attempt of an update is a new call the canister runs.
|
|
176
|
+
`reactorUpdateRetry` retries only a `SysTransient` rejection, which proves
|
|
177
|
+
the call never ran; a query of an update method that sets no `retry` uses
|
|
178
|
+
that rule within the `QueryClient`'s retry default.
|
|
179
|
+
|
|
180
|
+
## Network and the ic_env Cookie
|
|
181
|
+
|
|
182
|
+
- In a browser with no `agentOptions.host`, the agent calls the page origin on
|
|
183
|
+
a local page (`localhost`, loopback), a Codespaces or Gitpod domain (network
|
|
184
|
+
`"remote"`) or an IC boundary domain, and mainnet otherwise.
|
|
185
|
+
- `ClientManager` trusts the `ic_env` cookie (root key, Internet Identity
|
|
186
|
+
provider, `PUBLIC_CANISTER_ID:<name>`) only on loopback and `localhost`
|
|
187
|
+
hosts. Anywhere else, including Codespaces and Gitpod, pass
|
|
188
|
+
`allowEnvConfig: true` only for a host you control; without it a reactor with
|
|
189
|
+
no `canisterId` throws rather than read the id from the cookie.
|
|
190
|
+
- Off mainnet, `initialize()` fetches the replica's root key, unless you pass
|
|
191
|
+
`agentOptions.rootKey`, which is kept (`clientManager.explicitRootKey`).
|
|
192
|
+
- `isMainnetHost` recognises the boundary domains only; never use it as a
|
|
193
|
+
"safe to trust local configuration" test.
|
|
194
|
+
|
|
195
|
+
## Testing
|
|
196
|
+
|
|
197
|
+
`installFakeReplica({ canisters: { [id]: createTestCanister<_SERVICE>(idlFactory, handlers) } })`
|
|
198
|
+
from `@ic-reactor/core/testing` replaces the global `fetch`. Install it before
|
|
199
|
+
any `ClientManager` is built, pass `agentOptions: { host: replica.host }` (or
|
|
200
|
+
no host on either side), and call `replica.restore()` in `afterEach`.
|
|
201
|
+
Handlers get the decoded argument tuple and `{ caller }` and return raw Candid
|
|
202
|
+
values; return `{ Err: ... }` for a `CanisterError` and throw for a
|
|
203
|
+
`CallError`. `replica.requests` lists every request. The entry signs with
|
|
204
|
+
`@noble/curves`, an optional peer that `@icp-sdk/core` already installs.
|
|
205
|
+
|
|
206
|
+
## Do Not
|
|
207
|
+
|
|
208
|
+
- Leave out the `<_SERVICE>` type argument or cast results to `any`.
|
|
209
|
+
- Do token math with `Number`, `parseFloat`, `Math.pow` or `toFixed`.
|
|
210
|
+
- Retarget a shared reactor with `setCanisterId`; use `forCanister`.
|
|
211
|
+
- Hand-write query keys.
|
|
212
|
+
- Call an update method through `fetchQuery` unless repeating it is safe.
|
|
213
|
+
- Give an update call a numeric `retry`; use `reactorUpdateRetry`.
|
|
214
|
+
- Build a reactor or `ClientManager` at module scope on a server that serves
|
|
215
|
+
several users: keys carry no principal, so the cache is shared.
|
|
216
|
+
- Set `allowEnvConfig: true` for a host you do not control.
|
|
217
|
+
- Stub a reactor with `as unknown as Reactor` in tests.
|
|
218
|
+
- Edit generated declarations; regenerate them from the `.did`.
|
|
219
|
+
|
|
220
|
+
## Docs
|
|
221
|
+
|
|
222
|
+
- Core package: https://ic-reactor.b3pay.net/v3/packages/core.md
|
|
223
|
+
- ClientManager: https://ic-reactor.b3pay.net/v3/reference/ClientManager.md
|
|
224
|
+
- Reactor: https://ic-reactor.b3pay.net/v3/reference/Reactor.md
|
|
225
|
+
- DisplayReactor: https://ic-reactor.b3pay.net/v3/reference/DisplayReactor.md
|
|
226
|
+
- Utilities: https://ic-reactor.b3pay.net/v3/reference/Utilities.md
|
|
227
|
+
- Error handling: https://ic-reactor.b3pay.net/v3/guides/error-handling.md
|
|
228
|
+
- Local development: https://ic-reactor.b3pay.net/v3/getting-started/local-development.md
|
|
229
|
+
- Testing kit: https://ic-reactor.b3pay.net/v3/reference/testing.md
|
|
230
|
+
- Index of all docs: https://ic-reactor.b3pay.net/llms.txt
|
|
231
|
+
- Full guide: https://ic-reactor.b3pay.net/llms-full.txt
|
|
232
|
+
- Agent skill for Claude Code and other agents: https://github.com/B3Pay/ic-reactor/tree/main/skill-packages/ic-reactor
|