@avow-finance/sdk 0.0.0-stage → 0.2.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 (267) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +122 -2
  3. package/dist/agent-entry.d.ts +15 -0
  4. package/dist/agent-entry.d.ts.map +1 -0
  5. package/dist/agent-entry.js +11 -0
  6. package/dist/agent-entry.js.map +1 -0
  7. package/dist/agent-key.d.ts +34 -0
  8. package/dist/agent-key.d.ts.map +1 -0
  9. package/dist/agent-key.js +33 -0
  10. package/dist/agent-key.js.map +1 -0
  11. package/dist/agent.d.ts +261 -0
  12. package/dist/agent.d.ts.map +1 -0
  13. package/dist/agent.js +493 -0
  14. package/dist/agent.js.map +1 -0
  15. package/dist/avow-api.d.ts +78 -0
  16. package/dist/avow-api.d.ts.map +1 -0
  17. package/dist/avow-api.js +2 -0
  18. package/dist/avow-api.js.map +1 -0
  19. package/dist/contest.d.ts +135 -0
  20. package/dist/contest.d.ts.map +1 -0
  21. package/dist/contest.js +186 -0
  22. package/dist/contest.js.map +1 -0
  23. package/dist/http.d.ts +161 -0
  24. package/dist/http.d.ts.map +1 -0
  25. package/dist/http.js +311 -0
  26. package/dist/http.js.map +1 -0
  27. package/dist/index.d.ts +38 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +38 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/job/accept.d.ts +84 -0
  32. package/dist/job/accept.d.ts.map +1 -0
  33. package/dist/job/accept.js +136 -0
  34. package/dist/job/accept.js.map +1 -0
  35. package/dist/job/customer.d.ts +43 -0
  36. package/dist/job/customer.d.ts.map +1 -0
  37. package/dist/job/customer.js +83 -0
  38. package/dist/job/customer.js.map +1 -0
  39. package/dist/job/quote.d.ts +34 -0
  40. package/dist/job/quote.d.ts.map +1 -0
  41. package/dist/job/quote.js +37 -0
  42. package/dist/job/quote.js.map +1 -0
  43. package/dist/lock.d.ts +269 -0
  44. package/dist/lock.d.ts.map +1 -0
  45. package/dist/lock.js +283 -0
  46. package/dist/lock.js.map +1 -0
  47. package/dist/moderato.d.ts +27 -0
  48. package/dist/moderato.d.ts.map +1 -0
  49. package/dist/moderato.js +34 -0
  50. package/dist/moderato.js.map +1 -0
  51. package/dist/node/cli.d.ts +3 -0
  52. package/dist/node/cli.d.ts.map +1 -0
  53. package/dist/node/cli.js +346 -0
  54. package/dist/node/cli.js.map +1 -0
  55. package/dist/node/connect.d.ts +15 -0
  56. package/dist/node/connect.d.ts.map +1 -0
  57. package/dist/node/connect.js +91 -0
  58. package/dist/node/connect.js.map +1 -0
  59. package/dist/node/eval.d.ts +3 -0
  60. package/dist/node/eval.d.ts.map +1 -0
  61. package/dist/node/eval.js +67 -0
  62. package/dist/node/eval.js.map +1 -0
  63. package/dist/node/first-run.d.ts +50 -0
  64. package/dist/node/first-run.d.ts.map +1 -0
  65. package/dist/node/first-run.js +149 -0
  66. package/dist/node/first-run.js.map +1 -0
  67. package/dist/node/job.d.ts +50 -0
  68. package/dist/node/job.d.ts.map +1 -0
  69. package/dist/node/job.js +176 -0
  70. package/dist/node/job.js.map +1 -0
  71. package/dist/node/mailbox.d.ts +19 -0
  72. package/dist/node/mailbox.d.ts.map +1 -0
  73. package/dist/node/mailbox.js +81 -0
  74. package/dist/node/mailbox.js.map +1 -0
  75. package/dist/node/mcp.d.ts +74 -0
  76. package/dist/node/mcp.d.ts.map +1 -0
  77. package/dist/node/mcp.js +367 -0
  78. package/dist/node/mcp.js.map +1 -0
  79. package/dist/node/platform.d.ts +35 -0
  80. package/dist/node/platform.d.ts.map +1 -0
  81. package/dist/node/platform.js +102 -0
  82. package/dist/node/platform.js.map +1 -0
  83. package/dist/node/runner-session.d.ts +41 -0
  84. package/dist/node/runner-session.d.ts.map +1 -0
  85. package/dist/node/runner-session.js +100 -0
  86. package/dist/node/runner-session.js.map +1 -0
  87. package/dist/node/runner.d.ts +63 -0
  88. package/dist/node/runner.d.ts.map +1 -0
  89. package/dist/node/runner.js +341 -0
  90. package/dist/node/runner.js.map +1 -0
  91. package/dist/node/service-child.d.ts +2 -0
  92. package/dist/node/service-child.d.ts.map +1 -0
  93. package/dist/node/service-child.js +40 -0
  94. package/dist/node/service-child.js.map +1 -0
  95. package/dist/node/service-excerpt.d.ts +21 -0
  96. package/dist/node/service-excerpt.d.ts.map +1 -0
  97. package/dist/node/service-excerpt.js +32 -0
  98. package/dist/node/service-excerpt.js.map +1 -0
  99. package/dist/node/service-process.d.ts +12 -0
  100. package/dist/node/service-process.d.ts.map +1 -0
  101. package/dist/node/service-process.js +132 -0
  102. package/dist/node/service-process.js.map +1 -0
  103. package/dist/node/session-input.d.ts +12 -0
  104. package/dist/node/session-input.d.ts.map +1 -0
  105. package/dist/node/session-input.js +42 -0
  106. package/dist/node/session-input.js.map +1 -0
  107. package/dist/node/session-view.d.ts +20 -0
  108. package/dist/node/session-view.d.ts.map +1 -0
  109. package/dist/node/session-view.js +198 -0
  110. package/dist/node/session-view.js.map +1 -0
  111. package/dist/node-agent.d.ts +2 -0
  112. package/dist/node-agent.d.ts.map +1 -0
  113. package/dist/node-agent.js +6 -0
  114. package/dist/node-agent.js.map +1 -0
  115. package/dist/node.d.ts +2 -0
  116. package/dist/node.d.ts.map +1 -0
  117. package/dist/node.js +9 -0
  118. package/dist/node.js.map +1 -0
  119. package/dist/sandbox/agent.d.ts +187 -0
  120. package/dist/sandbox/agent.d.ts.map +1 -0
  121. package/dist/sandbox/agent.js +468 -0
  122. package/dist/sandbox/agent.js.map +1 -0
  123. package/dist/sandbox/business-store.d.ts +19 -0
  124. package/dist/sandbox/business-store.d.ts.map +1 -0
  125. package/dist/sandbox/business-store.js +19 -0
  126. package/dist/sandbox/business-store.js.map +1 -0
  127. package/dist/sandbox/business.d.ts +70 -0
  128. package/dist/sandbox/business.d.ts.map +1 -0
  129. package/dist/sandbox/business.js +115 -0
  130. package/dist/sandbox/business.js.map +1 -0
  131. package/dist/sandbox/connect.d.ts +64 -0
  132. package/dist/sandbox/connect.d.ts.map +1 -0
  133. package/dist/sandbox/connect.js +182 -0
  134. package/dist/sandbox/connect.js.map +1 -0
  135. package/dist/sandbox/deployment.d.ts +14 -0
  136. package/dist/sandbox/deployment.d.ts.map +1 -0
  137. package/dist/sandbox/deployment.js +38 -0
  138. package/dist/sandbox/deployment.js.map +1 -0
  139. package/dist/sandbox/keys.d.ts +45 -0
  140. package/dist/sandbox/keys.d.ts.map +1 -0
  141. package/dist/sandbox/keys.js +132 -0
  142. package/dist/sandbox/keys.js.map +1 -0
  143. package/dist/sandbox/mailbox.d.ts +90 -0
  144. package/dist/sandbox/mailbox.d.ts.map +1 -0
  145. package/dist/sandbox/mailbox.js +400 -0
  146. package/dist/sandbox/mailbox.js.map +1 -0
  147. package/dist/sandbox/mandate.d.ts +84 -0
  148. package/dist/sandbox/mandate.d.ts.map +1 -0
  149. package/dist/sandbox/mandate.js +107 -0
  150. package/dist/sandbox/mandate.js.map +1 -0
  151. package/dist/sandbox/namespace.d.ts +16 -0
  152. package/dist/sandbox/namespace.d.ts.map +1 -0
  153. package/dist/sandbox/namespace.js +16 -0
  154. package/dist/sandbox/namespace.js.map +1 -0
  155. package/dist/sandbox/session.d.ts +60 -0
  156. package/dist/sandbox/session.d.ts.map +1 -0
  157. package/dist/sandbox/session.js +94 -0
  158. package/dist/sandbox/session.js.map +1 -0
  159. package/dist/sandbox/setup.d.ts +136 -0
  160. package/dist/sandbox/setup.d.ts.map +1 -0
  161. package/dist/sandbox/setup.js +490 -0
  162. package/dist/sandbox/setup.js.map +1 -0
  163. package/dist/sandbox/store.d.ts +69 -0
  164. package/dist/sandbox/store.d.ts.map +1 -0
  165. package/dist/sandbox/store.js +115 -0
  166. package/dist/sandbox/store.js.map +1 -0
  167. package/dist/sandbox/supplier-key.d.ts +73 -0
  168. package/dist/sandbox/supplier-key.d.ts.map +1 -0
  169. package/dist/sandbox/supplier-key.js +180 -0
  170. package/dist/sandbox/supplier-key.js.map +1 -0
  171. package/dist/sandbox/suppliers.d.ts +7 -0
  172. package/dist/sandbox/suppliers.d.ts.map +1 -0
  173. package/dist/sandbox/suppliers.js +29 -0
  174. package/dist/sandbox/suppliers.js.map +1 -0
  175. package/dist/sandbox/terms.d.ts +32 -0
  176. package/dist/sandbox/terms.d.ts.map +1 -0
  177. package/dist/sandbox/terms.js +58 -0
  178. package/dist/sandbox/terms.js.map +1 -0
  179. package/dist/sandbox/vault.d.ts +24 -0
  180. package/dist/sandbox/vault.d.ts.map +1 -0
  181. package/dist/sandbox/vault.js +54 -0
  182. package/dist/sandbox/vault.js.map +1 -0
  183. package/dist/send.d.ts +122 -0
  184. package/dist/send.d.ts.map +1 -0
  185. package/dist/send.js +328 -0
  186. package/dist/send.js.map +1 -0
  187. package/dist/service-entry.d.ts +6 -0
  188. package/dist/service-entry.d.ts.map +1 -0
  189. package/dist/service-entry.js +6 -0
  190. package/dist/service-entry.js.map +1 -0
  191. package/dist/session/anthropic.d.ts +17 -0
  192. package/dist/session/anthropic.d.ts.map +1 -0
  193. package/dist/session/anthropic.js +215 -0
  194. package/dist/session/anthropic.js.map +1 -0
  195. package/dist/session/charge.d.ts +13 -0
  196. package/dist/session/charge.d.ts.map +1 -0
  197. package/dist/session/charge.js +33 -0
  198. package/dist/session/charge.js.map +1 -0
  199. package/dist/session/data.d.ts +8 -0
  200. package/dist/session/data.d.ts.map +1 -0
  201. package/dist/session/data.js +20 -0
  202. package/dist/session/data.js.map +1 -0
  203. package/dist/session/eval.d.ts +41 -0
  204. package/dist/session/eval.d.ts.map +1 -0
  205. package/dist/session/eval.js +281 -0
  206. package/dist/session/eval.js.map +1 -0
  207. package/dist/session/executor.d.ts +80 -0
  208. package/dist/session/executor.d.ts.map +1 -0
  209. package/dist/session/executor.js +381 -0
  210. package/dist/session/executor.js.map +1 -0
  211. package/dist/session/fixture-world.d.ts +29 -0
  212. package/dist/session/fixture-world.d.ts.map +1 -0
  213. package/dist/session/fixture-world.js +708 -0
  214. package/dist/session/fixture-world.js.map +1 -0
  215. package/dist/session/live-world.d.ts +22 -0
  216. package/dist/session/live-world.d.ts.map +1 -0
  217. package/dist/session/live-world.js +329 -0
  218. package/dist/session/live-world.js.map +1 -0
  219. package/dist/session/ollama.d.ts +29 -0
  220. package/dist/session/ollama.d.ts.map +1 -0
  221. package/dist/session/ollama.js +177 -0
  222. package/dist/session/ollama.js.map +1 -0
  223. package/dist/session/provider.d.ts +79 -0
  224. package/dist/session/provider.d.ts.map +1 -0
  225. package/dist/session/provider.js +19 -0
  226. package/dist/session/provider.js.map +1 -0
  227. package/dist/session/scripted.d.ts +45 -0
  228. package/dist/session/scripted.d.ts.map +1 -0
  229. package/dist/session/scripted.js +236 -0
  230. package/dist/session/scripted.js.map +1 -0
  231. package/dist/session/selection.d.ts +37 -0
  232. package/dist/session/selection.d.ts.map +1 -0
  233. package/dist/session/selection.js +104 -0
  234. package/dist/session/selection.js.map +1 -0
  235. package/dist/session/service-check.d.ts +48 -0
  236. package/dist/session/service-check.d.ts.map +1 -0
  237. package/dist/session/service-check.js +86 -0
  238. package/dist/session/service-check.js.map +1 -0
  239. package/dist/session/service.d.ts +128 -0
  240. package/dist/session/service.d.ts.map +1 -0
  241. package/dist/session/service.js +150 -0
  242. package/dist/session/service.js.map +1 -0
  243. package/dist/session/session.d.ts +95 -0
  244. package/dist/session/session.d.ts.map +1 -0
  245. package/dist/session/session.js +312 -0
  246. package/dist/session/session.js.map +1 -0
  247. package/dist/session/toolbox.d.ts +69 -0
  248. package/dist/session/toolbox.d.ts.map +1 -0
  249. package/dist/session/toolbox.js +391 -0
  250. package/dist/session/toolbox.js.map +1 -0
  251. package/dist/session/tools.d.ts +45 -0
  252. package/dist/session/tools.d.ts.map +1 -0
  253. package/dist/session/tools.js +137 -0
  254. package/dist/session/tools.js.map +1 -0
  255. package/dist/session/world.d.ts +188 -0
  256. package/dist/session/world.d.ts.map +1 -0
  257. package/dist/session/world.js +2 -0
  258. package/dist/session/world.js.map +1 -0
  259. package/dist/sign.d.ts +19 -0
  260. package/dist/sign.d.ts.map +1 -0
  261. package/dist/sign.js +33 -0
  262. package/dist/sign.js.map +1 -0
  263. package/dist/supplier.d.ts +41 -0
  264. package/dist/supplier.d.ts.map +1 -0
  265. package/dist/supplier.js +57 -0
  266. package/dist/supplier.js.map +1 -0
  267. package/package.json +56 -3
