@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.
Files changed (1041) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.yml +108 -0
  2. package/.github/ISSUE_TEMPLATE/config.yml +8 -0
  3. package/.github/ISSUE_TEMPLATE/feature_request.yml +77 -0
  4. package/.github/actions/setup-rust-wasm/action.yml +25 -0
  5. package/.github/dependabot.yml +107 -0
  6. package/.github/workflows/auth-latest.yml +67 -0
  7. package/.github/workflows/b3pay-site.yml +49 -0
  8. package/.github/workflows/ci.yml +430 -0
  9. package/.github/workflows/codeql.yml +41 -0
  10. package/.github/workflows/dependency-review.yml +68 -0
  11. package/.github/workflows/docs-check.yml +98 -0
  12. package/.github/workflows/docs.yml +265 -0
  13. package/.github/workflows/e2e.yml +90 -0
  14. package/.github/workflows/examples-published.yml +97 -0
  15. package/.github/workflows/release.yml +326 -0
  16. package/.husky/pre-commit +12 -0
  17. package/.prettierignore +109 -0
  18. package/.prettierrc +6 -0
  19. package/AGENTS.md +103 -0
  20. package/CHANGELOG.md +3268 -0
  21. package/CLAUDE.md +93 -0
  22. package/CNAME +1 -0
  23. package/CODE_OF_CONDUCT.md +7 -0
  24. package/CONTRIBUTING.md +433 -0
  25. package/LICENSE +21 -0
  26. package/README.md +2 -2
  27. package/SECURITY.md +74 -0
  28. package/b3pay-module.json +194 -0
  29. package/docs/.remarkrc.json +10 -0
  30. package/docs/README.md +64 -0
  31. package/docs/astro.config.mjs +205 -0
  32. package/docs/favicon.svg +15 -0
  33. package/docs/package.json +39 -0
  34. package/docs/public/favicon.svg +15 -0
  35. package/docs/public/ic-reactor-social-card.png +0 -0
  36. package/docs/scripts/b3pay-static.mjs +22 -0
  37. package/docs/scripts/check-example-docs.mjs +214 -0
  38. package/docs/scripts/check-links.mjs +212 -0
  39. package/docs/scripts/fix-dist-links.js +125 -0
  40. package/docs/scripts/fix-frontmatter.js +71 -0
  41. package/docs/scripts/remove-redundant-h1.cjs +48 -0
  42. package/docs/scripts/rewrite-typedoc-links.js +110 -0
  43. package/docs/scripts/split-index.js +69 -0
  44. package/docs/src/assets/ic-reactor-hero-dark.svg +23 -0
  45. package/docs/src/assets/ic-reactor-hero-light.svg +23 -0
  46. package/docs/src/assets/ic-reactor-lockup-dark.svg +15 -0
  47. package/docs/src/assets/ic-reactor-lockup-light.svg +15 -0
  48. package/docs/src/assets/ic-reactor-mark-dark.svg +14 -0
  49. package/docs/src/assets/ic-reactor-mark-light.svg +14 -0
  50. package/docs/src/assets/layers/candid-core-layer-icon-dark.svg +4 -0
  51. package/docs/src/assets/layers/candid-core-layer-icon-light.svg +4 -0
  52. package/docs/src/assets/layers/candid-profile-layer-icon-dark.svg +4 -0
  53. package/docs/src/assets/layers/candid-profile-layer-icon-light.svg +4 -0
  54. package/docs/src/assets/layers/ic-reactor-layer-icon-dark.svg +4 -0
  55. package/docs/src/assets/layers/ic-reactor-layer-icon-light.svg +4 -0
  56. package/docs/src/components/LibraryCards.astro +172 -0
  57. package/docs/src/components/LibraryIcon.astro +28 -0
  58. package/docs/src/components/SiteTitle.astro +241 -0
  59. package/docs/src/content/docs/404.mdx +19 -0
  60. package/docs/src/content/docs/build/agent-tools.mdx +593 -0
  61. package/docs/src/content/docs/build/icrc1-wallet.mdx +619 -0
  62. package/docs/src/content/docs/build/ssr-per-user.mdx +552 -0
  63. package/docs/src/content/docs/examples/canister-studio.mdx +95 -0
  64. package/docs/src/content/docs/examples/icrc-ledger.mdx +45 -0
  65. package/docs/src/content/docs/examples/index.mdx +38 -0
  66. package/docs/src/content/docs/examples/next-ssr.mdx +73 -0
  67. package/docs/src/content/docs/examples/node-agent-tool.mdx +80 -0
  68. package/docs/src/content/docs/examples/vite-wallet.mdx +71 -0
  69. package/docs/src/content/docs/guides/auth.mdx +1181 -0
  70. package/docs/src/content/docs/guides/client.mdx +551 -0
  71. package/docs/src/content/docs/guides/deploy.mdx +180 -0
  72. package/docs/src/content/docs/guides/errors.mdx +475 -0
  73. package/docs/src/content/docs/guides/getting-started.mdx +620 -0
  74. package/docs/src/content/docs/guides/reads.mdx +586 -0
  75. package/docs/src/content/docs/guides/ssr.mdx +529 -0
  76. package/docs/src/content/docs/guides/testing.mdx +401 -0
  77. package/docs/src/content/docs/guides/values.mdx +261 -0
  78. package/docs/src/content/docs/guides/vite-plugin.mdx +690 -0
  79. package/docs/src/content/docs/guides/writes.mdx +572 -0
  80. package/docs/src/content/docs/ic-reactor/index.mdx +167 -0
  81. package/docs/src/content/docs/index.mdx +65 -0
  82. package/docs/src/content/docs/migrating-from-3.mdx +535 -0
  83. package/docs/src/content/docs/packages/core.mdx +186 -0
  84. package/docs/src/content/docs/packages/mcp.mdx +163 -0
  85. package/docs/src/content/docs/packages/react.mdx +207 -0
  86. package/docs/src/content/docs/packages/vite-plugin.mdx +73 -0
  87. package/docs/src/content/docs/versioning.mdx +104 -0
  88. package/docs/src/content.config.ts +7 -0
  89. package/docs/src/styles/custom.css +189 -0
  90. package/docs/tsconfig.typedoc.json +26 -0
  91. package/docs/typedoc-entry.ts +17 -0
  92. package/docs/typedoc.json +37 -0
  93. package/e2e/Cargo.lock +646 -0
  94. package/e2e/Cargo.toml +3 -0
  95. package/e2e/README.md +101 -0
  96. package/e2e/frontends/build.mjs +94 -0
  97. package/e2e/frontends/index.html +10 -0
  98. package/e2e/global-setup.ts +65 -0
  99. package/e2e/icp.yaml +38 -0
  100. package/e2e/package.json +40 -0
  101. package/e2e/setup.ts +6 -0
  102. package/e2e/src/actor/Cargo.toml +14 -0
  103. package/e2e/src/actor/hello_actor.did +10 -0
  104. package/e2e/src/actor/src/lib.rs +73 -0
  105. package/e2e/src/calls.test.ts +132 -0
  106. package/e2e/src/declarations/hello_actor.envelope.json +175 -0
  107. package/e2e/src/declarations/hello_actor.ts +15 -0
  108. package/e2e/src/errors.test.ts +107 -0
  109. package/e2e/src/frontend-headers.test.ts +253 -0
  110. package/e2e/src/identity.test.ts +61 -0
  111. package/e2e/src/react.test.tsx +59 -0
  112. package/e2e/src/replica.ts +70 -0
  113. package/e2e/src/vite-env.test.ts +108 -0
  114. package/e2e/test.sh +47 -0
  115. package/e2e/tsconfig.json +20 -0
  116. package/e2e/tsconfig.typecheck.json +9 -0
  117. package/e2e/vitest.config.ts +22 -0
  118. package/eslint.config.mjs +100 -0
  119. package/evals/PREREGISTRATION.md +1346 -0
  120. package/evals/README.md +756 -0
  121. package/evals/conditions/thin/condition.json +8 -0
  122. package/evals/conditions/thin/docs/candid-core-cli.README.md +90 -0
  123. package/evals/conditions/thin/docs/candid-core-schema.README.md +339 -0
  124. package/evals/conditions/thin/package.json +25 -0
  125. package/evals/conditions/thin/starter/src/generated/icrc1.ts +57 -0
  126. package/evals/conditions/thin-guide/condition.json +10 -0
  127. package/evals/conditions/thin-guide/docs/llms.txt +292 -0
  128. package/evals/conditions/v3/condition.json +9 -0
  129. package/evals/conditions/v3/docs/ic-reactor-core.llms.txt +232 -0
  130. package/evals/conditions/v3/docs/ic-reactor-react.llms.txt +280 -0
  131. package/evals/conditions/v3/docs/llms-full.txt +1053 -0
  132. package/evals/conditions/v3/package.json +26 -0
  133. package/evals/conditions/v3/starter/src/declarations/icrc1.did.d.ts +95 -0
  134. package/evals/conditions/v3/starter/src/declarations/icrc1.did.js +140 -0
  135. package/evals/conditions/v4/PORTING.md +384 -0
  136. package/evals/conditions/v4/README.md +106 -0
  137. package/evals/conditions/v4/condition.json +5 -0
  138. package/evals/conditions/v4/docs/llms.txt +323 -0
  139. package/evals/conditions/v4/package.json +27 -0
  140. package/evals/conditions/v4/starter/src/generated/icrc1.ts +78 -0
  141. package/evals/conditions/v4-proto/condition.json +6 -0
  142. package/evals/conditions/v4-proto/docs/llms.txt +291 -0
  143. package/evals/conditions/v4-proto/lib/SHIM-NOTES.md +20 -0
  144. package/evals/conditions/v4-proto/lib/package.json +27 -0
  145. package/evals/conditions/v4-proto/lib/src/client.ts +471 -0
  146. package/evals/conditions/v4-proto/lib/src/errors.ts +214 -0
  147. package/evals/conditions/v4-proto/lib/src/index.ts +36 -0
  148. package/evals/conditions/v4-proto/lib/src/principal.ts +175 -0
  149. package/evals/conditions/v4-proto/lib/src/service.ts +69 -0
  150. package/evals/conditions/v4-proto/lib/src/types.ts +174 -0
  151. package/evals/conditions/v4-proto/lib/test/runtime.test.ts +170 -0
  152. package/evals/conditions/v4-proto/lib/test/tsconfig.json +10 -0
  153. package/evals/conditions/v4-proto/lib/test/types.test-d.ts +145 -0
  154. package/evals/conditions/v4-proto/lib/test/vitest.config.mjs +8 -0
  155. package/evals/conditions/v4-proto/lib/tsconfig.json +17 -0
  156. package/evals/conditions/v4-proto/package.json +26 -0
  157. package/evals/conditions/v4-proto/starter/src/generated/icrc1.service.ts +19 -0
  158. package/evals/conditions/v4-proto/starter/src/generated/icrc1.ts +57 -0
  159. package/evals/drive.mjs +1221 -0
  160. package/evals/gate.mjs +161 -0
  161. package/evals/harness/aggregate.mjs +534 -0
  162. package/evals/harness/aggregate.test.mjs +344 -0
  163. package/evals/harness/assemble.mjs +216 -0
  164. package/evals/harness/assemble.test.mjs +143 -0
  165. package/evals/harness/auth.mjs +91 -0
  166. package/evals/harness/check-docs.mjs +157 -0
  167. package/evals/harness/declarations/icrc1.did.d.ts +95 -0
  168. package/evals/harness/declarations/icrc1.did.js +140 -0
  169. package/evals/harness/drive-auth.test.mjs +584 -0
  170. package/evals/harness/drive.test.mjs +509 -0
  171. package/evals/harness/fake-auth.ts +67 -0
  172. package/evals/harness/fake-ledger.ts +178 -0
  173. package/evals/harness/gate-plan.mjs +104 -0
  174. package/evals/harness/gate-plan.test.mjs +243 -0
  175. package/evals/harness/icrc1.did +88 -0
  176. package/evals/harness/judge.mjs +63 -0
  177. package/evals/harness/judge.test.mjs +81 -0
  178. package/evals/harness/leak-scan.mjs +1373 -0
  179. package/evals/harness/leak-scan.test.mjs +1300 -0
  180. package/evals/harness/probes/amounts.ts +14 -0
  181. package/evals/harness/probes/node-tool.probe.ts +48 -0
  182. package/evals/harness/probes/probe.mjs +149 -0
  183. package/evals/harness/probes/react-wallet.probe.ts +96 -0
  184. package/evals/harness/public/support/auth.ts +38 -0
  185. package/evals/harness/public/support/fake-replica.d.ts +28 -0
  186. package/evals/harness/public/support/fake-replica.js +434 -0
  187. package/evals/harness/public/support/ledger.idl.d.ts +95 -0
  188. package/evals/harness/public/support/ledger.idl.js +140 -0
  189. package/evals/harness/public/support/world.ts +179 -0
  190. package/evals/harness/runs.mjs +139 -0
  191. package/evals/harness/sandbox.mjs +88 -0
  192. package/evals/harness/sandbox.test.mjs +134 -0
  193. package/evals/harness/ship.mjs +264 -0
  194. package/evals/harness/ship.test.mjs +552 -0
  195. package/evals/harness/world.ts +291 -0
  196. package/evals/package.json +26 -0
  197. package/evals/pnpm-lock.yaml +1537 -0
  198. package/evals/pnpm-workspace.yaml +12 -0
  199. package/evals/results/2026-09-30T14-22-05-924Z/pilot.json +384 -0
  200. package/evals/results/2026-09-30T14-22-05-924Z/pilot.rescanned.json +404 -0
  201. package/evals/results/2026-09-30T14-22-05-924Z/pilot.rescanned.rescored.json +404 -0
  202. package/evals/results/2026-09-30T14-22-05-924Z/plan.json +240 -0
  203. package/evals/results/2026-09-30T14-22-05-924Z/summary.json +1800 -0
  204. package/evals/results/2026-09-30T14-22-05-924Z/summary.rescanned.json +1843 -0
  205. package/evals/results/2026-09-30T14-22-05-924Z/summary.rescanned.rescored.json +2100 -0
  206. package/evals/results/2026-09-30T15-48-23-343Z/pilot.json +404 -0
  207. package/evals/results/2026-09-30T15-48-23-343Z/pilot.rescored.json +404 -0
  208. package/evals/results/2026-09-30T15-48-23-343Z/plan.json +242 -0
  209. package/evals/results/2026-09-30T15-48-23-343Z/summary.json +1843 -0
  210. package/evals/results/2026-09-30T15-48-23-343Z/summary.rescored.json +2195 -0
  211. package/evals/results/2026-10-03-beta1-gate/pilot.json +162 -0
  212. package/evals/results/2026-10-03-beta1-gate/plan.json +141 -0
  213. package/evals/results/2026-10-03-beta1-gate/summary.json +983 -0
  214. package/evals/results/2026-10-05-ga-gate/contaminated-run.json +55 -0
  215. package/evals/results/2026-10-05-ga-gate/pilot.json +162 -0
  216. package/evals/results/2026-10-05-ga-gate/plan.json +457 -0
  217. package/evals/results/2026-10-05-ga-gate/summary.json +1037 -0
  218. package/evals/results/2026-10-05-ga-gate/summary.rescanned.json +1037 -0
  219. package/evals/results/README.md +31 -0
  220. package/evals/runs-pilot.log +150 -0
  221. package/evals/runs-pilot2.log +150 -0
  222. package/evals/score.mjs +256 -0
  223. package/evals/setup.mjs +547 -0
  224. package/evals/tasks/node-tool/faulty/thin-accepts-exponent/meta.json +5 -0
  225. package/evals/tasks/node-tool/faulty/thin-accepts-exponent/src/index.ts +121 -0
  226. package/evals/tasks/node-tool/faulty/thin-anonymous-transfer/meta.json +5 -0
  227. package/evals/tasks/node-tool/faulty/thin-anonymous-transfer/src/index.ts +116 -0
  228. package/evals/tasks/node-tool/faulty/thin-every-reject-may-have-executed/meta.json +9 -0
  229. package/evals/tasks/node-tool/faulty/thin-every-reject-may-have-executed/src/index.ts +118 -0
  230. package/evals/tasks/node-tool/faulty/thin-fetches-root-key-off-local/meta.json +5 -0
  231. package/evals/tasks/node-tool/faulty/thin-fetches-root-key-off-local/src/index.ts +118 -0
  232. package/evals/tasks/node-tool/faulty/thin-ignores-root-key/meta.json +5 -0
  233. package/evals/tasks/node-tool/faulty/thin-ignores-root-key/src/index.ts +117 -0
  234. package/evals/tasks/node-tool/faulty/thin-misclassifies-reject-codes/meta.json +9 -0
  235. package/evals/tasks/node-tool/faulty/thin-misclassifies-reject-codes/src/index.ts +119 -0
  236. package/evals/tasks/node-tool/faulty/thin-no-nat64-cap/meta.json +9 -0
  237. package/evals/tasks/node-tool/faulty/thin-no-nat64-cap/src/index.ts +118 -0
  238. package/evals/tasks/node-tool/faulty/thin-number-amount/meta.json +10 -0
  239. package/evals/tasks/node-tool/faulty/thin-number-amount/src/index.ts +117 -0
  240. package/evals/tasks/node-tool/faulty/thin-truncates-fraction-digits/meta.json +5 -0
  241. package/evals/tasks/node-tool/faulty/thin-truncates-fraction-digits/src/index.ts +120 -0
  242. package/evals/tasks/node-tool/faulty/thin-unvalidated-recipient/meta.json +5 -0
  243. package/evals/tasks/node-tool/faulty/thin-unvalidated-recipient/src/index.ts +118 -0
  244. package/evals/tasks/node-tool/faulty/v3-retry-call-errors/meta.json +11 -0
  245. package/evals/tasks/node-tool/faulty/v3-retry-call-errors/src/index.ts +149 -0
  246. package/evals/tasks/node-tool/faulty/v4-anonymous-identity-sent/meta.json +5 -0
  247. package/evals/tasks/node-tool/faulty/v4-anonymous-identity-sent/src/index.ts +71 -0
  248. package/evals/tasks/node-tool/faulty/v4-never-may-have-executed/meta.json +9 -0
  249. package/evals/tasks/node-tool/faulty/v4-never-may-have-executed/src/index.ts +84 -0
  250. package/evals/tasks/node-tool/faulty/v4-proto-never-may-have-executed/meta.json +9 -0
  251. package/evals/tasks/node-tool/faulty/v4-proto-never-may-have-executed/src/index.ts +72 -0
  252. package/evals/tasks/node-tool/faulty/v4-proto-refuses-nat64-max/meta.json +5 -0
  253. package/evals/tasks/node-tool/faulty/v4-proto-refuses-nat64-max/src/index.ts +72 -0
  254. package/evals/tasks/node-tool/faulty/v4-refuses-nat64-max/meta.json +5 -0
  255. package/evals/tasks/node-tool/faulty/v4-refuses-nat64-max/src/index.ts +84 -0
  256. package/evals/tasks/node-tool/hidden/node-tool.test.ts +312 -0
  257. package/evals/tasks/node-tool/prompt.md +55 -0
  258. package/evals/tasks/node-tool/prompt.minimal.md +30 -0
  259. package/evals/tasks/node-tool/solutions/thin/reference/src/index.ts +118 -0
  260. package/evals/tasks/node-tool/solutions/thin/reference-module-scope/src/index.ts +145 -0
  261. package/evals/tasks/node-tool/solutions/thin-guide/reference/src/index.ts +118 -0
  262. package/evals/tasks/node-tool/solutions/thin-guide/reference-module-scope/src/index.ts +145 -0
  263. package/evals/tasks/node-tool/solutions/v3/reference/src/index.ts +140 -0
  264. package/evals/tasks/node-tool/solutions/v3/reference-module-scope/src/index.ts +153 -0
  265. package/evals/tasks/node-tool/solutions/v4/reference/src/index.ts +84 -0
  266. package/evals/tasks/node-tool/solutions/v4/reference-module-scope/src/index.ts +105 -0
  267. package/evals/tasks/node-tool/solutions/v4-proto/reference/src/index.ts +72 -0
  268. package/evals/tasks/node-tool/solutions/v4-proto/reference-module-scope/src/index.ts +87 -0
  269. package/evals/tasks/node-tool/starter/src/contract.ts +31 -0
  270. package/evals/tasks/node-tool/starter/src/index.ts +7 -0
  271. package/evals/tasks/node-tool/starter/test/smoke.test.ts +22 -0
  272. package/evals/tasks/node-tool/starter/tsconfig.json +17 -0
  273. package/evals/tasks/node-tool/task.json +63 -0
  274. package/evals/tasks/react-wallet/faulty/thin-accepts-exponent/meta.json +5 -0
  275. package/evals/tasks/react-wallet/faulty/thin-accepts-exponent/src/Wallet.tsx +216 -0
  276. package/evals/tasks/react-wallet/faulty/thin-anonymous-transfer/meta.json +5 -0
  277. package/evals/tasks/react-wallet/faulty/thin-anonymous-transfer/src/Wallet.tsx +212 -0
  278. package/evals/tasks/react-wallet/faulty/thin-both-auth-buttons/meta.json +5 -0
  279. package/evals/tasks/react-wallet/faulty/thin-both-auth-buttons/src/Wallet.tsx +210 -0
  280. package/evals/tasks/react-wallet/faulty/thin-constant-balance-key/meta.json +8 -0
  281. package/evals/tasks/react-wallet/faulty/thin-constant-balance-key/src/Wallet.tsx +213 -0
  282. package/evals/tasks/react-wallet/faulty/thin-no-nat64-cap/meta.json +9 -0
  283. package/evals/tasks/react-wallet/faulty/thin-no-nat64-cap/src/Wallet.tsx +213 -0
  284. package/evals/tasks/react-wallet/faulty/thin-number-balance/meta.json +5 -0
  285. package/evals/tasks/react-wallet/faulty/thin-number-balance/src/Wallet.tsx +213 -0
  286. package/evals/tasks/react-wallet/faulty/thin-transfer-as-query/meta.json +5 -0
  287. package/evals/tasks/react-wallet/faulty/thin-transfer-as-query/src/Wallet.tsx +254 -0
  288. package/evals/tasks/react-wallet/faulty/thin-truncates-fraction-digits/meta.json +5 -0
  289. package/evals/tasks/react-wallet/faulty/thin-truncates-fraction-digits/src/Wallet.tsx +215 -0
  290. package/evals/tasks/react-wallet/faulty/thin-unguarded-balance-effect/meta.json +5 -0
  291. package/evals/tasks/react-wallet/faulty/thin-unguarded-balance-effect/src/Wallet.tsx +214 -0
  292. package/evals/tasks/react-wallet/faulty/v3-http-4xx-unknown/meta.json +5 -0
  293. package/evals/tasks/react-wallet/faulty/v3-http-4xx-unknown/src/Wallet.tsx +224 -0
  294. package/evals/tasks/react-wallet/faulty/v3-mutation-retry-3/meta.json +12 -0
  295. package/evals/tasks/react-wallet/faulty/v3-mutation-retry-3/src/Wallet.tsx +225 -0
  296. package/evals/tasks/react-wallet/faulty/v3-unknown-as-error/meta.json +11 -0
  297. package/evals/tasks/react-wallet/faulty/v3-unknown-as-error/src/Wallet.tsx +182 -0
  298. package/evals/tasks/react-wallet/faulty/v4-every-reject-unknown/meta.json +5 -0
  299. package/evals/tasks/react-wallet/faulty/v4-every-reject-unknown/src/Wallet.tsx +160 -0
  300. package/evals/tasks/react-wallet/faulty/v4-keep-previous-data/meta.json +5 -0
  301. package/evals/tasks/react-wallet/faulty/v4-keep-previous-data/src/Wallet.tsx +166 -0
  302. package/evals/tasks/react-wallet/faulty/v4-proto-every-reject-unknown/meta.json +5 -0
  303. package/evals/tasks/react-wallet/faulty/v4-proto-every-reject-unknown/src/Wallet.tsx +161 -0
  304. package/evals/tasks/react-wallet/faulty/v4-proto-keep-previous-data/meta.json +5 -0
  305. package/evals/tasks/react-wallet/faulty/v4-proto-keep-previous-data/src/Wallet.tsx +163 -0
  306. package/evals/tasks/react-wallet/faulty/v4-proto-retry-spread/meta.json +12 -0
  307. package/evals/tasks/react-wallet/faulty/v4-proto-retry-spread/src/Wallet.tsx +162 -0
  308. package/evals/tasks/react-wallet/faulty/v4-proto-status-not-idle/meta.json +5 -0
  309. package/evals/tasks/react-wallet/faulty/v4-proto-status-not-idle/src/Wallet.tsx +163 -0
  310. package/evals/tasks/react-wallet/faulty/v4-retry-spread/meta.json +12 -0
  311. package/evals/tasks/react-wallet/faulty/v4-retry-spread/src/Wallet.tsx +163 -0
  312. package/evals/tasks/react-wallet/faulty/v4-status-not-idle/meta.json +5 -0
  313. package/evals/tasks/react-wallet/faulty/v4-status-not-idle/src/Wallet.tsx +162 -0
  314. package/evals/tasks/react-wallet/hidden/react-wallet.test.ts +536 -0
  315. package/evals/tasks/react-wallet/prompt.md +88 -0
  316. package/evals/tasks/react-wallet/prompt.minimal.md +51 -0
  317. package/evals/tasks/react-wallet/solutions/thin/reference/src/Wallet.tsx +213 -0
  318. package/evals/tasks/react-wallet/solutions/thin/reference-module-scope/src/Wallet.tsx +227 -0
  319. package/evals/tasks/react-wallet/solutions/thin-guide/reference/src/Wallet.tsx +213 -0
  320. package/evals/tasks/react-wallet/solutions/thin-guide/reference-module-scope/src/Wallet.tsx +227 -0
  321. package/evals/tasks/react-wallet/solutions/v3/reference/src/Wallet.tsx +224 -0
  322. package/evals/tasks/react-wallet/solutions/v3/reference-module-scope/src/Wallet.tsx +230 -0
  323. package/evals/tasks/react-wallet/solutions/v4/reference/src/Wallet.tsx +160 -0
  324. package/evals/tasks/react-wallet/solutions/v4/reference-module-scope/src/Wallet.tsx +178 -0
  325. package/evals/tasks/react-wallet/solutions/v4-proto/reference/src/Wallet.tsx +161 -0
  326. package/evals/tasks/react-wallet/solutions/v4-proto/reference-module-scope/src/Wallet.tsx +161 -0
  327. package/evals/tasks/react-wallet/starter/src/Wallet.tsx +12 -0
  328. package/evals/tasks/react-wallet/starter/src/auth.ts +16 -0
  329. package/evals/tasks/react-wallet/starter/src/config.ts +14 -0
  330. package/evals/tasks/react-wallet/starter/src/ii-auth.ts +43 -0
  331. package/evals/tasks/react-wallet/starter/src/main.tsx +15 -0
  332. package/evals/tasks/react-wallet/starter/test/smoke.test.ts +34 -0
  333. package/evals/tasks/react-wallet/starter/tsconfig.json +18 -0
  334. package/evals/tasks/react-wallet/task.json +84 -0
  335. package/examples/canister-studio/.stackblitzrc +4 -0
  336. package/examples/canister-studio/README.md +183 -0
  337. package/examples/canister-studio/did/ckbtc_minter.did +806 -0
  338. package/examples/canister-studio/did/icp_ledger.did +586 -0
  339. package/examples/canister-studio/did/icrc1.did +88 -0
  340. package/examples/canister-studio/package.json +45 -0
  341. package/examples/canister-studio/scripts/smoke.ts +188 -0
  342. package/examples/canister-studio/src/calls/CacheKeyPanel.tsx +104 -0
  343. package/examples/canister-studio/src/calls/ConfirmWrite.tsx +265 -0
  344. package/examples/canister-studio/src/calls/ErrorPanel.test.tsx +113 -0
  345. package/examples/canister-studio/src/calls/ErrorPanel.tsx +214 -0
  346. package/examples/canister-studio/src/calls/MethodRunner.test.tsx +354 -0
  347. package/examples/canister-studio/src/calls/MethodRunner.tsx +57 -0
  348. package/examples/canister-studio/src/calls/ReadRunner.tsx +244 -0
  349. package/examples/canister-studio/src/calls/ResendPanel.tsx +165 -0
  350. package/examples/canister-studio/src/calls/ShareLink.tsx +59 -0
  351. package/examples/canister-studio/src/calls/WriteRunner.test.tsx +678 -0
  352. package/examples/canister-studio/src/calls/WriteRunner.tsx +670 -0
  353. package/examples/canister-studio/src/calls/dedupe.ts +189 -0
  354. package/examples/canister-studio/src/calls/error-info.ts +168 -0
  355. package/examples/canister-studio/src/calls/history.test.ts +284 -0
  356. package/examples/canister-studio/src/calls/history.ts +287 -0
  357. package/examples/canister-studio/src/calls/kinds.ts +68 -0
  358. package/examples/canister-studio/src/calls/prepare.ts +32 -0
  359. package/examples/canister-studio/src/calls/query-options.ts +30 -0
  360. package/examples/canister-studio/src/calls/read.ts +47 -0
  361. package/examples/canister-studio/src/calls/readback.ts +100 -0
  362. package/examples/canister-studio/src/calls/record.ts +123 -0
  363. package/examples/canister-studio/src/calls/safe-calls.test.ts +299 -0
  364. package/examples/canister-studio/src/calls/share.ts +46 -0
  365. package/examples/canister-studio/src/calls/testing/doubles.tsx +108 -0
  366. package/examples/canister-studio/src/calls/testing/fixtures.ts +185 -0
  367. package/examples/canister-studio/src/calls/useCanisterHandle.ts +35 -0
  368. package/examples/canister-studio/src/canisters/ckbtc_minter.envelope.json +4228 -0
  369. package/examples/canister-studio/src/canisters/ckbtc_minter.ts +868 -0
  370. package/examples/canister-studio/src/canisters/icp_ledger.envelope.json +3454 -0
  371. package/examples/canister-studio/src/canisters/icp_ledger.ts +584 -0
  372. package/examples/canister-studio/src/canisters/icrc1.envelope.json +840 -0
  373. package/examples/canister-studio/src/canisters/icrc1.ts +78 -0
  374. package/examples/canister-studio/src/components/ActionButton.tsx +32 -0
  375. package/examples/canister-studio/src/components/AppHeader.tsx +83 -0
  376. package/examples/canister-studio/src/components/AppShell.tsx +29 -0
  377. package/examples/canister-studio/src/components/AuthButton.tsx +79 -0
  378. package/examples/canister-studio/src/components/Badge.tsx +79 -0
  379. package/examples/canister-studio/src/components/CanisterHeader.tsx +200 -0
  380. package/examples/canister-studio/src/components/CanisterJump.tsx +130 -0
  381. package/examples/canister-studio/src/components/Card.tsx +64 -0
  382. package/examples/canister-studio/src/components/Code.tsx +101 -0
  383. package/examples/canister-studio/src/components/CopyButton.tsx +126 -0
  384. package/examples/canister-studio/src/components/Disclosure.tsx +34 -0
  385. package/examples/canister-studio/src/components/EmptyState.tsx +34 -0
  386. package/examples/canister-studio/src/components/MethodList.test.tsx +137 -0
  387. package/examples/canister-studio/src/components/MethodList.tsx +244 -0
  388. package/examples/canister-studio/src/components/Notice.tsx +36 -0
  389. package/examples/canister-studio/src/components/ProvenanceBadge.tsx +44 -0
  390. package/examples/canister-studio/src/components/RouteError.tsx +42 -0
  391. package/examples/canister-studio/src/components/SectionBoundary.tsx +76 -0
  392. package/examples/canister-studio/src/components/Spinner.tsx +33 -0
  393. package/examples/canister-studio/src/components/Tabs.tsx +96 -0
  394. package/examples/canister-studio/src/components/canister/CanisterLoadFailure.test.tsx +56 -0
  395. package/examples/canister-studio/src/components/canister/CanisterLoadFailure.tsx +165 -0
  396. package/examples/canister-studio/src/components/canister/CanisterNotFound.tsx +59 -0
  397. package/examples/canister-studio/src/components/canister/CanisterPending.tsx +33 -0
  398. package/examples/canister-studio/src/components/canister/MethodOverview.tsx +93 -0
  399. package/examples/canister-studio/src/components/canister/MethodWorkspace.test.tsx +201 -0
  400. package/examples/canister-studio/src/components/canister/MethodWorkspace.tsx +187 -0
  401. package/examples/canister-studio/src/components/canister/shared-call.test.ts +186 -0
  402. package/examples/canister-studio/src/components/canister/shared-call.ts +133 -0
  403. package/examples/canister-studio/src/components/canister/shared-link-loader.test.ts +116 -0
  404. package/examples/canister-studio/src/components/canister/use-canister-page.ts +44 -0
  405. package/examples/canister-studio/src/components/canister/workspace-key.test.ts +27 -0
  406. package/examples/canister-studio/src/components/canister/workspace-key.ts +36 -0
  407. package/examples/canister-studio/src/components/canister-id-input.ts +69 -0
  408. package/examples/canister-studio/src/components/canister-names.ts +11 -0
  409. package/examples/canister-studio/src/components/download.ts +34 -0
  410. package/examples/canister-studio/src/components/fallbacks.tsx +33 -0
  411. package/examples/canister-studio/src/components/helpers.test.ts +107 -0
  412. package/examples/canister-studio/src/components/history/HistoryList.tsx +284 -0
  413. package/examples/canister-studio/src/components/home/FeaturedLedger.tsx +149 -0
  414. package/examples/canister-studio/src/components/home/OpenCanister.tsx +99 -0
  415. package/examples/canister-studio/src/components/home/featured.test.tsx +92 -0
  416. package/examples/canister-studio/src/components/home/featured.ts +64 -0
  417. package/examples/canister-studio/src/components/interface/CandidTab.tsx +38 -0
  418. package/examples/canister-studio/src/components/interface/CompatReport.tsx +92 -0
  419. package/examples/canister-studio/src/components/interface/CompatibilityTab.tsx +190 -0
  420. package/examples/canister-studio/src/components/interface/ProjectTab.tsx +196 -0
  421. package/examples/canister-studio/src/components/interface/TypeScriptTab.tsx +114 -0
  422. package/examples/canister-studio/src/components/interface/tools.test.tsx +169 -0
  423. package/examples/canister-studio/src/components/modes.ts +31 -0
  424. package/examples/canister-studio/src/components/playground/MethodPicker.tsx +67 -0
  425. package/examples/canister-studio/src/components/playground/PlaygroundForms.tsx +112 -0
  426. package/examples/canister-studio/src/components/playground/PlaygroundTools.tsx +219 -0
  427. package/examples/canister-studio/src/components/playground/sample.ts +43 -0
  428. package/examples/canister-studio/src/components/playground/target.test.tsx +86 -0
  429. package/examples/canister-studio/src/components/primitives.test.tsx +121 -0
  430. package/examples/canister-studio/src/components/provenance.ts +38 -0
  431. package/examples/canister-studio/src/components/route-render.test.tsx +71 -0
  432. package/examples/canister-studio/src/components/use-task.ts +56 -0
  433. package/examples/canister-studio/src/components/wallet/BalancePanel.tsx +110 -0
  434. package/examples/canister-studio/src/components/wallet/LedgerSummary.tsx +63 -0
  435. package/examples/canister-studio/src/components/wallet/MinterPanel.tsx +255 -0
  436. package/examples/canister-studio/src/components/wallet/SendPanel.test.tsx +297 -0
  437. package/examples/canister-studio/src/components/wallet/SendPanel.tsx +446 -0
  438. package/examples/canister-studio/src/components/wallet/ledgers.test.ts +36 -0
  439. package/examples/canister-studio/src/components/wallet/ledgers.ts +111 -0
  440. package/examples/canister-studio/src/forms/JsonPanel.tsx +157 -0
  441. package/examples/canister-studio/src/forms/MethodForm.test.tsx +369 -0
  442. package/examples/canister-studio/src/forms/MethodForm.tsx +368 -0
  443. package/examples/canister-studio/src/forms/TypedForm.tsx +55 -0
  444. package/examples/canister-studio/src/forms/context.ts +62 -0
  445. package/examples/canister-studio/src/forms/convert.ts +131 -0
  446. package/examples/canister-studio/src/forms/edge.test.ts +252 -0
  447. package/examples/canister-studio/src/forms/engine.test.ts +358 -0
  448. package/examples/canister-studio/src/forms/engine.ts +1492 -0
  449. package/examples/canister-studio/src/forms/fields/BytesField.tsx +210 -0
  450. package/examples/canister-studio/src/forms/fields/Field.tsx +106 -0
  451. package/examples/canister-studio/src/forms/fields/FieldShell.tsx +101 -0
  452. package/examples/canister-studio/src/forms/fields/Group.tsx +74 -0
  453. package/examples/canister-studio/src/forms/fields/ListField.tsx +256 -0
  454. package/examples/canister-studio/src/forms/fields/Segmented.tsx +78 -0
  455. package/examples/canister-studio/src/forms/fields/TimestampField.tsx +108 -0
  456. package/examples/canister-studio/src/forms/fields/UnitsField.tsx +119 -0
  457. package/examples/canister-studio/src/forms/fields/composites.tsx +389 -0
  458. package/examples/canister-studio/src/forms/fields/leaves.tsx +350 -0
  459. package/examples/canister-studio/src/forms/fields.test.tsx +396 -0
  460. package/examples/canister-studio/src/forms/helpers.test.ts +225 -0
  461. package/examples/canister-studio/src/forms/hints.ts +128 -0
  462. package/examples/canister-studio/src/forms/json.ts +119 -0
  463. package/examples/canister-studio/src/forms/parsing.test.ts +217 -0
  464. package/examples/canister-studio/src/forms/useMethodForm.ts +251 -0
  465. package/examples/canister-studio/src/interface/browser.test.ts +23 -0
  466. package/examples/canister-studio/src/interface/browser.ts +153 -0
  467. package/examples/canister-studio/src/interface/cache.ts +68 -0
  468. package/examples/canister-studio/src/interface/cli-cache.test.ts +155 -0
  469. package/examples/canister-studio/src/interface/cli-cache.ts +125 -0
  470. package/examples/canister-studio/src/interface/compile.server.test.ts +198 -0
  471. package/examples/canister-studio/src/interface/compile.server.ts +262 -0
  472. package/examples/canister-studio/src/interface/compile.test.ts +108 -0
  473. package/examples/canister-studio/src/interface/compile.ts +305 -0
  474. package/examples/canister-studio/src/interface/docs.test.ts +75 -0
  475. package/examples/canister-studio/src/interface/docs.ts +100 -0
  476. package/examples/canister-studio/src/interface/functions.test.ts +42 -0
  477. package/examples/canister-studio/src/interface/functions.ts +200 -0
  478. package/examples/canister-studio/src/interface/live-candid.server.ts +91 -0
  479. package/examples/canister-studio/src/interface/live-loader.test.ts +515 -0
  480. package/examples/canister-studio/src/interface/live-loader.ts +364 -0
  481. package/examples/canister-studio/src/interface/load.test.ts +328 -0
  482. package/examples/canister-studio/src/interface/load.ts +249 -0
  483. package/examples/canister-studio/src/interface/read-candid.test.ts +185 -0
  484. package/examples/canister-studio/src/interface/read-candid.ts +233 -0
  485. package/examples/canister-studio/src/interface/server-result.ts +42 -0
  486. package/examples/canister-studio/src/interface/typed.ts +68 -0
  487. package/examples/canister-studio/src/interface/types.ts +121 -0
  488. package/examples/canister-studio/src/lib/format.test.ts +107 -0
  489. package/examples/canister-studio/src/lib/format.ts +139 -0
  490. package/examples/canister-studio/src/lib/hex.test.ts +43 -0
  491. package/examples/canister-studio/src/lib/hex.ts +33 -0
  492. package/examples/canister-studio/src/lib/ids.test.ts +70 -0
  493. package/examples/canister-studio/src/lib/ids.ts +93 -0
  494. package/examples/canister-studio/src/lib/reactor.test.ts +55 -0
  495. package/examples/canister-studio/src/lib/reactor.ts +55 -0
  496. package/examples/canister-studio/src/lib/registry.test.ts +74 -0
  497. package/examples/canister-studio/src/lib/registry.ts +238 -0
  498. package/examples/canister-studio/src/lib/schema.ts +148 -0
  499. package/examples/canister-studio/src/routeTree.gen.ts +227 -0
  500. package/examples/canister-studio/src/router.test.ts +290 -0
  501. package/examples/canister-studio/src/router.tsx +127 -0
  502. package/examples/canister-studio/src/routes/__root.tsx +58 -0
  503. package/examples/canister-studio/src/routes/canister.$canisterId.index.tsx +172 -0
  504. package/examples/canister-studio/src/routes/canister.$canisterId.interface.tsx +98 -0
  505. package/examples/canister-studio/src/routes/canister.$canisterId.tsx +91 -0
  506. package/examples/canister-studio/src/routes/history.tsx +55 -0
  507. package/examples/canister-studio/src/routes/index.tsx +169 -0
  508. package/examples/canister-studio/src/routes/playground.tsx +286 -0
  509. package/examples/canister-studio/src/routes/safety.tsx +57 -0
  510. package/examples/canister-studio/src/routes/wallet.tsx +213 -0
  511. package/examples/canister-studio/src/safety/LabTransferForm.tsx +84 -0
  512. package/examples/canister-studio/src/safety/RequestLog.tsx +79 -0
  513. package/examples/canister-studio/src/safety/SafetyLab.test.tsx +89 -0
  514. package/examples/canister-studio/src/safety/SafetyLab.tsx +140 -0
  515. package/examples/canister-studio/src/safety/ScenarioCard.tsx +262 -0
  516. package/examples/canister-studio/src/safety/lab-run.ts +283 -0
  517. package/examples/canister-studio/src/safety/mock-ledger.test.ts +99 -0
  518. package/examples/canister-studio/src/safety/mock-ledger.ts +263 -0
  519. package/examples/canister-studio/src/safety/scenarios.test.ts +157 -0
  520. package/examples/canister-studio/src/safety/scenarios.ts +924 -0
  521. package/examples/canister-studio/src/styles.css +3453 -0
  522. package/examples/canister-studio/src/styles.test.ts +46 -0
  523. package/examples/canister-studio/src/values/CallPreview.test.tsx +86 -0
  524. package/examples/canister-studio/src/values/CallPreview.tsx +148 -0
  525. package/examples/canister-studio/src/values/ErrValueView.tsx +66 -0
  526. package/examples/canister-studio/src/values/Inspector.tsx +133 -0
  527. package/examples/canister-studio/src/values/ReplyView.test.tsx +341 -0
  528. package/examples/canister-studio/src/values/ReplyView.tsx +164 -0
  529. package/examples/canister-studio/src/values/candid-text.test.ts +516 -0
  530. package/examples/canister-studio/src/values/candid-text.ts +479 -0
  531. package/examples/canister-studio/src/values/hints.ts +58 -0
  532. package/examples/canister-studio/src/values/json.test.ts +66 -0
  533. package/examples/canister-studio/src/values/json.ts +31 -0
  534. package/examples/canister-studio/src/values/leaves.tsx +309 -0
  535. package/examples/canister-studio/src/values/schema.test.ts +123 -0
  536. package/examples/canister-studio/src/values/schema.ts +78 -0
  537. package/examples/canister-studio/src/values/test-router.tsx +21 -0
  538. package/examples/canister-studio/src/values/tree.tsx +670 -0
  539. package/examples/canister-studio/src/values/use-sha256.ts +29 -0
  540. package/examples/canister-studio/tsconfig.json +20 -0
  541. package/examples/canister-studio/vite.config.ts +50 -0
  542. package/examples/canister-studio/vitest.config.ts +20 -0
  543. package/examples/icrc-ledger/.stackblitzrc +4 -0
  544. package/examples/icrc-ledger/README.md +100 -0
  545. package/examples/icrc-ledger/ckbtc_minter.did +12 -0
  546. package/examples/icrc-ledger/icp_ledger.did +147 -0
  547. package/examples/icrc-ledger/icrc1.did +88 -0
  548. package/examples/icrc-ledger/index.html +13 -0
  549. package/examples/icrc-ledger/package.json +40 -0
  550. package/examples/icrc-ledger/scripts/smoke.ts +151 -0
  551. package/examples/icrc-ledger/src/App.tsx +71 -0
  552. package/examples/icrc-ledger/src/ErrorPanel.tsx +105 -0
  553. package/examples/icrc-ledger/src/MainnetTab.tsx +450 -0
  554. package/examples/icrc-ledger/src/SandboxTab.test.tsx +379 -0
  555. package/examples/icrc-ledger/src/SandboxTab.tsx +761 -0
  556. package/examples/icrc-ledger/src/blocks.test.ts +247 -0
  557. package/examples/icrc-ledger/src/blocks.ts +140 -0
  558. package/examples/icrc-ledger/src/canisters/ckbtc_minter.envelope.json +96 -0
  559. package/examples/icrc-ledger/src/canisters/ckbtc_minter.ts +16 -0
  560. package/examples/icrc-ledger/src/canisters/icp_ledger.envelope.json +690 -0
  561. package/examples/icrc-ledger/src/canisters/icp_ledger.ts +223 -0
  562. package/examples/icrc-ledger/src/canisters/icrc1.envelope.json +840 -0
  563. package/examples/icrc-ledger/src/canisters/icrc1.ts +78 -0
  564. package/examples/icrc-ledger/src/format.test.ts +41 -0
  565. package/examples/icrc-ledger/src/format.ts +68 -0
  566. package/examples/icrc-ledger/src/ledger.ts +15 -0
  567. package/examples/icrc-ledger/src/main.tsx +10 -0
  568. package/examples/icrc-ledger/src/minter.ts +16 -0
  569. package/examples/icrc-ledger/src/sandbox.test.ts +464 -0
  570. package/examples/icrc-ledger/src/sandbox.ts +281 -0
  571. package/examples/icrc-ledger/src/styles.css +391 -0
  572. package/examples/icrc-ledger/src/transfer-form.test.ts +62 -0
  573. package/examples/icrc-ledger/src/transfer-form.ts +97 -0
  574. package/examples/icrc-ledger/tsconfig.json +19 -0
  575. package/examples/icrc-ledger/vite.config.ts +44 -0
  576. package/examples/icrc-ledger/vitest.config.ts +12 -0
  577. package/examples/next-ssr/.stackblitzrc +4 -0
  578. package/examples/next-ssr/README.md +112 -0
  579. package/examples/next-ssr/icrc1.did +88 -0
  580. package/examples/next-ssr/next.config.ts +10 -0
  581. package/examples/next-ssr/package.json +41 -0
  582. package/examples/next-ssr/scripts/smoke.ts +169 -0
  583. package/examples/next-ssr/src/app/account/CertifiedBalances.tsx +58 -0
  584. package/examples/next-ssr/src/app/account/account.test.tsx +165 -0
  585. package/examples/next-ssr/src/app/account/page.tsx +82 -0
  586. package/examples/next-ssr/src/app/api/balance/[ledger]/[principal]/route.ts +10 -0
  587. package/examples/next-ssr/src/app/globals.css +278 -0
  588. package/examples/next-ssr/src/app/layout.tsx +34 -0
  589. package/examples/next-ssr/src/app/page.tsx +46 -0
  590. package/examples/next-ssr/src/app/providers.browser.test.tsx +127 -0
  591. package/examples/next-ssr/src/app/providers.test.tsx +73 -0
  592. package/examples/next-ssr/src/app/providers.tsx +60 -0
  593. package/examples/next-ssr/src/canisters/icrc1.envelope.json +840 -0
  594. package/examples/next-ssr/src/canisters/icrc1.ts +78 -0
  595. package/examples/next-ssr/src/components/BalanceTable.tsx +43 -0
  596. package/examples/next-ssr/src/components/LedgerCard.test.tsx +96 -0
  597. package/examples/next-ssr/src/components/LedgerCard.tsx +230 -0
  598. package/examples/next-ssr/src/components/LedgerError.tsx +32 -0
  599. package/examples/next-ssr/src/components/LedgerSections.tsx +22 -0
  600. package/examples/next-ssr/src/components/MyBalances.test.tsx +253 -0
  601. package/examples/next-ssr/src/components/MyBalances.tsx +129 -0
  602. package/examples/next-ssr/src/components/SessionBadge.tsx +18 -0
  603. package/examples/next-ssr/src/components/hydration.test.tsx +259 -0
  604. package/examples/next-ssr/src/components/server-data.ts +10 -0
  605. package/examples/next-ssr/src/format.ts +46 -0
  606. package/examples/next-ssr/src/ledgers.ts +38 -0
  607. package/examples/next-ssr/src/server/balance-route.test.ts +151 -0
  608. package/examples/next-ssr/src/server/balance-route.ts +157 -0
  609. package/examples/next-ssr/src/server/error-summary.test.ts +34 -0
  610. package/examples/next-ssr/src/server/error-summary.ts +37 -0
  611. package/examples/next-ssr/src/server/parse-owner.test.ts +39 -0
  612. package/examples/next-ssr/src/server/parse-owner.ts +34 -0
  613. package/examples/next-ssr/src/server/prefetch-ledgers.test.ts +137 -0
  614. package/examples/next-ssr/src/server/prefetch-ledgers.ts +70 -0
  615. package/examples/next-ssr/src/server/read-balances.test.ts +103 -0
  616. package/examples/next-ssr/src/server/read-balances.ts +78 -0
  617. package/examples/next-ssr/src/server/request-client.rsc.test.tsx +110 -0
  618. package/examples/next-ssr/src/server/request-client.ts +24 -0
  619. package/examples/next-ssr/src/testing/mock-ledgers.ts +115 -0
  620. package/examples/next-ssr/src/testing/react-server-dom-turbopack.d.ts +15 -0
  621. package/examples/next-ssr/src/testing/setup.ts +10 -0
  622. package/examples/next-ssr/tsconfig.json +31 -0
  623. package/examples/next-ssr/vitest.config.ts +59 -0
  624. package/examples/node-agent-tool/.stackblitzrc +4 -0
  625. package/examples/node-agent-tool/README.md +165 -0
  626. package/examples/node-agent-tool/icp.yaml +11 -0
  627. package/examples/node-agent-tool/icrc1.did +88 -0
  628. package/examples/node-agent-tool/package.json +32 -0
  629. package/examples/node-agent-tool/src/canisters/icrc1.envelope.json +840 -0
  630. package/examples/node-agent-tool/src/canisters/icrc1.ts +78 -0
  631. package/examples/node-agent-tool/src/cli.test.ts +64 -0
  632. package/examples/node-agent-tool/src/cli.ts +23 -0
  633. package/examples/node-agent-tool/src/command-line.ts +159 -0
  634. package/examples/node-agent-tool/src/commands/balance.ts +73 -0
  635. package/examples/node-agent-tool/src/commands/demo.test.ts +51 -0
  636. package/examples/node-agent-tool/src/commands/demo.ts +359 -0
  637. package/examples/node-agent-tool/src/commands/info.ts +69 -0
  638. package/examples/node-agent-tool/src/commands/reads.test.ts +133 -0
  639. package/examples/node-agent-tool/src/commands/resend.test.ts +363 -0
  640. package/examples/node-agent-tool/src/commands/transfer.test.ts +313 -0
  641. package/examples/node-agent-tool/src/commands/transfer.ts +415 -0
  642. package/examples/node-agent-tool/src/commands/watch.test.ts +159 -0
  643. package/examples/node-agent-tool/src/commands/watch.ts +135 -0
  644. package/examples/node-agent-tool/src/commands/whoami.ts +36 -0
  645. package/examples/node-agent-tool/src/context.ts +20 -0
  646. package/examples/node-agent-tool/src/dispatch.ts +70 -0
  647. package/examples/node-agent-tool/src/failure.test.ts +59 -0
  648. package/examples/node-agent-tool/src/failure.ts +176 -0
  649. package/examples/node-agent-tool/src/identity.test.ts +242 -0
  650. package/examples/node-agent-tool/src/identity.ts +228 -0
  651. package/examples/node-agent-tool/src/input.ts +110 -0
  652. package/examples/node-agent-tool/src/ledgers.test.ts +74 -0
  653. package/examples/node-agent-tool/src/ledgers.ts +62 -0
  654. package/examples/node-agent-tool/src/mock-ledger.ts +211 -0
  655. package/examples/node-agent-tool/src/network.test.ts +128 -0
  656. package/examples/node-agent-tool/src/network.ts +101 -0
  657. package/examples/node-agent-tool/src/output.test.ts +208 -0
  658. package/examples/node-agent-tool/src/output.ts +163 -0
  659. package/examples/node-agent-tool/src/run.ts +73 -0
  660. package/examples/node-agent-tool/src/test-kit.ts +167 -0
  661. package/examples/node-agent-tool/tsconfig.json +18 -0
  662. package/examples/node-agent-tool/vitest.config.ts +8 -0
  663. package/examples/vite-wallet/.stackblitzrc +4 -0
  664. package/examples/vite-wallet/Cargo.lock +646 -0
  665. package/examples/vite-wallet/Cargo.toml +5 -0
  666. package/examples/vite-wallet/README.md +107 -0
  667. package/examples/vite-wallet/backend/Cargo.toml +12 -0
  668. package/examples/vite-wallet/backend/backend.did +37 -0
  669. package/examples/vite-wallet/backend/src/lib.rs +133 -0
  670. package/examples/vite-wallet/icp.yaml +44 -0
  671. package/examples/vite-wallet/index.html +13 -0
  672. package/examples/vite-wallet/ledger.did +54 -0
  673. package/examples/vite-wallet/package.json +46 -0
  674. package/examples/vite-wallet/public/.ic-assets.json5 +26 -0
  675. package/examples/vite-wallet/scripts/faucet-args.test.ts +30 -0
  676. package/examples/vite-wallet/scripts/faucet-args.ts +41 -0
  677. package/examples/vite-wallet/scripts/faucet.ts +41 -0
  678. package/examples/vite-wallet/src/AddressBook.test.tsx +191 -0
  679. package/examples/vite-wallet/src/AddressBook.tsx +147 -0
  680. package/examples/vite-wallet/src/App.tsx +53 -0
  681. package/examples/vite-wallet/src/Balance.test.tsx +57 -0
  682. package/examples/vite-wallet/src/Balance.tsx +58 -0
  683. package/examples/vite-wallet/src/EnvironmentPanel.test.tsx +83 -0
  684. package/examples/vite-wallet/src/EnvironmentPanel.tsx +103 -0
  685. package/examples/vite-wallet/src/ErrorNote.tsx +70 -0
  686. package/examples/vite-wallet/src/Profile.test.tsx +145 -0
  687. package/examples/vite-wallet/src/Profile.tsx +92 -0
  688. package/examples/vite-wallet/src/SendIcp.test.tsx +231 -0
  689. package/examples/vite-wallet/src/SendIcp.tsx +244 -0
  690. package/examples/vite-wallet/src/SendToContact.test.tsx +113 -0
  691. package/examples/vite-wallet/src/SendToContact.tsx +102 -0
  692. package/examples/vite-wallet/src/SignIn.test.tsx +106 -0
  693. package/examples/vite-wallet/src/SignIn.tsx +120 -0
  694. package/examples/vite-wallet/src/Wallet.test.tsx +89 -0
  695. package/examples/vite-wallet/src/account-switch.test.tsx +108 -0
  696. package/examples/vite-wallet/src/auth/dev-accounts.test.ts +113 -0
  697. package/examples/vite-wallet/src/auth/dev-accounts.ts +216 -0
  698. package/examples/vite-wallet/src/auth/local-page.test.ts +28 -0
  699. package/examples/vite-wallet/src/auth/local-page.ts +20 -0
  700. package/examples/vite-wallet/src/auth/wallet-auth.test.ts +159 -0
  701. package/examples/vite-wallet/src/auth/wallet-auth.ts +131 -0
  702. package/examples/vite-wallet/src/canisters/backend.envelope.json +275 -0
  703. package/examples/vite-wallet/src/canisters/backend.ts +58 -0
  704. package/examples/vite-wallet/src/canisters/ledger.envelope.json +451 -0
  705. package/examples/vite-wallet/src/canisters/ledger.ts +56 -0
  706. package/examples/vite-wallet/src/client.ts +45 -0
  707. package/examples/vite-wallet/src/main.tsx +18 -0
  708. package/examples/vite-wallet/src/optimistic-contacts.ts +113 -0
  709. package/examples/vite-wallet/src/refusal.ts +17 -0
  710. package/examples/vite-wallet/src/styles.css +282 -0
  711. package/examples/vite-wallet/src/test/test-wallet.tsx +322 -0
  712. package/examples/vite-wallet/src/token.ts +50 -0
  713. package/examples/vite-wallet/src/transfer.test.ts +178 -0
  714. package/examples/vite-wallet/src/transfer.ts +110 -0
  715. package/examples/vite-wallet/src/use-canisters.ts +49 -0
  716. package/examples/vite-wallet/tsconfig.json +19 -0
  717. package/examples/vite-wallet/vite.config.ts +47 -0
  718. package/examples/vite-wallet/vitest.config.ts +17 -0
  719. package/package.json +9 -4
  720. package/packages/core/.size-limit.js +47 -0
  721. package/packages/core/LICENSE +21 -0
  722. package/packages/core/README.md +84 -0
  723. package/packages/core/llms.txt +610 -0
  724. package/packages/core/package.json +89 -0
  725. package/packages/core/src/call.ts +961 -0
  726. package/packages/core/src/canister.ts +259 -0
  727. package/packages/core/src/client.ts +2061 -0
  728. package/packages/core/src/errors.ts +1079 -0
  729. package/packages/core/src/hydration.ts +239 -0
  730. package/packages/core/src/index.ts +23 -0
  731. package/packages/core/src/keys.ts +108 -0
  732. package/packages/core/src/management.ts +138 -0
  733. package/packages/core/src/network.ts +1020 -0
  734. package/packages/core/src/options.ts +1000 -0
  735. package/packages/core/src/runtime.ts +50 -0
  736. package/packages/core/src/testing/fake-replica.ts +1166 -0
  737. package/packages/core/src/testing/index.ts +16 -0
  738. package/packages/core/src/testing/test-auth.ts +340 -0
  739. package/packages/core/src/testing/test-client.ts +559 -0
  740. package/packages/core/src/types.ts +541 -0
  741. package/packages/core/src/units.ts +299 -0
  742. package/packages/core/src/version.ts +4 -0
  743. package/packages/core/tests/canister-helpers.ts +187 -0
  744. package/packages/core/tests/canister-id.test.ts +158 -0
  745. package/packages/core/tests/canister-unwrap.test.ts +94 -0
  746. package/packages/core/tests/canister.test-d.ts +406 -0
  747. package/packages/core/tests/canister.test.ts +1921 -0
  748. package/packages/core/tests/client-account-change.test.ts +131 -0
  749. package/packages/core/tests/client-agents.test.ts +402 -0
  750. package/packages/core/tests/client-auth-network.test.ts +719 -0
  751. package/packages/core/tests/client-disposed.test.ts +403 -0
  752. package/packages/core/tests/client-helpers.ts +136 -0
  753. package/packages/core/tests/client-hydration.test.ts +166 -0
  754. package/packages/core/tests/client-pinned.test.ts +626 -0
  755. package/packages/core/tests/client-session.test.ts +348 -0
  756. package/packages/core/tests/client.test-d.ts +181 -0
  757. package/packages/core/tests/client.test.ts +1162 -0
  758. package/packages/core/tests/encode.test.ts +171 -0
  759. package/packages/core/tests/env-canister-id.test.ts +666 -0
  760. package/packages/core/tests/env-cookie-copies.test.ts +182 -0
  761. package/packages/core/tests/error-guard.test.ts +222 -0
  762. package/packages/core/tests/errors.test-d.ts +280 -0
  763. package/packages/core/tests/errors.test.ts +1359 -0
  764. package/packages/core/tests/fixtures/README.md +28 -0
  765. package/packages/core/tests/fixtures/accounts.did +21 -0
  766. package/packages/core/tests/fixtures/accounts.envelope.json +367 -0
  767. package/packages/core/tests/fixtures/accounts.ts +26 -0
  768. package/packages/core/tests/fixtures/archive.did +31 -0
  769. package/packages/core/tests/fixtures/archive.envelope.json +259 -0
  770. package/packages/core/tests/fixtures/archive.ts +55 -0
  771. package/packages/core/tests/fixtures/icrc1.did +88 -0
  772. package/packages/core/tests/fixtures/icrc1.envelope.json +840 -0
  773. package/packages/core/tests/fixtures/icrc1.ts +78 -0
  774. package/packages/core/tests/fixtures/management.did +724 -0
  775. package/packages/core/tests/fixtures/management.envelope.json +4455 -0
  776. package/packages/core/tests/fixtures/management.ts +486 -0
  777. package/packages/core/tests/fixtures/shapes.did +33 -0
  778. package/packages/core/tests/fixtures/shapes.envelope.json +440 -0
  779. package/packages/core/tests/fixtures/shapes.ts +56 -0
  780. package/packages/core/tests/fixtures/skippable.did +15 -0
  781. package/packages/core/tests/fixtures/skippable.envelope.json +182 -0
  782. package/packages/core/tests/fixtures/skippable.ts +33 -0
  783. package/packages/core/tests/func.test.ts +154 -0
  784. package/packages/core/tests/identity-attributes.test.ts +214 -0
  785. package/packages/core/tests/keys.test.ts +289 -0
  786. package/packages/core/tests/management.test.ts +206 -0
  787. package/packages/core/tests/network-helpers.ts +121 -0
  788. package/packages/core/tests/network.test-d.ts +78 -0
  789. package/packages/core/tests/network.test.ts +1051 -0
  790. package/packages/core/tests/options.test.ts +1594 -0
  791. package/packages/core/tests/redirect-sign-in.test.ts +393 -0
  792. package/packages/core/tests/resend.test-d.ts +81 -0
  793. package/packages/core/tests/resend.test.ts +723 -0
  794. package/packages/core/tests/skip.test-d.ts +125 -0
  795. package/packages/core/tests/testing-entry.test.ts +73 -0
  796. package/packages/core/tests/testing-fake-replica.test.ts +1242 -0
  797. package/packages/core/tests/testing-test-auth.test-d.ts +84 -0
  798. package/packages/core/tests/testing-test-auth.test.ts +483 -0
  799. package/packages/core/tests/testing-test-client.test-d.ts +184 -0
  800. package/packages/core/tests/testing-test-client.test.ts +1272 -0
  801. package/packages/core/tests/time-realm.test.ts +63 -0
  802. package/packages/core/tests/time.test.ts +238 -0
  803. package/packages/core/tests/traps/README.md +39 -0
  804. package/packages/core/tests/traps/anonymous-write.test.ts +145 -0
  805. package/packages/core/tests/traps/classification-table.test.ts +256 -0
  806. package/packages/core/tests/traps/err-arm.test.ts +144 -0
  807. package/packages/core/tests/traps/fetch-spy.ts +39 -0
  808. package/packages/core/tests/traps/invalidation-after-write.test.ts +178 -0
  809. package/packages/core/tests/traps/ledger.ts +248 -0
  810. package/packages/core/tests/traps/root-key-off-local.test.ts +130 -0
  811. package/packages/core/tests/traps/stale-data-across-users.test.ts +173 -0
  812. package/packages/core/tests/traps/unresolved-name.test.ts +155 -0
  813. package/packages/core/tests/traps/update-as-query.test.ts +244 -0
  814. package/packages/core/tests/traps/update-not-resent.test.ts +126 -0
  815. package/packages/core/tests/traps/update-resent-when-never-delivered.test.ts +159 -0
  816. package/packages/core/tests/traps.test-d.ts +476 -0
  817. package/packages/core/tests/units.test-d.ts +118 -0
  818. package/packages/core/tests/units.test.ts +634 -0
  819. package/packages/core/tsconfig.json +19 -0
  820. package/packages/core/tsconfig.typecheck.json +16 -0
  821. package/packages/core/vitest.config.ts +13 -0
  822. package/packages/mcp/LICENSE +21 -0
  823. package/packages/mcp/README.md +189 -0
  824. package/packages/mcp/package.json +62 -0
  825. package/packages/mcp/src/candid/candid-text.test.ts +455 -0
  826. package/packages/mcp/src/candid/candid-text.ts +501 -0
  827. package/packages/mcp/src/candid/contract.test.ts +398 -0
  828. package/packages/mcp/src/candid/formats.ts +155 -0
  829. package/packages/mcp/src/candid/hex.ts +29 -0
  830. package/packages/mcp/src/candid/json-schema.test.ts +758 -0
  831. package/packages/mcp/src/candid/json-schema.ts +454 -0
  832. package/packages/mcp/src/candid/json.test.ts +1207 -0
  833. package/packages/mcp/src/candid/json.ts +1053 -0
  834. package/packages/mcp/src/candid/schema-walk.ts +189 -0
  835. package/packages/mcp/src/candid/type-text.test.ts +179 -0
  836. package/packages/mcp/src/candid/type-text.ts +238 -0
  837. package/packages/mcp/src/cli.ts +134 -0
  838. package/packages/mcp/src/identity.ts +188 -0
  839. package/packages/mcp/src/interface/cache.test.ts +48 -0
  840. package/packages/mcp/src/interface/cache.ts +68 -0
  841. package/packages/mcp/src/interface/cli-cache.test.ts +150 -0
  842. package/packages/mcp/src/interface/cli-cache.ts +122 -0
  843. package/packages/mcp/src/interface/compile-worker.test.ts +246 -0
  844. package/packages/mcp/src/interface/compile-worker.ts +290 -0
  845. package/packages/mcp/src/interface/compile.test.ts +155 -0
  846. package/packages/mcp/src/interface/compile.ts +281 -0
  847. package/packages/mcp/src/interface/docs.test.ts +105 -0
  848. package/packages/mcp/src/interface/docs.ts +86 -0
  849. package/packages/mcp/src/interface/fixtures/icrc1.did +88 -0
  850. package/packages/mcp/src/interface/hex.ts +8 -0
  851. package/packages/mcp/src/interface/ids.test.ts +71 -0
  852. package/packages/mcp/src/interface/ids.ts +87 -0
  853. package/packages/mcp/src/interface/loader.test.ts +804 -0
  854. package/packages/mcp/src/interface/loader.ts +519 -0
  855. package/packages/mcp/src/interface/read-candid.test.ts +300 -0
  856. package/packages/mcp/src/interface/read-candid.ts +259 -0
  857. package/packages/mcp/src/interface/types.ts +113 -0
  858. package/packages/mcp/src/network.ts +122 -0
  859. package/packages/mcp/src/options.ts +149 -0
  860. package/packages/mcp/src/server/approval.ts +159 -0
  861. package/packages/mcp/src/server/naming.ts +43 -0
  862. package/packages/mcp/src/server/results.ts +102 -0
  863. package/packages/mcp/src/server/server.ts +797 -0
  864. package/packages/mcp/src/server/tools.ts +116 -0
  865. package/packages/mcp/src/usage.ts +40 -0
  866. package/packages/mcp/tests/approval.test.ts +60 -0
  867. package/packages/mcp/tests/identity.test.ts +234 -0
  868. package/packages/mcp/tests/naming.test.ts +62 -0
  869. package/packages/mcp/tests/options.test.ts +140 -0
  870. package/packages/mcp/tests/server.test.ts +997 -0
  871. package/packages/mcp/tsconfig.json +19 -0
  872. package/packages/mcp/tsconfig.typecheck.json +10 -0
  873. package/packages/mcp/vitest.config.ts +10 -0
  874. package/packages/react/LICENSE +21 -0
  875. package/packages/react/README.md +328 -0
  876. package/packages/react/llms.txt +95 -0
  877. package/packages/react/package.json +95 -0
  878. package/packages/react/src/index.tsx +678 -0
  879. package/packages/react/tests/abandoned-render.test.tsx +816 -0
  880. package/packages/react/tests/auth.test.tsx +315 -0
  881. package/packages/react/tests/caller-keys.test.tsx +2334 -0
  882. package/packages/react/tests/client-time.test.ts +40 -0
  883. package/packages/react/tests/entry.test.ts +52 -0
  884. package/packages/react/tests/helpers.tsx +291 -0
  885. package/packages/react/tests/hydration.test.tsx +262 -0
  886. package/packages/react/tests/ownership.test.tsx +260 -0
  887. package/packages/react/tests/provider.server.test.tsx +169 -0
  888. package/packages/react/tests/query-client.test.tsx +107 -0
  889. package/packages/react/tests/strict-mode.test.tsx +288 -0
  890. package/packages/react/tests/suspense.test-d.tsx +357 -0
  891. package/packages/react/tests/two-query-cores.test.tsx +135 -0
  892. package/packages/react/tests/types.test-d.tsx +63 -0
  893. package/packages/react/tsconfig.json +23 -0
  894. package/packages/react/tsconfig.test.json +8 -0
  895. package/packages/react/tsconfig.typecheck.json +16 -0
  896. package/packages/react/vitest.config.ts +39 -0
  897. package/packages/vite-plugin/LICENSE +21 -0
  898. package/packages/vite-plugin/README.md +532 -0
  899. package/packages/vite-plugin/package.json +76 -0
  900. package/packages/vite-plugin/src/describe-value.test.ts +43 -0
  901. package/packages/vite-plugin/src/describe-value.ts +167 -0
  902. package/packages/vite-plugin/src/dev-environment.test.ts +747 -0
  903. package/packages/vite-plugin/src/dev-environment.ts +510 -0
  904. package/packages/vite-plugin/src/env.ts +431 -0
  905. package/packages/vite-plugin/src/fetch.ts +348 -0
  906. package/packages/vite-plugin/src/file-identity.ts +106 -0
  907. package/packages/vite-plugin/src/generate.ts +691 -0
  908. package/packages/vite-plugin/src/index.test.ts +1243 -0
  909. package/packages/vite-plugin/src/index.ts +2565 -0
  910. package/packages/vite-plugin/src/interface.ts +339 -0
  911. package/packages/vite-plugin/src/local-host.ts +34 -0
  912. package/packages/vite-plugin/src/options.ts +641 -0
  913. package/packages/vite-plugin/src/principal-text.test.ts +87 -0
  914. package/packages/vite-plugin/src/principal-text.ts +98 -0
  915. package/packages/vite-plugin/tests/close.test.ts +141 -0
  916. package/packages/vite-plugin/tests/environment-mode.test.ts +136 -0
  917. package/packages/vite-plugin/tests/fake-ic.ts +214 -0
  918. package/packages/vite-plugin/tests/fetch-sdk.test.ts +27 -0
  919. package/packages/vite-plugin/tests/fetch.test.ts +1196 -0
  920. package/packages/vite-plugin/tests/fixtures/fake-cli/bin.js +90 -0
  921. package/packages/vite-plugin/tests/fixtures/fake-cli/package.json +8 -0
  922. package/packages/vite-plugin/tests/fixtures/icrc1.did +88 -0
  923. package/packages/vite-plugin/tests/generation.test.ts +1036 -0
  924. package/packages/vite-plugin/tests/icp-command.test.ts +194 -0
  925. package/packages/vite-plugin/tests/icp-timeout.test.ts +83 -0
  926. package/packages/vite-plugin/tests/no-process-exit.test.ts +83 -0
  927. package/packages/vite-plugin/tests/on-generated.test.ts +323 -0
  928. package/packages/vite-plugin/tests/output-collision.test.ts +329 -0
  929. package/packages/vite-plugin/tests/package.test.ts +62 -0
  930. package/packages/vite-plugin/tests/project.test.ts +2993 -0
  931. package/packages/vite-plugin/tests/support.ts +339 -0
  932. package/packages/vite-plugin/tests/timeout.test.ts +107 -0
  933. package/packages/vite-plugin/tsconfig.json +23 -0
  934. package/packages/vite-plugin/tsconfig.typecheck.json +16 -0
  935. package/packages/vite-plugin/vitest.config.ts +9 -0
  936. package/pnpm-workspace.yaml +23 -0
  937. package/scripts/ai-context-files.js +72 -0
  938. package/scripts/assemble-docs-site.mjs +485 -0
  939. package/scripts/assemble-docs-site.test.mjs +568 -0
  940. package/scripts/build-examples.js +58 -0
  941. package/scripts/check-ai-context.js +963 -0
  942. package/scripts/check-ai-context.test.mjs +811 -0
  943. package/scripts/check-exports.mjs +767 -0
  944. package/scripts/check-exports.test.mjs +1136 -0
  945. package/scripts/check-snippets/ambient.d.ts +428 -0
  946. package/scripts/check-snippets/app/generated/backend.did +7 -0
  947. package/scripts/check-snippets/app/generated/backend.ts +15 -0
  948. package/scripts/check-snippets/app/generated/icrc1.did +88 -0
  949. package/scripts/check-snippets/app/generated/icrc1.ts +78 -0
  950. package/scripts/check-snippets/app/globals.ts +26 -0
  951. package/scripts/check-snippets/docs/guides/App.tsx +21 -0
  952. package/scripts/check-snippets/docs/guides/app/providers.tsx +23 -0
  953. package/scripts/check-snippets/docs/guides/auth-client.ts +47 -0
  954. package/scripts/check-snippets/docs/guides/canisters/backend.ts +3 -0
  955. package/scripts/check-snippets/docs/guides/canisters/icrc1.ts +3 -0
  956. package/scripts/check-snippets/docs/guides/components/LedgerCard.tsx +26 -0
  957. package/scripts/check-snippets/docs/guides/components/shell.tsx +11 -0
  958. package/scripts/check-snippets/docs/guides/components/sign-in-page.tsx +29 -0
  959. package/scripts/check-snippets/docs/guides/components/slow-section.tsx +5 -0
  960. package/scripts/check-snippets/docs/guides/generated/accounts.ts +95 -0
  961. package/scripts/check-snippets/docs/guides/generated/ckbtc_minter.ts +40 -0
  962. package/scripts/check-snippets/docs/guides/generated/icp_ledger.ts +267 -0
  963. package/scripts/check-snippets/docs/guides/ledger.ts +10 -0
  964. package/scripts/check-snippets/docs/guides/server/request-client.ts +8 -0
  965. package/scripts/check-snippets.mjs +993 -0
  966. package/scripts/check-snippets.test.mjs +338 -0
  967. package/scripts/check-stack.mjs +501 -0
  968. package/scripts/check-stack.test.mjs +800 -0
  969. package/scripts/clean-node-modules.js +67 -0
  970. package/scripts/example-projects.js +58 -0
  971. package/scripts/export-budget.mjs +145 -0
  972. package/scripts/faults.json +6749 -0
  973. package/scripts/lib/fault-workspace.mjs +210 -0
  974. package/scripts/lib/io.mjs +29 -0
  975. package/scripts/lib/io.test.mjs +38 -0
  976. package/scripts/lib/markdown-fences.mjs +56 -0
  977. package/scripts/lib/markdown-fences.test.mjs +84 -0
  978. package/scripts/lib/package-exports.mjs +54 -0
  979. package/scripts/lib/package-exports.test.mjs +66 -0
  980. package/scripts/lib/release-pr-steps.mjs +47 -0
  981. package/scripts/release-tag.mjs +95 -0
  982. package/scripts/release-tag.test.mjs +278 -0
  983. package/scripts/release-workflow.test.mjs +98 -0
  984. package/scripts/release.js +167 -0
  985. package/scripts/release.test.mjs +347 -0
  986. package/scripts/removed-v3-names.js +125 -0
  987. package/scripts/size-app/.size-limit.js +90 -0
  988. package/scripts/size-app/core.js +3 -0
  989. package/scripts/size-app/package.json +24 -0
  990. package/scripts/size-app/react.js +4 -0
  991. package/scripts/size-app.test.mjs +73 -0
  992. package/scripts/sync-ai-context-versions.js +102 -0
  993. package/scripts/sync-example-versions.js +151 -0
  994. package/scripts/test-examples-published.mjs +1585 -0
  995. package/scripts/test-examples-published.test.mjs +1586 -0
  996. package/scripts/traps/any-method-vars-not-a-list.json +5 -0
  997. package/scripts/traps/canister-method-unknown.json +5 -0
  998. package/scripts/traps/client-says-who-calls-once.json +5 -0
  999. package/scripts/traps/client-says-who-calls.json +5 -0
  1000. package/scripts/traps/err-only-on-canister-err.json +14 -0
  1001. package/scripts/traps/format-units-refuses-missing-value.json +5 -0
  1002. package/scripts/traps/format-units-refuses-number.json +5 -0
  1003. package/scripts/traps/format-units-unknown-option.json +5 -0
  1004. package/scripts/traps/guard-err-is-the-methods.json +5 -0
  1005. package/scripts/traps/guard-false-keeps-every-kind.json +5 -0
  1006. package/scripts/traps/internals-not-exported.json +9 -0
  1007. package/scripts/traps/network-refuses-unknown-name.json +5 -0
  1008. package/scripts/traps/never-err-has-no-type.json +5 -0
  1009. package/scripts/traps/options-method-unknown.json +5 -0
  1010. package/scripts/traps/options-vars-wrong-type.json +5 -0
  1011. package/scripts/traps/parse-units-refuses-number.json +5 -0
  1012. package/scripts/traps/parse-units-unknown-option.json +5 -0
  1013. package/scripts/traps/principal-is-not-plain-text.json +14 -0
  1014. package/scripts/traps/query-options-refuses-oneway.json +5 -0
  1015. package/scripts/traps/query-options-refuses-update.json +5 -0
  1016. package/scripts/traps/refuse-next-unknown-option.json +5 -0
  1017. package/scripts/traps/resend-key-reads-the-methods-arg.json +5 -0
  1018. package/scripts/traps/resend-states-its-dedupe-key.json +5 -0
  1019. package/scripts/traps/suspense-refuses-argument-skip.json +5 -0
  1020. package/scripts/traps/suspense-refuses-skippable-read.json +5 -0
  1021. package/scripts/traps/suspense-refuses-vars-skip-fits.json +5 -0
  1022. package/scripts/traps/test-handler-method-unknown.json +5 -0
  1023. package/scripts/traps/test-handler-nat-is-bigint.json +5 -0
  1024. package/scripts/traps/test-handler-takes-the-domain-value.json +5 -0
  1025. package/scripts/traps/vars-of-two-arguments-are-the-tuple.json +5 -0
  1026. package/scripts/typecheck-examples.js +122 -0
  1027. package/scripts/verify-faults.mjs +375 -0
  1028. package/scripts/verify-faults.test.mjs +402 -0
  1029. package/scripts/verify-package-artifacts.mjs +590 -0
  1030. package/scripts/verify-peer-floors.js +399 -0
  1031. package/scripts/verify-peer-floors.test.mjs +422 -0
  1032. package/scripts/verify-test-fails-rules.mjs +104 -0
  1033. package/scripts/verify-test-fails-rules.test.mjs +215 -0
  1034. package/scripts/verify-test-fails.js +371 -0
  1035. package/scripts/verify-traps.mjs +505 -0
  1036. package/scripts/verify-traps.test.mjs +521 -0
  1037. package/scripts/verify-typescript-floor.js +239 -0
  1038. package/skill-packages/ic-reactor/SKILL.md +103 -0
  1039. package/stack.json +8 -0
  1040. package/tsconfig.base.json +23 -0
  1041. package/tsconfig.json +8 -0
