@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,107 @@
|
|
|
1
|
+
# ICP wallet on ic-reactor 4
|
|
2
|
+
|
|
3
|
+
A React and Vite wallet on a local icp-cli network: the NNS ICP ledger, a
|
|
4
|
+
Rust `backend` canister of its own (a profile and an address book per
|
|
5
|
+
caller), and Internet Identity. One client per tab,
|
|
6
|
+
`createClient({ network: "env", auth })`, and TanStack Query's own hooks with
|
|
7
|
+
the options the client builds. Every scenario below is a small file whose
|
|
8
|
+
header names the rule it shows, and each has tests.
|
|
9
|
+
|
|
10
|
+
## Scenarios
|
|
11
|
+
|
|
12
|
+
| # | Scenario | Files | See it |
|
|
13
|
+
| --- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
|
|
14
|
+
| 1 | `network: "env"`; the backend as `{ name: "backend" }` from the `ic_env` cookie the Vite plugin sets (with its `/api` proxy), the ledger by `{ id }` | `src/client.ts`, `src/use-canisters.ts`, `src/EnvironmentPanel.tsx` | "Network and canisters": the origin, the id the client resolved, the cookie |
|
|
15
|
+
| 2 | Internet Identity through `@icp-sdk/auth` 10's `AuthClient`, built from the network the client hands its `auth` factory: the local II on a local page | `src/client.ts` | "Sign in with Internet Identity": a window on the local II, which asks for a seed index, not a passkey |
|
|
16
|
+
| 3 | A sign-in of the app's own as an `AuthLike` (dev account, local only) beside II behind one `auth`; a switch shows the next account nothing of the last | `src/auth/dev-accounts.ts`, `src/auth/wallet-auth.ts`, `src/SignIn.tsx`, `src/App.tsx` | "Sign in with a dev account", "New dev account", then switch back and forth |
|
|
17
|
+
| 4 | Balance with `skipToken` while signed out and `refetchInterval` spread onto the client's options | `src/Balance.tsx` | `pnpm faucet <principal>` in a terminal: the balance changes within 3 s |
|
|
18
|
+
| 5 | Send ICP: `parseUnits` input, the fee, a `memo` per transfer and `created_at_time`, typed `canister_err`, and `mayHaveExecuted` (outcome unknown, the client's re-read, "send the same transfer again", offered by `client.resendOf` to its sender only) | `src/SendIcp.tsx`, `src/transfer.ts` | Send; type `1e3` (refused before sending); send more than you hold (`InsufficientFunds`) |
|
|
19
|
+
| 6 | Profile reads and writes as the caller; a write while signed out is refused `unauthenticated` | `src/Profile.tsx` | Save a name; save a long one (the backend's `Err`); sign out and save |
|
|
20
|
+
| 7 | Optimistic add and remove that keep the client's `onMutate` and `onSettled`, rolled back on `canister_err` or a failure; the list is a certified read, since a contact decides where a payment goes | `src/optimistic-contacts.ts`, `src/AddressBook.tsx`, `src/use-canisters.ts` | Add a contact; add the same name in another case (`DuplicateName`: shown, then rolled back) |
|
|
21
|
+
| 8 | Paying a contact: which reads the write changes (the ledger's, not the backend's) | `src/SendToContact.tsx` | "Pay": your balance and the contact's both change |
|
|
22
|
+
| 9 | A production build of the same code | `vite.config.ts` | `pnpm build && pnpm preview`, http://localhost:5185 |
|
|
23
|
+
| 10 | The production build on an asset canister: a Content-Security-Policy that runs the app's own files only, a `Cross-Origin-Opener-Policy` that keeps the II window, the `hardened` headers, and the raw host redirected | `public/.ic-assets.json5`, `icp.yaml` | `pnpm icp:deploy`, then http://frontend.local.localhost:8000 (and `curl -sI` on it) |
|
|
24
|
+
|
|
25
|
+
The unknown outcome of scenario 5 and the trap of scenario 7 need a fault a
|
|
26
|
+
local network does not make on demand: the tests inject them.
|
|
27
|
+
|
|
28
|
+
## Run it
|
|
29
|
+
|
|
30
|
+
You need Node 22.18 or later, and for the backend the Rust toolchain with the
|
|
31
|
+
`wasm32-unknown-unknown` target and `ic-wasm` on your PATH (what icp-cli's
|
|
32
|
+
Rust recipe calls). icp-cli 1.2.0 itself is a devDependency of this example.
|
|
33
|
+
From the repository root, `pnpm install` and `pnpm build`, then:
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
cd examples/vite-wallet
|
|
37
|
+
pnpm icp:start # local network on port 8000, with II and the NNS
|
|
38
|
+
pnpm icp:deploy # builds and deploys the backend and the app
|
|
39
|
+
pnpm faucet <principal> [amount] # sends local ICP (10 by default) to a principal
|
|
40
|
+
pnpm dev # http://localhost:5175
|
|
41
|
+
pnpm icp:stop # when you are done
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Open http://localhost:5175, sign in with a dev account, and copy the
|
|
45
|
+
`pnpm faucet ...` line the Balance panel shows into a terminal. The faucet
|
|
46
|
+
sends from icp-cli's anonymous identity, which every local network funds.
|
|
47
|
+
Dev accounts live in the tab's sessionStorage: a reload keeps them, a new tab
|
|
48
|
+
starts with none. The balance is read again every 3 s while the tab is
|
|
49
|
+
visible (TanStack Query pauses `refetchInterval` in a hidden tab, and reads
|
|
50
|
+
again when it is shown).
|
|
51
|
+
|
|
52
|
+
`pnpm icp:deploy` also builds the app and serves it from an asset canister
|
|
53
|
+
at http://frontend.local.localhost:8000, with the response headers of
|
|
54
|
+
`public/.ic-assets.json5` (scenario 10); the docs guide "Deploy to a
|
|
55
|
+
frontend canister" says what each one does. Sign in there with a dev
|
|
56
|
+
account: the asset canister's `ic_env` cookie names no Internet Identity, so
|
|
57
|
+
the II button opens mainnet's, not the local one.
|
|
58
|
+
|
|
59
|
+
"Sign in with Internet Identity" opens the local II in a new window. It is a
|
|
60
|
+
test build that makes no passkey: choose Create, then "Create with passkey",
|
|
61
|
+
name the identity, and answer its "Enter seed index" prompt with a number.
|
|
62
|
+
Continue returns you to the wallet, signed in, and the session survives a
|
|
63
|
+
reload. Next time, Continue as the identity it remembers and give the same
|
|
64
|
+
number: the principal is the same.
|
|
65
|
+
|
|
66
|
+
## Test it
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
pnpm test # every scenario, on createTestClient(): no replica, no network
|
|
70
|
+
pnpm typecheck
|
|
71
|
+
pnpm build
|
|
72
|
+
pnpm gen:check # fails if src/canisters/ is stale
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The tests run a real client over the in-memory replica of
|
|
76
|
+
`@ic-reactor/core/testing`, with the ledger and the backend mocked per caller
|
|
77
|
+
(`src/test/test-wallet.tsx`), in jsdom, whose page carries an `ic_env` cookie
|
|
78
|
+
like the plugin's. `src/canisters/` is generated from `backend/backend.did` and
|
|
79
|
+
`ledger.did` by `@ic-reactor/vite-plugin` on every `vite dev` and `vite build`
|
|
80
|
+
(`pnpm gen` runs `meant gen` by hand), committed, and never edited. `ledger.did`
|
|
81
|
+
is the projection of the mainnet ICP ledger's interface to the five methods the
|
|
82
|
+
wallet calls (the ledger entry's `methods` in `vite.config.ts`), as the plugin
|
|
83
|
+
wrote it from the live canister. It is committed, so builds read it and make no
|
|
84
|
+
request. `IC_REACTOR_FETCH=ledger` writes it again from the canister, and
|
|
85
|
+
`IC_REACTOR_VERIFY=ledger pnpm build` checks it against the live ledger.
|
|
86
|
+
|
|
87
|
+
## The env network in production
|
|
88
|
+
|
|
89
|
+
`vite build` writes static files, and the code does not change for a deployed
|
|
90
|
+
page: with `network: "env"` it calls its own origin's `/api`, which an asset
|
|
91
|
+
canister's domain (`<id>.icp0.io`) serves as the dev server's proxy does
|
|
92
|
+
locally. What changes is the cookie. An asset canister sets an `ic_env`
|
|
93
|
+
cookie too. On `<id>.icp0.io`, a public suffix no other canister can set a
|
|
94
|
+
cookie for, ic-reactor believes its canister ids (never its root key); on
|
|
95
|
+
`<id>.ic0.app` and a custom domain it does not, because a sibling subdomain
|
|
96
|
+
can write a cookie there, so `{ name: "backend" }` stays unresolved and its
|
|
97
|
+
calls are refused before sending (`invalid_args`, code
|
|
98
|
+
`canister_id_unresolved`). For a build that works on every domain, give it
|
|
99
|
+
the id instead, as
|
|
100
|
+
`{ id: import.meta.env.VITE_BACKEND_ID }`. `allowEnvConfig: true` is safe only
|
|
101
|
+
on `<id>.icp0.io`, a public suffix, or a custom domain whose every subdomain is
|
|
102
|
+
yours; on `ic0.app` `createClient` refuses it, because any other canister's
|
|
103
|
+
page can set the cookie there. Even with it, the cookie's root key is not
|
|
104
|
+
used on mainnet. The root key
|
|
105
|
+
there is mainnet's, built into the agent; nothing is fetched. Internet
|
|
106
|
+
Identity is mainnet's (the `AuthClient` defaults), and the dev account is not
|
|
107
|
+
offered.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// The wallet's own canister: per caller, a profile name and an address book.
|
|
2
|
+
// Every method reads or writes the caller's own entry. The anonymous
|
|
3
|
+
// principal has none, and every write it sends is refused.
|
|
4
|
+
|
|
5
|
+
type Contact = record {
|
|
6
|
+
name : text;
|
|
7
|
+
owner : principal;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
type Profile = record {
|
|
11
|
+
name : text;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
// Why a write was refused. ic-reactor rejects such a reply as a
|
|
15
|
+
// `canister_err`, with this value in its `err`.
|
|
16
|
+
type Refusal = variant {
|
|
17
|
+
// The caller is the anonymous principal.
|
|
18
|
+
Anonymous;
|
|
19
|
+
// The name is empty, longer than 32 characters, or has a control character.
|
|
20
|
+
InvalidName : text;
|
|
21
|
+
// The address book already has a contact of this name.
|
|
22
|
+
DuplicateName : text;
|
|
23
|
+
// The address book has no contact of this name.
|
|
24
|
+
NotFound : text;
|
|
25
|
+
// The address book holds at most this many contacts.
|
|
26
|
+
Full : nat32;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
service : {
|
|
30
|
+
// The caller's profile, or null before their first set_name.
|
|
31
|
+
get_profile : () -> (opt Profile) query;
|
|
32
|
+
set_name : (text) -> (variant { Ok : Profile; Err : Refusal });
|
|
33
|
+
// The caller's contacts, in the order they were added.
|
|
34
|
+
contacts : () -> (vec Contact) query;
|
|
35
|
+
add_contact : (Contact) -> (variant { Ok; Err : Refusal });
|
|
36
|
+
remove_contact : (text) -> (variant { Ok; Err : Refusal });
|
|
37
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
//! The wallet's backend: per caller, a profile name and an address book.
|
|
2
|
+
//!
|
|
3
|
+
//! The interface is written out by hand in `backend.did`, which the build
|
|
4
|
+
//! embeds as the `candid:service` metadata and the app generates its module
|
|
5
|
+
//! from, so a method added here must be added there too.
|
|
6
|
+
//!
|
|
7
|
+
//! State lives on the heap and starts over on an upgrade: enough for a local
|
|
8
|
+
//! demo, not for a canister that keeps users' data.
|
|
9
|
+
|
|
10
|
+
use std::cell::RefCell;
|
|
11
|
+
use std::collections::BTreeMap;
|
|
12
|
+
|
|
13
|
+
use candid::{CandidType, Deserialize, Principal};
|
|
14
|
+
|
|
15
|
+
#[derive(CandidType, Deserialize, Clone)]
|
|
16
|
+
struct Contact {
|
|
17
|
+
name: String,
|
|
18
|
+
owner: Principal,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
#[derive(CandidType, Deserialize, Clone)]
|
|
22
|
+
struct Profile {
|
|
23
|
+
name: String,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/// Why a write was refused: the `Err` arm of every write's result.
|
|
27
|
+
#[derive(CandidType, Deserialize)]
|
|
28
|
+
enum Refusal {
|
|
29
|
+
Anonymous,
|
|
30
|
+
InvalidName(String),
|
|
31
|
+
DuplicateName(String),
|
|
32
|
+
NotFound(String),
|
|
33
|
+
Full(u32),
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
#[derive(Default)]
|
|
37
|
+
struct Entry {
|
|
38
|
+
profile: Option<Profile>,
|
|
39
|
+
contacts: Vec<Contact>,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const MAX_NAME_CHARS: usize = 32;
|
|
43
|
+
const MAX_CONTACTS: u32 = 20;
|
|
44
|
+
|
|
45
|
+
thread_local! {
|
|
46
|
+
static ENTRIES: RefCell<BTreeMap<Principal, Entry>> = RefCell::default();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/// The caller, unless it is the anonymous principal, which owns nothing here.
|
|
50
|
+
fn signed_caller() -> Result<Principal, Refusal> {
|
|
51
|
+
let caller = ic_cdk::api::msg_caller();
|
|
52
|
+
if caller == Principal::anonymous() {
|
|
53
|
+
Err(Refusal::Anonymous)
|
|
54
|
+
} else {
|
|
55
|
+
Ok(caller)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/// `name` without surrounding spaces, or why it is refused.
|
|
60
|
+
fn checked_name(name: &str) -> Result<String, Refusal> {
|
|
61
|
+
let name = name.trim();
|
|
62
|
+
let length = name.chars().count();
|
|
63
|
+
if length == 0 || length > MAX_NAME_CHARS || name.chars().any(char::is_control) {
|
|
64
|
+
return Err(Refusal::InvalidName(format!(
|
|
65
|
+
"a name is 1 to {MAX_NAME_CHARS} characters, with no control characters"
|
|
66
|
+
)));
|
|
67
|
+
}
|
|
68
|
+
Ok(name.to_string())
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
#[ic_cdk::query]
|
|
72
|
+
fn get_profile() -> Option<Profile> {
|
|
73
|
+
let caller = ic_cdk::api::msg_caller();
|
|
74
|
+
ENTRIES.with_borrow(|entries| entries.get(&caller)?.profile.clone())
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
#[ic_cdk::update]
|
|
78
|
+
fn set_name(name: String) -> Result<Profile, Refusal> {
|
|
79
|
+
let caller = signed_caller()?;
|
|
80
|
+
let profile = Profile {
|
|
81
|
+
name: checked_name(&name)?,
|
|
82
|
+
};
|
|
83
|
+
ENTRIES.with_borrow_mut(|entries| {
|
|
84
|
+
entries.entry(caller).or_default().profile = Some(profile.clone());
|
|
85
|
+
});
|
|
86
|
+
Ok(profile)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
#[ic_cdk::query]
|
|
90
|
+
fn contacts() -> Vec<Contact> {
|
|
91
|
+
let caller = ic_cdk::api::msg_caller();
|
|
92
|
+
ENTRIES.with_borrow(|entries| {
|
|
93
|
+
entries
|
|
94
|
+
.get(&caller)
|
|
95
|
+
.map(|entry| entry.contacts.clone())
|
|
96
|
+
.unwrap_or_default()
|
|
97
|
+
})
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
#[ic_cdk::update]
|
|
101
|
+
fn add_contact(contact: Contact) -> Result<(), Refusal> {
|
|
102
|
+
let caller = signed_caller()?;
|
|
103
|
+
let name = checked_name(&contact.name)?;
|
|
104
|
+
ENTRIES.with_borrow_mut(|entries| {
|
|
105
|
+
let book = &mut entries.entry(caller).or_default().contacts;
|
|
106
|
+
if book.iter().any(|c| c.name.to_lowercase() == name.to_lowercase()) {
|
|
107
|
+
return Err(Refusal::DuplicateName(name));
|
|
108
|
+
}
|
|
109
|
+
if book.len() >= MAX_CONTACTS as usize {
|
|
110
|
+
return Err(Refusal::Full(MAX_CONTACTS));
|
|
111
|
+
}
|
|
112
|
+
book.push(Contact {
|
|
113
|
+
name,
|
|
114
|
+
owner: contact.owner,
|
|
115
|
+
});
|
|
116
|
+
Ok(())
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
#[ic_cdk::update]
|
|
121
|
+
fn remove_contact(name: String) -> Result<(), Refusal> {
|
|
122
|
+
let caller = signed_caller()?;
|
|
123
|
+
ENTRIES.with_borrow_mut(|entries| {
|
|
124
|
+
let book = &mut entries.entry(caller).or_default().contacts;
|
|
125
|
+
let before = book.len();
|
|
126
|
+
book.retain(|c| c.name != name);
|
|
127
|
+
if book.len() == before {
|
|
128
|
+
Err(Refusal::NotFound(name))
|
|
129
|
+
} else {
|
|
130
|
+
Ok(())
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# yaml-language-server: $schema=https://raw.githubusercontent.com/dfinity/icp-cli/refs/tags/v1.2.0/docs/schemas/icp-yaml-schema.json
|
|
2
|
+
|
|
3
|
+
# The wallet's local canisters, for the icp-cli 1.2.0 this example installs
|
|
4
|
+
# (`pnpm icp:start`, `pnpm icp:deploy`, `pnpm icp:stop`).
|
|
5
|
+
|
|
6
|
+
canisters:
|
|
7
|
+
# The app's own canister. A project canister, so `icp deploy` gives it an
|
|
8
|
+
# id and @ic-reactor/vite-plugin puts that id in the ic_env cookie as
|
|
9
|
+
# PUBLIC_CANISTER_ID:backend: the app calls it as { name: "backend" }.
|
|
10
|
+
- name: backend
|
|
11
|
+
recipe:
|
|
12
|
+
type: "@dfinity/rust@v3.2.0"
|
|
13
|
+
configuration:
|
|
14
|
+
package: backend
|
|
15
|
+
candid: backend/backend.did
|
|
16
|
+
locked: true
|
|
17
|
+
|
|
18
|
+
# The app itself, built by Vite and served by an asset canister with the
|
|
19
|
+
# headers of public/.ic-assets.json5, at http://frontend.local.localhost:8000.
|
|
20
|
+
# Its ic_env cookie names the backend, as the Vite plugin's does in dev.
|
|
21
|
+
- name: frontend
|
|
22
|
+
recipe:
|
|
23
|
+
type: "@dfinity/asset-canister@v2.3.0"
|
|
24
|
+
configuration:
|
|
25
|
+
version: 0.30.2
|
|
26
|
+
build:
|
|
27
|
+
- pnpm run build
|
|
28
|
+
dir: dist
|
|
29
|
+
|
|
30
|
+
networks:
|
|
31
|
+
# The implicit `local` network, with its network launcher pinned like
|
|
32
|
+
# e2e/icp.yaml's: left at "latest", `icp network start` asks the GitHub API
|
|
33
|
+
# which release that is, unauthenticated, and fails with "403 rate limit
|
|
34
|
+
# exceeded" when many starts share an address. An exact version is
|
|
35
|
+
# downloaded straight from its release.
|
|
36
|
+
- name: local
|
|
37
|
+
mode: managed
|
|
38
|
+
version: v16.0.0-2026-09-18-03-28
|
|
39
|
+
# Internet Identity, at http://id.ai.localhost:8000, for the
|
|
40
|
+
# "Internet Identity" sign-in.
|
|
41
|
+
ii: true
|
|
42
|
+
# The NNS, whose ICP ledger (ryjl3-tyaaa-aaaaa-aaaba-cai, the same id as
|
|
43
|
+
# on mainnet) holds the wallet's balances.
|
|
44
|
+
nns: true
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<meta name="color-scheme" content="light dark" />
|
|
7
|
+
<title>ICP wallet on ic-reactor 4</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="root"></div>
|
|
11
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Subaccount is an arbitrary 32-byte byte array.
|
|
2
|
+
// Ledger uses subaccounts to compute the source address, which enables one
|
|
3
|
+
// principal to control multiple ledger accounts.
|
|
4
|
+
type SubAccount = blob;
|
|
5
|
+
type Icrc1BlockIndex = nat;
|
|
6
|
+
// Number of nanoseconds since the UNIX epoch in UTC timezone.
|
|
7
|
+
type Icrc1Timestamp = nat64;
|
|
8
|
+
type Icrc1Tokens = nat;
|
|
9
|
+
type Account = record {
|
|
10
|
+
owner : principal;
|
|
11
|
+
subaccount : opt SubAccount;
|
|
12
|
+
};
|
|
13
|
+
type TransferArg = record {
|
|
14
|
+
to : Account;
|
|
15
|
+
fee : opt Icrc1Tokens;
|
|
16
|
+
memo : opt blob;
|
|
17
|
+
from_subaccount : opt SubAccount;
|
|
18
|
+
created_at_time : opt Icrc1Timestamp;
|
|
19
|
+
amount : Icrc1Tokens;
|
|
20
|
+
};
|
|
21
|
+
type Icrc1TransferError = variant {
|
|
22
|
+
GenericError : record {
|
|
23
|
+
message : text;
|
|
24
|
+
error_code : nat;
|
|
25
|
+
};
|
|
26
|
+
TemporarilyUnavailable;
|
|
27
|
+
BadBurn : record {
|
|
28
|
+
min_burn_amount : Icrc1Tokens;
|
|
29
|
+
};
|
|
30
|
+
Duplicate : record {
|
|
31
|
+
duplicate_of : Icrc1BlockIndex;
|
|
32
|
+
};
|
|
33
|
+
BadFee : record {
|
|
34
|
+
expected_fee : Icrc1Tokens;
|
|
35
|
+
};
|
|
36
|
+
CreatedInFuture : record {
|
|
37
|
+
ledger_time : nat64;
|
|
38
|
+
};
|
|
39
|
+
TooOld;
|
|
40
|
+
InsufficientFunds : record {
|
|
41
|
+
balance : Icrc1Tokens;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
type Icrc1TransferResult = variant {
|
|
45
|
+
Ok : Icrc1BlockIndex;
|
|
46
|
+
Err : Icrc1TransferError;
|
|
47
|
+
};
|
|
48
|
+
service : {
|
|
49
|
+
icrc1_balance_of : (Account) -> (Icrc1Tokens) query;
|
|
50
|
+
icrc1_decimals : () -> (nat8) query;
|
|
51
|
+
icrc1_fee : () -> (Icrc1Tokens) query;
|
|
52
|
+
icrc1_symbol : () -> (text) query;
|
|
53
|
+
icrc1_transfer : (TransferArg) -> (Icrc1TransferResult);
|
|
54
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vite-wallet",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "tsc --noEmit && vite build",
|
|
9
|
+
"preview": "vite preview",
|
|
10
|
+
"typecheck": "tsc --noEmit",
|
|
11
|
+
"test": "vitest run",
|
|
12
|
+
"gen": "meant gen backend/backend.did ledger.did -o src/canisters",
|
|
13
|
+
"gen:check": "meant gen backend/backend.did ledger.did -o src/canisters --check",
|
|
14
|
+
"icp:start": "icp network start -d",
|
|
15
|
+
"icp:deploy": "icp deploy",
|
|
16
|
+
"icp:status": "icp network status",
|
|
17
|
+
"icp:stop": "icp network stop",
|
|
18
|
+
"faucet": "node scripts/faucet.ts"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@meantjs/schema": "0.6.0",
|
|
22
|
+
"@ic-reactor/core": "^4.1.1",
|
|
23
|
+
"@ic-reactor/react": "^4.1.1",
|
|
24
|
+
"@icp-sdk/auth": "^10.0.1",
|
|
25
|
+
"@icp-sdk/core": "^6.1.0",
|
|
26
|
+
"@tanstack/react-query": "^5.102.8",
|
|
27
|
+
"react": "^19.3.0",
|
|
28
|
+
"react-dom": "^19.3.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@meantjs/cli": "0.5.1",
|
|
32
|
+
"@ic-reactor/vite-plugin": "^4.1.1",
|
|
33
|
+
"@icp-sdk/icp-cli": "1.2.0",
|
|
34
|
+
"@noble/curves": "^2.2.0",
|
|
35
|
+
"@testing-library/dom": "^10.4.1",
|
|
36
|
+
"@testing-library/react": "^16.3.3",
|
|
37
|
+
"@types/node": "^26.5.1",
|
|
38
|
+
"@types/react": "^19.3.0",
|
|
39
|
+
"@types/react-dom": "^19.3.0",
|
|
40
|
+
"@vitejs/plugin-react": "^6.1.1",
|
|
41
|
+
"jsdom": "30.0.1",
|
|
42
|
+
"typescript": "^6.0.3",
|
|
43
|
+
"vite": "^8.3.4",
|
|
44
|
+
"vitest": "^5.0.0"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// The response headers of every file the frontend canister serves. Vite
|
|
2
|
+
// copies public/ into dist/, `icp deploy frontend` uploads dist/, and the
|
|
3
|
+
// asset canister reads this file from there. The docs guide "Deploy to a
|
|
4
|
+
// frontend canister" explains each line, and e2e/ checks what is served.
|
|
5
|
+
[
|
|
6
|
+
{
|
|
7
|
+
match: "**/*",
|
|
8
|
+
// The asset canister's own security headers: Strict-Transport-Security,
|
|
9
|
+
// X-Frame-Options, X-Content-Type-Options, Referrer-Policy and a
|
|
10
|
+
// Permissions-Policy that turns off every feature it lists. "hardened"
|
|
11
|
+
// says that the headers below replace its Content-Security-Policy.
|
|
12
|
+
security_policy: "hardened",
|
|
13
|
+
headers: {
|
|
14
|
+
// The app's own scripts, styles, fonts and images only; calls to the
|
|
15
|
+
// page's origin ("env") and to icp-api.io ("ic"); no frame, plugin,
|
|
16
|
+
// <base> or form submission; and never framed itself.
|
|
17
|
+
"Content-Security-Policy": "default-src 'none'; script-src 'self'; connect-src 'self' https://icp-api.io; img-src 'self' data:; style-src 'self'; font-src 'self'; frame-ancestors 'none'; base-uri 'none'; form-action 'none'",
|
|
18
|
+
// Not "same-origin": the Internet Identity window answers the page
|
|
19
|
+
// that opened it.
|
|
20
|
+
"Cross-Origin-Opener-Policy": "same-origin-allow-popups",
|
|
21
|
+
},
|
|
22
|
+
// <id>.raw.icp0.io serves pages no gateway checks: send them to
|
|
23
|
+
// <id>.icp0.io instead.
|
|
24
|
+
allow_raw_access: false,
|
|
25
|
+
},
|
|
26
|
+
]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// What `pnpm faucet` accepts before it moves any ICP.
|
|
2
|
+
import { describe, expect, it } from "vitest"
|
|
3
|
+
import { readFaucetArgs } from "./faucet-args.ts"
|
|
4
|
+
|
|
5
|
+
const ME = "psith-oknjz-x73tv-7x3p4-a2sji-7o6lo-g2754-yfgfl-3vlqe-irrrt-4ae"
|
|
6
|
+
|
|
7
|
+
describe("the faucet's arguments", () => {
|
|
8
|
+
it("sends 10 ICP unless told how much", () => {
|
|
9
|
+
expect(readFaucetArgs([ME])).toEqual({ ok: true, to: ME, amount: "10" })
|
|
10
|
+
expect(readFaucetArgs([ME, "0.5"])).toEqual({
|
|
11
|
+
ok: true,
|
|
12
|
+
to: ME,
|
|
13
|
+
amount: "0.5",
|
|
14
|
+
})
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
it.each([
|
|
18
|
+
[[], "Usage: pnpm faucet <principal> [amount in ICP]"],
|
|
19
|
+
[[ME, "1", "2"], "Usage: pnpm faucet <principal> [amount in ICP]"],
|
|
20
|
+
[["me"], "Not a principal: me"],
|
|
21
|
+
[[ME, "1e3"], "Not an ICP amount: 1e3 (plain digits, at most 8 decimals)"],
|
|
22
|
+
[
|
|
23
|
+
[ME, "0.000000001"],
|
|
24
|
+
"Not an ICP amount: 0.000000001 (plain digits, at most 8 decimals)",
|
|
25
|
+
],
|
|
26
|
+
[[ME, "0"], "Send more than zero."],
|
|
27
|
+
])("refuses %j", (args, reason) => {
|
|
28
|
+
expect(readFaucetArgs(args)).toEqual({ ok: false, reason })
|
|
29
|
+
})
|
|
30
|
+
})
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// What `pnpm faucet <principal> [amount]` was asked for, checked before any
|
|
2
|
+
// ICP moves: a principal made with `principal()` (never cast), and an amount
|
|
3
|
+
// read with `parseUnits` (no exponent, no grouping, at most 8 decimals).
|
|
4
|
+
import { principal, type Principal } from "@meantjs/schema"
|
|
5
|
+
import { parseUnits } from "@ic-reactor/core"
|
|
6
|
+
|
|
7
|
+
/** ICP's decimals, which `icp token transfer` amounts are written in. */
|
|
8
|
+
const ICP_DECIMALS = 8
|
|
9
|
+
|
|
10
|
+
export const DEFAULT_AMOUNT = "10"
|
|
11
|
+
|
|
12
|
+
export type FaucetRequest =
|
|
13
|
+
| { readonly ok: true; readonly to: Principal; readonly amount: string }
|
|
14
|
+
| { readonly ok: false; readonly reason: string }
|
|
15
|
+
|
|
16
|
+
export function readFaucetArgs(args: readonly string[]): FaucetRequest {
|
|
17
|
+
const [to, amount = DEFAULT_AMOUNT, ...rest] = args
|
|
18
|
+
if (to === undefined || rest.length > 0) {
|
|
19
|
+
return {
|
|
20
|
+
ok: false,
|
|
21
|
+
reason: "Usage: pnpm faucet <principal> [amount in ICP]",
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
let receiver: Principal
|
|
25
|
+
try {
|
|
26
|
+
receiver = principal(to)
|
|
27
|
+
} catch {
|
|
28
|
+
return { ok: false, reason: `Not a principal: ${to}` }
|
|
29
|
+
}
|
|
30
|
+
let units: bigint
|
|
31
|
+
try {
|
|
32
|
+
units = parseUnits(amount, ICP_DECIMALS)
|
|
33
|
+
} catch {
|
|
34
|
+
return {
|
|
35
|
+
ok: false,
|
|
36
|
+
reason: `Not an ICP amount: ${amount} (plain digits, at most ${ICP_DECIMALS} decimals)`,
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (units === 0n) return { ok: false, reason: "Send more than zero." }
|
|
40
|
+
return { ok: true, to: receiver, amount }
|
|
41
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// `pnpm faucet <principal> [amount]`: sends local ICP (10 unless told) to a
|
|
2
|
+
// principal, such as a dev account the wallet shows, so it has something to
|
|
3
|
+
// send. Run it from this directory, with the local network up
|
|
4
|
+
// (`pnpm icp:start`).
|
|
5
|
+
//
|
|
6
|
+
// It runs `icp token transfer` as icp-cli's anonymous identity, the default
|
|
7
|
+
// identity of a fresh icp-cli, which every local network funds with ICP when
|
|
8
|
+
// it starts; whatever identity is your default, it is left alone. The icp-cli
|
|
9
|
+
// of this example's devDependencies (1.2.0) runs it, not one on your PATH.
|
|
10
|
+
import { execFileSync } from "node:child_process"
|
|
11
|
+
import { createRequire } from "node:module"
|
|
12
|
+
import { readFaucetArgs } from "./faucet-args.ts"
|
|
13
|
+
|
|
14
|
+
const request = readFaucetArgs(process.argv.slice(2))
|
|
15
|
+
if (!request.ok) {
|
|
16
|
+
console.error(request.reason)
|
|
17
|
+
process.exit(1)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const icp = createRequire(import.meta.url).resolve(
|
|
21
|
+
"@icp-sdk/icp-cli/bin/icp.js"
|
|
22
|
+
)
|
|
23
|
+
const args = [
|
|
24
|
+
"token",
|
|
25
|
+
"transfer",
|
|
26
|
+
request.amount,
|
|
27
|
+
request.to,
|
|
28
|
+
"--identity",
|
|
29
|
+
"anonymous",
|
|
30
|
+
"--environment",
|
|
31
|
+
"local",
|
|
32
|
+
]
|
|
33
|
+
console.log(`icp ${args.join(" ")}`)
|
|
34
|
+
try {
|
|
35
|
+
execFileSync(process.execPath, [icp, ...args], { stdio: "inherit" })
|
|
36
|
+
} catch {
|
|
37
|
+
console.error(
|
|
38
|
+
"The transfer failed. Is the local network running (pnpm icp:start)?"
|
|
39
|
+
)
|
|
40
|
+
process.exit(1)
|
|
41
|
+
}
|