@@ -0,0 +1,400 @@
1
+ import { commitmentReferenceJson, computeOffersPath, computeOfferTerms, DEMO_JOB_TIMING, GPU_RESERVATION, isChainedTerms, isFirmOffer, offerTakes, parseComputeOffers, parseMailboxInbox, parseMailboxOrder, parseMailboxOrderRequest, parseSupplierProfile, parseTerms, quoteTermsProblem, SANDBOX_PATHS, TESTNET_DEMO_PROFILE, testnetDemoJobTerms, } from '@avow-finance/spec';
2
+ import { readBacking, tempoChainReader, tempoLockReader } from '@avow-finance/verifier';
3
+ import { parseAbi, toHex } from 'viem';
4
+ import { privateKeyToAccount } from 'viem/accounts';
5
+ import { Account } from 'viem/tempo';
6
+ import { createAgent } from '../agent.js';
7
+ import { AvowApiError, agentRequestKey, avowRequests, httpAvowApi, requestSupplierAuthorization, signingRequestKey, } from '../http.js';
8
+ import { acceptJob } from '../job/accept.js';
9
+ import { quoteJob } from '../job/quote.js';
10
+ import { moderatoClient, moderatoUsdToken } from '../moderato.js';
11
+ import { sendOwn, sendSponsored } from '../send.js';
12
+ import { platformStore, sandboxAgent } from './agent.js';
13
+ import { fundFees } from './business.js';
14
+ import { pause } from './connect.js';
15
+ import { loadSandboxDeployment } from './deployment.js';
16
+ import { SANDBOX_SCREEN_URL } from './session.js';
17
+ import { isRecord, loadAgentItem, readJson, write, } from './store.js';
18
+ import { loadSupplierItem } from './supplier-key.js';
19
+ /**
20
+ * The sandbox mailbox from an agent's side. A buyer's agent orders a job from another business,
21
+ * checks the quote that comes back and funds it. A supplier's agent reads its inbox, books the
22
+ * compute the job relies on, quotes, and accepts once the buyer has funded. Avow keeps every order,
23
+ * so an agent that stops part way picks up where it was, and each step it repeats is answered the
24
+ * same, so it never makes a second commitment.
25
+ */
26
+ const APPROVAL_KEY_ABI = parseAbi(['function approvalKey() view returns (address)']);
27
+ const systemClock = () => BigInt(Math.floor(Date.now() / 1000));
28
+ const random = (bytes) => toHex(crypto.getRandomValues(new Uint8Array(bytes)));
29
+ /** How long an order waits to be funded unless the buyer says otherwise, in seconds. */
30
+ export const MAILBOX_ORDER_SECONDS = 600n;
31
+ /** How long a supplier's quote stays valid, in seconds. */
32
+ const QUOTE_VALIDITY = 120n;
33
+ /** The sales kept in the store, read back to the types they were written from. */
34
+ function readSales(json) {
35
+ const sales = {};
36
+ for (const [orderId, value] of Object.entries(isRecord(json.sales) ? json.sales : {})) {
37
+ const kept = isRecord(value) && isRecord(value.compute) ? value.compute : {};
38
+ const reference = commitmentReferenceJson.safeParse(kept.reference);
39
+ const terms = parseTerms(kept.terms);
40
+ const salt = typeof kept.salt === 'string' && /^0x[0-9a-f]{64}$/i.test(kept.salt);
41
+ if (!reference.success ||
42
+ reference.data.side !== 'buyer' ||
43
+ !terms.ok ||
44
+ terms.value.template !== GPU_RESERVATION ||
45
+ !salt) {
46
+ throw new Error(`The sandbox's mailbox file holds a sale it can't read, for ${orderId}.`);
47
+ }
48
+ sales[orderId] = {
49
+ compute: {
50
+ reference: { ...reference.data, side: 'buyer' },
51
+ terms: terms.value,
52
+ salt: kept.salt,
53
+ },
54
+ };
55
+ }
56
+ return sales;
57
+ }
58
+ /** The mailbox for the agent in this folder, as buyer and, when it holds a signing key, supplier. */
59
+ export async function sandboxMailbox(o = {}) {
60
+ const send = o.fetch ?? ((input, init) => fetch(input, init));
61
+ const maybeStore = o.store ?? platformStore();
62
+ if (!maybeStore)
63
+ throw new Error('Pass a store, outside Node.');
64
+ const store = maybeStore;
65
+ const found = await loadAgentItem(store);
66
+ if (!found)
67
+ throw new Error('This folder has no agent. Run avow-sandbox connect first.');
68
+ const item = found;
69
+ const deployment = await loadSandboxDeployment(o.screenUrl ?? SANDBOX_SCREEN_URL, send);
70
+ const client = moderatoClient(deployment.rpcUrl);
71
+ const { business } = item;
72
+ const agentKey = Account.fromSecp256k1(item.agentKey, { access: business.account });
73
+ const domain = { chainId: deployment.chainId, verifyingContract: business.lock };
74
+ const lockReader = tempoLockReader(client, {
75
+ factory: deployment.factory,
76
+ chainId: deployment.chainId,
77
+ });
78
+ const asAgent = avowRequests({
79
+ baseUrl: deployment.apiUrl,
80
+ key: agentRequestKey(agentKey),
81
+ retryFor: 120n,
82
+ fetch: send,
83
+ });
84
+ const orderReader = (json) => {
85
+ const order = parseMailboxOrder(json);
86
+ return order
87
+ ? { ok: true, value: order }
88
+ : { ok: false, reason: 'message.invalid' };
89
+ };
90
+ async function supplierProfile(businessId) {
91
+ const answer = await send(`${deployment.apiUrl}${SANDBOX_PATHS.supplier(businessId)}`, {
92
+ signal: AbortSignal.timeout(15_000),
93
+ });
94
+ const profile = parseSupplierProfile(await answer.json().catch(() => null));
95
+ if (!answer.ok || !profile.ok)
96
+ throw new Error(`Avow has no sandbox supplier ${businessId}`);
97
+ return profile.value;
98
+ }
99
+ // The buyer's side.
100
+ /** What the store keeps for the mailbox: a seller's bookings, and a buyer's unfinished orders. */
101
+ async function kept() {
102
+ const text = await store.read('mailbox');
103
+ const json = text ? readJson(text, 'mailbox') : {};
104
+ const buying = (Array.isArray(json.buying) ? json.buying : []).map((r) => {
105
+ const request = parseMailboxOrderRequest(r);
106
+ if (!request)
107
+ throw new Error("The sandbox's mailbox file holds an order it can't read.");
108
+ return request;
109
+ });
110
+ return { sales: readSales(json), buying };
111
+ }
112
+ async function keep(change) {
113
+ const now = await kept();
114
+ await write(store, 'mailbox', { ...now, ...change(now) });
115
+ }
116
+ const finish = (orderId) => keep((k) => ({ buying: k.buying.filter((r) => r.orderId !== orderId) }));
117
+ const place = (request) => asAgent({ domain, path: SANDBOX_PATHS.mailboxOrders, body: request, read: orderReader });
118
+ async function order(p) {
119
+ const expiry = systemClock() + (p.expiresIn ?? MAILBOX_ORDER_SECONDS);
120
+ const request = {
121
+ orderId: random(16).slice(2),
122
+ commitmentId: random(32),
123
+ supplierBusinessId: p.supplier,
124
+ terms: testnetDemoJobTerms(expiry + DEMO_JOB_TIMING.accept, deployment.arbiter),
125
+ requirement: { template: GPU_RESERVATION, condition: 'accepted', disclosed: 'subject' },
126
+ expiry,
127
+ };
128
+ await keep((k) => ({ buying: [...k.buying, request] }));
129
+ return place(request);
130
+ }
131
+ const unfinished = async () => (await kept()).buying;
132
+ const read = (orderId) => asAgent({ domain, path: SANDBOX_PATHS.mailboxOrder(orderId), body: {}, read: orderReader });
133
+ async function buy(p) {
134
+ const every = p.pollEvery ?? 3000;
135
+ const resumed = p.resume ? (await unfinished()).find((r) => r.orderId === p.resume) : null;
136
+ if (p.resume && !resumed)
137
+ throw new Error(`This agent has no unfinished order ${p.resume}.`);
138
+ // Sending a kept order again is answered with where it stands.
139
+ let current = resumed ? await place(resumed) : await order(p);
140
+ p.onStep?.({ step: 'ordered', order: current });
141
+ const end = async (outcome) => {
142
+ await finish(current.orderId);
143
+ return outcome;
144
+ };
145
+ while (current.status === 'requested') {
146
+ await pause(every, p.signal);
147
+ current = await read(current.orderId);
148
+ }
149
+ if (current.status === 'expired')
150
+ return end({ ok: false, reason: 'order.expired', order: current });
151
+ if (current.status === 'quoted') {
152
+ const funded = await fund(current, p);
153
+ if ('reason' in funded)
154
+ return end(funded);
155
+ current = funded.order;
156
+ }
157
+ return end(await awaitAcceptance(current, every, p));
158
+ }
159
+ /** Checks the quote and funds it, unless the lock already holds it, and tells the mailbox. */
160
+ async function fund(current, p) {
161
+ p.onStep?.({ step: 'quoted', order: current });
162
+ const quote = current.quote;
163
+ // The buyer's own checks, before anything is reserved.
164
+ if (!isChainedTerms(quote.terms))
165
+ return { ok: false, reason: 'dependency.required', order: current };
166
+ const changed = quoteTermsProblem(current.terms, quote.terms) ??
167
+ (quote.agreement.commitmentId.toLowerCase() === current.commitmentId.toLowerCase()
168
+ ? null
169
+ : 'order.commitment_mismatch');
170
+ if (changed)
171
+ return { ok: false, reason: changed, order: current };
172
+ // A reserve already on the lock, from a run that stopped after funding, is reported as it is.
173
+ let fundedIn = null;
174
+ const held = await readBacking(client, business.lock, current.commitmentId, 'buyer');
175
+ if (!held) {
176
+ const avow = httpAvowApi({
177
+ baseUrl: deployment.apiUrl,
178
+ key: agentRequestKey(agentKey),
179
+ domain,
180
+ retryFor: 120n,
181
+ fetch: send,
182
+ });
183
+ const buyer = createAgent({
184
+ client,
185
+ key: agentKey,
186
+ mandate: item.mandate,
187
+ token: moderatoUsdToken(deployment.token),
188
+ profile: TESTNET_DEMO_PROFILE,
189
+ avow,
190
+ send: async (calls) => {
191
+ const receipt = await sendSponsored({
192
+ client,
193
+ account: agentKey,
194
+ calls,
195
+ sponsor: (transaction) => avow.sponsor(transaction),
196
+ });
197
+ return { transactionHash: receipt.transactionHash, blockNumber: receipt.blockNumber };
198
+ },
199
+ dependencies: { readers: [lockReader] },
200
+ });
201
+ const result = await buyer.commitToQuote({
202
+ supplier: await supplierProfile(current.supplierBusinessId),
203
+ terms: quote.terms,
204
+ salt: quote.salt,
205
+ agreement: quote.agreement,
206
+ supplierSignature: quote.supplierSignature,
207
+ disclosed: quote.disclosed,
208
+ });
209
+ if (!result.ok)
210
+ return { ok: false, reason: result.reason, order: current };
211
+ fundedIn = result.commitment.reservedIn ?? null;
212
+ }
213
+ // A node that lags can hide a reserve that landed for a few seconds, so Avow is asked again.
214
+ for (let tries = 0;; tries++) {
215
+ try {
216
+ const reported = await asAgent({
217
+ domain,
218
+ path: SANDBOX_PATHS.mailboxReserved(current.orderId),
219
+ body: { fundedIn },
220
+ read: orderReader,
221
+ });
222
+ p.onStep?.({ step: 'reserved', fundedIn });
223
+ return { order: reported };
224
+ }
225
+ catch (error) {
226
+ const lagging = error instanceof AvowApiError && error.reason === 'chain.reserve_missing';
227
+ if (!lagging || tries >= 12)
228
+ throw error;
229
+ await pause(5000, p.signal);
230
+ }
231
+ }
232
+ }
233
+ /** Waits for the seller to accept, under the lock's rules. Past its deadline the reserve goes back. */
234
+ async function awaitAcceptance(from, every, p) {
235
+ let current = from;
236
+ const acceptBy = current.status === 'reserved' ? current.reserve.acceptBy : 0n;
237
+ while (current.status === 'reserved') {
238
+ if (systemClock() > acceptBy)
239
+ return { ok: false, reason: 'acceptance.missed', order: current };
240
+ await pause(every, p.signal);
241
+ current = await read(current.orderId);
242
+ }
243
+ if (current.status !== 'accepted')
244
+ return { ok: false, reason: 'message.invalid', order: current };
245
+ p.onStep?.({ step: 'accepted', acceptedIn: current.acceptedIn });
246
+ return { ok: true, order: current };
247
+ }
248
+ // The supplier's side.
249
+ const supplierItem = await loadSupplierItem(store);
250
+ const signing = supplierItem ? privateKeyToAccount(supplierItem.signingKey) : null;
251
+ const asSupplier = signing
252
+ ? avowRequests({
253
+ baseUrl: deployment.apiUrl,
254
+ key: signingRequestKey(signing),
255
+ retryFor: 120n,
256
+ fetch: send,
257
+ })
258
+ : null;
259
+ const needSupplier = () => {
260
+ if (!asSupplier || !signing || !supplierItem) {
261
+ throw new Error('This agent has no signing key to sell with. Connect it with --sell.');
262
+ }
263
+ return { asSupplier, signing, supplier: supplierItem };
264
+ };
265
+ async function inbox() {
266
+ const { asSupplier } = needSupplier();
267
+ return asSupplier({
268
+ domain,
269
+ path: SANDBOX_PATHS.mailboxInbox,
270
+ body: {},
271
+ read: (json) => {
272
+ const read = parseMailboxInbox(json);
273
+ return read ? { ok: true, value: read.orders } : { ok: false, reason: 'message.invalid' };
274
+ },
275
+ });
276
+ }
277
+ /** A firm offer that holds the job's GPUs for its whole run, the cheapest per GPU-hour. */
278
+ async function computeFor(job) {
279
+ const s = job.terms.subject;
280
+ const url = `${new URL(deployment.supplierUrl).origin}${computeOffersPath(s)}`;
281
+ const answer = await send(url, { headers: { accept: 'application/json' }, redirect: 'error' });
282
+ const listing = parseComputeOffers(await answer.json().catch(() => null));
283
+ if (!answer.ok || !listing.ok)
284
+ throw new Error('The compute supplier listed no offers');
285
+ const gpus = s.compute.count;
286
+ const fits = listing.value.offers.filter((offer) => isFirmOffer(offer, listing.value.listedAt) &&
287
+ offer.startsAt <= s.startsAt &&
288
+ offer.startsAt + BigInt(offer.minutes) * 60n >= s.deliverBy &&
289
+ offerTakes(offer, gpus) &&
290
+ offer.gpu === s.compute.gpu);
291
+ const [cheapest] = fits.sort((a, b) => (a.pricePerGpuHour < b.pricePerGpuHour ? -1 : 1));
292
+ if (!cheapest)
293
+ throw new Error('No compute offer holds the job for its whole run');
294
+ return { offer: cheapest, gpus };
295
+ }
296
+ async function sell(job, onStep) {
297
+ const { asSupplier, signing, supplier } = needSupplier();
298
+ if (job.status === 'requested') {
299
+ let compute = (await kept()).sales[job.orderId]?.compute ?? null;
300
+ if (!compute) {
301
+ const agent = await sandboxAgent({
302
+ store,
303
+ deployment,
304
+ session: null,
305
+ log: () => { },
306
+ fetch: send,
307
+ });
308
+ const { offer, gpus } = await computeFor(job);
309
+ const terms = computeOfferTerms(offer, gpus, deployment);
310
+ const booked = await agent.bookTerms({ supplier: offer.supplier, terms });
311
+ if (!(await booked.accepted()))
312
+ throw new Error('The compute supplier never accepted');
313
+ compute = {
314
+ reference: booked.reference,
315
+ terms,
316
+ salt: booked.commitment.salt,
317
+ };
318
+ const booking = compute;
319
+ await keep((k) => ({ sales: { ...k.sales, [job.orderId]: { compute: booking } } }));
320
+ onStep?.({ step: 'compute', reservedIn: booked.commitment.reservedIn });
321
+ }
322
+ const quote = await quoteJob({
323
+ offer: job,
324
+ customer: job.buyer,
325
+ supplier: supplier.profile,
326
+ signingKey: signingRequestKey(signing),
327
+ compute,
328
+ expiry: systemClock() + QUOTE_VALIDITY,
329
+ });
330
+ await asSupplier({
331
+ domain,
332
+ path: SANDBOX_PATHS.mailboxQuote(job.orderId),
333
+ body: quote,
334
+ read: orderReader,
335
+ });
336
+ onStep?.({ step: 'quoted' });
337
+ return;
338
+ }
339
+ if (job.status === 'reserved') {
340
+ const approvalKey = await client.readContract({
341
+ address: job.buyer.lock,
342
+ abi: APPROVAL_KEY_ABI,
343
+ functionName: 'approvalKey',
344
+ });
345
+ await fundFees(client, signing.address);
346
+ const sender = Account.fromSecp256k1(supplier.signingKey);
347
+ const accepted = await acceptJob({
348
+ config: {
349
+ chainId: deployment.chainId,
350
+ avowKeys: [approvalKey],
351
+ businessId: supplier.profile.businessId,
352
+ payee: supplier.profile.payee,
353
+ acceptedTokens: [moderatoUsdToken(deployment.token)],
354
+ profile: TESTNET_DEMO_PROFILE,
355
+ acceptTestData: true,
356
+ account: supplier.profile.account,
357
+ signingKey: supplier.profile.signingKey,
358
+ },
359
+ chain: tempoChainReader(client, {
360
+ factory: deployment.factory,
361
+ chainId: deployment.chainId,
362
+ }),
363
+ dependencies: { readers: [lockReader] },
364
+ authorize: (commitment) => requestSupplierAuthorization({ baseUrl: deployment.apiUrl, key: signingRequestKey(signing), fetch: send }, commitment),
365
+ signingKey: signing,
366
+ send: async (call) => {
367
+ const receipt = await sendOwn({ client, account: sender, calls: [call] });
368
+ return { transactionHash: receipt.transactionHash, blockNumber: receipt.blockNumber };
369
+ },
370
+ now: systemClock,
371
+ }, { customer: job.buyer, quote: job.quote });
372
+ if (!accepted.ok)
373
+ throw new Error(`The acceptance was refused: ${accepted.code}`);
374
+ // Null when an earlier run's acceptance was already on the lock, which Avow reads either way.
375
+ const acceptedIn = accepted.sent?.landed.transactionHash ?? null;
376
+ await asSupplier({
377
+ domain,
378
+ path: SANDBOX_PATHS.mailboxAccepted(job.orderId),
379
+ body: { acceptedIn },
380
+ read: orderReader,
381
+ });
382
+ onStep?.({ step: 'accepted', acceptedIn });
383
+ }
384
+ }
385
+ async function listen(p = {}) {
386
+ for (;;) {
387
+ if (p.signal?.aborted)
388
+ return;
389
+ const orders = await inbox().catch(() => []);
390
+ for (const job of orders) {
391
+ if (job.status === 'requested' && p.accept && !(await p.accept(job)))
392
+ continue;
393
+ await sell(job, (step) => p.onStep?.(job, step)).catch((error) => p.onError?.(job, error));
394
+ }
395
+ await pause(p.every ?? 5000, p.signal).catch(() => { });
396
+ }
397
+ }
398
+ return { businessId: business.businessId, order, unfinished, read, buy, inbox, sell, listen };
399
+ }
400
+ //# sourceMappingURL=mailbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mailbox.js","sourceRoot":"","sources":["../../src/sandbox/mailbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ import { type Enrollment, type Mandate, type SandboxDeployment, type Signed, type SupplierProfile } from '@avow-finance/spec';
2
+ import { type Address, type Hex } from 'viem';
3
+ import { Account } from 'viem/tempo';
4
+ import type { AgentKey } from '../agent.js';
5
+ import type { SandboxClient } from './business.js';
6
+ /** What the agent's key can move in a day when the business names no daily limit, $1,000. */
7
+ export declare const SANDBOX_DAILY_LIMIT = 1000000000n;
8
+ /**
9
+ * The mandate a sandbox business's root key signs for its agent. The agent may reserve, cancel and
10
+ * start commitments in the named categories with the named suppliers, up to `capPerCommitment` for
11
+ * one and `capOpenReserves` across those it holds at once, until `expiry`. Its key can move at most
12
+ * `dailyLimit` in a day, which the account's keychain holds whatever Avow approves. Every booking
13
+ * goes ahead without a person's approval, which a real business would set to fit its own rules.
14
+ */
15
+ export declare function sandboxMandate(m: {
16
+ businessId: string;
17
+ agentId: string;
18
+ account: Address;
19
+ agentKey: Address;
20
+ /** The business ids of the suppliers the agent may book. */
21
+ suppliers: readonly string[];
22
+ /**
23
+ * What the agent may commit to, compute bookings when left out. An agent that buys jobs from
24
+ * another business names `JOB_CATEGORY` beside them.
25
+ */
26
+ categories?: readonly string[];
27
+ token: Address;
28
+ capPerCommitment: bigint;
29
+ capOpenReserves: bigint;
30
+ /** The most the agent's key can move in a day, `SANDBOX_DAILY_LIMIT` when left out. */
31
+ dailyLimit?: bigint;
32
+ /** Unix seconds. */
33
+ expiry: bigint;
34
+ }): Mandate;
35
+ /** The agent's key on the account, under the mandate the root key signed. */
36
+ export interface AuthorizedSandboxKey {
37
+ mandate: Signed<Mandate>;
38
+ mandateHash: Hex;
39
+ /** The transaction that put the agent's key on the account. */
40
+ keyAuthorizedIn: Hex;
41
+ }
42
+ /** The agent, enrolled with Avow under the mandate the root key signed. */
43
+ export interface EnrolledSandboxAgent extends AuthorizedSandboxKey {
44
+ enrollment: Enrollment;
45
+ }
46
+ export interface SandboxAuthorizeDeps {
47
+ deployment: Pick<SandboxDeployment, 'chainId'>;
48
+ client: SandboxClient;
49
+ root: Account.RootAccount;
50
+ /**
51
+ * The agent's access key on the account, which the mandate names. Only its address and type are
52
+ * read, so a business's console can authorize a key that lives on the developer's machine.
53
+ */
54
+ agent: Pick<AgentKey, 'accessKeyAddress' | 'keyType'>;
55
+ lock: Address;
56
+ mandate: Mandate;
57
+ /** The suppliers the mandate names, each approved on the lock. */
58
+ suppliers: readonly SupplierProfile[];
59
+ /** The agent key this one replaces, revoked in the account's keychain in the same transaction. */
60
+ revoke?: Address;
61
+ /** Supplier accounts the previous mandate allowed and this one doesn't, removed from the lock. */
62
+ remove?: readonly Address[];
63
+ onSigned?: (mandate: Signed<Mandate>) => void;
64
+ }
65
+ /**
66
+ * Signs the mandate with the root key and puts the agent's key on the account, in one transaction
67
+ * from the root key. The key is bound to the mandate's hash with the mandate's limits and expiry,
68
+ * and each supplier the mandate names is approved on the lock. When the key replaces another, the
69
+ * same transaction revokes the old key in the account's keychain, so the old key can't sign for the
70
+ * account again, and removes from the lock each supplier the new mandate drops. Bookings the old key
71
+ * made stay in the lock until their release. A new mandate needs a new key, since the account binds
72
+ * each key to one mandate's hash.
73
+ */
74
+ export declare function authorizeSandboxKey(deps: SandboxAuthorizeDeps): Promise<AuthorizedSandboxKey>;
75
+ /**
76
+ * Puts the agent's key on the account as `authorizeSandboxKey` does, then enrolls the agent with
77
+ * Avow, which checks the mandate against that transaction.
78
+ */
79
+ export declare function enrollSandboxAgent(deps: SandboxAuthorizeDeps & {
80
+ agent: AgentKey;
81
+ deployment: Pick<SandboxDeployment, 'chainId' | 'apiUrl'>;
82
+ fetch?: typeof fetch;
83
+ }): Promise<EnrolledSandboxAgent>;
84
+ //# sourceMappingURL=mandate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mandate.d.ts","sourceRoot":"","sources":["../../src/sandbox/mandate.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,OAAO,EAEZ,KAAK,iBAAiB,EACtB,KAAK,MAAM,EACX,KAAK,eAAe,EACrB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,KAAK,OAAO,EAAsB,KAAK,GAAG,EAAS,MAAM,MAAM,CAAA;AACxE,OAAO,EAAQ,OAAO,EAAa,MAAM,YAAY,CAAA;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAM3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAIlD,6FAA6F;AAC7F,eAAO,MAAM,mBAAmB,cAAiB,CAAA;AAEjD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,OAAO,CAAA;IACjB,4DAA4D;IAC5D,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;IAC5B;;;OAGG;IACH,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC9B,KAAK,EAAE,OAAO,CAAA;IACd,gBAAgB,EAAE,MAAM,CAAA;IACxB,eAAe,EAAE,MAAM,CAAA;IACvB,uFAAuF;IACvF,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,oBAAoB;IACpB,MAAM,EAAE,MAAM,CAAA;CACf,GAAG,OAAO,CAkBV;AAED,6EAA6E;AAC7E,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAA;IACxB,WAAW,EAAE,GAAG,CAAA;IAChB,+DAA+D;IAC/D,eAAe,EAAE,GAAG,CAAA;CACrB;AAED,2EAA2E;AAC3E,MAAM,WAAW,oBAAqB,SAAQ,oBAAoB;IAChE,UAAU,EAAE,UAAU,CAAA;CACvB;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAA;IAC9C,MAAM,EAAE,aAAa,CAAA;IACrB,IAAI,EAAE,OAAO,CAAC,WAAW,CAAA;IACzB;;;OAGG;IACH,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,kBAAkB,GAAG,SAAS,CAAC,CAAA;IACrD,IAAI,EAAE,OAAO,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,kEAAkE;IAClE,SAAS,EAAE,SAAS,eAAe,EAAE,CAAA;IACrC,kGAAkG;IAClG,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,kGAAkG;IAClG,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;IAC3B,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,CAAA;CAC9C;AAED;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,oBAAoB,CAAC,CA6C/B;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,oBAAoB,GAAG;IAC3B,KAAK,EAAE,QAAQ,CAAA;IACf,UAAU,EAAE,IAAI,CAAC,iBAAiB,EAAE,SAAS,GAAG,QAAQ,CAAC,CAAA;IACzD,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;CACrB,GACA,OAAO,CAAC,oBAAoB,CAAC,CAY/B"}
@@ -0,0 +1,107 @@
1
+ import { mandateHash, } from '@avow-finance/spec';
2
+ import { encodeFunctionData, toHex } from 'viem';
3
+ import { Abis, Account, Addresses } from 'viem/tempo';
4
+ import { agentKeyTerms } from '../agent-key.js';
5
+ import { agentRequestKey, enrollAgent } from '../http.js';
6
+ import { approveSupplierCall, RESERVE_SELECTOR, removeSupplierCall } from '../lock.js';
7
+ import { sendOwn } from '../send.js';
8
+ import { accountSigner, signMandate } from '../sign.js';
9
+ const DAY = 86400n;
10
+ /** What the agent's key can move in a day when the business names no daily limit, $1,000. */
11
+ export const SANDBOX_DAILY_LIMIT = 1000000000n;
12
+ /**
13
+ * The mandate a sandbox business's root key signs for its agent. The agent may reserve, cancel and
14
+ * start commitments in the named categories with the named suppliers, up to `capPerCommitment` for
15
+ * one and `capOpenReserves` across those it holds at once, until `expiry`. Its key can move at most
16
+ * `dailyLimit` in a day, which the account's keychain holds whatever Avow approves. Every booking
17
+ * goes ahead without a person's approval, which a real business would set to fit its own rules.
18
+ */
19
+ export function sandboxMandate(m) {
20
+ return {
21
+ mandateId: toHex(crypto.getRandomValues(new Uint8Array(32))),
22
+ businessId: m.businessId,
23
+ agentId: m.agentId,
24
+ account: m.account,
25
+ agentKey: m.agentKey,
26
+ actions: ['reserve', 'cancel', 'start'],
27
+ currency: 'USD',
28
+ capPerCommitment: m.capPerCommitment,
29
+ capOpenReserves: m.capOpenReserves,
30
+ suppliers: [...m.suppliers],
31
+ categories: [...(m.categories ?? ['compute'])],
32
+ paymentLimits: [{ token: m.token, amount: m.dailyLimit ?? SANDBOX_DAILY_LIMIT, period: DAY }],
33
+ approvalRule: { kind: 'never' },
34
+ expiry: m.expiry,
35
+ nonce: 1n,
36
+ };
37
+ }
38
+ /**
39
+ * Signs the mandate with the root key and puts the agent's key on the account, in one transaction
40
+ * from the root key. The key is bound to the mandate's hash with the mandate's limits and expiry,
41
+ * and each supplier the mandate names is approved on the lock. When the key replaces another, the
42
+ * same transaction revokes the old key in the account's keychain, so the old key can't sign for the
43
+ * account again, and removes from the lock each supplier the new mandate drops. Bookings the old key
44
+ * made stay in the lock until their release. A new mandate needs a new key, since the account binds
45
+ * each key to one mandate's hash.
46
+ */
47
+ export async function authorizeSandboxKey(deps) {
48
+ const { deployment, client, root, agent, lock, mandate } = deps;
49
+ const d = { chainId: deployment.chainId, verifyingContract: lock };
50
+ const signed = await signMandate(mandate, d, accountSigner(root.address, root));
51
+ deps.onSigned?.(signed);
52
+ const keyAuthorization = await Account.signKeyAuthorization(root, {
53
+ key: agent,
54
+ chainId: BigInt(deployment.chainId),
55
+ ...agentKeyTerms(mandate, d, { lock, lockSelectors: [RESERVE_SELECTOR] }),
56
+ });
57
+ const calls = [
58
+ ...(deps.revoke
59
+ ? [
60
+ {
61
+ to: Addresses.accountKeychain,
62
+ data: encodeFunctionData({
63
+ abi: Abis.accountKeychain,
64
+ functionName: 'revokeKey',
65
+ args: [deps.revoke],
66
+ }),
67
+ },
68
+ ]
69
+ : []),
70
+ ...(deps.remove ?? []).map((s) => removeSupplierCall(lock, s)),
71
+ ...deps.suppliers.map((s) => approveSupplierCall(lock, s.account)),
72
+ ];
73
+ // Tempo refuses a transaction with no calls, and a mandate that names no supplier, such as one
74
+ // whose agent approves each supplier as it books, would send none. Reading the key just put on the
75
+ // account gives the transaction a call that changes nothing.
76
+ if (calls.length === 0) {
77
+ calls.push({
78
+ to: Addresses.accountKeychain,
79
+ data: encodeFunctionData({
80
+ abi: Abis.accountKeychain,
81
+ functionName: 'getKey',
82
+ args: [root.address, agent.accessKeyAddress],
83
+ }),
84
+ });
85
+ }
86
+ const receipt = await sendOwn({ client, account: root, calls, keyAuthorization });
87
+ return {
88
+ mandate: signed,
89
+ mandateHash: mandateHash(mandate, d),
90
+ keyAuthorizedIn: receipt.transactionHash,
91
+ };
92
+ }
93
+ /**
94
+ * Puts the agent's key on the account as `authorizeSandboxKey` does, then enrolls the agent with
95
+ * Avow, which checks the mandate against that transaction.
96
+ */
97
+ export async function enrollSandboxAgent(deps) {
98
+ const authorized = await authorizeSandboxKey(deps);
99
+ const enrollment = await enrollAgent({
100
+ baseUrl: deps.deployment.apiUrl,
101
+ key: agentRequestKey(deps.agent),
102
+ retryFor: 120n,
103
+ ...(deps.fetch ? { fetch: deps.fetch } : {}),
104
+ }, { mandate: authorized.mandate, keyAuthorizedIn: authorized.keyAuthorizedIn });
105
+ return { ...authorized, enrollment };
106
+ }
107
+ //# sourceMappingURL=mandate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mandate.js","sourceRoot":"","sources":["../../src/sandbox/mandate.ts"],"names":[],"mappings":"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"}