@botanary/agent 0.1.0-alpha.1

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 (60) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/LICENSE +21 -0
  3. package/README.md +123 -0
  4. package/dist/errors.d.ts +49 -0
  5. package/dist/errors.d.ts.map +1 -0
  6. package/dist/errors.js +40 -0
  7. package/dist/errors.js.map +1 -0
  8. package/dist/exact-action.d.ts +48 -0
  9. package/dist/exact-action.d.ts.map +1 -0
  10. package/dist/exact-action.js +178 -0
  11. package/dist/exact-action.js.map +1 -0
  12. package/dist/fingerprint.d.ts +21 -0
  13. package/dist/fingerprint.d.ts.map +1 -0
  14. package/dist/fingerprint.js +47 -0
  15. package/dist/fingerprint.js.map +1 -0
  16. package/dist/generated/routes.d.ts +68 -0
  17. package/dist/generated/routes.d.ts.map +1 -0
  18. package/dist/generated/routes.js +92 -0
  19. package/dist/generated/routes.js.map +1 -0
  20. package/dist/generated/schema.d.ts +2903 -0
  21. package/dist/generated/schema.d.ts.map +1 -0
  22. package/dist/generated/schema.js +2 -0
  23. package/dist/generated/schema.js.map +1 -0
  24. package/dist/http-path.d.ts +92 -0
  25. package/dist/http-path.d.ts.map +1 -0
  26. package/dist/http-path.js +201 -0
  27. package/dist/http-path.js.map +1 -0
  28. package/dist/index.d.ts +11 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +7 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/pairing-code.d.ts +41 -0
  33. package/dist/pairing-code.d.ts.map +1 -0
  34. package/dist/pairing-code.js +60 -0
  35. package/dist/pairing-code.js.map +1 -0
  36. package/dist/registration.d.ts +21 -0
  37. package/dist/registration.d.ts.map +1 -0
  38. package/dist/registration.js +62 -0
  39. package/dist/registration.js.map +1 -0
  40. package/dist/runtime.d.ts +203 -0
  41. package/dist/runtime.d.ts.map +1 -0
  42. package/dist/runtime.js +559 -0
  43. package/dist/runtime.js.map +1 -0
  44. package/dist/signer.d.ts +33 -0
  45. package/dist/signer.d.ts.map +1 -0
  46. package/dist/signer.js +13 -0
  47. package/dist/signer.js.map +1 -0
  48. package/dist/transport.d.ts +13 -0
  49. package/dist/transport.d.ts.map +1 -0
  50. package/dist/transport.js +135 -0
  51. package/dist/transport.js.map +1 -0
  52. package/dist/validation.d.ts +15 -0
  53. package/dist/validation.d.ts.map +1 -0
  54. package/dist/validation.js +108 -0
  55. package/dist/validation.js.map +1 -0
  56. package/dist/views.d.ts +182 -0
  57. package/dist/views.d.ts.map +1 -0
  58. package/dist/views.js +2 -0
  59. package/dist/views.js.map +1 -0
  60. package/package.json +50 -0
