@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,476 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trap types: the mistakes the types of `@ic-reactor/core` are written to make
|
|
3
|
+
* a compile error, each proven to bite.
|
|
4
|
+
*
|
|
5
|
+
* A `@ts-expect-error` is only worth something while the line below it really
|
|
6
|
+
* is an error. If a refactor widens a type until the line compiles, TypeScript
|
|
7
|
+
* reports the directive as unused (TS2578), but only to whoever runs `tsc`
|
|
8
|
+
* over this file, and a trap that stopped trapping looks the same as a trap
|
|
9
|
+
* that still does in a green build. `scripts/verify-traps.mjs`
|
|
10
|
+
* (`pnpm verify:traps`, a CI gate) closes that gap: for every trap below it
|
|
11
|
+
* applies a fault that removes exactly that trap to a copy of this package,
|
|
12
|
+
* runs `tsc` on the copy, and requires TS2578 on exactly the trap's line and
|
|
13
|
+
* nothing else. A trap with no fault fixture, or a fixture whose fault leaves
|
|
14
|
+
* the trap standing, fails CI.
|
|
15
|
+
*
|
|
16
|
+
* ## Adding a trap
|
|
17
|
+
*
|
|
18
|
+
* 1. Write the line that must not compile, with a tag on the line above the
|
|
19
|
+
* directive, the id first and the directive straight after it, on a line
|
|
20
|
+
* of its own:
|
|
21
|
+
*
|
|
22
|
+
* // trap: <id>
|
|
23
|
+
* // @ts-expect-error <what the line gets wrong, and what to do instead>
|
|
24
|
+
* theLineThatMustNotCompile()
|
|
25
|
+
*
|
|
26
|
+
* The id is lowercase words joined by `-`. Several lines may share one id
|
|
27
|
+
* when one fault removes them all. A `@ts-expect-error` with no tag, a tag
|
|
28
|
+
* with no directive under it, and any `@ts-ignore` or `@ts-nocheck` in this
|
|
29
|
+
* file fail the script.
|
|
30
|
+
*
|
|
31
|
+
* 2. Write `scripts/traps/<id>.json`, the fault that makes the line compile:
|
|
32
|
+
*
|
|
33
|
+
* {
|
|
34
|
+
* "file": "src/units.ts",
|
|
35
|
+
* "search": "export function formatUnits(\n value: bigint,",
|
|
36
|
+
* "replace": "export function formatUnits(\n value: bigint | number,"
|
|
37
|
+
* }
|
|
38
|
+
*
|
|
39
|
+
* `file` is relative to this package, and `search` must occur exactly once
|
|
40
|
+
* in it. For several edits write `{ "edits": [ { "file", "search",
|
|
41
|
+
* "replace" }, ... ] }`; for more than text replacement, write
|
|
42
|
+
* `scripts/traps/<id>.mjs` exporting a default function that takes
|
|
43
|
+
* `{ dir, applyEdits }`, where `dir` is the copy of this package and
|
|
44
|
+
* `applyEdits(edits)` applies a list of the same edits.
|
|
45
|
+
*
|
|
46
|
+
* The fault is the *natural* regression: widening the type, dropping the
|
|
47
|
+
* check, exporting the internal. It must change nothing else: no other
|
|
48
|
+
* diagnostic may appear, so repair what the fault breaks in the same
|
|
49
|
+
* fixture.
|
|
50
|
+
*
|
|
51
|
+
* 3. Run `pnpm verify:traps`, then check by hand that the fault is one a
|
|
52
|
+
* refactor could really commit.
|
|
53
|
+
*
|
|
54
|
+
* A trap about another package belongs in a `traps.test-d.ts` of its own,
|
|
55
|
+
* registered in `SUITES` of `scripts/verify-traps.mjs`.
|
|
56
|
+
*
|
|
57
|
+
* Checked by `pnpm typecheck` (this file is in the typecheck project), not run
|
|
58
|
+
* by vitest.
|
|
59
|
+
*/
|
|
60
|
+
import type { Principal } from "@meantjs/schema"
|
|
61
|
+
import { Ed25519KeyIdentity } from "@icp-sdk/core/identity"
|
|
62
|
+
import {
|
|
63
|
+
MutationObserver,
|
|
64
|
+
QueryObserver,
|
|
65
|
+
keepPreviousData,
|
|
66
|
+
skipToken,
|
|
67
|
+
type OmitKeyof,
|
|
68
|
+
type QueryKey,
|
|
69
|
+
type QueryObserverOptions,
|
|
70
|
+
type SkipToken,
|
|
71
|
+
} from "@tanstack/query-core"
|
|
72
|
+
import {
|
|
73
|
+
createClient,
|
|
74
|
+
formatUnits,
|
|
75
|
+
isReactorError,
|
|
76
|
+
parseUnits,
|
|
77
|
+
} from "../src/index.js"
|
|
78
|
+
import type { Canister, Network, ReactorError } from "../src/index.js"
|
|
79
|
+
import { createTestClient, type TestHandlers } from "../src/testing/index.js"
|
|
80
|
+
import { createTestAuth } from "../src/testing/test-auth.js"
|
|
81
|
+
import * as icrc1 from "./fixtures/icrc1.js"
|
|
82
|
+
import * as shapes from "./fixtures/shapes.js"
|
|
83
|
+
import * as skippable from "./fixtures/skippable.js"
|
|
84
|
+
|
|
85
|
+
// What a generated module's `Err` arm looks like for ICRC-1 `icrc1_transfer`.
|
|
86
|
+
type TransferError =
|
|
87
|
+
| { BadFee: { expected_fee: bigint } }
|
|
88
|
+
| { InsufficientFunds: { balance: bigint } }
|
|
89
|
+
|
|
90
|
+
// `icrc1_decimals : () -> (nat8) query` and a balance that is still loading.
|
|
91
|
+
declare const decimals: number
|
|
92
|
+
declare const balance: bigint
|
|
93
|
+
declare const loading: bigint | undefined
|
|
94
|
+
|
|
95
|
+
// ---------------------------------------------------------------------------
|
|
96
|
+
// Units: a `Number` is the lossy input they exist to replace
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
|
|
99
|
+
// trap: format-units-refuses-number
|
|
100
|
+
// @ts-expect-error a Number amount cannot hold every balance; pass the bigint a ledger returned
|
|
101
|
+
formatUnits(1.5, 8)
|
|
102
|
+
|
|
103
|
+
// trap: format-units-refuses-missing-value
|
|
104
|
+
// @ts-expect-error the amount may still be loading; show a placeholder instead of formatting undefined
|
|
105
|
+
formatUnits(loading, 8)
|
|
106
|
+
|
|
107
|
+
// trap: parse-units-refuses-number
|
|
108
|
+
// @ts-expect-error read the text a person typed, not a Number: Number math turns 0.29 into 28999999
|
|
109
|
+
parseUnits(1.5, decimals)
|
|
110
|
+
|
|
111
|
+
// trap: parse-units-unknown-option
|
|
112
|
+
// @ts-expect-error v3 called it allowNegative; the option is `signed`
|
|
113
|
+
parseUnits("-1", 8, { allowNegative: true })
|
|
114
|
+
|
|
115
|
+
// trap: format-units-unknown-option
|
|
116
|
+
// @ts-expect-error v3 had rounding modes; this cuts and never rounds
|
|
117
|
+
formatUnits(balance, 8, { roundingMode: "halfExpand" })
|
|
118
|
+
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
// Networks: one of the names, or an object with a host
|
|
121
|
+
// ---------------------------------------------------------------------------
|
|
122
|
+
|
|
123
|
+
// trap: network-refuses-unknown-name
|
|
124
|
+
// @ts-expect-error a network is "ic", "local", "env" or an object; "mainnet" would be a typo that falls through
|
|
125
|
+
export const unknownName: Network = "mainnet"
|
|
126
|
+
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
// Errors: `err` is typed only where the canister returned one
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
|
|
131
|
+
export const readNeverErr = (error: ReactorError) => {
|
|
132
|
+
if (error.kind === "canister_err") {
|
|
133
|
+
// trap: never-err-has-no-type
|
|
134
|
+
// @ts-expect-error a method without an Err arm has no typed `err`; it is undefined for every kind
|
|
135
|
+
return error.err.BadFee
|
|
136
|
+
}
|
|
137
|
+
return undefined
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export const readErrOffTheArm = (error: ReactorError<TransferError>) => {
|
|
141
|
+
if (error.kind !== "canister_err") {
|
|
142
|
+
// trap: err-only-on-canister-err
|
|
143
|
+
// @ts-expect-error `err` is undefined for every kind but canister_err; check the kind first
|
|
144
|
+
return "BadFee" in error.err
|
|
145
|
+
}
|
|
146
|
+
return undefined
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// ---------------------------------------------------------------------------
|
|
150
|
+
// The entry: the classifier and the resolver are the client's, not an app's
|
|
151
|
+
// ---------------------------------------------------------------------------
|
|
152
|
+
|
|
153
|
+
// trap: internals-not-exported
|
|
154
|
+
// @ts-expect-error classifyError is internal; an app reads `mayHaveExecuted` off the error it is given
|
|
155
|
+
import { classifyError } from "../src/index.js"
|
|
156
|
+
// trap: internals-not-exported
|
|
157
|
+
// @ts-expect-error resolveNetwork is internal; an app passes a Network to createClient
|
|
158
|
+
import { resolveNetwork } from "../src/index.js"
|
|
159
|
+
|
|
160
|
+
export const internals = { classifyError, resolveNetwork }
|
|
161
|
+
|
|
162
|
+
// ---------------------------------------------------------------------------
|
|
163
|
+
// The client: who calls is written down exactly once
|
|
164
|
+
// ---------------------------------------------------------------------------
|
|
165
|
+
|
|
166
|
+
const someone = Ed25519KeyIdentity.generate()
|
|
167
|
+
|
|
168
|
+
// trap: client-says-who-calls
|
|
169
|
+
// @ts-expect-error neither identity nor auth: who calls is not written down; pass identity: "anonymous" for a read-only client
|
|
170
|
+
createClient({ network: "ic" })
|
|
171
|
+
|
|
172
|
+
// trap: client-says-who-calls-once
|
|
173
|
+
// @ts-expect-error identity and auth together: who calls is written twice; identity fixes the caller, auth signs users in
|
|
174
|
+
createClient({ network: "ic", identity: someone, auth: () => createTestAuth() })
|
|
175
|
+
|
|
176
|
+
// ---------------------------------------------------------------------------
|
|
177
|
+
// Canisters: methods, variables and principals come from the generated Actor
|
|
178
|
+
// ---------------------------------------------------------------------------
|
|
179
|
+
|
|
180
|
+
const client = createClient({ network: "ic", identity: "anonymous" })
|
|
181
|
+
const ledger = client.canister<icrc1.Actor>(icrc1.actor, {
|
|
182
|
+
id: "ryjl3-tyaaa-aaaaa-aaaba-cai",
|
|
183
|
+
})
|
|
184
|
+
const shapesCanister = client.canister<shapes.Actor>(shapes.actor, {
|
|
185
|
+
id: "rrkah-fqaaa-aaaaa-aaaaq-cai",
|
|
186
|
+
})
|
|
187
|
+
declare const owner: Principal
|
|
188
|
+
const account: icrc1.Account = { owner, subaccount: null }
|
|
189
|
+
declare const transferArg: icrc1.TransferArg
|
|
190
|
+
|
|
191
|
+
// trap: canister-method-unknown
|
|
192
|
+
// @ts-expect-error icrc1_balance is not a method of the ICRC-1 ledger; it is icrc1_balance_of
|
|
193
|
+
void ledger.icrc1_balance(account)
|
|
194
|
+
|
|
195
|
+
// trap: options-method-unknown
|
|
196
|
+
// @ts-expect-error a typo in the method name: the builders take the generated Actor's method names only
|
|
197
|
+
client.queryOptions(ledger, "icrc1_balance", account)
|
|
198
|
+
|
|
199
|
+
// trap: options-vars-wrong-type
|
|
200
|
+
// @ts-expect-error icrc1_balance_of takes an Account, not its owner: { owner, subaccount: null }
|
|
201
|
+
client.queryOptions(ledger, "icrc1_balance_of", owner)
|
|
202
|
+
|
|
203
|
+
// trap: principal-is-not-plain-text
|
|
204
|
+
// @ts-expect-error a principal is checked text: principal("aaaaa-aa") from @meantjs/schema, not a string literal
|
|
205
|
+
void ledger.icrc1_balance_of({ owner: "aaaaa-aa", subaccount: null })
|
|
206
|
+
|
|
207
|
+
// trap: vars-of-two-arguments-are-the-tuple
|
|
208
|
+
// @ts-expect-error pair takes two arguments: pass them as the tuple [left, right]
|
|
209
|
+
client.queryOptions(shapesCanister, "pair", 1n)
|
|
210
|
+
|
|
211
|
+
// ---------------------------------------------------------------------------
|
|
212
|
+
// The typed guard: `err` is the Err arm of the method it names, not another's
|
|
213
|
+
// ---------------------------------------------------------------------------
|
|
214
|
+
|
|
215
|
+
// An ICRC-2 ledger: icrc2_approve has an Err arm of its own, which has no
|
|
216
|
+
// BadBurn; that is icrc1_transfer's.
|
|
217
|
+
type ApproveError =
|
|
218
|
+
| { tag: "AllowanceChanged"; value: { current_allowance: bigint } }
|
|
219
|
+
| { tag: "Expired"; value: { ledger_time: bigint } }
|
|
220
|
+
| { tag: "InsufficientFunds"; value: { balance: bigint } }
|
|
221
|
+
declare const icrc2Ledger: Canister<
|
|
222
|
+
icrc1.Actor & {
|
|
223
|
+
icrc2_approve: (
|
|
224
|
+
arg: unknown
|
|
225
|
+
) => Promise<
|
|
226
|
+
{ tag: "Ok"; value: bigint } | { tag: "Err"; value: ApproveError }
|
|
227
|
+
>
|
|
228
|
+
}
|
|
229
|
+
>
|
|
230
|
+
|
|
231
|
+
export const readAnotherMethodsErr = (error: unknown) => {
|
|
232
|
+
if (
|
|
233
|
+
isReactorError(error, icrc2Ledger, "icrc2_approve") &&
|
|
234
|
+
error.kind === "canister_err"
|
|
235
|
+
) {
|
|
236
|
+
// trap: guard-err-is-the-methods
|
|
237
|
+
// @ts-expect-error an approve cannot fail with BadBurn, a transfer's Err: the guard types `err` by the method named, so name the one that was called
|
|
238
|
+
return error.err.tag === "BadBurn"
|
|
239
|
+
}
|
|
240
|
+
return undefined
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// A false three-argument guard means only "not this call's error". The error
|
|
244
|
+
// can still be of any kind, even once the one-argument guard has narrowed it.
|
|
245
|
+
export const readAnotherCallsKind = (error: unknown) => {
|
|
246
|
+
if (!isReactorError(error)) throw error
|
|
247
|
+
if (isReactorError(error, ledger, "icrc1_transfer")) return undefined
|
|
248
|
+
// trap: guard-false-keeps-every-kind
|
|
249
|
+
// @ts-expect-error another call's error can be of any kind, not only canister_err: check kind before reading err
|
|
250
|
+
const kind: "canister_err" = error.kind
|
|
251
|
+
return kind
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// ---------------------------------------------------------------------------
|
|
255
|
+
// Re-sending: only a write the app says the canister deduplicates
|
|
256
|
+
// ---------------------------------------------------------------------------
|
|
257
|
+
|
|
258
|
+
export const resendWithoutAKey = (error: unknown) =>
|
|
259
|
+
// trap: resend-states-its-dedupe-key
|
|
260
|
+
// @ts-expect-error re-sending is safe only for a write the canister deduplicates: state what it deduplicates on with { dedupedBy }
|
|
261
|
+
client.resendOf(error, ledger, "icrc1_transfer")
|
|
262
|
+
|
|
263
|
+
export const resendByAFieldItLacks = (error: unknown) =>
|
|
264
|
+
client.resendOf(error, ledger, "icrc1_transfer", {
|
|
265
|
+
// trap: resend-key-reads-the-methods-arg
|
|
266
|
+
// @ts-expect-error dedupedBy reads the method's own argument, and a TransferArg has no nonce: name the field the canister deduplicates on
|
|
267
|
+
dedupedBy: (arg) => arg.nonce,
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
// A method named by data, given as `any` (#874): its variables are the value
|
|
271
|
+
// of a one-argument method, as at run time, not a list.
|
|
272
|
+
export const writeOfANamedMethod = (named: string) =>
|
|
273
|
+
new MutationObserver(client.queryClient, {
|
|
274
|
+
...client.mutationOptions<icrc1.Actor, any>(ledger, named),
|
|
275
|
+
// trap: any-method-vars-not-a-list
|
|
276
|
+
// @ts-expect-error under <A, any> the variables are the value of a one-argument method, not a list: vars[0] is not its argument
|
|
277
|
+
onSuccess: (_data, vars) => vars[0],
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
// What `useSuspenseQuery` of `@tanstack/react-query` takes, written over
|
|
281
|
+
// query-core: the options of a `QueryObserver`, without the ones a suspense
|
|
282
|
+
// read has no use for, and a `queryFn` that is never `skipToken`, since a
|
|
283
|
+
// suspense read cannot wait for its variables.
|
|
284
|
+
type SuspenseQueryOptions<T, E, K extends QueryKey> = OmitKeyof<
|
|
285
|
+
QueryObserverOptions<T, E, T, T, K>,
|
|
286
|
+
"queryFn" | "enabled" | "throwOnError" | "placeholderData"
|
|
287
|
+
> & {
|
|
288
|
+
queryFn?: Exclude<QueryObserverOptions<T, E, T, T, K>["queryFn"], SkipToken>
|
|
289
|
+
}
|
|
290
|
+
declare function useSuspenseQuery<T, E, K extends QueryKey>(
|
|
291
|
+
options: SuspenseQueryOptions<T, E, K>
|
|
292
|
+
): { data: T }
|
|
293
|
+
declare const ready: boolean
|
|
294
|
+
|
|
295
|
+
// Variables that cannot be skipped give options a suspense read takes as they
|
|
296
|
+
// are. The read with variables is a tuple: under the fault of
|
|
297
|
+
// options-vars-wrong-type a single argument is `unknown`, which may hold
|
|
298
|
+
// `skipToken`, and its read would be refused too.
|
|
299
|
+
useSuspenseQuery(client.queryOptions(ledger, "icrc1_fee"))
|
|
300
|
+
useSuspenseQuery(client.queryOptions(shapesCanister, "pair", [1n, "x"]))
|
|
301
|
+
|
|
302
|
+
// Variables that may be skipped give options it refuses. The traps read a
|
|
303
|
+
// method without arguments: under the fault of options-vars-wrong-type, which
|
|
304
|
+
// widens every argument to `unknown`, the variables of a method with
|
|
305
|
+
// arguments can no longer be told from `skipToken`, and one fault must remove
|
|
306
|
+
// one trap. packages/react/tests/suspense.test-d.tsx refuses an `Account |
|
|
307
|
+
// SkipToken` under the real `useSuspenseQuery`.
|
|
308
|
+
|
|
309
|
+
const gated = client.queryOptions(
|
|
310
|
+
ledger,
|
|
311
|
+
"icrc1_fee",
|
|
312
|
+
ready ? undefined : skipToken
|
|
313
|
+
)
|
|
314
|
+
// trap: suspense-refuses-skippable-read
|
|
315
|
+
// @ts-expect-error a suspense read cannot be skipped: render it once it can run, or read it with useQuery
|
|
316
|
+
useSuspenseQuery(gated)
|
|
317
|
+
// trap: suspense-refuses-skippable-read
|
|
318
|
+
// @ts-expect-error skipToken is for useQuery; a suspense read always runs
|
|
319
|
+
useSuspenseQuery(client.queryOptions(ledger, "icrc1_fee", skipToken))
|
|
320
|
+
|
|
321
|
+
// Variables of a type `skipToken` is assignable to may always be skipped, and
|
|
322
|
+
// the options keep SkipToken: a Candid `reserved` argument, which the
|
|
323
|
+
// generator writes `unknown`, and an empty record written `{}` by hand
|
|
324
|
+
// (`meant gen` writes `record {}` as `Record<string, never>`, which
|
|
325
|
+
// a symbol is not). tests/skip.test-d.ts pins what the generator writes.
|
|
326
|
+
const skippableIds = { id: "rrkah-fqaaa-aaaaa-aaaaq-cai" }
|
|
327
|
+
const gen = client.canister<skippable.Actor>(skippable.actor, skippableIds)
|
|
328
|
+
declare const braces: Canister<{ braces: (r: {}) => Promise<bigint> }>
|
|
329
|
+
// trap: suspense-refuses-vars-skip-fits
|
|
330
|
+
// @ts-expect-error a reserved argument may be skipToken, so a suspense read refuses it; read it with useQuery
|
|
331
|
+
useSuspenseQuery(client.queryOptions(gen, "anything", skipToken))
|
|
332
|
+
// trap: suspense-refuses-vars-skip-fits
|
|
333
|
+
// @ts-expect-error skipToken is assignable to `{}`, so a suspense read refuses it; read it with useQuery
|
|
334
|
+
useSuspenseQuery(client.queryOptions(braces, "braces", skipToken))
|
|
335
|
+
|
|
336
|
+
// An argument `skipToken` is not assignable to, such as an empty record as the
|
|
337
|
+
// generator writes it, still takes `skipToken` in its place, and the options
|
|
338
|
+
// keep SkipToken.
|
|
339
|
+
// trap: suspense-refuses-argument-skip
|
|
340
|
+
// @ts-expect-error skipToken is for useQuery; a suspense read always runs
|
|
341
|
+
useSuspenseQuery(client.queryOptions(gen, "empty_record", skipToken))
|
|
342
|
+
|
|
343
|
+
// ---------------------------------------------------------------------------
|
|
344
|
+
// Reads: a query refetches, so an update or a oneway is not a read
|
|
345
|
+
// ---------------------------------------------------------------------------
|
|
346
|
+
//
|
|
347
|
+
// The generated Actor says each method's mode (`$.WithMode<"update">`), and
|
|
348
|
+
// `queryOptions` reads it: every refetch of a read built from an update would
|
|
349
|
+
// run the update again, and a oneway has no reply to cache.
|
|
350
|
+
|
|
351
|
+
// trap: query-options-refuses-update
|
|
352
|
+
// @ts-expect-error icrc1_transfer is an update: every refetch would transfer again; use client.mutationOptions(ledger, "icrc1_transfer")
|
|
353
|
+
client.queryOptions(ledger, "icrc1_transfer", transferArg)
|
|
354
|
+
// trap: query-options-refuses-update
|
|
355
|
+
// @ts-expect-error an update is not a read while its variables load either; use client.mutationOptions for a write
|
|
356
|
+
client.queryOptions(shapesCanister, "bump", skipToken)
|
|
357
|
+
|
|
358
|
+
// trap: query-options-refuses-oneway
|
|
359
|
+
// @ts-expect-error fire is a oneway method: it has no reply to cache; call it directly, or through client.mutationOptions
|
|
360
|
+
client.queryOptions(shapesCanister, "fire", "x")
|
|
361
|
+
// trap: query-options-refuses-oneway
|
|
362
|
+
// @ts-expect-error { update: "idempotent" } opts in an update, not a oneway, which has no reply to cache whatever the options say
|
|
363
|
+
client.queryOptions(shapesCanister, "fire", "x", { update: "idempotent" })
|
|
364
|
+
|
|
365
|
+
// Each of these compiles. A query and a composite query are reads (a
|
|
366
|
+
// composite query of a certified canister is refused at run time: no type
|
|
367
|
+
// says a canister is certified).
|
|
368
|
+
export const queryRead = client.queryOptions(shapesCanister, "one", 1n)
|
|
369
|
+
export const compositeRead = client.queryOptions(
|
|
370
|
+
shapesCanister,
|
|
371
|
+
"composite",
|
|
372
|
+
1n
|
|
373
|
+
)
|
|
374
|
+
// An update that answers the same however often it runs is read with the
|
|
375
|
+
// opt-in, its variables first, even `undefined` for a method without
|
|
376
|
+
// arguments. Its options are a suspense read's like any other, and may wait
|
|
377
|
+
// for their variables like any other.
|
|
378
|
+
useSuspenseQuery(
|
|
379
|
+
client.queryOptions(shapesCanister, "three", undefined, {
|
|
380
|
+
update: "idempotent",
|
|
381
|
+
})
|
|
382
|
+
)
|
|
383
|
+
export const idempotentRead = client.queryOptions(
|
|
384
|
+
shapesCanister,
|
|
385
|
+
"address",
|
|
386
|
+
"seed",
|
|
387
|
+
{ update: "idempotent" }
|
|
388
|
+
)
|
|
389
|
+
export const idempotentWhileLoading = client.queryOptions(
|
|
390
|
+
shapesCanister,
|
|
391
|
+
"address",
|
|
392
|
+
ready ? "seed" : skipToken,
|
|
393
|
+
{ update: "idempotent" }
|
|
394
|
+
)
|
|
395
|
+
// An Actor written by hand says no mode: each of its methods may be read, and
|
|
396
|
+
// the client refuses an update or a oneway at run time instead
|
|
397
|
+
// (tests/traps/update-as-query.test.ts reads the ledger through one).
|
|
398
|
+
type HandWrittenLedger = {
|
|
399
|
+
icrc1_fee: () => Promise<bigint>
|
|
400
|
+
icrc1_transfer: (arg: icrc1.TransferArg) => Promise<icrc1.TransferResult>
|
|
401
|
+
}
|
|
402
|
+
const handWritten = client.canister<HandWrittenLedger>(icrc1.actor, {
|
|
403
|
+
id: "ryjl3-tyaaa-aaaaa-aaaba-cai",
|
|
404
|
+
})
|
|
405
|
+
export const handWrittenFee = client.queryOptions(handWritten, "icrc1_fee")
|
|
406
|
+
export const handWrittenTransfer = client.queryOptions(
|
|
407
|
+
handWritten,
|
|
408
|
+
"icrc1_transfer",
|
|
409
|
+
transferArg
|
|
410
|
+
)
|
|
411
|
+
|
|
412
|
+
// ---------------------------------------------------------------------------
|
|
413
|
+
// The test client: handlers answer in the generated Actor's domain values
|
|
414
|
+
// ---------------------------------------------------------------------------
|
|
415
|
+
|
|
416
|
+
type LedgerHandlers = TestHandlers<icrc1.Actor>
|
|
417
|
+
|
|
418
|
+
// trap: test-handler-nat-is-bigint
|
|
419
|
+
// @ts-expect-error icrc1_fee replies a nat, which is a bigint: 10_000 is a number, write 10_000n
|
|
420
|
+
export const feeAsNumber: LedgerHandlers = { icrc1_fee: () => 10_000 }
|
|
421
|
+
|
|
422
|
+
// trap: test-handler-method-unknown
|
|
423
|
+
// @ts-expect-error icrc1_balance is not a method of the ICRC-1 ledger; it is icrc1_balance_of
|
|
424
|
+
export const balanceTypo: LedgerHandlers = { icrc1_balance: () => 1n }
|
|
425
|
+
|
|
426
|
+
// trap: test-handler-takes-the-domain-value
|
|
427
|
+
// @ts-expect-error icrc1_balance_of takes an Account, not text: ({ owner }) => ...
|
|
428
|
+
export const ofText: LedgerHandlers = { icrc1_balance_of: (_o: string) => 1n }
|
|
429
|
+
|
|
430
|
+
// A refusal aimed at a method: an option it does not have would be ignored,
|
|
431
|
+
// and the refusal would land on whatever request came next.
|
|
432
|
+
const { refuseNext } = createTestClient()
|
|
433
|
+
refuseNext(429, { method: "icrc1_transfer", times: 3 })
|
|
434
|
+
// trap: refuse-next-unknown-option
|
|
435
|
+
// @ts-expect-error refuseNext() has no option `methd`; it is `method`
|
|
436
|
+
refuseNext(429, { methd: "icrc1_transfer" })
|
|
437
|
+
|
|
438
|
+
// ---------------------------------------------------------------------------
|
|
439
|
+
// Known holes (D36): these COMPILE on purpose
|
|
440
|
+
// ---------------------------------------------------------------------------
|
|
441
|
+
//
|
|
442
|
+
// D36 records what the types do not stop, and decides against an ESLint plugin
|
|
443
|
+
// to stop it: each is a mistake the eval scores, a runtime refusal where there
|
|
444
|
+
// is one, and a line in the guide's "Do not" list. They are written here as
|
|
445
|
+
// code that compiles, with no directive and no trap tag, so that nobody adds a
|
|
446
|
+
// `@ts-expect-error` for one, and so that the day a type does start refusing
|
|
447
|
+
// one shows up as a failing build here: a decision, not a surprise.
|
|
448
|
+
|
|
449
|
+
// D36: spreading `retry: 3` into the options of a write. A mutation is never
|
|
450
|
+
// retried (an update re-sent after an unknown outcome can run twice), but the
|
|
451
|
+
// options are plain TanStack options, so nothing refuses the spread.
|
|
452
|
+
export const retriedWrite = new MutationObserver(client.queryClient, {
|
|
453
|
+
...client.mutationOptions(ledger, "icrc1_transfer"),
|
|
454
|
+
retry: 3,
|
|
455
|
+
})
|
|
456
|
+
|
|
457
|
+
// D36: `placeholderData: keepPreviousData` on a read. The previous key's data
|
|
458
|
+
// is shown for the new key, which for a caller-scoped key can be another
|
|
459
|
+
// principal's balance. It is a TanStack option; the type cannot tell.
|
|
460
|
+
export const previousBalance = new QueryObserver(client.queryClient, {
|
|
461
|
+
...client.queryOptions(ledger, "icrc1_balance_of", account),
|
|
462
|
+
placeholderData: keepPreviousData,
|
|
463
|
+
})
|
|
464
|
+
|
|
465
|
+
// D36: an array-literal key. Typed by hand it is a `QueryKey` like any other,
|
|
466
|
+
// so it compiles, and then matches nothing the client builds: keys start with
|
|
467
|
+
// "ic-reactor" and hold the caller. `client.queryKey(...)` is the only builder.
|
|
468
|
+
void client.queryClient.invalidateQueries({ queryKey: ["balance", owner] })
|
|
469
|
+
|
|
470
|
+
// D36: a hand-built query function calling an update. To TanStack any
|
|
471
|
+
// function is a query function: this runs the transfer again on every
|
|
472
|
+
// refetch, as whoever is signed in at that moment, not the key's caller.
|
|
473
|
+
export const transferAsRead = new QueryObserver(client.queryClient, {
|
|
474
|
+
queryKey: ["transfer", owner],
|
|
475
|
+
queryFn: () => ledger.icrc1_transfer(transferArg),
|
|
476
|
+
})
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The types of `parseUnits` and `formatUnits`.
|
|
3
|
+
*
|
|
4
|
+
* Both are strict about what they take: `parseUnits` reads text only, since a
|
|
5
|
+
* `Number` amount is the lossy input it replaces, and `formatUnits` shows a
|
|
6
|
+
* `bigint` only, which is what a ledger's `nat` is in a generated module.
|
|
7
|
+
* Neither takes an option it does not implement, so a v3 name such as
|
|
8
|
+
* `allowNegative` or `locale` is a compile error and not silently ignored.
|
|
9
|
+
*
|
|
10
|
+
* Checked by `pnpm typecheck` (tests are in the typecheck project), not by
|
|
11
|
+
* vitest.
|
|
12
|
+
*/
|
|
13
|
+
import { describe, it, expectTypeOf } from "vitest"
|
|
14
|
+
import { formatUnits, parseUnits } from "../src/index.js"
|
|
15
|
+
|
|
16
|
+
// `icrc1_balance_of : (Account) -> (nat) query` and
|
|
17
|
+
// `icrc1_decimals : () -> (nat8) query`, as a generated module returns them.
|
|
18
|
+
declare const balance: bigint
|
|
19
|
+
declare const decimals: number
|
|
20
|
+
declare const loading: bigint | undefined
|
|
21
|
+
declare const input: string
|
|
22
|
+
|
|
23
|
+
describe("parseUnits", () => {
|
|
24
|
+
it("returns a bigint", () => {
|
|
25
|
+
expectTypeOf(parseUnits("1.5", 8)).toEqualTypeOf<bigint>()
|
|
26
|
+
expectTypeOf(parseUnits(input, decimals)).toEqualTypeOf<bigint>()
|
|
27
|
+
expectTypeOf(parseUnits("-1", 8, { signed: true })).toEqualTypeOf<bigint>()
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it("takes text only", () => {
|
|
31
|
+
// @ts-expect-error a Number amount is the lossy input this replaces
|
|
32
|
+
parseUnits(1.5, 8)
|
|
33
|
+
// @ts-expect-error nor is a bigint
|
|
34
|
+
parseUnits(balance, 8)
|
|
35
|
+
// @ts-expect-error nor an amount that may still be missing
|
|
36
|
+
parseUnits(undefined, 8)
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it("takes decimals as a number, and requires it", () => {
|
|
40
|
+
// @ts-expect-error decimals are required
|
|
41
|
+
parseUnits("1.5")
|
|
42
|
+
// @ts-expect-error a bigint decimals is converted with Number() first
|
|
43
|
+
parseUnits("1.5", 8n)
|
|
44
|
+
// @ts-expect-error digit text is not decimals
|
|
45
|
+
parseUnits("1.5", "8")
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it("types its options", () => {
|
|
49
|
+
expectTypeOf(parseUnits)
|
|
50
|
+
.parameter(2)
|
|
51
|
+
.toEqualTypeOf<{ signed?: boolean } | undefined>()
|
|
52
|
+
|
|
53
|
+
parseUnits("1.5", 8, {})
|
|
54
|
+
parseUnits("1.5", 8, { signed: false })
|
|
55
|
+
// @ts-expect-error signed is a boolean
|
|
56
|
+
parseUnits("-1", 8, { signed: "true" })
|
|
57
|
+
// @ts-expect-error v3 called it allowNegative
|
|
58
|
+
parseUnits("-1", 8, { allowNegative: true })
|
|
59
|
+
// @ts-expect-error not an option
|
|
60
|
+
parseUnits("1.5", 8, { decimals: 2 })
|
|
61
|
+
})
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
describe("formatUnits", () => {
|
|
65
|
+
it("returns a string", () => {
|
|
66
|
+
expectTypeOf(formatUnits(balance, 8)).toEqualTypeOf<string>()
|
|
67
|
+
expectTypeOf(formatUnits(150_000_000n, decimals)).toEqualTypeOf<string>()
|
|
68
|
+
expectTypeOf(
|
|
69
|
+
formatUnits(balance, 8, { maxFractionDigits: 2, minFractionDigits: 2 })
|
|
70
|
+
).toEqualTypeOf<string>()
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it("takes a bigint only", () => {
|
|
74
|
+
// @ts-expect-error a Number amount cannot hold every balance
|
|
75
|
+
formatUnits(1.5, 8)
|
|
76
|
+
// @ts-expect-error not even a whole one
|
|
77
|
+
formatUnits(150_000_000, 8)
|
|
78
|
+
// @ts-expect-error integer text is not an amount; read it with BigInt
|
|
79
|
+
formatUnits("150000000", 8)
|
|
80
|
+
// @ts-expect-error the amount may be undefined while it loads
|
|
81
|
+
formatUnits(loading, 8)
|
|
82
|
+
// @ts-expect-error null is not an amount
|
|
83
|
+
formatUnits(null, 8)
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it("takes decimals as a number, and requires it", () => {
|
|
87
|
+
// @ts-expect-error decimals are required
|
|
88
|
+
formatUnits(balance)
|
|
89
|
+
// @ts-expect-error a bigint decimals is converted with Number() first
|
|
90
|
+
formatUnits(balance, 8n)
|
|
91
|
+
// @ts-expect-error digit text is not decimals
|
|
92
|
+
formatUnits(balance, "8")
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it("types its options", () => {
|
|
96
|
+
expectTypeOf(formatUnits)
|
|
97
|
+
.parameter(2)
|
|
98
|
+
.toEqualTypeOf<
|
|
99
|
+
{ maxFractionDigits?: number; minFractionDigits?: number } | undefined
|
|
100
|
+
>()
|
|
101
|
+
|
|
102
|
+
formatUnits(balance, 8, {})
|
|
103
|
+
formatUnits(balance, 8, { maxFractionDigits: 2 })
|
|
104
|
+
formatUnits(balance, 8, { minFractionDigits: 2 })
|
|
105
|
+
// @ts-expect-error the digit counts are numbers
|
|
106
|
+
formatUnits(balance, 8, { maxFractionDigits: "2" })
|
|
107
|
+
// @ts-expect-error v3 had rounding modes; this cuts and never rounds
|
|
108
|
+
formatUnits(balance, 8, { roundingMode: "halfExpand" })
|
|
109
|
+
// @ts-expect-error v3 had a locale; format the plain text with Intl
|
|
110
|
+
formatUnits(balance, 8, { locale: "de-DE" })
|
|
111
|
+
// @ts-expect-error v3 had grouping; format the plain text with Intl
|
|
112
|
+
formatUnits(balance, 8, { useGrouping: true })
|
|
113
|
+
// @ts-expect-error v3 had trimTrailingZeros; minFractionDigits pads
|
|
114
|
+
formatUnits(balance, 8, { trimTrailingZeros: false })
|
|
115
|
+
// @ts-expect-error not an option
|
|
116
|
+
formatUnits(balance, 8, { decimals: 2 })
|
|
117
|
+
})
|
|
118
|
+
})
|