@lamplitisles/dsh-nanocodex 0.1.0-beta.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 (276) hide show
  1. package/LICENSE +65 -0
  2. package/NOTICE +2 -0
  3. package/README.md +182 -0
  4. package/THIRD_PARTY_NOTICES.md +29 -0
  5. package/cordis.patch.yml +52 -0
  6. package/dist/index.d.ts +435 -0
  7. package/dist/index.js +3405 -0
  8. package/dist/standard-preset.d.ts +7 -0
  9. package/dist/standard-preset.js +25 -0
  10. package/engine-release.json +14 -0
  11. package/package.json +119 -0
  12. package/presets/standard/agent.cordis.yml +6 -0
  13. package/presets/standard/preset.yml +2 -0
  14. package/vendor/nanocodex/README.md +1344 -0
  15. package/vendor/nanocodex/actions/events.d.mts +10 -0
  16. package/vendor/nanocodex/actions/events.mjs +163 -0
  17. package/vendor/nanocodex/actions/index.d.mts +13 -0
  18. package/vendor/nanocodex/actions/index.mjs +35 -0
  19. package/vendor/nanocodex/actions/session.d.mts +66 -0
  20. package/vendor/nanocodex/actions/session.mjs +59 -0
  21. package/vendor/nanocodex/actions/turn.d.mts +59 -0
  22. package/vendor/nanocodex/actions/turn.mjs +37 -0
  23. package/vendor/nanocodex/actions/voice.d.mts +22 -0
  24. package/vendor/nanocodex/actions/voice.mjs +50 -0
  25. package/vendor/nanocodex/browser/Agent.d.mts +55 -0
  26. package/vendor/nanocodex/browser/Agent.mjs +11 -0
  27. package/vendor/nanocodex/browser/ChatGptSubscription.d.mts +7 -0
  28. package/vendor/nanocodex/browser/ChatGptSubscription.mjs +19 -0
  29. package/vendor/nanocodex/browser/InlineAgent.mjs +266 -0
  30. package/vendor/nanocodex/browser/Transport.d.mts +74 -0
  31. package/vendor/nanocodex/browser/Transport.mjs +61 -0
  32. package/vendor/nanocodex/browser/Voice.d.mts +71 -0
  33. package/vendor/nanocodex/browser/Voice.mjs +291 -0
  34. package/vendor/nanocodex/browser/VoiceSession.mjs +688 -0
  35. package/vendor/nanocodex/browser/WorkerAgent.d.mts +65 -0
  36. package/vendor/nanocodex/browser/WorkerAgent.mjs +1472 -0
  37. package/vendor/nanocodex/browser/agent.worker.mjs +3 -0
  38. package/vendor/nanocodex/browser/config.d.mts +36 -0
  39. package/vendor/nanocodex/browser/config.mjs +439 -0
  40. package/vendor/nanocodex/browser/engine.mjs +13 -0
  41. package/vendor/nanocodex/browser/harness.mjs +55 -0
  42. package/vendor/nanocodex/browser/host.d.mts +83 -0
  43. package/vendor/nanocodex/browser/host.mjs +555 -0
  44. package/vendor/nanocodex/browser/hostManagedWebSocket.d.mts +14 -0
  45. package/vendor/nanocodex/browser/hostManagedWebSocket.mjs +110 -0
  46. package/vendor/nanocodex/browser/index.d.mts +92 -0
  47. package/vendor/nanocodex/browser/index.mjs +23 -0
  48. package/vendor/nanocodex/browser/indexeddb-durability-store.mjs +197 -0
  49. package/vendor/nanocodex/browser/workspace.d.mts +16 -0
  50. package/vendor/nanocodex/browser/workspace.mjs +107 -0
  51. package/vendor/nanocodex/cloud/Client.d.mts +83 -0
  52. package/vendor/nanocodex/cloud/Client.mjs +231 -0
  53. package/vendor/nanocodex/cloud/Decorator.d.mts +31 -0
  54. package/vendor/nanocodex/cloud/Decorator.mjs +37 -0
  55. package/vendor/nanocodex/cloud/Dialog.d.mts +113 -0
  56. package/vendor/nanocodex/cloud/Dialog.mjs +366 -0
  57. package/vendor/nanocodex/cloud/Errors.d.mts +22 -0
  58. package/vendor/nanocodex/cloud/Errors.mjs +39 -0
  59. package/vendor/nanocodex/cloud/Principal.d.mts +26 -0
  60. package/vendor/nanocodex/cloud/Principal.mjs +88 -0
  61. package/vendor/nanocodex/cloud/RemoteProvider.mjs +88 -0
  62. package/vendor/nanocodex/cloud/Transport.d.mts +47 -0
  63. package/vendor/nanocodex/cloud/Transport.mjs +454 -0
  64. package/vendor/nanocodex/cloud/actions/account.d.mts +9 -0
  65. package/vendor/nanocodex/cloud/actions/account.mjs +19 -0
  66. package/vendor/nanocodex/cloud/actions/agent.d.mts +18 -0
  67. package/vendor/nanocodex/cloud/actions/agent.mjs +428 -0
  68. package/vendor/nanocodex/cloud/actions/connection.d.mts +133 -0
  69. package/vendor/nanocodex/cloud/actions/connection.mjs +580 -0
  70. package/vendor/nanocodex/cloud/actions/grant.d.mts +10 -0
  71. package/vendor/nanocodex/cloud/actions/grant.mjs +12 -0
  72. package/vendor/nanocodex/cloud/actions/index.d.mts +7 -0
  73. package/vendor/nanocodex/cloud/actions/index.mjs +7 -0
  74. package/vendor/nanocodex/cloud/actions/machineUsd.d.mts +23 -0
  75. package/vendor/nanocodex/cloud/actions/machineUsd.mjs +37 -0
  76. package/vendor/nanocodex/cloud/actions/model.d.mts +12 -0
  77. package/vendor/nanocodex/cloud/actions/model.mjs +50 -0
  78. package/vendor/nanocodex/cloud/actions/mpp.d.mts +28 -0
  79. package/vendor/nanocodex/cloud/actions/mpp.mjs +39 -0
  80. package/vendor/nanocodex/cloud/index.d.mts +30 -0
  81. package/vendor/nanocodex/cloud/index.mjs +9 -0
  82. package/vendor/nanocodex/cloud/internal.mjs +533 -0
  83. package/vendor/nanocodex/cloud/mercator.mjs +108 -0
  84. package/vendor/nanocodex/cloud/server/HostPrincipal.d.mts +34 -0
  85. package/vendor/nanocodex/cloud/server/HostPrincipal.mjs +202 -0
  86. package/vendor/nanocodex/cloud/server/index.d.mts +1 -0
  87. package/vendor/nanocodex/cloud/server/index.mjs +1 -0
  88. package/vendor/nanocodex/cloud/types.d.mts +211 -0
  89. package/vendor/nanocodex/cloudflare/Agent.d.mts +133 -0
  90. package/vendor/nanocodex/cloudflare/Agent.mjs +811 -0
  91. package/vendor/nanocodex/cloudflare/egress-subject.mjs +19 -0
  92. package/vendor/nanocodex/cloudflare/egress.d.mts +41 -0
  93. package/vendor/nanocodex/cloudflare/egress.mjs +119 -0
  94. package/vendor/nanocodex/cloudflare/event-socket.mjs +316 -0
  95. package/vendor/nanocodex/cloudflare/index.d.mts +7 -0
  96. package/vendor/nanocodex/cloudflare/index.mjs +6 -0
  97. package/vendor/nanocodex/host/Agent.d.mts +55 -0
  98. package/vendor/nanocodex/host/Agent.mjs +1 -0
  99. package/vendor/nanocodex/host/index.d.mts +82 -0
  100. package/vendor/nanocodex/host/index.mjs +10 -0
  101. package/vendor/nanocodex/index.d.mts +81 -0
  102. package/vendor/nanocodex/index.mjs +12 -0
  103. package/vendor/nanocodex/internal.mjs +1275 -0
  104. package/vendor/nanocodex/managed/Agent.d.mts +380 -0
  105. package/vendor/nanocodex/managed/Agent.mjs +1694 -0
  106. package/vendor/nanocodex/managed/ManagedError.d.mts +9 -0
  107. package/vendor/nanocodex/managed/ManagedError.mjs +8 -0
  108. package/vendor/nanocodex/managed/README.md +241 -0
  109. package/vendor/nanocodex/managed/Voice.mjs +202 -0
  110. package/vendor/nanocodex/managed/index.d.mts +20 -0
  111. package/vendor/nanocodex/managed/index.mjs +2 -0
  112. package/vendor/nanocodex/managed/internal.mjs +119 -0
  113. package/vendor/nanocodex/node/Agent.d.mts +50 -0
  114. package/vendor/nanocodex/node/Agent.mjs +203 -0
  115. package/vendor/nanocodex/node/ChatGptSubscription.d.mts +9 -0
  116. package/vendor/nanocodex/node/ChatGptSubscription.mjs +17 -0
  117. package/vendor/nanocodex/node/Transport.d.mts +44 -0
  118. package/vendor/nanocodex/node/Transport.mjs +46 -0
  119. package/vendor/nanocodex/node/host.mjs +731 -0
  120. package/vendor/nanocodex/node/index.d.mts +73 -0
  121. package/vendor/nanocodex/node/index.mjs +17 -0
  122. package/vendor/nanocodex/node/workspace.d.mts +10 -0
  123. package/vendor/nanocodex/node/workspace.mjs +198 -0
  124. package/vendor/nanocodex/package.json +200 -0
  125. package/vendor/nanocodex/pkg-node/nanocodex.d.ts +675 -0
  126. package/vendor/nanocodex/pkg-node/nanocodex.js +2628 -0
  127. package/vendor/nanocodex/pkg-node/nanocodex_bg.wasm.d.ts +105 -0
  128. package/vendor/nanocodex/pkg-node/package.json +1 -0
  129. package/vendor/nanocodex/pkg-web/.nanocodex-bindgen-stamp +6 -0
  130. package/vendor/nanocodex/pkg-web/nanocodex-build.json +1 -0
  131. package/vendor/nanocodex/pkg-web/nanocodex.d.ts +805 -0
  132. package/vendor/nanocodex/pkg-web/nanocodex.js +2714 -0
  133. package/vendor/nanocodex/pkg-web/nanocodex_bg.js +2615 -0
  134. package/vendor/nanocodex/pkg-web/nanocodex_bg.wasm +0 -0
  135. package/vendor/nanocodex/pkg-web/nanocodex_bg.wasm.d.ts +105 -0
  136. package/vendor/nanocodex/pkg-web/nanocodex_worker.js +9 -0
  137. package/vendor/nanocodex/pkg-web/package.json +1 -0
  138. package/vendor/nanocodex/runtime/chatgpt-subscription.mjs +212 -0
  139. package/vendor/nanocodex/runtime/cloudflare-durability-store.d.mts +26 -0
  140. package/vendor/nanocodex/runtime/cloudflare-durability-store.mjs +168 -0
  141. package/vendor/nanocodex/runtime/code-evaluator.worker.mjs +137 -0
  142. package/vendor/nanocodex/runtime/code-runtime.mjs +1 -0
  143. package/vendor/nanocodex/runtime/durability-store.d.mts +85 -0
  144. package/vendor/nanocodex/runtime/durability-store.mjs +631 -0
  145. package/vendor/nanocodex/runtime/durability.mjs +153 -0
  146. package/vendor/nanocodex/runtime/managed-transport.mjs +460 -0
  147. package/vendor/nanocodex/runtime/mcp-runtime.mjs +534 -0
  148. package/vendor/nanocodex/runtime/postgres-durability-store.d.mts +64 -0
  149. package/vendor/nanocodex/runtime/postgres-durability-store.mjs +532 -0
  150. package/vendor/nanocodex/runtime/quickjs-evaluator.d.mts +17 -0
  151. package/vendor/nanocodex/runtime/quickjs-evaluator.mjs +236 -0
  152. package/vendor/nanocodex/runtime/responses-transport.mjs +22 -0
  153. package/vendor/nanocodex/runtime/subagents.d.mts +107 -0
  154. package/vendor/nanocodex/runtime/subagents.mjs +54 -0
  155. package/vendor/nanocodex/runtime/subscription-store.d.mts +8 -0
  156. package/vendor/nanocodex/runtime/subscription-store.mjs +42 -0
  157. package/vendor/nanocodex/runtime/tempo-provider.d.mts +125 -0
  158. package/vendor/nanocodex/runtime/tempo-provider.mjs +264 -0
  159. package/vendor/nanocodex/runtime/tool-configuration.mjs +1 -0
  160. package/vendor/nanocodex/runtime/tool-router.mjs +1 -0
  161. package/vendor/nanocodex/runtime/utf8.mjs +1 -0
  162. package/vendor/nanocodex/runtime/worker-evaluator.mjs +162 -0
  163. package/vendor/nanocodex/runtime/workspace.d.mts +1 -0
  164. package/vendor/nanocodex/runtime/workspace.mjs +1 -0
  165. package/vendor/nanocodex/tools/Tools.d.mts +56 -0
  166. package/vendor/nanocodex/tools/Tools.mjs +136 -0
  167. package/vendor/nanocodex/tools/artifact.d.mts +1 -0
  168. package/vendor/nanocodex/tools/artifact.mjs +1 -0
  169. package/vendor/nanocodex/tools/attachment.mjs +1 -0
  170. package/vendor/nanocodex/tools/bash.d.mts +1 -0
  171. package/vendor/nanocodex/tools/bash.mjs +1 -0
  172. package/vendor/nanocodex/tools/browser/accountInfo.mjs +795 -0
  173. package/vendor/nanocodex/tools/browser/browserBuffer.mjs +18 -0
  174. package/vendor/nanocodex/tools/browser/browserCompiler.mjs +155 -0
  175. package/vendor/nanocodex/tools/browser/browserEgress.mjs +161 -0
  176. package/vendor/nanocodex/tools/browser/browserPython.mjs +133 -0
  177. package/vendor/nanocodex/tools/browser/browserShell.mjs +1075 -0
  178. package/vendor/nanocodex/tools/browser/browserSprintf.mjs +4 -0
  179. package/vendor/nanocodex/tools/browser/browserSsh.mjs +201 -0
  180. package/vendor/nanocodex/tools/browser/browserZlib.mjs +136 -0
  181. package/vendor/nanocodex/tools/browser/compiler.worker.mjs +160 -0
  182. package/vendor/nanocodex/tools/browser/devTunnelsSshBrowser.mjs +13 -0
  183. package/vendor/nanocodex/tools/browser/index.d.mts +209 -0
  184. package/vendor/nanocodex/tools/browser/index.mjs +174 -0
  185. package/vendor/nanocodex/tools/browser/opfsGit.mjs +248 -0
  186. package/vendor/nanocodex/tools/browser/python.worker.mjs +114 -0
  187. package/vendor/nanocodex/tools/browser/threadGit.mjs +197 -0
  188. package/vendor/nanocodex/tools/browser/unsupportedNodeRsa.mjs +5 -0
  189. package/vendor/nanocodex/tools/browser/workspace.mjs +83 -0
  190. package/vendor/nanocodex/tools/dataset.d.mts +1 -0
  191. package/vendor/nanocodex/tools/dataset.mjs +1 -0
  192. package/vendor/nanocodex/tools/datasetContract.mjs +1 -0
  193. package/vendor/nanocodex/tools/datasetEngine.mjs +1 -0
  194. package/vendor/nanocodex/tools/hostedCatalog.d.mts +1 -0
  195. package/vendor/nanocodex/tools/hostedCatalog.mjs +1 -0
  196. package/vendor/nanocodex/tools/index.d.mts +49 -0
  197. package/vendor/nanocodex/tools/index.mjs +19 -0
  198. package/vendor/nanocodex/tools/namedTool.mjs +1 -0
  199. package/vendor/nanocodex/tools/repository-workspace.d.mts +1 -0
  200. package/vendor/nanocodex/tools/repository-workspace.mjs +1 -0
  201. package/vendor/nanocodex/tools/ssh.d.mts +1 -0
  202. package/vendor/nanocodex/tools/ssh.mjs +1 -0
  203. package/vendor/nanocodex/tools/standard.mjs +1 -0
  204. package/vendor/nanocodex/tools/standardDescriptions.mjs +1 -0
  205. package/vendor/nanocodex/types.d.mts +663 -0
  206. package/vendor/nanocodex/wasm.d.mts +4 -0
  207. package/vendor/nanocodex/worker/ChatGptSubscription.d.mts +9 -0
  208. package/vendor/nanocodex/worker/ChatGptSubscription.mjs +29 -0
  209. package/vendor/nanocodex/worker/index.d.mts +18 -0
  210. package/vendor/nanocodex/worker/index.mjs +5 -0
  211. package/vendor/nanocodex-tools/README.md +65 -0
  212. package/vendor/nanocodex-tools/dist/hosted/app-tool-catalog.d.ts +7 -0
  213. package/vendor/nanocodex-tools/dist/hosted/app-tool-catalog.js +14 -0
  214. package/vendor/nanocodex-tools/dist/hosted/broker-core.d.ts +172 -0
  215. package/vendor/nanocodex-tools/dist/hosted/broker-core.js +1278 -0
  216. package/vendor/nanocodex-tools/dist/hosted/index.d.ts +3 -0
  217. package/vendor/nanocodex-tools/dist/hosted/index.js +3 -0
  218. package/vendor/nanocodex-tools/dist/hosted/protocol.d.ts +120 -0
  219. package/vendor/nanocodex-tools/dist/hosted/protocol.js +415 -0
  220. package/vendor/nanocodex-tools/dist/index.d.ts +19 -0
  221. package/vendor/nanocodex-tools/dist/index.js +14 -0
  222. package/vendor/nanocodex-tools/dist/memory.d.ts +204 -0
  223. package/vendor/nanocodex-tools/dist/memory.js +411 -0
  224. package/vendor/nanocodex-tools/dist/namespace.d.ts +87 -0
  225. package/vendor/nanocodex-tools/dist/namespace.js +338 -0
  226. package/vendor/nanocodex-tools/dist/repository-archive.d.ts +4 -0
  227. package/vendor/nanocodex-tools/dist/repository-archive.js +104 -0
  228. package/vendor/nanocodex-tools/dist/runtime.d.ts +30 -0
  229. package/vendor/nanocodex-tools/dist/runtime.js +37 -0
  230. package/vendor/nanocodex-tools/dist/session.d.ts +167 -0
  231. package/vendor/nanocodex-tools/dist/session.js +286 -0
  232. package/vendor/nanocodex-tools/dist/shell.d.ts +51 -0
  233. package/vendor/nanocodex-tools/dist/shell.js +553 -0
  234. package/vendor/nanocodex-tools/dist/ssh.d.ts +29 -0
  235. package/vendor/nanocodex-tools/dist/ssh.js +66 -0
  236. package/vendor/nanocodex-tools/dist/workspace.d.ts +45 -0
  237. package/vendor/nanocodex-tools/dist/workspace.js +237 -0
  238. package/vendor/nanocodex-tools/package.json +122 -0
  239. package/vendor/nanocodex-tools/runtime/code-runtime.mjs +817 -0
  240. package/vendor/nanocodex-tools/runtime/tool-configuration.mjs +50 -0
  241. package/vendor/nanocodex-tools/runtime/tool-router.mjs +730 -0
  242. package/vendor/nanocodex-tools/runtime/utf8.d.mts +2 -0
  243. package/vendor/nanocodex-tools/runtime/utf8.mjs +25 -0
  244. package/vendor/nanocodex-tools/tools/artifact.d.mts +69 -0
  245. package/vendor/nanocodex-tools/tools/artifact.mjs +270 -0
  246. package/vendor/nanocodex-tools/tools/attachment.mjs +603 -0
  247. package/vendor/nanocodex-tools/tools/bash.d.mts +90 -0
  248. package/vendor/nanocodex-tools/tools/bash.mjs +742 -0
  249. package/vendor/nanocodex-tools/tools/dataset.d.mts +9 -0
  250. package/vendor/nanocodex-tools/tools/dataset.mjs +47 -0
  251. package/vendor/nanocodex-tools/tools/datasetContract.mjs +54 -0
  252. package/vendor/nanocodex-tools/tools/datasetEngine.mjs +1167 -0
  253. package/vendor/nanocodex-tools/tools/execution-contract.d.mts +5 -0
  254. package/vendor/nanocodex-tools/tools/execution-contract.mjs +63 -0
  255. package/vendor/nanocodex-tools/tools/hostedCatalog.d.mts +20 -0
  256. package/vendor/nanocodex-tools/tools/hostedCatalog.mjs +67 -0
  257. package/vendor/nanocodex-tools/tools/hostedMachine.d.mts +10 -0
  258. package/vendor/nanocodex-tools/tools/hostedMachine.mjs +56 -0
  259. package/vendor/nanocodex-tools/tools/just-bash-browser.d.mts +1 -0
  260. package/vendor/nanocodex-tools/tools/just-bash-browser.mjs +1 -0
  261. package/vendor/nanocodex-tools/tools/namedTool.d.mts +3 -0
  262. package/vendor/nanocodex-tools/tools/namedTool.mjs +3 -0
  263. package/vendor/nanocodex-tools/tools/nodeProcess.d.mts +10 -0
  264. package/vendor/nanocodex-tools/tools/nodeProcess.mjs +314 -0
  265. package/vendor/nanocodex-tools/tools/processOutput.mjs +56 -0
  266. package/vendor/nanocodex-tools/tools/repository-workspace.d.mts +55 -0
  267. package/vendor/nanocodex-tools/tools/repository-workspace.mjs +397 -0
  268. package/vendor/nanocodex-tools/tools/ssh.d.mts +56 -0
  269. package/vendor/nanocodex-tools/tools/ssh.mjs +503 -0
  270. package/vendor/nanocodex-tools/tools/standard.mjs +458 -0
  271. package/vendor/nanocodex-tools/tools/standardDescriptions.mjs +3 -0
  272. package/vendor/nanocodex-tools/tools/types.d.mts +83 -0
  273. package/vendor/nanocodex-tools/tools/workspace.d.mts +25 -0
  274. package/vendor/nanocodex-tools/tools/workspace.mjs +282 -0
  275. package/vendor/nanocodex-tools/tools/x.d.mts +30 -0
  276. package/vendor/nanocodex-tools/tools/x.mjs +91 -0