@@ -0,0 +1,559 @@
1
+ import { exactActionInput, actionBinding, validateExactAction, exactActionReceipt } from './exact-action.js';
2
+ import { keccak256, toHex, encodePacked, encodeAbiParameters } from 'viem';
3
+ import { PairingCodeManager } from './pairing-code.js';
4
+ import { AgentApiClient } from './transport.js';
5
+ import { BotanaryApiError } from './errors.js';
6
+ import { recoverAddress } from 'viem';
7
+ import { publicIdentity, hex, record, resourceId, invalidResponse, unsignedUserOp, readyRequirement, apiCallStatus } from './validation.js';
8
+ /**
9
+ * Poll `get` until the op reports a terminal status or `budgetMs` is spent, then return whatever the
10
+ * backend last said - VERBATIM. A budget lapse returns the real `pending` answer; this helper never
11
+ * invents a status, and never blocks forever.
12
+ *
13
+ * Pure and injectable (clock + sleep) so its behaviour is testable without timers or a network.
14
+ */
15
+ export async function awaitTerminalWith(get, opId, budgetMs, now, sleep) {
16
+ if (!Number.isFinite(budgetMs) || budgetMs < 0 || budgetMs > 3_600_000)
17
+ throw new Error('Invalid wait budget.');
18
+ const started = now();
19
+ let last = await get(opId);
20
+ while (['pending', 'pending_approval', 'submitted', 'queued'].includes(String(last.status)) && now() - started < budgetMs) {
21
+ await sleep(1_500);
22
+ last = await get(opId);
23
+ }
24
+ return last;
25
+ }
26
+ /** Re-mint this many ms before the backend's own `expiresAt` - session TTL is an hour
27
+ * (`agent-session.store.ts`), so this is a small, deliberately conservative margin, not a tuned value. */
28
+ const SESSION_REFRESH_SKEW_MS = 30_000;
29
+ /** How long `callApi` polls a `pending_approval` call before giving up and reporting its OWN timeout -
30
+ * distinct from the backend's `expired`, which is a real verdict (see `callApi`'s decline branch).
31
+ * Matches the backend's own `REQUIREMENT_TTL_MS` (`botanary-be/src/common/x402-ttl.ts`, 5 minutes),
32
+ * copied rather than imported because this package is deploy-isolated from botanary-be (no shared
33
+ * import, ever - see the workspace AGENTS.md). A longer budget here would just keep polling after the
34
+ * backend itself has already started answering `expired`. */
35
+ const APPROVAL_POLL_BUDGET_MS = 5 * 60 * 1000;
36
+ /** Default API origin. The shared runtime reads no environment variables; its host supplies overrides. */
37
+ export const DEFAULT_API_BASE_URL = 'https://api.app.botanary.xyz';
38
+ /** Per-instance agent identity and sessions. The signer owns all private-key storage. */
39
+ export class AgentRuntime {
40
+ #store;
41
+ #api;
42
+ #apiBaseUrl;
43
+ #provenance;
44
+ #identity = null;
45
+ #pairing = null;
46
+ #session = null;
47
+ #identityPending = null;
48
+ #mintPending = null;
49
+ #generation = 0;
50
+ constructor(signer, options = {}) {
51
+ this.#store = signer;
52
+ this.#apiBaseUrl = options.baseUrl ?? DEFAULT_API_BASE_URL;
53
+ this.#api = options.transport ?? new AgentApiClient(this.#apiBaseUrl, options.fetch);
54
+ this.#provenance = options.provenance ?? {};
55
+ }
56
+ get apiBaseUrl() { return this.#apiBaseUrl; }
57
+ get identityMaterialized() { return this.#identity !== null || this.#identityPending !== null; }
58
+ setProvenance(value) { this.#provenance = value; }
59
+ replaceSigner(signer) {
60
+ if (this.identityMaterialized)
61
+ throw new Error('Cannot replace a materialized agent signer.');
62
+ this.#store = signer;
63
+ this.reset();
64
+ }
65
+ /** The agent's public identity, creating it on first call if none exists yet. Cached for the life of
66
+ * this runtime (the address/fingerprint cannot change without a forget(), which calls reset()). */
67
+ async identity() {
68
+ if (this.#identity)
69
+ return this.#identity;
70
+ if (this.#identityPending)
71
+ return this.#identityPending;
72
+ const generation = this.#generation;
73
+ const pending = (async () => {
74
+ let value;
75
+ try {
76
+ value = await this.#store.ensure();
77
+ }
78
+ catch {
79
+ throw this.#signerFailure();
80
+ }
81
+ if (generation !== this.#generation)
82
+ throw this.#signerFailure();
83
+ const identity = publicIdentity(value);
84
+ this.#identity = identity;
85
+ return identity;
86
+ })();
87
+ this.#identityPending = pending;
88
+ try {
89
+ return await pending;
90
+ }
91
+ finally {
92
+ if (this.#identityPending === pending)
93
+ this.#identityPending = null;
94
+ }
95
+ }
96
+ #signerFailure() {
97
+ const error = new BotanaryApiError('The agent signer could not complete the request.', 0);
98
+ error.code = 'signer_error';
99
+ return error;
100
+ }
101
+ async #signHash(hash) {
102
+ hex(hash, 32);
103
+ const generation = this.#generation;
104
+ const identity = await this.identity();
105
+ if (generation !== this.#generation)
106
+ throw this.#signerFailure();
107
+ try {
108
+ const signature = await this.#store.signHash(hash);
109
+ hex(signature, 65);
110
+ const recovered = await recoverAddress({ hash, signature });
111
+ if (generation !== this.#generation || recovered.toLowerCase() !== identity.address.toLowerCase())
112
+ throw this.#signerFailure();
113
+ return signature;
114
+ }
115
+ catch {
116
+ throw this.#signerFailure();
117
+ }
118
+ }
119
+ async pairingCode() {
120
+ const pairing = await this.#ensurePairing();
121
+ return pairing.current();
122
+ }
123
+ async regeneratePairingCode() {
124
+ const pairing = await this.#ensurePairing();
125
+ return pairing.regenerate();
126
+ }
127
+ async pair() {
128
+ const code = await this.pairingCode();
129
+ const timestamp = Math.floor(Date.now() / 1000);
130
+ const identity = await this.identity();
131
+ const message = `${code.code}|${timestamp}`;
132
+ const messageHash = keccak256(toHex(message));
133
+ await this.#api.post('/v1/agents/pair', {
134
+ code: code.code,
135
+ publicKey: identity.publicKey,
136
+ timestamp,
137
+ signature: await this.#signHash(messageHash),
138
+ // Provenance travels WITH THE SIGNED PROOF, not with the owner's claim, so which tool a pairing
139
+ // says it is gets fixed by the connector that actually holds the key. Omitted entirely rather
140
+ // than sent as null when nothing was reported - the backend's DTO makes both optional, and a
141
+ // stored null must mean "reported nothing", never "reported the empty string".
142
+ ...(this.#provenance.client ? { client: this.#provenance.client } : {}),
143
+ ...(this.#provenance.profile ? { profile: this.#provenance.profile } : {}),
144
+ });
145
+ return code;
146
+ }
147
+ /** Mint a FRESH session unconditionally (bypasses the cache - this is what re-minting after expiry or
148
+ * a 401 calls). Also (re)populates the cache, so an ordinary tool call right after this one reuses it
149
+ * via `ensureSession()` instead of minting again. */
150
+ async mintSession() {
151
+ if (this.#mintPending)
152
+ return this.#mintPending;
153
+ const generation = this.#generation;
154
+ const pending = (async () => {
155
+ const identity = await this.identity();
156
+ const challenge = record(await this.#api.post('/v1/agents/session/nonce', { address: identity.address }));
157
+ hex(challenge.nonce, 32);
158
+ if (generation !== this.#generation)
159
+ throw this.#signerFailure();
160
+ const signature = await this.#signHash(challenge.nonce);
161
+ const response = record(await this.#api.post('/v1/agents/session', {
162
+ address: identity.address, nonce: challenge.nonce, signature,
163
+ }));
164
+ if (typeof response.token !== 'string' || !/^ags_[a-f0-9]{64}$/.test(response.token) ||
165
+ typeof response.expiresAt !== 'string' || !Number.isFinite(Date.parse(response.expiresAt)) ||
166
+ Date.parse(response.expiresAt) <= Date.now() || Date.parse(response.expiresAt) > Date.now() + 3_660_000)
167
+ invalidResponse();
168
+ if (generation !== this.#generation)
169
+ throw this.#signerFailure();
170
+ this.#session = { token: response.token, safeUntil: Date.parse(response.expiresAt) - SESSION_REFRESH_SKEW_MS };
171
+ return response.token;
172
+ })();
173
+ this.#mintPending = pending;
174
+ try {
175
+ return await pending;
176
+ }
177
+ finally {
178
+ if (this.#mintPending === pending)
179
+ this.#mintPending = null;
180
+ }
181
+ }
182
+ /** The token every read/build/spend call below actually uses: the cached session if it is still safe
183
+ * to reuse, otherwise a freshly minted one. This is what makes "every tool call does not re-mint" true
184
+ * without any caller having to think about session lifetime. */
185
+ async ensureSession() {
186
+ if (this.#session && this.#session.safeUntil > Date.now())
187
+ return this.#session.token;
188
+ return this.mintSession();
189
+ }
190
+ /** `GET /agents/me` - this agent's own identity, its bound account, and its live grant if any (or an
191
+ * honest `grant: null`). Re-mints the session once and retries on a 401 (a token that expired between
192
+ * `ensureSession()`'s check and the request landing, or one the backend otherwise no longer honors). */
193
+ async me() {
194
+ return this.#withSession((token) => this.#api.get('/v1/agents/me', token));
195
+ }
196
+ /** `GET /balance` - the account address and its token/holdings breakdown, exactly as the backend
197
+ * reports it. */
198
+ async getBalance() {
199
+ return this.#withSession((token) => this.#api.get('/v1/balance', token));
200
+ }
201
+ /** `GET /agents/requests` - every approval request this agent has filed, with the owner's verdict
202
+ * (`status`, `declineReason`) and deadline. The read half of `request_approval`: without it an agent
203
+ * files a request it can never learn the outcome of. */
204
+ async listRequests() {
205
+ return this.#withSession((token) => this.#api.get('/v1/agents/requests', token));
206
+ }
207
+ /** `GET /chains` - every chain this build serves, each with the `chainTier` that decides what it can
208
+ * do (`watch` read-only, `basic` no AgentGuard, `botanary` full authority). */
209
+ async listChains() {
210
+ return this.#withSession((token) => this.#api.get('/v1/chains', token));
211
+ }
212
+ /** `GET /gas/methods` - only the gas methods actually AVAILABLE on the given chain (the backend
213
+ * filters unavailable/sponsored ones out itself). Every parameter is optional and passed through
214
+ * untouched; `key` is the Stellar/Solana key-keyed lane, `chainId` the EVM numeric one. */
215
+ async getGasMethods(params) {
216
+ const query = new URLSearchParams();
217
+ if (params.chainId !== undefined)
218
+ query.set('chainId', String(params.chainId));
219
+ if (params.accountId)
220
+ query.set('accountId', params.accountId);
221
+ if (params.key)
222
+ query.set('key', params.key);
223
+ const suffix = query.toString();
224
+ return this.#withSession((token) => this.#api.get(`/v1/gas/methods${suffix ? `?${suffix}` : ''}`, token));
225
+ }
226
+ /** `GET /account` - SINGULAR: the one account this agent's session resolves to, optionally for a
227
+ * specific chain. Carries `address` and `deploymentStatus`. */
228
+ async getAccount(params) {
229
+ const query = new URLSearchParams();
230
+ if (params.chainId !== undefined)
231
+ query.set('chainId', String(params.chainId));
232
+ const suffix = query.toString();
233
+ return this.#withSession((token) => this.#api.get(`/v1/account${suffix ? `?${suffix}` : ''}`, token));
234
+ }
235
+ /** Build and verify a bound action. Submission is explicit and attempted at most once per handle. */
236
+ async prepareExactAction(input, binding) {
237
+ const request = exactActionInput(input);
238
+ const expected = actionBinding(binding, request);
239
+ const generation = this.#generation;
240
+ const response = await this.#withSession(token => this.#api.post(`/v1/delegations/${expected.delegationId}/actions/exact`, request, token), false);
241
+ const built = await validateExactAction(response, request, expected);
242
+ let attempt;
243
+ return Object.freeze({ userOpHash: built.userOpHash, execution: built.execution, submit: () => {
244
+ if (!attempt)
245
+ attempt = (async () => {
246
+ if (generation !== this.#generation)
247
+ throw this.#signerFailure();
248
+ const token = await this.ensureSession();
249
+ if (generation !== this.#generation)
250
+ throw this.#signerFailure();
251
+ return exactActionReceipt(await this.spendUnderGrant(built.userOp, built.userOpHash, expected.permissionId, token, 'delegated_action'), built.userOpHash);
252
+ })();
253
+ return attempt;
254
+ }, reconcile: () => this.getUserOpByHash(request.chainId, built.userOpHash) });
255
+ }
256
+ /**
257
+ * `POST /delegations/{delegationId}/actions` - an UNSIGNED delegated-action op, built in the
258
+ * delegation's OWN Smart Sessions nonce lane with fixed native gas (the session validator cannot
259
+ * gas-estimate a stub signature). This is the ONLY build lane a session-key signature can validate:
260
+ * `POST /money/send/build` (this package's earlier, WRONG choice) builds in the Kernel account's ROOT
261
+ * nonce lane for the OWNER's key - an op built there, then signed with this agent's session key and
262
+ * wrapped in `spendUnderGrant`'s USE envelope, would route validation to the root ECDSA validator,
263
+ * which cannot parse a `(bytes1, bytes32, bytes)` envelope as a 65-byte ECDSA signature. `delegationId`
264
+ * is this agent's OWN grant id (`GET /agents/me`'s `grant.id` - never invented, never another agent's:
265
+ * the backend refuses that with a named 403, see the workspace's delegation.controller.ts). `amount` is
266
+ * DISPLAY units (e.g. `12.5` for 12.5 USDC), matching `DelegatedActionInput.amount` - never wei.
267
+ * `token`, when given, disambiguates which of the delegation's budgeted tokens to move - a contract
268
+ * address or CAIP-19 asset ref (Task A11), required whenever the grant budgets more than one
269
+ * stablecoin. Omitted, the backend defaults to it ONLY when exactly one token is budgeted; a
270
+ * multi-budget grant given neither refuses rather than silently picking the first (`propose_payment`
271
+ * always resolves and passes one - see `agent-actions.ts`).
272
+ */
273
+ async buildDelegatedAction(params) {
274
+ const body = {
275
+ recipient: params.recipient,
276
+ amount: params.amount,
277
+ ...(params.token ? { token: params.token } : {}),
278
+ };
279
+ return this.#withSession((token) => this.#api.post(`/v1/delegations/${params.delegationId}/actions`, body, token), false);
280
+ }
281
+ /**
282
+ * `POST /delegations/{delegationId}/actions` with `action: 'swap'` - the SAME endpoint, the same session
283
+ * nonce lane and the same fixed gas as `buildDelegatedAction` above; only the body's shape differs. The
284
+ * backend discriminates on `action` explicitly and NEVER infers it from the presence of `tokenIn`, so a
285
+ * transfer body with a typo stays a 422 on the wrong field rather than silently becoming a swap.
286
+ *
287
+ * Symbols, not addresses: unlike `buildDelegatedAction`'s `token` (Task A11), this shape was NOT widened
288
+ * to accept an address or asset ref - the backend re-resolves both legs from ITS OWN per-chain manifest,
289
+ * which is the same resolution `buildGrant` used when it compiled the venue's `EQ` rule, so the two
290
+ * cannot disagree. `propose_swap` (`agent-actions.ts`) still takes an address/asset ref from ITS OWN
291
+ * caller (`assetIn`/`assetOut`) and resolves each to a verified symbol before calling this - so the
292
+ * package-external argument names moved even though this wire shape did not. `amountIn` is DISPLAY
293
+ * units (e.g. `25` for 25 USDC), matching `amount` on the transfer shape.
294
+ *
295
+ * The op this produces is ONE call into `GrantExecutor.executeUnderGrantWithAllowance` - approve, route,
296
+ * zero, assert no residual - which the grant's session authorises only when the grant named a
297
+ * `swapVenue`. A grant without one has no such action at all and the backend declines
298
+ * `grant_swap_not_authorised` rather than handing back an op Smart Sessions would refuse in validation.
299
+ */
300
+ async buildDelegatedSwap(params) {
301
+ const body = {
302
+ action: 'swap',
303
+ tokenIn: params.tokenIn,
304
+ tokenOut: params.tokenOut,
305
+ amountIn: params.amountIn,
306
+ ...(params.maxSlippageBps != null ? { maxSlippageBps: params.maxSlippageBps } : {}),
307
+ };
308
+ return this.#withSession((token) => this.#api.post(`/v1/delegations/${params.delegationId}/actions`, body, token), false);
309
+ }
310
+ /** `POST /agents/requests` - the "ask" half of the design (Flow 7d step 5): raise a request naming the
311
+ * calls that were declined and why, returning which bound was crossed and the deadline exactly as the
312
+ * backend computed them. */
313
+ async raiseRequest(calls, reason) {
314
+ return this.#withSession((token) => this.#api.post('/v1/agents/requests', { calls, reason }, token), false);
315
+ }
316
+ /**
317
+ * Sign a built op as the grant's session key and relay it. The USE envelope is EXACTLY the three lines
318
+ * `botanary-fe/src/lib/wallet/signing.ts:49` already uses - `SmartSessionMode.USE` is `0x00`, and the
319
+ * packing is `(bytes1, bytes32, bytes)`. Reproduced rather than re-derived: a second encoding of the same
320
+ * envelope is a second thing to get byte-exact, and only one of them would be tested.
321
+ *
322
+ * `intentType` is the SAME value the build response itself reported (`UserOpBuildResult.intentType`,
323
+ * `'delegated_action'` for `buildDelegatedAction`'s builds) - never assumed or hardcoded here, so the
324
+ * relay always describes what was actually built, which is what `OrchestratorService.submit` uses to
325
+ * label the audit trail entry.
326
+ *
327
+ * Returns the backend's OWN relay response (status/txHash/error, whatever `POST /userops` actually
328
+ * said) rather than nothing - a caller (`propose_payment`) reporting success has to report what the
329
+ * backend reported, never a string this package made up.
330
+ */
331
+ async spendUnderGrant(userOp, userOpHash, permissionId, token, intentType) {
332
+ unsignedUserOp(userOp);
333
+ hex(userOpHash, 32);
334
+ hex(permissionId, 32);
335
+ const raw = await this.#signHash(userOpHash);
336
+ const signature = encodePacked(['bytes1', 'bytes32', 'bytes'], ['0x00', permissionId, raw]);
337
+ try {
338
+ return await this.#api.post('/v1/userops', { userOp: { ...userOp, signature }, userOpHash, intentType }, token);
339
+ }
340
+ catch (error) {
341
+ if (error instanceof BotanaryApiError)
342
+ error.userOpHash = userOpHash;
343
+ throw error;
344
+ }
345
+ }
346
+ /** `GET /userops/{opId}` - the receipt for an op THIS agent relayed. Reachable only because that route
347
+ * now carries `@AgentAllowed()`; before that it 403'd an `ags_` token before the handler ran. */
348
+ async getUserOp(opId) {
349
+ resourceId(opId);
350
+ return this.#withSession((token) => this.#api.get(`/v1/userops/${opId}`, token));
351
+ }
352
+ /** Read the original agent submission without building or signing another operation. */
353
+ async getUserOpByHash(chainId, hash) {
354
+ if (!Number.isSafeInteger(chainId) || chainId < 1)
355
+ invalidResponse();
356
+ hex(hash, 32);
357
+ return exactActionReceipt(await this.#withSession(token => this.#api.get(`/v1/userops/by-hash/${chainId}/${hash}`, token)), hash);
358
+ }
359
+ /** Follow an op to a terminal status, bounded. See `awaitTerminalWith`. */
360
+ async awaitTerminal(opId, budgetMs) {
361
+ return awaitTerminalWith((id) => this.getUserOp(id), opId, budgetMs, () => Date.now(), (ms) => new Promise((r) => setTimeout(r, ms)));
362
+ }
363
+ /** `GET /apis/providers` - the ranked, searchable catalog of API providers on a chain, with each
364
+ * provider's endpoint count, verified count, minimum and maximum price in atomic units (nullable).
365
+ * Does NOT call an endpoint or spend anything. Returns
366
+ * `{ providers, total, hidden, reasons, reasonsTruncated }`.
367
+ *
368
+ * The route is `/apis/providers`, not the `/apis/list` this file used to call: the backend's
369
+ * api-catalog controller serves `providers` and `providers/:providerId` and has no `list` route at
370
+ * all, so the old path 404s. botanary-mcp@0.6.1 was published with this corrected route but the
371
+ * change was never committed, which is how the repository came to describe a dead endpoint while
372
+ * the published package worked. */
373
+ async listApis(chainId) {
374
+ return this.#withSession((token) => this.#api.get(`/v1/apis/providers?chainId=${chainId}`, token));
375
+ }
376
+ /** `GET /apis/providers/{providerId}` - one provider with a page of its endpoints, each with its
377
+ * live price as measured or declared (nullable), and whether it is payable on this chain. Returns
378
+ * the `ApiProviderDetail` shape, with an `endpoints` array. */
379
+ async getApiProvider(providerId, chainId) {
380
+ const query = chainId !== undefined ? `?chainId=${chainId}` : '';
381
+ return this.#withSession((token) => this.#api.get(`/v1/apis/providers/${providerId}${query}`, token));
382
+ }
383
+ /**
384
+ * Call a paid third-party API endpoint and pay for it from the owner's wallet, within the budget the
385
+ * owner committed on chain. Build -> sign -> relay, exactly like every other spending lane here.
386
+ *
387
+ * This used to `POST /v1/apis/calls`, a route that has never existed - the contract has
388
+ * `/apis/calls/requirements` and `/apis/calls/relay`, and there is no composite. There could not be
389
+ * one: a single endpoint would have to sign, and the backend holds no key. So the two halves are both
390
+ * real calls, with the signature produced HERE, from this agent's own key.
391
+ *
392
+ * `payload` is a 32-byte EIP-712 digest over an EIP-3009 `TransferWithAuthorization`. Signing it
393
+ * authorises exactly one transfer, of a value and to a recipient the digest already fixes; USDC
394
+ * verifies the result via ERC-1271 against the owner's account, which routes to
395
+ * `X402PaymentValidator` and is refused unless this agent key is inside a live budget.
396
+ */
397
+ async callApi(params) {
398
+ const built = await this.#withSession(token => this.#api.post('/v1/apis/calls/requirements', params, token), false);
399
+ resourceId(built?.requirementId);
400
+ if (!['ready', 'pending_approval'].includes(built.status))
401
+ invalidResponse();
402
+ return this.#finishApiRequirement(built);
403
+ }
404
+ /** Read durable submission status first. A submitted payment is never signed or forwarded again. */
405
+ async resumeApi(requirementId, budgetMs = APPROVAL_POLL_BUDGET_MS) {
406
+ resourceId(requirementId);
407
+ const status = apiCallStatus(await this.#withSession(token => this.#api.get(`/v1/apis/calls/relay/${requirementId}`, token)), requirementId);
408
+ if (status.status === 'ready')
409
+ return this.#finishApiRequirement({ requirementId, status: 'ready', ...readyRequirement(status.ready) }, budgetMs);
410
+ if (status.status !== 'pending_approval')
411
+ return status;
412
+ return this.#finishApiRequirement({ requirementId, status: 'pending_approval', approvalId: requirementId, expiresAt: '' }, budgetMs);
413
+ }
414
+ async #finishApiRequirement(built, budgetMs = APPROVAL_POLL_BUDGET_MS) {
415
+ let ready;
416
+ if (built.status === 'pending_approval') {
417
+ // Task 11's confirmation threshold: the digest is withheld until the owner answers. The poll
418
+ // route's own `'pending'` status IS the exact sentinel `awaitTerminalWith` already knows to loop
419
+ // past (see that function's own doc comment), so this reuses it rather than growing a second
420
+ // copy of the same loop `awaitTerminal` already runs for a userOp. Read as `Record<string,
421
+ // unknown>` through the helper (its own contract - see doc comment: "returns whatever the
422
+ // backend last said, VERBATIM") and cast once here, where the endpoint's real shape is known.
423
+ const polled = (await awaitTerminalWith((id) => this.#withSession(token => this.#api.get(`/v1/apis/calls/requirements/${id}`, token)), built.requirementId, budgetMs, () => Date.now(), (ms) => new Promise((r) => setTimeout(r, ms))));
424
+ if (polled.status === 'approved' &&
425
+ polled.payload &&
426
+ polled.authorization &&
427
+ polled.index !== undefined &&
428
+ polled.validator) {
429
+ ready = {
430
+ payload: polled.payload,
431
+ authorization: polled.authorization,
432
+ index: polled.index,
433
+ validator: polled.validator,
434
+ };
435
+ }
436
+ else {
437
+ // 'declined' and 'expired' are the backend's own terminal verdicts. A lingering 'pending' here
438
+ // means OUR OWN poll budget ran out while the owner still had not answered - a client-side
439
+ // timeout, not a server one (the backend's own requirement TTL outlives this budget on
440
+ // purpose - see APPROVAL_POLL_BUDGET_MS). Every branch below is a STRUCTURED decline, never a
441
+ // thrown error: the caller's ordinary result-handling path must see it, the same way it sees
442
+ // any other decline this lane reports, and none of them ever attempts a signature - there is
443
+ // no digest to sign for a call the owner did not approve.
444
+ const declineReason = polled.status === 'declined'
445
+ ? 'owner_declined'
446
+ : polled.status === 'expired'
447
+ ? 'approval_timed_out'
448
+ : 'approval_still_pending';
449
+ const message = declineReason === 'owner_declined'
450
+ ? 'The owner declined this call. Nothing was signed and nothing was charged.'
451
+ : declineReason === 'approval_timed_out'
452
+ ? 'The owner did not respond before the approval window closed. Nothing was signed and ' +
453
+ 'nothing was charged.'
454
+ : 'The owner has not answered yet. Nothing was signed or charged. Resume this requirement ' +
455
+ 'or ask the owner to check their pending approvals.';
456
+ if (!['pending', 'declined', 'expired'].includes(polled.status))
457
+ invalidResponse();
458
+ return { status: polled.status === 'pending' ? 'pending_approval' : 'declined', declineReason, message,
459
+ requirementId: built.requirementId, approvalId: built.status === 'pending_approval' ? built.approvalId : undefined };
460
+ }
461
+ }
462
+ else {
463
+ ready = built;
464
+ }
465
+ ready = readyRequirement(ready);
466
+ const identity = await this.identity();
467
+ const rawSig = await this.#signHash(ready.payload);
468
+ // For an ERC-7579 (Kernel) owner - the only account type this product creates - the relay
469
+ // signature is NOT a bare 65-byte ECDSA signature. Kernel reads sig[0] as its validator-routing
470
+ // byte, so posting `rawSig` directly routes to whatever r[0] happens to be, which can never
471
+ // verify. The envelope below is what `X402PaymentValidator.isValidSignatureWithSender` decodes at
472
+ // step 1, and `botanary-contracts/test/X402PaymentValidator.integration.t.sol` pins the exact byte
473
+ // layout. `rawSig` itself stays a signature over the RAW digest - the validator recovers against
474
+ // the raw digest at step 13 deliberately, so the agent signs EIP-3009 typed data the way any x402
475
+ // client would, and this envelope is an account-side wrapper the agent's own signature never sees
476
+ // (never double-wrap: `signHash` above is the only signature produced here).
477
+ const signature = encodePacked(['bytes1', 'address', 'bytes'], [
478
+ '0x01',
479
+ ready.validator,
480
+ encodeAbiParameters([
481
+ { type: 'address' },
482
+ {
483
+ type: 'tuple',
484
+ components: [
485
+ { name: 'from', type: 'address' },
486
+ { name: 'to', type: 'address' },
487
+ { name: 'value', type: 'uint256' },
488
+ { name: 'validAfter', type: 'uint256' },
489
+ { name: 'validBefore', type: 'uint256' },
490
+ { name: 'nonce', type: 'bytes32' },
491
+ ],
492
+ },
493
+ { type: 'uint32' },
494
+ { type: 'bytes' },
495
+ ], [
496
+ identity.address,
497
+ {
498
+ from: ready.authorization.from,
499
+ to: ready.authorization.to,
500
+ value: BigInt(ready.authorization.value),
501
+ validAfter: BigInt(ready.authorization.validAfter),
502
+ validBefore: BigInt(ready.authorization.validBefore),
503
+ nonce: ready.authorization.nonce,
504
+ },
505
+ ready.index,
506
+ rawSig,
507
+ ]),
508
+ ]);
509
+ try {
510
+ return apiCallStatus(await this.#withSession(token => this.#api.post('/v1/apis/calls/relay', { requirementId: built.requirementId, signature }, token), false), built.requirementId);
511
+ }
512
+ catch (error) {
513
+ if (error instanceof BotanaryApiError)
514
+ error.requirementId = built.requirementId;
515
+ throw error;
516
+ }
517
+ }
518
+ /** `GET /apis/budget` - remaining authorizations, per-call maximum, expiry and epoch for this agent
519
+ * on a chain. Does NOT tell you which endpoints this agent may reach. */
520
+ async getApiBudget(chainId) {
521
+ return this.#withSession((token) => this.#api.get(`/v1/apis/budget?chainId=${chainId}`, token));
522
+ }
523
+ /** Drops cached identity/pairing/session state. Call after `store.forget()` so the next call re-derives
524
+ * from storage (and, in the ordinary case, creates a brand new identity) instead of continuing to serve
525
+ * an in-memory identity - or a session minted for it - whose key is now gone. */
526
+ reset() {
527
+ this.#generation += 1;
528
+ this.#identityPending = null;
529
+ this.#mintPending = null;
530
+ this.#identity = null;
531
+ this.#pairing = null;
532
+ this.#session = null;
533
+ }
534
+ async #ensurePairing() {
535
+ if (!this.#pairing) {
536
+ const identity = await this.identity();
537
+ this.#pairing ??= new PairingCodeManager(identity.fingerprint);
538
+ }
539
+ return this.#pairing;
540
+ }
541
+ /** Run `fn` against a valid session token; on a 401 (the cached token expired or was revoked
542
+ * server-side between calls), mint exactly one fresh session and retry once. Any other failure - a
543
+ * 4xx policy decline, a 5xx - is the backend's own answer and is never swallowed or retried. */
544
+ async #withSession(fn, retryRead = true) {
545
+ const token = await this.ensureSession();
546
+ try {
547
+ return await fn(token);
548
+ }
549
+ catch (e) {
550
+ if (retryRead && e instanceof BotanaryApiError && e.status === 401) {
551
+ const fresh = this.#session && this.#session.token !== token
552
+ ? await this.ensureSession() : await this.mintSession();
553
+ return await fn(fresh);
554
+ }
555
+ throw e;
556
+ }
557
+ }
558
+ }
559
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import type { Hex } from 'viem';
2
+ /** Public metadata only. The runtime never accepts or exports a private key. */
3
+ export interface AgentIdentity {
4
+ address: Hex;
5
+ publicKey: Hex;
6
+ fingerprint: string;
7
+ createdAt: string;
8
+ /** A non-secret description of the injected signer, such as an HSM or desktop keychain. */
9
+ backend: string;
10
+ }
11
+ /** A server, HSM or desktop adapter supplies signing without exposing key material. */
12
+ export interface AgentSigner {
13
+ ensure(): Promise<AgentIdentity>;
14
+ /** EIP-191 personal message signing, used for app registration proofs. */
15
+ sign(message: string): Promise<Hex>;
16
+ /** Raw secp256k1 digest signing, used by existing agent sessions and grant execution. */
17
+ signHash(hash: Hex): Promise<Hex>;
18
+ }
19
+ /** Adapts an already-owned viem-compatible account. Key loading remains the caller's responsibility. */
20
+ export declare function createViemAgentSigner(account: {
21
+ address: Hex;
22
+ publicKey: Hex;
23
+ signMessage(input: {
24
+ message: string;
25
+ }): Promise<Hex>;
26
+ sign(input: {
27
+ hash: Hex;
28
+ }): Promise<Hex>;
29
+ }, options?: {
30
+ backend?: string;
31
+ createdAt?: string;
32
+ }): AgentSigner;
33
+ //# sourceMappingURL=signer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../src/signer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAGhC,gFAAgF;AAChF,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,GAAG,CAAC;IACb,SAAS,EAAE,GAAG,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,2FAA2F;IAC3F,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,uFAAuF;AACvF,MAAM,WAAW,WAAW;IAC1B,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IACjC,0EAA0E;IAC1E,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,yFAAyF;IACzF,QAAQ,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CACnC;AAED,wGAAwG;AACxG,wBAAgB,qBAAqB,CAAC,OAAO,EAAE;IAC7C,OAAO,EAAE,GAAG,CAAC;IACb,SAAS,EAAE,GAAG,CAAC;IACf,WAAW,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACtD,IAAI,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,GAAG,CAAA;KAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CAC1C,EAAE,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,WAAW,CAStE"}
package/dist/signer.js ADDED
@@ -0,0 +1,13 @@
1
+ import { deriveFingerprint } from './fingerprint.js';
2
+ /** Adapts an already-owned viem-compatible account. Key loading remains the caller's responsibility. */
3
+ export function createViemAgentSigner(account, options = {}) {
4
+ const identity = { address: account.address, publicKey: account.publicKey,
5
+ fingerprint: deriveFingerprint(account.address), backend: options.backend ?? 'injected',
6
+ createdAt: options.createdAt ?? new Date().toISOString() };
7
+ return {
8
+ ensure: async () => ({ ...identity }),
9
+ sign: message => account.signMessage({ message }),
10
+ signHash: hash => account.sign({ hash }),
11
+ };
12
+ }
13
+ //# sourceMappingURL=signer.js.map