@@ -0,0 +1,1000 @@
1
+ /**
2
+ * The builders on a client: `queryKey`, `queryOptions`, `mutationOptions`
3
+ * and `func`, with `canister` from `canister.ts`. Each returns a fresh plain
4
+ * object (DECISIONS Q3): TanStack compares keys by their hash, so nothing is
5
+ * gained by caching one, and a cached read would pin the caller it was built
6
+ * for.
7
+ *
8
+ * The types the `Client` interface gives these functions are generic over the
9
+ * generated `Actor`; the implementations below read plain values and are cast
10
+ * to those types once, in {@link createBuilders}. `decodeArgs` returns
11
+ * `unknown[]`, and the generated `Actor` type is the static description of
12
+ * what the schemas just checked, so that cast is where the one unavoidable
13
+ * `unknown` becomes the `Actor`'s reply type.
14
+ *
15
+ * Internal: not exported from the package entry.
16
+ *
17
+ * @module
18
+ */
19
+ import { isPrincipal, resolveSchema } from "@meantjs/schema"
20
+ import { encodeArgs, type EncodeResult } from "@meantjs/schema/codec"
21
+ import {
22
+ skipToken,
23
+ type QueryClient,
24
+ type QueryFunctionContext,
25
+ type QueryKey,
26
+ } from "@tanstack/query-core"
27
+ import { lookupResultToBuffer } from "@icp-sdk/core/agent"
28
+ import { Principal } from "@icp-sdk/core/principal"
29
+ import {
30
+ UNKNOWN_WRITES,
31
+ differs,
32
+ invoke,
33
+ isWrite,
34
+ prepareMethod,
35
+ notEncoded,
36
+ valuesOf,
37
+ type ResolvedTarget,
38
+ } from "./call.js"
39
+ import {
40
+ canisterFactory,
41
+ describe,
42
+ badTimeout,
43
+ methodOf,
44
+ recordOf,
45
+ type CanisterRecord,
46
+ } from "./canister.js"
47
+ import type { Caller, Client, ClientInternals } from "./client.js"
48
+ import {
49
+ classifyError,
50
+ createReactorError,
51
+ fromCanister,
52
+ isReactorError,
53
+ retryQuery,
54
+ timedOutError,
55
+ } from "./errors.js"
56
+ import {
57
+ CERTIFIED,
58
+ INVALID,
59
+ KEY_ROOT,
60
+ SKIP,
61
+ stableText,
62
+ toHex,
63
+ } from "./keys.js"
64
+ import { MANAGEMENT_CANISTER } from "./management.js"
65
+
66
+ /** The builders `createClient` puts on a client. */
67
+ export type Builders = Pick<
68
+ Client,
69
+ | "canister"
70
+ | "queryKey"
71
+ | "queryOptions"
72
+ | "mutationOptions"
73
+ | "resendOf"
74
+ | "encode"
75
+ | "func"
76
+ | "time"
77
+ >
78
+
79
+ /** What an update read with `{ update: "idempotent" }` adds to its options (DECISIONS Q2). */
80
+ const IDEMPOTENT = Object.freeze({
81
+ staleTime: Infinity,
82
+ refetchOnMount: false,
83
+ refetchOnWindowFocus: false,
84
+ refetchOnReconnect: false,
85
+ })
86
+
87
+ const never = (): boolean => false
88
+
89
+ const slotOf = (target: ResolvedTarget): string =>
90
+ target.ok ? target.id : target.slot
91
+
92
+ /** The args segments of a key: the hex of the encoding, or the tag and text of arguments that do not encode. */
93
+ const argsSegments = (encoded: EncodeResult, vars: unknown): string[] =>
94
+ encoded.ok ? [toHex(encoded.bytes)] : [INVALID, stableText(vars)]
95
+
96
+ /**
97
+ * Checks the fourth argument of `queryOptions`, and says whether it opts an
98
+ * update in as a read.
99
+ */
100
+ function readQueryOptionsArg(options: unknown): boolean {
101
+ if (options === undefined) return false
102
+ if (
103
+ typeof options === "object" &&
104
+ options !== null &&
105
+ Object.keys(options).length === 1 &&
106
+ (options as { update?: unknown }).update === "idempotent"
107
+ ) {
108
+ return true
109
+ }
110
+ throw new TypeError(
111
+ `[ic-reactor] client.queryOptions() takes { update: "idempotent" } as its fourth argument, or nothing; got ${describe(options)}.`
112
+ )
113
+ }
114
+
115
+ /**
116
+ * The `time` path of the state tree, copied into the global `Uint8Array`, the
117
+ * one the agent's CBOR encoder knows bytes by (`instanceof`). Under a test's
118
+ * jsdom that is jsdom's, while `TextEncoder` hands out Node's, and the encoder
119
+ * sent such a label as a map: the `read_state` the replica received was not
120
+ * the one the agent signed, so a signed-in caller's was refused (#949). The
121
+ * fake replica copies its labels for the same reason.
122
+ */
123
+ const TIME_PATH = [Uint8Array.from(new TextEncoder().encode("time"))]
124
+
125
+ /** An unsigned LEB128 number, as the state tree writes `time`. */
126
+ function readLeb128(bytes: Uint8Array): bigint {
127
+ let value = 0n
128
+ let shift = 0n
129
+ for (const byte of bytes) {
130
+ value |= BigInt(byte & 0x7f) << shift
131
+ if ((byte & 0x80) === 0) return value
132
+ shift += 7n
133
+ }
134
+ throw new Error("the certificate's time is not a complete LEB128 number")
135
+ }
136
+
137
+ /**
138
+ * What a builder says when it is handed a symbol that is not the
139
+ * `skipToken` of the `@tanstack/query-core` this package imports. Correct
140
+ * variables are never a symbol (but see {@link takesAnything}), so such a
141
+ * symbol is almost always the `skipToken` of another copy of
142
+ * `@tanstack/query-core`: npm installs one beside the exact version
143
+ * `@tanstack/react-query` depends on when the two do not match, and each copy
144
+ * has its own `skipToken`. Encoded, it would make a read that is never
145
+ * skipped and rejects `invalid_args`.
146
+ */
147
+ const twoQueryCores = (call: string): string =>
148
+ `[ic-reactor] ${call}: the variables are a symbol, not core's skipToken: two copies of @tanstack/query-core are installed (or a bundler loads it twice). ` +
149
+ "Install it at the exact version @tanstack/react-query depends on; `npm ls @tanstack/query-core` must show one copy."
150
+
151
+ /**
152
+ * Whether a method's one argument is Candid `reserved`, which every value
153
+ * inhabits, a symbol included: the one method whose variables may be a
154
+ * symbol.
155
+ */
156
+ const takesAnything = (method: {
157
+ readonly args: readonly unknown[]
158
+ }): boolean => {
159
+ if (method.args.length !== 1) return false
160
+ try {
161
+ const node = resolveSchema(
162
+ method.args[0] as Parameters<typeof resolveSchema>[0]
163
+ )
164
+ return (
165
+ node.kind === "primitive" &&
166
+ (node as { primitive?: unknown }).primitive === "reserved"
167
+ )
168
+ } catch {
169
+ // A schema resolveSchema refuses takes no symbol either.
170
+ return false
171
+ }
172
+ }
173
+
174
+ /** Throws {@link twoQueryCores} for a symbol that is not our `skipToken`, unless the method takes anything. */
175
+ const refuseForeignSymbol = (
176
+ vars: unknown,
177
+ method: { readonly args: readonly unknown[] },
178
+ call: string
179
+ ): void => {
180
+ if (
181
+ typeof vars === "symbol" &&
182
+ vars !== skipToken &&
183
+ !takesAnything(method)
184
+ ) {
185
+ throw new TypeError(twoQueryCores(call))
186
+ }
187
+ }
188
+
189
+ /** Whether a settled mutation may have changed what its canister's reads return. */
190
+ const mayHaveChanged = (error: unknown): boolean =>
191
+ error === null ||
192
+ error === undefined ||
193
+ // Not ours (a bug, or code the app wrapped around the call): it proves
194
+ // nothing, so the reads are refreshed.
195
+ !isReactorError(error) ||
196
+ error.kind === "canister_err" ||
197
+ error.mayHaveExecuted
198
+
199
+ /**
200
+ * What one run of a mutation resolved, in one synchronous step when it
201
+ * started: the caller it goes out as, the canister it writes to, and the
202
+ * canisterId segments (and method) of every read it invalidates. TanStack
203
+ * Query can run `mutationFn` long after `mutate()` (paused offline, or queued
204
+ * behind another mutation of its `scope`); the write goes out as the caller
205
+ * current when it started, or not at all. A `{ name }` is resolved from the
206
+ * `ic_env` cookie, which a local redeploy can rewrite while an update is in
207
+ * flight; resolving once keeps the write and its invalidation on the same
208
+ * canister.
209
+ */
210
+ interface MutationRun {
211
+ /** Read by our `onMutate`; none for a run it did not start. */
212
+ readonly caller?: Caller
213
+ readonly target: ResolvedTarget
214
+ readonly invalidates: readonly {
215
+ readonly slots: readonly string[]
216
+ readonly method?: string
217
+ }[]
218
+ }
219
+
220
+ /** Whether two callers read for runs are the same one, `undefined` (not read) never matching. */
221
+ const sameCaller = (a: Caller | undefined, b: Caller | undefined): boolean =>
222
+ a !== undefined &&
223
+ b !== undefined &&
224
+ a.principal === b.principal &&
225
+ a.authenticated === b.authenticated
226
+
227
+ /**
228
+ * The property a run is kept under in what `onMutate` returns. A symbol, so
229
+ * it cannot collide with a context of the app's, and `{ ...context }` copies
230
+ * it when an app's own `onMutate` spreads this one's result into its own.
231
+ */
232
+ const RUN = Symbol("ic-reactor.mutationRun")
233
+
234
+ /** The run carried by what `onMutate` returned, if it carries one. */
235
+ const runIn = (onMutateResult: unknown): MutationRun | undefined =>
236
+ typeof onMutateResult === "object" && onMutateResult !== null
237
+ ? (onMutateResult as { readonly [RUN]?: MutationRun })[RUN]
238
+ : undefined
239
+
240
+ /**
241
+ * The function context TanStack Query (5.89 and later) creates for one run of
242
+ * a mutation and passes to `onMutate`, `mutationFn` and `onSettled` alike, if
243
+ * one was passed: the key a run is kept under in `runsByContext`.
244
+ */
245
+ const runKey = (context: unknown): object | undefined =>
246
+ typeof context === "object" && context !== null ? context : undefined
247
+
248
+ /**
249
+ * The builders of one client. `owner` returns the client, which is built
250
+ * after its builders.
251
+ *
252
+ * `current` says whom `queryKey` and `queryOptions` build for: the client's
253
+ * live caller, or the principal a view of the client is pinned to (see
254
+ * `CLIENT_AS` in `client.ts`). A read built for it still asks `agentFor` for
255
+ * that principal's agent, so it is cancelled rather than sent while someone
256
+ * else is current. A write reads the live caller when it starts (its
257
+ * `onMutate`, run by `mutate()`), and direct calls and `func` when they run.
258
+ */
259
+ export function createBuilders(
260
+ internals: ClientInternals,
261
+ owner: () => Client,
262
+ current: () => Caller = internals.current,
263
+ refusals?: WeakSet<object>
264
+ ): Builders {
265
+ const network = internals.network.keySegment
266
+ const pinned = current !== internals.current
267
+
268
+ /**
269
+ * A read built for a pinned principal, refused because someone else is
270
+ * current (`caller_changed`), must not leave the refusal as its query's
271
+ * error: a component that shows the key once that principal is current
272
+ * again (a sign-out after a signed-in reload) would show it. A query with
273
+ * data is left as it was found: TanStack reverts the fetch, as it reverts
274
+ * one its last observer left. A query with no data keeps the error for
275
+ * now, since a suspense read of a reverted one would fetch it again at once
276
+ * and be refused again (a hydrating boundary then never settles); the error
277
+ * goes into `refusals`, and the client clears it from the query once the
278
+ * pinned principal is current again.
279
+ */
280
+ const keepOnRefusal = async (
281
+ context: QueryFunctionContext,
282
+ read: Promise<unknown>
283
+ ): Promise<unknown> => {
284
+ try {
285
+ return await read
286
+ } catch (error) {
287
+ if (
288
+ !context.signal.aborted &&
289
+ isReactorError(error) &&
290
+ error.code === "caller_changed"
291
+ ) {
292
+ // TanStack 5.62 does not hand the context its `QueryClient`.
293
+ const queryClient =
294
+ (context as { client?: QueryClient }).client ?? owner().queryClient
295
+ const query = queryClient
296
+ .getQueryCache()
297
+ .find({ queryKey: context.queryKey, exact: true })
298
+ if (query?.state.data !== undefined) void query.cancel({ revert: true })
299
+ else refusals?.add(error)
300
+ }
301
+ throw error
302
+ }
303
+ }
304
+
305
+ /**
306
+ * What was resolved for each run of a mutation, by the function context
307
+ * TanStack Query (5.89 and later) creates for the run and passes to
308
+ * `onMutate`, `mutationFn` and `onSettled` alike: how `mutationFn` finds
309
+ * what `onMutate` resolved, and `onSettled` what `mutationFn` wrote to,
310
+ * even when an `onMutate` of the app's replaced ours.
311
+ */
312
+ const runsByContext = new WeakMap<object, MutationRun>()
313
+
314
+ /**
315
+ * Before 5.89 TanStack passes `onMutate`, `mutationFn` and `onSettled` no
316
+ * context, but calls them as methods of the run's options object
317
+ * (`mutation.options.onMutate(variables)`). That object is not the run's
318
+ * own: every `mutate()` of one `MutationObserver` builds its run with the
319
+ * observer's options, so the runs of an observer share it. Kept for it, on
320
+ * a `QueryClient` other than the client's: the caller our `onMutate` read
321
+ * for the runs not yet settled, or `undefined` once two of them started as
322
+ * different callers, which refuses their writes, since `mutationFn`
323
+ * cannot tell which of them it runs for. Our `onSettled` counts them out.
324
+ * Weak, so an entry lives as long as those options. A later render that
325
+ * hands a pending run new options (`setOptions`) leaves its `mutationFn`
326
+ * nothing here, which refuses it.
327
+ */
328
+ const callersByOptions = new WeakMap<
329
+ object,
330
+ { readonly caller: Caller | undefined; readonly runs: number }
331
+ >()
332
+
333
+ /** The methods whose `onMutate` read a caller with no context. */
334
+ const startedMethods = new WeakSet<object>()
335
+
336
+ /**
337
+ * The runs of the client's own `queryClient` not yet settled whose options
338
+ * object is `options`: the runs a `mutationFn` called on it may run for.
339
+ * More than one when an observer's `mutate()` started another before the
340
+ * first settled, as for writes held back offline.
341
+ */
342
+ const ownRuns = (options: unknown): object[] =>
343
+ typeof options === "object" && options !== null
344
+ ? owner()
345
+ .queryClient.getMutationCache()
346
+ .getAll()
347
+ .filter(
348
+ (mutation) =>
349
+ mutation.options === options &&
350
+ mutation.state.status === "pending"
351
+ )
352
+ : []
353
+
354
+ const { offered } = internals
355
+
356
+ /** The run kept for a run's function context, if TanStack passed one and a run was kept for it. */
357
+ const keptRun = (context: unknown): MutationRun | undefined => {
358
+ const key = runKey(context)
359
+ return key === undefined ? undefined : runsByContext.get(key)
360
+ }
361
+
362
+ /** A read's key, cut short where `method` or `args` are left out. */
363
+ const readKey = (
364
+ record: CanisterRecord,
365
+ caller: string,
366
+ target: ResolvedTarget,
367
+ method?: string,
368
+ args?: readonly string[]
369
+ ): string[] => {
370
+ const key = [KEY_ROOT, network, caller, slotOf(target)]
371
+ if (method === undefined) return key
372
+ key.push(method)
373
+ if (args === undefined) return key
374
+ key.push(...args)
375
+ if (record.certified) key.push(CERTIFIED)
376
+ return key
377
+ }
378
+
379
+ const queryKey = (canister: unknown, ...rest: unknown[]): QueryKey => {
380
+ const call = "client.queryKey()"
381
+ const record = recordOf(canister, internals, call)
382
+ const caller = current().principal
383
+ const target = record.resolve()
384
+ const [method, vars] = rest
385
+ if (method === undefined) return readKey(record, caller, target)
386
+ const prepared = methodOf(record, method, call)
387
+ // Two arguments give the method's prefix, and three one read's key. A
388
+ // method without arguments has one read, so two arguments give its key:
389
+ // the one `queryOptions(c, method)` gives, which `getQueryData` and
390
+ // `setQueryData` must be handed whole.
391
+ if (rest.length < 2 && prepared.args.length > 0) {
392
+ return readKey(record, caller, target, prepared.name)
393
+ }
394
+ if (vars === skipToken) {
395
+ return readKey(record, caller, target, prepared.name, [SKIP])
396
+ }
397
+ refuseForeignSymbol(vars, prepared, call)
398
+ const encoded = encodeArgs(prepared.args, valuesOf(prepared, vars))
399
+ return readKey(
400
+ record,
401
+ caller,
402
+ target,
403
+ prepared.name,
404
+ argsSegments(encoded, vars)
405
+ )
406
+ }
407
+
408
+ const queryOptions = (
409
+ canister: unknown,
410
+ method: unknown,
411
+ vars: unknown,
412
+ options?: unknown
413
+ ) => {
414
+ const call = "client.queryOptions()"
415
+ const record = recordOf(canister, internals, call)
416
+ const prepared = methodOf(record, method, call)
417
+ const idempotent = readQueryOptionsArg(options)
418
+ if (prepared.mode === "oneway") {
419
+ throw new TypeError(
420
+ `[ic-reactor] ${call}: ${prepared.name} is a oneway method; it has no reply to cache. Call it directly, or through mutationOptions().`
421
+ )
422
+ }
423
+ // A call of a method without results resolves `undefined`, and TanStack
424
+ // Query takes a query function that resolves `undefined` for a failed
425
+ // read: it reports an error and caches nothing, although the call
426
+ // succeeded. Refused here, at build time, like a oneway.
427
+ if (prepared.results.length === 0) {
428
+ throw new TypeError(
429
+ `[ic-reactor] ${call}: ${prepared.name} has no results, and a method without results has nothing to cache. ` +
430
+ `Call it directly${isWrite(prepared.mode) ? ", or through mutationOptions()" : ""}.`
431
+ )
432
+ }
433
+ if (isWrite(prepared.mode) && !idempotent) {
434
+ throw new TypeError(
435
+ `[ic-reactor] ${call}: ${prepared.name} is an update method, and a query refetches: every refetch would run the update again. ` +
436
+ `Use client.mutationOptions() for a write. Only for an update that returns the same answer however often it runs ` +
437
+ `(such as ckBTC's get_btc_address), pass { update: "idempotent" } as the fourth argument.`
438
+ )
439
+ }
440
+ if (record.certified && prepared.mode === "composite_query") {
441
+ throw new TypeError(
442
+ `[ic-reactor] ${call}: ${prepared.name} is a composite query, which has no certified path. Read it from the canister made without certified: true.`
443
+ )
444
+ }
445
+ // The read is made as the caller current now (or the one a view is
446
+ // pinned to), and only ever as them: the key holds their principal, and
447
+ // the query function asks for their agent, which is refused while someone
448
+ // else is signed in.
449
+ const caller = current()
450
+ const target = record.resolve()
451
+ const write = isWrite(prepared.mode)
452
+ const base = {
453
+ // A read of `aaaaa-aa` made from an update is never sent twice, like
454
+ // every other write to it.
455
+ retry:
456
+ write && target.ok && target.id === MANAGEMENT_CANISTER
457
+ ? never
458
+ : retryQuery,
459
+ ...(idempotent ? IDEMPOTENT : {}),
460
+ }
461
+ if (vars === skipToken) {
462
+ return {
463
+ queryKey: readKey(record, caller.principal, target, prepared.name, [
464
+ SKIP,
465
+ ]),
466
+ queryFn: skipToken,
467
+ ...base,
468
+ }
469
+ }
470
+ refuseForeignSymbol(vars, prepared, call)
471
+ const values = valuesOf(prepared, vars)
472
+ const encoded = encodeArgs(prepared.args, values)
473
+ return {
474
+ queryKey: readKey(
475
+ record,
476
+ caller.principal,
477
+ target,
478
+ prepared.name,
479
+ argsSegments(encoded, vars)
480
+ ),
481
+ queryFn: (context: QueryFunctionContext) => {
482
+ const read = invoke(internals, {
483
+ method: prepared,
484
+ target,
485
+ certified: record.certified,
486
+ caller,
487
+ values,
488
+ encoded,
489
+ signal: context.signal,
490
+ timeoutMs: record.timeoutMs,
491
+ resend: false,
492
+ canister: canister as object,
493
+ })
494
+ return pinned ? keepOnRefusal(context, read) : read
495
+ },
496
+ ...base,
497
+ }
498
+ }
499
+
500
+ /** Checks the third argument of `mutationOptions`, and returns the reads it names. */
501
+ const readInvalidates = (
502
+ canister: unknown,
503
+ options: unknown
504
+ ): { readonly record: CanisterRecord; readonly method?: string }[] => {
505
+ const call = "client.mutationOptions()"
506
+ if (options !== undefined) {
507
+ const keys =
508
+ typeof options === "object" && options !== null
509
+ ? Object.keys(options)
510
+ : undefined
511
+ if (
512
+ keys === undefined ||
513
+ keys.some((key) => key !== "invalidates" && key !== "timeoutMs") ||
514
+ badTimeout((options as { timeoutMs?: unknown }).timeoutMs)
515
+ ) {
516
+ throw new TypeError(
517
+ `[ic-reactor] ${call} takes { invalidates, timeoutMs } (timeoutMs: 1 to 2147483647 ms) as its third argument, or nothing; got ${describe(options)}. ` +
518
+ "A mutation is never retried: an update re-sent after an unknown outcome can run twice."
519
+ )
520
+ }
521
+ }
522
+ const listed = (options as { invalidates?: unknown } | undefined)
523
+ ?.invalidates
524
+ if (listed === undefined) {
525
+ return [{ record: recordOf(canister, internals, call) }]
526
+ }
527
+ if (!Array.isArray(listed)) {
528
+ throw new TypeError(
529
+ `[ic-reactor] ${call}: invalidates is a list of canisters and [canister, method] pairs, got ${describe(listed)}.`
530
+ )
531
+ }
532
+ return listed.map((entry: unknown) => {
533
+ if (Array.isArray(entry)) {
534
+ const [target, method] = entry as unknown[]
535
+ const record = recordOf(target, internals, `${call} invalidates`)
536
+ return {
537
+ record,
538
+ method: methodOf(record, method, `${call} invalidates`).name,
539
+ }
540
+ }
541
+ return { record: recordOf(entry, internals, `${call} invalidates`) }
542
+ })
543
+ }
544
+
545
+ const mutationOptions = (
546
+ canister: unknown,
547
+ method: unknown,
548
+ options?: unknown
549
+ ) => {
550
+ const call = "client.mutationOptions()"
551
+ const record = recordOf(canister, internals, call)
552
+ const prepared = methodOf(record, method, call)
553
+ const invalidates = readInvalidates(canister, options)
554
+ const timeoutMs = (options as { timeoutMs?: number } | undefined)?.timeoutMs
555
+ // One synchronous step, so that every `{ name }` here (the canister
556
+ // written to, and any listed in `invalidates`) is read from the same
557
+ // cookie.
558
+ const resolveRun = (caller?: Caller): MutationRun => ({
559
+ caller,
560
+ target: record.resolve(),
561
+ invalidates: invalidates.map(({ record: listed, method: only }) => ({
562
+ slots: listed.slots(),
563
+ method: only,
564
+ })),
565
+ })
566
+
567
+ /**
568
+ * The caller a run of this write goes out as: the one current when
569
+ * `mutate()` started it, or `undefined` when that is not known, which
570
+ * refuses the write. Found, in order:
571
+ *
572
+ * - by the run's context (5.89 and later): what the client's
573
+ * `MutationCache` read for it, which no option replaces, else what our
574
+ * `onMutate` read (a run on another `QueryClient`). Neither, for a run
575
+ * TanStack restored from a persister (it runs no `onMutate` for one),
576
+ * or one on another `QueryClient` whose `onMutate` replaced ours.
577
+ * - without a context (before 5.89, or a call by hand), by `options`,
578
+ * the object TanStack called `mutationFn` on, which the pending runs
579
+ * of one observer share: the caller its `MutationCache` read for the
580
+ * pending runs of the client's own cache with those options, if they
581
+ * all started as one (none for a restored run), else what our
582
+ * `onMutate` read for them (runs on another `QueryClient`, the same
583
+ * rule). Only when no `onMutate` of ours ever ran without a context
584
+ * for this method is this a call by hand, made as the caller current
585
+ * now.
586
+ */
587
+ const callerOf = (
588
+ options: unknown,
589
+ key: object | undefined,
590
+ run: MutationRun | undefined
591
+ ): Caller | undefined => {
592
+ if (key !== undefined) {
593
+ return internals.mutationCallers.get(key) ?? run?.caller
594
+ }
595
+ const own = ownRuns(options)
596
+ if (own.length > 0) {
597
+ const callers = own.map((run) => internals.mutationCallers.get(run))
598
+ const [first] = callers
599
+ return callers.every((caller) => sameCaller(caller, first))
600
+ ? first
601
+ : undefined
602
+ }
603
+ const read =
604
+ typeof options === "object" && options !== null
605
+ ? callersByOptions.get(options)
606
+ : undefined
607
+ if (read !== undefined) return read.caller
608
+ return startedMethods.has(prepared) ? undefined : internals.current()
609
+ }
610
+
611
+ // The write goes out as the caller current when `mutate()` started it
612
+ // (`callerOf`), or not at all: `agentFor` refuses it (`caller_changed`,
613
+ // nothing sent) while someone else is current, as when TanStack held it
614
+ // back offline or behind its `scope` and the account was switched
615
+ // meanwhile, and a caller not known is refused here. A re-send
616
+ // `resendOf` offered goes out as its first sender, to the canister id it
617
+ // went to, with the bytes it had, or not at all (`run` checks the rest).
618
+ // The target is the one onMutate resolved for this run where TanStack
619
+ // passes the run's context (5.89 and later), and is resolved now
620
+ // otherwise.
621
+ const mutationFn = function (
622
+ this: unknown,
623
+ vars: unknown,
624
+ context?: unknown
625
+ ) {
626
+ // TanStack hands a pending mutation the options of a later render
627
+ // only when their mutationKey is the same (another key detaches the
628
+ // observer instead), so a run found here was made by options for the
629
+ // same canister and method.
630
+ let run = keptRun(context)
631
+ const key = runKey(context)
632
+ if (run === undefined && key !== undefined) {
633
+ // An onMutate of the app's replaced ours, so nothing is resolved
634
+ // for this run yet: resolve it now, and keep it for onSettled,
635
+ // which TanStack hands the same context.
636
+ run = resolveRun()
637
+ runsByContext.set(key, run)
638
+ }
639
+ const target = run?.target ?? record.resolve()
640
+ const again = offered.get(vars as object)
641
+ const caller = again?.caller ?? callerOf(this, key, run)
642
+ // A disposed client cancels every call itself (`client_disposed`).
643
+ if (caller === undefined && !internals.disposed()) {
644
+ return Promise.reject(
645
+ fromCanister(
646
+ createReactorError("cancelled", {
647
+ method: prepared.name,
648
+ canisterId: target.ok ? target.id : target.slot,
649
+ code: "caller_changed",
650
+ reason: "who started this write is not known; it was not sent",
651
+ }),
652
+ canister as object
653
+ )
654
+ )
655
+ }
656
+ return invoke(internals, {
657
+ method: prepared,
658
+ target,
659
+ certified: record.certified,
660
+ caller: caller ?? internals.current(),
661
+ values: valuesOf(prepared, vars),
662
+ timeoutMs: timeoutMs ?? record.timeoutMs,
663
+ resend: true,
664
+ canister: canister as object,
665
+ again,
666
+ })
667
+ }
668
+ internals.ownMutationFns.add(mutationFn)
669
+
670
+ return {
671
+ mutationKey: [
672
+ KEY_ROOT,
673
+ network,
674
+ slotOf(record.resolve()),
675
+ prepared.name,
676
+ ] as const,
677
+ // TanStack runs this first, before mutationFn, and hands what it
678
+ // returns to onSettled. The caller it reads matters only on a
679
+ // `QueryClient` other than the client's, whose own `MutationCache`
680
+ // reads it otherwise.
681
+ onMutate: function (
682
+ this: unknown,
683
+ _vars: unknown,
684
+ context?: unknown
685
+ ): object {
686
+ const caller = internals.current()
687
+ const run = resolveRun(caller)
688
+ const key = runKey(context)
689
+ if (key !== undefined) runsByContext.set(key, run)
690
+ else {
691
+ startedMethods.add(prepared)
692
+ if (typeof this === "object" && this !== null) {
693
+ const kept = callersByOptions.get(this)
694
+ callersByOptions.set(
695
+ this,
696
+ kept === undefined || kept.runs === 0
697
+ ? { caller, runs: 1 }
698
+ : {
699
+ caller: sameCaller(kept.caller, caller)
700
+ ? caller
701
+ : undefined,
702
+ runs: kept.runs + 1,
703
+ }
704
+ )
705
+ }
706
+ }
707
+ return { [RUN]: run }
708
+ },
709
+ mutationFn,
710
+ retry: false as const,
711
+ onSettled: async function (
712
+ this: unknown,
713
+ _data: unknown,
714
+ error: unknown,
715
+ _vars: unknown,
716
+ onMutateResult?: unknown,
717
+ context?: unknown
718
+ ): Promise<void> {
719
+ // A run of another QueryClient with no context settled: one fewer
720
+ // shares its options' caller.
721
+ const kept =
722
+ runKey(context) === undefined &&
723
+ typeof this === "object" &&
724
+ this !== null
725
+ ? callersByOptions.get(this)
726
+ : undefined
727
+ if (kept !== undefined && kept.runs > 0) {
728
+ callersByOptions.set(this as object, {
729
+ caller: kept.runs > 1 ? kept.caller : undefined,
730
+ runs: kept.runs - 1,
731
+ })
732
+ }
733
+ if (!mayHaveChanged(error)) return
734
+ // The reads of the run mutationFn wrote with, found by the run's
735
+ // context (5.89 and later); else those onMutate returned (before
736
+ // 5.89); else, when an onMutate of the app's replaced ours before
737
+ // 5.89 or onSettled is called by hand, the reads resolved now.
738
+ const run = keptRun(context) ?? runIn(onMutateResult) ?? resolveRun()
739
+ const targets = run.invalidates
740
+ if (targets.length === 0) return
741
+ // Every caller's reads, certified or not: a write changes what the
742
+ // canister answers to everyone. On the QueryClient the mutation ran
743
+ // on, which TanStack (5.89 and later) hands onSettled, as well as the
744
+ // client's own: an app that nests its own QueryClientProvider keeps
745
+ // its reads there (#903).
746
+ const own = owner().queryClient
747
+ const ran = (runKey(context) as { client?: QueryClient } | undefined)
748
+ ?.client
749
+ const queryClients =
750
+ ran !== undefined && ran !== own ? [own, ran] : [own]
751
+ const filters = {
752
+ predicate: ({ queryKey: key }: { queryKey: QueryKey }) =>
753
+ key[0] === KEY_ROOT &&
754
+ key[1] === network &&
755
+ targets.some(
756
+ ({ slots, method: only }) =>
757
+ slots.includes(key[3] as string) &&
758
+ (only === undefined || key[4] === only)
759
+ ),
760
+ }
761
+ await Promise.all(
762
+ queryClients.map((queryClient) =>
763
+ queryClient.invalidateQueries(filters)
764
+ )
765
+ )
766
+ },
767
+ }
768
+ }
769
+
770
+ const resendOf = (
771
+ error: unknown,
772
+ canister: unknown,
773
+ method: unknown,
774
+ options?: { readonly dedupedBy?: unknown }
775
+ ) => {
776
+ const call = "client.resendOf()"
777
+ const record = recordOf(canister, internals, call)
778
+ const prepared = methodOf(record, method, call)
779
+ const { name, args } = prepared
780
+ const dedupedBy = options?.dedupedBy
781
+ if (typeof dedupedBy !== "function") {
782
+ throw new TypeError(
783
+ `[ic-reactor] ${call} needs { dedupedBy: (arg) => key }: what makes ${name} run the same argument at most once, such as an ICRC-1 transfer's created_at_time. ` +
784
+ "A write without one has no safe re-send."
785
+ )
786
+ }
787
+ // Kept only for a write whose outcome is unknown, made on `canister`
788
+ // (`differs` below compares the method).
789
+ const attempt = UNKNOWN_WRITES.get(error as object)
790
+ if (attempt === undefined || attempt.canister !== canister) {
791
+ return undefined
792
+ }
793
+ const { values, caller } = attempt
794
+ const arg = args.length > 1 ? values : values[0]
795
+ if (
796
+ typeof arg !== "object" ||
797
+ arg === null ||
798
+ // The sender, and no one else, may send it again.
799
+ internals.current().principal !== caller.principal ||
800
+ // Only for the method it called, while the argument is what was sent
801
+ // and the canister object still resolves to the canister it went to.
802
+ differs(attempt, prepared, record.resolve(), encodeArgs(args, values)) ||
803
+ (dedupedBy(arg) ?? null) === null
804
+ ) {
805
+ return undefined
806
+ }
807
+ offered.set(arg, attempt)
808
+ const sent = (attempt.encoded as { bytes: Uint8Array }).bytes
809
+ return {
810
+ arg,
811
+ from: caller.principal,
812
+ // A copy on every read: `send()` sends the attempt's own bytes, which
813
+ // nothing outside the client can reach to change.
814
+ get bytes() {
815
+ return sent.slice()
816
+ },
817
+ // The attempt itself: its canister id and the bytes it sent.
818
+ // Marked as a re-send of itself, which it is: a timeout before it
819
+ // goes out keeps its unknown outcome (see `run`).
820
+ send: () => invoke(internals, { ...attempt, again: attempt }),
821
+ }
822
+ }
823
+
824
+ /**
825
+ * The bytes a call of `method` with `vars` sends: the same arity rule and
826
+ * the same encoder as the call path, so they are those bytes, not a second
827
+ * encoding of the value.
828
+ */
829
+ const encode = (canister: unknown, method: unknown, vars: unknown) => {
830
+ const call = "client.encode()"
831
+ const record = recordOf(canister, internals, call)
832
+ const prepared = methodOf(record, method, call)
833
+ const encoded = encodeArgs(prepared.args, valuesOf(prepared, vars))
834
+ if (!encoded.ok) {
835
+ // Marked with the canister, as a call's error is, so that
836
+ // `isReactorError(error, canister, method)` reads its issues.
837
+ throw fromCanister(
838
+ notEncoded(
839
+ { method: prepared.name, canisterId: slotOf(record.resolve()) },
840
+ encoded
841
+ ),
842
+ canister as object
843
+ )
844
+ }
845
+ return encoded.bytes
846
+ }
847
+
848
+ const func = (funcSchema: unknown, ref: unknown) => {
849
+ const call = "client.func()"
850
+ let node: ReturnType<typeof resolveSchema>
851
+ try {
852
+ node = resolveSchema(funcSchema as Parameters<typeof resolveSchema>[0])
853
+ } catch (cause) {
854
+ const error = new TypeError(
855
+ `[ic-reactor] ${call} takes a func schema, such as the generated QueryArchiveFn: ${
856
+ cause instanceof Error ? cause.message : String(cause)
857
+ }.`
858
+ )
859
+ Object.defineProperty(error, "cause", { value: cause })
860
+ throw error
861
+ }
862
+ if (node.kind !== "func") {
863
+ throw new TypeError(
864
+ `[ic-reactor] ${call} takes a func schema, such as the generated QueryArchiveFn; got a ${node.kind} schema.`
865
+ )
866
+ }
867
+ const { principal, method } = (
868
+ typeof ref === "object" && ref !== null ? ref : {}
869
+ ) as { principal?: unknown; method?: unknown }
870
+ if (!isPrincipal(principal)) {
871
+ throw new TypeError(
872
+ `[ic-reactor] ${call}: ${describe(principal)} is not a canister's principal text. Pass the func value the reply carried, { principal, method }.`
873
+ )
874
+ }
875
+ if (typeof method !== "string" || method === "") {
876
+ throw new TypeError(
877
+ `[ic-reactor] ${call}: ${describe(method)} is not a method name. Pass the func value the reply carried, { principal, method }.`
878
+ )
879
+ }
880
+ const prepared = prepareMethod({
881
+ name: method,
882
+ mode: node.mode,
883
+ args: node.args,
884
+ results: node.results,
885
+ })
886
+ const target: ResolvedTarget = { ok: true, id: principal }
887
+ return async (...args: unknown[]): Promise<unknown> =>
888
+ invoke(internals, {
889
+ method: prepared,
890
+ target,
891
+ certified: false,
892
+ caller: internals.current(),
893
+ values: args,
894
+ resend: true,
895
+ })
896
+ }
897
+
898
+ /**
899
+ * The IC's time, from a certified `read_state` of the `time` path routed by
900
+ * the canister's subnet, sent by the caller's agent. The certificate's
901
+ * signature is verified against the network's root key; its freshness is
902
+ * not compared with the host clock, which may be the clock that is wrong
903
+ * (as `HttpAgent.syncTime()` reads it).
904
+ */
905
+ const time = async (canister: unknown): Promise<bigint> => {
906
+ const record = recordOf(canister, internals, "client.time()")
907
+ const target = record.resolve()
908
+ const method = "read_state"
909
+ if (!target.ok) {
910
+ throw createReactorError("invalid_args", {
911
+ method,
912
+ canisterId: target.slot,
913
+ code: "canister_id_unresolved",
914
+ reason: target.message,
915
+ })
916
+ }
917
+ // A read_state is routed by a canister in a subnet's range, and the
918
+ // management canister is in none: the IC would refuse it.
919
+ if (target.id === MANAGEMENT_CANISTER) {
920
+ throw createReactorError("invalid_args", {
921
+ method,
922
+ canisterId: target.id,
923
+ code: "management_canister",
924
+ reason: "the management canister routes no read_state",
925
+ })
926
+ }
927
+ const where = { method, canisterId: target.id }
928
+ const ms = record.timeoutMs
929
+ let timedOut = false
930
+ const read = readTime(where, () => timedOut)
931
+ if (ms === undefined) return read
932
+ // The canister object's timeoutMs bounds the wait from here, as it bounds
933
+ // a call through it: when it passes, the time rejects `cancelled` (code
934
+ // `timeout`), and a read_state not sent yet is never sent. One already
935
+ // out goes on, but nobody waits for it.
936
+ let timer: ReturnType<typeof setTimeout> | undefined
937
+ const timeout = new Promise<never>((_, reject) => {
938
+ timer = setTimeout(() => {
939
+ timedOut = true
940
+ reject(timedOutError(where, false))
941
+ }, ms)
942
+ })
943
+ try {
944
+ return await Promise.race([read, timeout])
945
+ } finally {
946
+ clearTimeout(timer)
947
+ }
948
+ }
949
+
950
+ /**
951
+ * The IC's time, read for `client.time()`. `timedOut` says whether its
952
+ * bound passed while the caller's agent was awaited: nothing is sent then.
953
+ */
954
+ const readTime = async (
955
+ where: { readonly method: string; readonly canisterId: string },
956
+ timedOut: () => boolean
957
+ ): Promise<bigint> => {
958
+ const agent = await internals.agentFor(internals.current().principal, where)
959
+ // As in the call path: a dispose() in the microtask after agentFor's own
960
+ // check still sends nothing.
961
+ if (internals.disposed()) {
962
+ throw createReactorError("cancelled", {
963
+ ...where,
964
+ code: "client_disposed",
965
+ reason: "the client was disposed before the time was read",
966
+ })
967
+ }
968
+ if (timedOut()) throw timedOutError(where, false)
969
+ try {
970
+ // The agent verifies the certificate against the network's root key
971
+ // and the canister's subnet delegation. Its age is not checked: that
972
+ // would compare it with the host's clock, the clock this replaces, and
973
+ // a host clock out by minutes would first make the agent re-sync.
974
+ const { verifiedCertificate } = await agent.readState(
975
+ { canisterId: Principal.fromText(where.canisterId) },
976
+ { paths: [TIME_PATH], disableTimeVerification: true }
977
+ )
978
+ const raw = lookupResultToBuffer(
979
+ verifiedCertificate.lookup_path(TIME_PATH)
980
+ )
981
+ if (raw === undefined) {
982
+ throw new Error("the certificate holds no time")
983
+ }
984
+ return readLeb128(raw)
985
+ } catch (error) {
986
+ throw classifyError(error, { ...where, mode: "query" })
987
+ }
988
+ }
989
+
990
+ return {
991
+ canister: canisterFactory(internals),
992
+ time,
993
+ queryKey,
994
+ queryOptions,
995
+ mutationOptions,
996
+ resendOf,
997
+ encode,
998
+ func,
999
+ } as unknown as Builders
1000
+ }