@@ -0,0 +1,580 @@
1
+ import {
2
+ connectionRequestFromGrant,
3
+ connectionFromWire,
4
+ connectionMatchesRequest,
5
+ reconnectRequestFromConnection,
6
+ } from "../internal.mjs";
7
+ import { InvalidResponseError } from "../Errors.mjs";
8
+ import {
9
+ hostedAppToolCatalog,
10
+ hostedToolCatalogDigest,
11
+ } from "../../tools/hostedCatalog.mjs";
12
+
13
+ const CLOUD_ACCOUNT_PROVIDERS = Object.freeze([
14
+ "github",
15
+ "gmail",
16
+ "gdrive",
17
+ "gcalendar",
18
+ "gtasks",
19
+ "gdocs",
20
+ "gsheets",
21
+ "gslides",
22
+ "gcontacts",
23
+ "slack",
24
+ "x",
25
+ "chatgpt",
26
+ ]);
27
+ const CONNECTOR_RESOURCE_PREFIX = "urn:nanocodex:connector:";
28
+ const CONNECTORS_RESOURCE_PREFIX = "urn:nanocodex:connectors:";
29
+ const APP_RESOURCE_PREFIX = "urn:nanocodex:app:";
30
+ const APP_ORIGIN_RESOURCE_PREFIX = "urn:nanocodex:origin:";
31
+ const APP_TOOL_CATALOG_RESOURCE_PREFIX = "urn:nanocodex:app-tool-catalog:sha256:";
32
+ const HOSTED_AUTHORIZATION_RESOURCE = "urn:nanocodex:authorization:hosted";
33
+ const HOST_PRINCIPAL_EXCHANGE_RESOURCE_PREFIX = "urn:nanocodex:host-principal:exchange:";
34
+ const HOST_PRINCIPAL_ID = /^[A-Za-z0-9_-]{43}$/;
35
+ const MPP_RESOURCE_PREFIX = "urn:nanocodex:mpp:";
36
+ const MCP_CONNECTION_ID = /^[A-Za-z0-9_-]{43}$/;
37
+ const MCP_CONNECTION_RESOURCE_PREFIX = "urn:nanocodex:mcp:";
38
+ const MCP_FOCUS_RESOURCE_PREFIX = "urn:nanocodex:mcp-focus:";
39
+ const AGENT_VISIBILITY_RESOURCES = Object.freeze({
40
+ finalMessages: "urn:nanocodex:agent:output:final",
41
+ actionSummaries: "urn:nanocodex:agent:output:actions",
42
+ conversationHistory: "urn:nanocodex:agent:history:read",
43
+ rawTraces: "urn:nanocodex:agent:trace:read",
44
+ });
45
+ const AGENT_VISIBILITY_RESOURCE_PREFIX = "urn:nanocodex:agent:visibility:";
46
+ const AGENT_CONVERSATION_RESOURCE_PREFIX = "urn:nanocodex:agent:conversation:";
47
+ const AGENT_CONVERSATION_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
48
+ const AGENT_VISIBILITY_NAMES = Object.freeze({
49
+ finalMessages: "reply",
50
+ actionSummaries: "actions",
51
+ conversationHistory: "history",
52
+ rawTraces: "traces",
53
+ });
54
+
55
+ export async function connect(client, options) {
56
+ options ??= {};
57
+ const permission = options.permission ?? "agent.run";
58
+ if (typeof permission !== "string" || permission.length === 0) throw new TypeError("connect permission must be a non-empty string");
59
+ const requestedConnectors = normalizeCloudAccounts(options.capabilities?.cloudAccounts);
60
+ const agentVisibility = normalizeAgentVisibility(options.capabilities?.agent);
61
+ const authorization = options.authorization ?? (client.principal ? "hosted" : "access_key");
62
+ if (authorization !== "access_key" && authorization !== "hosted") {
63
+ throw new TypeError("connect authorization must be access_key or hosted");
64
+ }
65
+ if (client.principal && authorization !== "hosted") {
66
+ throw new TypeError("host principal connections require hosted authorization");
67
+ }
68
+ if (client.principal && options.capabilities?.authorizeAccessKey !== undefined) {
69
+ throw new TypeError("host principal connections cannot request access-key or MPP authority");
70
+ }
71
+ const appToolCatalog = hostedAppToolCatalog(options.tools ?? []);
72
+ const appToolCatalogDigest = appToolCatalog.length === 0
73
+ ? undefined
74
+ : await hostedToolCatalogDigest(appToolCatalog);
75
+ const conversationId = normalizeAgentConversationId(options.conversationId);
76
+ const mcpConnections = normalizeMcpConnections(options.mcpConnections ?? []);
77
+ const focusMcpConnectionId = normalizeMcpFocus(options.focusMcpConnectionId, mcpConnections);
78
+ const exactRequest = connectionRequestFromGrant({
79
+ connectors: requestedConnectors,
80
+ mcpConnections,
81
+ permission,
82
+ visibility: agentVisibility,
83
+ authorization,
84
+ ...(appToolCatalogDigest ? { appToolCatalogDigest } : {}),
85
+ ...(conversationId ? { conversationId } : {}),
86
+ });
87
+ const baseAuth = withConnectionResources(
88
+ options.capabilities?.auth ?? client.auth,
89
+ client.appId,
90
+ client.appOrigin,
91
+ requestedConnectors,
92
+ agentVisibility,
93
+ mcpConnections,
94
+ focusMcpConnectionId,
95
+ conversationId,
96
+ authorization,
97
+ appToolCatalogDigest,
98
+ );
99
+ if (client.principal
100
+ && baseAuth.resources.some((resource) => resource.startsWith(MPP_RESOURCE_PREFIX))) {
101
+ throw new TypeError("host principal connections cannot request access-key or MPP authority");
102
+ }
103
+ const principalExchange = client.principal
104
+ ? await client.principal.create({ resources: baseAuth.resources, signal: options.signal })
105
+ : undefined;
106
+ const auth = principalExchange
107
+ ? withHostPrincipalExchange(baseAuth, principalExchange.token)
108
+ : baseAuth;
109
+ const walletAuth = delegateAuthVerification(auth);
110
+ if (!principalExchange) client.dialog.showWallet?.();
111
+ let connected = false;
112
+ try {
113
+ if (!principalExchange) await client.dialog.waitForWallet?.();
114
+ const activeAccount = authorization === "access_key" && !client.principal
115
+ ? activeAccountAddress(client.provider)
116
+ : undefined;
117
+ const reusable = activeAccount
118
+ ? await registeredAccessKey(client, activeAccount, options.signal)
119
+ : undefined;
120
+ // Reuse only keys already registered with the Connect control plane. Older
121
+ // browser-only keys are replaced in this same passkey ceremony, after which
122
+ // both the private signer and public grant record remain durable.
123
+ const authorizeAccessKey = authorization === "hosted"
124
+ ? undefined
125
+ : options.capabilities?.authorizeAccessKey
126
+ ?? (reusable
127
+ ? undefined
128
+ : freshAccessKeyAuthorization(client.accessKey?.authorize));
129
+ const result = await client.provider.request({
130
+ method: "wallet_connect",
131
+ params: [{
132
+ chainId: "0x1079",
133
+ capabilities: {
134
+ ...(walletAuth ? { auth: walletAuth } : {}),
135
+ ...(authorizeAccessKey ? { authorizeAccessKey: serializeAuthorizeAccessKey(authorizeAccessKey) } : {}),
136
+ },
137
+ }],
138
+ ...(!principalExchange && mcpConnections.length === 0 ? {} : {
139
+ context: {
140
+ ...(principalExchange ? { hostPrincipal: principalExchange } : {}),
141
+ ...(mcpConnections.length === 0 ? {} : {
142
+ requestedMcpConnections: mcpConnections.map(({ id, name }) => ({
143
+ id,
144
+ name,
145
+ status: "authorization_required",
146
+ })),
147
+ }),
148
+ ...(focusMcpConnectionId ? { focusMcpConnection: focusMcpConnectionId } : {}),
149
+ },
150
+ }),
151
+ });
152
+ const account = result.accounts?.[0];
153
+ if (!account) throw new Error("Nanocodex Connect returned no account");
154
+ const hostPrincipalId = principalExchange
155
+ ? account.principal?.kind === "host" && HOST_PRINCIPAL_ID.test(account.principal?.id)
156
+ ? account.principal.id
157
+ : undefined
158
+ : undefined;
159
+ if (principalExchange && !hostPrincipalId) {
160
+ throw new Error("Nanocodex Connect returned no host principal");
161
+ }
162
+ if (!principalExchange && typeof account.address !== "string") {
163
+ throw new Error("Nanocodex Connect returned no wallet account");
164
+ }
165
+ const approvalId = account.capabilities?.auth?.approval_id;
166
+ if (typeof approvalId !== "string" || approvalId.length === 0) {
167
+ throw new Error("Nanocodex Connect returned no signed approval identifier");
168
+ }
169
+ const keyAuthorization = account.capabilities?.keyAuthorization;
170
+ const preflightKeyMatchesAccount = reusable
171
+ && typeof activeAccount === "string"
172
+ && activeAccount.toLowerCase() === account.address.toLowerCase();
173
+ const reusedAccessKey = authorization === "hosted"
174
+ ? undefined
175
+ : keyAuthorization
176
+ ? undefined
177
+ : preflightKeyMatchesAccount
178
+ ? reusable
179
+ : await registeredAccessKey(client, account.address, options.signal);
180
+ if (authorization === "access_key" && !keyAuthorization && !reusedAccessKey) {
181
+ throw new Error("Nanocodex Connect returned no new or reusable access key");
182
+ }
183
+ const wire = await client.request({
184
+ method: "POST",
185
+ path: "/v1/connections",
186
+ body: {
187
+ app_id: client.appId,
188
+ ...(hostPrincipalId
189
+ ? { principal: { kind: "host", id: hostPrincipalId } }
190
+ : { account_address: account.address }),
191
+ approval_id: approvalId,
192
+ authorization_mode: authorization,
193
+ ...(authorization === "hosted" ? {} : keyAuthorization ? {
194
+ key_authorization: keyAuthorization,
195
+ signed_key_authorization: account.capabilities?.personalSign?.keyAuthorization,
196
+ } : {
197
+ reuse_access_key: reusedAccessKey,
198
+ }),
199
+ permission,
200
+ ...(requestedConnectors.length === 0 ? {} : { requested_connectors: requestedConnectors }),
201
+ ...(mcpConnections.length === 0
202
+ ? {}
203
+ : { requested_mcp_connections: mcpConnections.map(({ id }) => id) }),
204
+ ...(appToolCatalogDigest ? { requested_app_tool_catalog_digest: appToolCatalogDigest } : {}),
205
+ },
206
+ signal: options.signal,
207
+ });
208
+ const grantToken = wire?.grant_token;
209
+ if (typeof grantToken !== "string" || grantToken.length === 0) {
210
+ throw new Error("Nanocodex Connect returned no grant-scoped session");
211
+ }
212
+ const connection = connectionFromWire(wire);
213
+ if (!connectionMatchesRequest(connection, exactRequest)) {
214
+ throw new InvalidResponseError("Nanocodex Connect returned a grant outside the exact approved request");
215
+ }
216
+ if (hostPrincipalId && connection.principal?.id !== hostPrincipalId) {
217
+ throw new InvalidResponseError("Nanocodex Connect returned a different host principal");
218
+ }
219
+ if (!hostPrincipalId && connection.principal) {
220
+ throw new InvalidResponseError("Nanocodex Connect replaced the wallet account with a host principal");
221
+ }
222
+ client._setSession({
223
+ grantId: connection.grant.id,
224
+ token: grantToken,
225
+ connection: sessionConnectionWire(wire),
226
+ ...(principalExchange ? { resources: baseAuth.resources } : {}),
227
+ });
228
+ connected = true;
229
+ return connection;
230
+ } finally {
231
+ // The host stays covered until the grant session is committed. React owns
232
+ // manual closure from a layout effect so its connected tree is committed
233
+ // before the modal disappears; imperative callers retain automatic close.
234
+ if (!connected || options.dialog?.close !== "manual") {
235
+ client.dialog.hideWallet?.();
236
+ }
237
+ }
238
+ }
239
+
240
+ // The Nanocodex wallet host owns the complete SIWE ceremony so it can keep
241
+ // the authenticated session in the iframe while the user resolves requested
242
+ // connectors. Omitting `verify` here also prevents the forwarding Provider
243
+ // from replaying the wallet host's one-time challenge after approval.
244
+ function delegateAuthVerification(auth) {
245
+ if (!auth || typeof auth === "string") return auth;
246
+ const { verify: _verify, ...forwarded } = auth;
247
+ return forwarded;
248
+ }
249
+
250
+ function normalizeCloudAccounts(cloudAccounts) {
251
+ if (!cloudAccounts || typeof cloudAccounts !== "object" || Array.isArray(cloudAccounts)) return [];
252
+ return CLOUD_ACCOUNT_PROVIDERS.filter((provider) => cloudAccounts[provider] === true);
253
+ }
254
+
255
+ function normalizeAgentVisibility(agent) {
256
+ const rawTraces = agent?.rawTraces === true;
257
+ return Object.freeze({
258
+ finalMessages: rawTraces || agent?.finalMessages !== false,
259
+ actionSummaries: rawTraces || agent?.actionSummaries !== false,
260
+ conversationHistory: rawTraces || agent?.conversationHistory === true,
261
+ rawTraces,
262
+ });
263
+ }
264
+
265
+ function normalizeAgentConversationId(value) {
266
+ if (value === undefined) return undefined;
267
+ if (typeof value !== "string" || !AGENT_CONVERSATION_ID.test(value)) {
268
+ throw new TypeError("conversationId must be a lowercase UUIDv4");
269
+ }
270
+ return value;
271
+ }
272
+
273
+ function normalizeMcpConnections(value) {
274
+ if (!Array.isArray(value) || value.length > 16) {
275
+ throw new TypeError("mcpConnections must be an array of at most 16 pre-registered connections");
276
+ }
277
+ const ids = new Set();
278
+ return Object.freeze(value.map((connection) => {
279
+ if (!connection || typeof connection !== "object"
280
+ || typeof connection.id !== "string" || !MCP_CONNECTION_ID.test(connection.id)
281
+ || typeof connection.name !== "string" || connection.name.length < 1
282
+ || connection.name.length > 256 || connection.name.trim() !== connection.name
283
+ || ids.has(connection.id)) {
284
+ throw new TypeError("mcpConnections must contain unique opaque 43-character IDs and bounded display names");
285
+ }
286
+ ids.add(connection.id);
287
+ return Object.freeze({ id: connection.id, name: connection.name });
288
+ }));
289
+ }
290
+
291
+ function normalizeMcpFocus(value, connections) {
292
+ if (value === undefined) return undefined;
293
+ if (typeof value !== "string" || !MCP_CONNECTION_ID.test(value)
294
+ || !connections.some(({ id }) => id === value)) {
295
+ throw new TypeError("focusMcpConnectionId must identify one requested MCP connection");
296
+ }
297
+ return value;
298
+ }
299
+
300
+ function withConnectionResources(
301
+ auth,
302
+ appId,
303
+ appOrigin,
304
+ requestedConnectors,
305
+ agentVisibility,
306
+ mcpConnections,
307
+ focusMcpConnectionId,
308
+ conversationId,
309
+ authorization,
310
+ appToolCatalogDigest,
311
+ ) {
312
+ const configured = typeof auth === "object" && auth !== null
313
+ ? (auth.resources ?? []).filter((resource) =>
314
+ !Object.values(AGENT_VISIBILITY_RESOURCES).includes(resource)
315
+ && !resource.startsWith(AGENT_VISIBILITY_RESOURCE_PREFIX)
316
+ && !resource.startsWith(AGENT_CONVERSATION_RESOURCE_PREFIX)
317
+ && !resource.startsWith(CONNECTOR_RESOURCE_PREFIX)
318
+ && !resource.startsWith(CONNECTORS_RESOURCE_PREFIX)
319
+ && !resource.startsWith(MCP_CONNECTION_RESOURCE_PREFIX)
320
+ && !resource.startsWith(MCP_FOCUS_RESOURCE_PREFIX)
321
+ && !resource.startsWith(APP_RESOURCE_PREFIX)
322
+ && !resource.startsWith(APP_ORIGIN_RESOURCE_PREFIX)
323
+ && !resource.startsWith(APP_TOOL_CATALOG_RESOURCE_PREFIX)
324
+ && !resource.startsWith(HOST_PRINCIPAL_EXCHANGE_RESOURCE_PREFIX)
325
+ && resource !== HOSTED_AUTHORIZATION_RESOURCE)
326
+ : [];
327
+ const visibility = Object.entries(AGENT_VISIBILITY_NAMES)
328
+ .filter(([name]) => agentVisibility[name])
329
+ .map(([, value]) => value);
330
+ const resources = [...new Set([
331
+ ...configured,
332
+ `${APP_RESOURCE_PREFIX}${encodeURIComponent(appId)}`,
333
+ ...(appOrigin ? [`${APP_ORIGIN_RESOURCE_PREFIX}${encodeURIComponent(appOrigin)}`] : []),
334
+ ...(requestedConnectors.length === 0
335
+ ? []
336
+ : [`${CONNECTORS_RESOURCE_PREFIX}${requestedConnectors.join(",")}`]),
337
+ ...(visibility.length === 0
338
+ ? []
339
+ : [`${AGENT_VISIBILITY_RESOURCE_PREFIX}${visibility.join(",")}`]),
340
+ ...(conversationId ? [`${AGENT_CONVERSATION_RESOURCE_PREFIX}${conversationId}`] : []),
341
+ ...(authorization === "hosted" ? [HOSTED_AUTHORIZATION_RESOURCE] : []),
342
+ ...(appToolCatalogDigest
343
+ ? [`${APP_TOOL_CATALOG_RESOURCE_PREFIX}${appToolCatalogDigest.slice(2)}`]
344
+ : []),
345
+ ...mcpConnections.map(({ id }) => `${MCP_CONNECTION_RESOURCE_PREFIX}${id}`),
346
+ ...(focusMcpConnectionId ? [`${MCP_FOCUS_RESOURCE_PREFIX}${focusMcpConnectionId}`] : []),
347
+ ])];
348
+ if (typeof auth === "string") return { url: auth, resources };
349
+ return { ...auth, resources };
350
+ }
351
+
352
+ function withHostPrincipalExchange(auth, token) {
353
+ if (!HOST_PRINCIPAL_ID.test(token)) {
354
+ throw new TypeError("host principal returned an invalid exchange token");
355
+ }
356
+ return {
357
+ ...auth,
358
+ resources: [
359
+ ...auth.resources.filter((resource) => !resource.startsWith(HOST_PRINCIPAL_EXCHANGE_RESOURCE_PREFIX)),
360
+ `${HOST_PRINCIPAL_EXCHANGE_RESOURCE_PREFIX}${token}`,
361
+ ],
362
+ };
363
+ }
364
+
365
+ function reusableAccessKeys(provider, accountAddress) {
366
+ const records = provider?.store?.getState?.().accessKeys;
367
+ if (!Array.isArray(records)) return undefined;
368
+ const now = Math.floor(Date.now() / 1000);
369
+ const matching = records.filter((record) =>
370
+ record
371
+ && typeof record === "object"
372
+ && typeof record.address === "string"
373
+ && typeof record.expiry === "number"
374
+ && record.expiry > now
375
+ && typeof record.access === "string"
376
+ && record.access.toLowerCase() === accountAddress.toLowerCase()
377
+ && Number(record.chainId) === 4217
378
+ );
379
+ const channelAuthorities = persistedChannelAuthorities(accountAddress);
380
+ matching.sort((left, right) => {
381
+ const leftOwnsChannel = channelAuthorities.has(left.address.toLowerCase()) ? 1 : 0;
382
+ const rightOwnsChannel = channelAuthorities.has(right.address.toLowerCase()) ? 1 : 0;
383
+ return rightOwnsChannel - leftOwnsChannel || right.expiry - left.expiry;
384
+ });
385
+ return matching.map((selected) => ({ key_id: selected.address, expiry: selected.expiry }));
386
+ }
387
+
388
+ function activeAccountAddress(provider) {
389
+ const state = provider?.store?.getState?.();
390
+ const account = state?.accounts?.[state.activeAccount ?? 0];
391
+ return typeof account?.address === "string" ? account.address : undefined;
392
+ }
393
+
394
+ async function isRegisteredAccessKey(client, accountAddress, keyId, signal) {
395
+ try {
396
+ const value = await client.request({
397
+ method: "GET",
398
+ path: `/v1/access-keys/${accountAddress}/${keyId}?app_id=${encodeURIComponent(client.appId)}`,
399
+ signal,
400
+ });
401
+ return value?.registered === true;
402
+ } catch {
403
+ // Registration discovery is only an optimization. If it is unavailable,
404
+ // create a fresh authorization in the one passkey ceremony and fail closed.
405
+ return false;
406
+ }
407
+ }
408
+
409
+ async function registeredAccessKey(client, accountAddress, signal) {
410
+ for (const candidate of reusableAccessKeys(client.provider, accountAddress)) {
411
+ if (await isRegisteredAccessKey(client, accountAddress, candidate.key_id, signal)) {
412
+ return candidate;
413
+ }
414
+ }
415
+ return undefined;
416
+ }
417
+
418
+ function freshAccessKeyAuthorization(authorization) {
419
+ if (!authorization || typeof authorization !== "object") return authorization;
420
+ const { reuse: _reuse, ...fresh } = authorization;
421
+ return fresh;
422
+ }
423
+
424
+ function persistedChannelAuthorities(accountAddress) {
425
+ const authorities = new Set();
426
+ if (typeof localStorage === "undefined") return authorities;
427
+ const prefix = `nanocodex:connect:mpp:${accountAddress.toLowerCase()}:`;
428
+ for (const name of Object.keys(localStorage)) {
429
+ if (!name.startsWith(prefix) || !name.includes(":chan:")) continue;
430
+ try {
431
+ const snapshot = JSON.parse(localStorage.getItem(name));
432
+ const authority = snapshot?.descriptor?.authorizedSigner;
433
+ if (typeof authority === "string") authorities.add(authority.toLowerCase());
434
+ } catch {
435
+ // Ignore unrelated or corrupt browser storage; the MPP store owns its
436
+ // eventual validation and will fail closed if selected directly.
437
+ }
438
+ }
439
+ return authorities;
440
+ }
441
+
442
+ function serializeAuthorizeAccessKey(value) {
443
+ const { limits, scopes, ...authorization } = value;
444
+ if (limits !== undefined && (!Array.isArray(limits) || limits.length === 0)) {
445
+ throw new TypeError("access-key limits must contain at least one explicit spending constraint");
446
+ }
447
+ if (scopes !== undefined && !Array.isArray(scopes)) {
448
+ throw new TypeError("access-key scopes must be an array when provided");
449
+ }
450
+ return {
451
+ ...authorization,
452
+ ...(value.chainId === undefined ? {} : { chainId: toHex(value.chainId) }),
453
+ ...(limits === undefined ? {} : {
454
+ limits: limits.map((limit) => ({
455
+ ...limit,
456
+ limit: toHex(limit.limit),
457
+ })),
458
+ }),
459
+ ...(scopes === undefined ? {} : { scopes }),
460
+ };
461
+ }
462
+
463
+ function toHex(value) {
464
+ return `0x${BigInt(value).toString(16)}`;
465
+ }
466
+
467
+ export async function disconnect(client, options = {}) {
468
+ const session = client._captureSession?.();
469
+ client._clearSession();
470
+ if (!session) return;
471
+ await session.request({
472
+ method: "POST",
473
+ path: "/v1/connections/disconnect",
474
+ signal: options.signal,
475
+ });
476
+ }
477
+
478
+ export async function reconnect(client, options = {}) {
479
+ const session = client._getSession();
480
+ if (!session) return undefined;
481
+ const retainedAuthorization = session.connection?.authorization_mode
482
+ ?? (session.connection?.access_key ? "access_key" : undefined);
483
+ const authorization = options.authorization
484
+ ?? (retainedAuthorization === "access_key" || retainedAuthorization === "hosted"
485
+ ? retainedAuthorization
486
+ : (client.principal ? "hosted" : "access_key"));
487
+ if (client.principal && authorization !== "hosted") {
488
+ client._clearSession();
489
+ throw new TypeError("host principal connections require hosted authorization");
490
+ }
491
+ const appToolCatalog = hostedAppToolCatalog(options.tools ?? []);
492
+ const requestOptions = {
493
+ ...options,
494
+ authorization,
495
+ appToolCatalogDigest: appToolCatalog.length === 0
496
+ ? undefined
497
+ : await hostedToolCatalogDigest(appToolCatalog),
498
+ };
499
+ let retainedRequest;
500
+ let retained;
501
+ if (session.connection) {
502
+ try {
503
+ retained = connectionFromWire(session.connection);
504
+ if (retained.grant.id.toLowerCase() !== session.grantId.toLowerCase()
505
+ || !connectionMatchesRequest(retained, requestOptions)) {
506
+ client._clearSession();
507
+ return undefined;
508
+ }
509
+ retainedRequest = reconnectRequestFromConnection(retained);
510
+ } catch {
511
+ // A legacy or corrupt projection can still be validated against the live
512
+ // grant. Current sessions always retain a complete exact projection.
513
+ }
514
+ }
515
+ if (client.principal) {
516
+ if (!retained?.principal || !Array.isArray(session.resources) || session.resources.length === 0) {
517
+ client._clearSession();
518
+ return undefined;
519
+ }
520
+ } else if (retained?.principal) {
521
+ client._clearSession();
522
+ return undefined;
523
+ }
524
+ let principalExchange;
525
+ if (client.principal) {
526
+ try {
527
+ principalExchange = await client.principal.create({
528
+ resources: session.resources,
529
+ signal: options.signal,
530
+ });
531
+ } catch (error) {
532
+ client._clearSession();
533
+ throw error;
534
+ }
535
+ }
536
+ client._setSessionToken(session.token);
537
+ try {
538
+ const wire = await client.request({
539
+ // POST makes browsers attach their caller Origin. A simple cross-origin
540
+ // GET from an extension can omit Origin even when the app ID header is set.
541
+ method: "POST",
542
+ path: `/v1/grants/${session.grantId}/reconnect`,
543
+ ...(principalExchange ? { body: { host_principal_exchange: principalExchange.token } } : {}),
544
+ signal: options.signal,
545
+ });
546
+ const connection = connectionFromWire(wire);
547
+ if (connection.grant.status !== "active"
548
+ || connection.grant.expiresAt <= Math.floor(Date.now() / 1_000)) {
549
+ client._clearSession();
550
+ return undefined;
551
+ }
552
+ if (retained?.principal && connection.principal?.id !== retained.principal.id) {
553
+ client._clearSession();
554
+ return undefined;
555
+ }
556
+ if (!connectionMatchesRequest(connection, requestOptions)
557
+ || (retainedRequest && !connectionMatchesRequest(connection, retainedRequest))) {
558
+ client._clearSession();
559
+ return undefined;
560
+ }
561
+ client._setSession({
562
+ grantId: session.grantId,
563
+ token: typeof wire?.grant_token === "string" && wire.grant_token
564
+ ? wire.grant_token
565
+ : session.token,
566
+ connection: sessionConnectionWire(wire),
567
+ ...(principalExchange ? { resources: session.resources } : {}),
568
+ });
569
+ return connection;
570
+ } catch (error) {
571
+ client._setSessionToken(undefined);
572
+ if (error?.status === 401 || error?.status === 403) client._clearSession();
573
+ throw error;
574
+ }
575
+ }
576
+
577
+ function sessionConnectionWire(wire) {
578
+ const { grant_token: _grantToken, ...connection } = wire;
579
+ return connection;
580
+ }
@@ -0,0 +1,10 @@
1
+ import type { Client } from "../Client.mjs";
2
+ import type { Grant, Hex } from "../types.mjs";
3
+
4
+ export declare namespace revoke {
5
+ type Options = Readonly<{ grantId: Hex; signal?: AbortSignal | undefined }>;
6
+ type ReturnType = Promise<Grant>;
7
+ type ErrorType = Error;
8
+ }
9
+
10
+ export function revoke(client: Client, options: revoke.Options): revoke.ReturnType;
@@ -0,0 +1,12 @@
1
+ import { grantFromWire } from "../internal.mjs";
2
+
3
+ export async function revoke(client, options) {
4
+ if (!options?.grantId) throw new TypeError("revoke requires grantId");
5
+ const grant = grantFromWire(await client.request({
6
+ method: "POST",
7
+ path: `/v1/grants/${options.grantId}/revoke`,
8
+ signal: options.signal,
9
+ }));
10
+ client._clearSession();
11
+ return grant;
12
+ }
@@ -0,0 +1,7 @@
1
+ export * as account from "./account.mjs";
2
+ export * as agent from "./agent.mjs";
3
+ export * as connection from "./connection.mjs";
4
+ export * as grant from "./grant.mjs";
5
+ export * as machineUsd from "./machineUsd.mjs";
6
+ export * as model from "./model.mjs";
7
+ export * as mpp from "./mpp.mjs";
@@ -0,0 +1,7 @@
1
+ export * as account from "./account.mjs";
2
+ export * as agent from "./agent.mjs";
3
+ export * as connection from "./connection.mjs";
4
+ export * as grant from "./grant.mjs";
5
+ export * as machineUsd from "./machineUsd.mjs";
6
+ export * as model from "./model.mjs";
7
+ export * as mpp from "./mpp.mjs";
@@ -0,0 +1,23 @@
1
+ import type { Client } from "../Client.mjs";
2
+ import type { Hex, MachineUsdConfig, MachineUsdFunding } from "../types.mjs";
3
+
4
+ export declare namespace getConfig {
5
+ type Options = Readonly<{ signal?: AbortSignal | undefined }>;
6
+ type ReturnType = Promise<MachineUsdConfig>;
7
+ type ErrorType = Error;
8
+ }
9
+
10
+ export function getConfig(client: Client, options?: getConfig.Options | undefined): getConfig.ReturnType;
11
+
12
+ export declare namespace fund {
13
+ type Options = Readonly<{
14
+ grantId: Hex;
15
+ accountAddress: Hex;
16
+ usdAmountCents: number;
17
+ signal?: AbortSignal | undefined;
18
+ }>;
19
+ type ReturnType = Promise<MachineUsdFunding>;
20
+ type ErrorType = Error;
21
+ }
22
+
23
+ export function fund(client: Client, options: fund.Options): fund.ReturnType;
@@ -0,0 +1,37 @@
1
+ import { fundResultFromWire, machineUsdConfigFromWire } from "../internal.mjs";
2
+
3
+ export async function getConfig(client, options = {}) {
4
+ return machineUsdConfigFromWire(await client.request({
5
+ method: "GET",
6
+ path: "/v1/machine-usd/config",
7
+ signal: options.signal,
8
+ }));
9
+ }
10
+
11
+ export async function fund(client, options) {
12
+ if (!options?.grantId) throw new TypeError("fund requires grantId");
13
+ if (!Number.isSafeInteger(options.usdAmountCents)) {
14
+ throw new TypeError("fund requires an integer usdAmountCents");
15
+ }
16
+ const config = await getConfig(client, { signal: options.signal });
17
+ if (!config.onrampEnabled) throw new Error("The MACH onramp is unavailable");
18
+ if (options.usdAmountCents < config.minUsdAmountCents || options.usdAmountCents > config.maxUsdAmountCents) {
19
+ throw new RangeError(`MACH amount must be from ${config.minUsdAmountCents} through ${config.maxUsdAmountCents} cents`);
20
+ }
21
+ const approval = await client.dialog.open(Object.freeze({
22
+ id: crypto.randomUUID(),
23
+ type: "machineUsdFund",
24
+ grantId: options.grantId,
25
+ accountAddress: options.accountAddress,
26
+ usdAmountCents: options.usdAmountCents,
27
+ tokenAddress: config.tokenAddress,
28
+ chainId: config.chainId,
29
+ apiUrl: client.transport.baseUrl.replace(/\/+$/, ""),
30
+ stripePublishableKey: config.stripePublishableKey,
31
+ }));
32
+ return fundResultFromWire(await client.request({
33
+ method: "GET",
34
+ path: `/v1/grants/${options.grantId}/mpp/balance`,
35
+ signal: options.signal,
36
+ }).then((connection) => ({ order: approval.order, connection })), client);
37
+ }