botanary-mcp 0.6.5 → 0.8.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 (93) hide show
  1. package/README.md +204 -12
  2. package/dist/bin/botanary-mcp.js +0 -0
  3. package/dist/src/agent-actions.d.ts +12 -3
  4. package/dist/src/agent-actions.d.ts.map +1 -1
  5. package/dist/src/agent-actions.js +43 -23
  6. package/dist/src/agent-actions.js.map +1 -1
  7. package/dist/src/agent-grant-helpers.d.ts +7 -18
  8. package/dist/src/agent-grant-helpers.d.ts.map +1 -1
  9. package/dist/src/agent-grant-helpers.js +7 -21
  10. package/dist/src/agent-grant-helpers.js.map +1 -1
  11. package/dist/src/api-client.d.ts +9 -1
  12. package/dist/src/api-client.d.ts.map +1 -1
  13. package/dist/src/api-client.js +27 -2
  14. package/dist/src/api-client.js.map +1 -1
  15. package/dist/src/cli.d.ts.map +1 -1
  16. package/dist/src/cli.js +36 -0
  17. package/dist/src/cli.js.map +1 -1
  18. package/dist/src/diagnose.d.ts.map +1 -1
  19. package/dist/src/diagnose.js +9 -3
  20. package/dist/src/diagnose.js.map +1 -1
  21. package/dist/src/hitl/context.d.ts +60 -0
  22. package/dist/src/hitl/context.d.ts.map +1 -0
  23. package/dist/src/hitl/context.js +59 -0
  24. package/dist/src/hitl/context.js.map +1 -0
  25. package/dist/src/hitl/handles.d.ts +45 -0
  26. package/dist/src/hitl/handles.d.ts.map +1 -0
  27. package/dist/src/hitl/handles.js +120 -0
  28. package/dist/src/hitl/handles.js.map +1 -0
  29. package/dist/src/hitl/resume.d.ts +37 -0
  30. package/dist/src/hitl/resume.d.ts.map +1 -0
  31. package/dist/src/hitl/resume.js +148 -0
  32. package/dist/src/hitl/resume.js.map +1 -0
  33. package/dist/src/hitl/wait.d.ts +59 -0
  34. package/dist/src/hitl/wait.d.ts.map +1 -0
  35. package/dist/src/hitl/wait.js +142 -0
  36. package/dist/src/hitl/wait.js.map +1 -0
  37. package/dist/src/http-path.d.ts +92 -0
  38. package/dist/src/http-path.d.ts.map +1 -0
  39. package/dist/src/http-path.js +201 -0
  40. package/dist/src/http-path.js.map +1 -0
  41. package/dist/src/index.d.ts +3 -1
  42. package/dist/src/index.d.ts.map +1 -1
  43. package/dist/src/index.js +2 -1
  44. package/dist/src/index.js.map +1 -1
  45. package/dist/src/paths.d.ts +3 -0
  46. package/dist/src/paths.d.ts.map +1 -1
  47. package/dist/src/paths.js +5 -0
  48. package/dist/src/paths.js.map +1 -1
  49. package/dist/src/runtime.d.ts +16 -5
  50. package/dist/src/runtime.d.ts.map +1 -1
  51. package/dist/src/runtime.js +39 -5
  52. package/dist/src/runtime.js.map +1 -1
  53. package/dist/src/server.d.ts.map +1 -1
  54. package/dist/src/server.js +13 -3
  55. package/dist/src/server.js.map +1 -1
  56. package/dist/src/tools.d.ts +11 -1
  57. package/dist/src/tools.d.ts.map +1 -1
  58. package/dist/src/tools.js +511 -46
  59. package/dist/src/tools.js.map +1 -1
  60. package/dist/src/wallet/api-get.d.ts +4 -2
  61. package/dist/src/wallet/api-get.d.ts.map +1 -1
  62. package/dist/src/wallet/api-get.js +50 -26
  63. package/dist/src/wallet/api-get.js.map +1 -1
  64. package/dist/src/wallet/api-write.d.ts +50 -0
  65. package/dist/src/wallet/api-write.d.ts.map +1 -0
  66. package/dist/src/wallet/api-write.js +122 -0
  67. package/dist/src/wallet/api-write.js.map +1 -0
  68. package/dist/src/wallet/composites.d.ts +1 -1
  69. package/dist/src/wallet/login.d.ts +28 -0
  70. package/dist/src/wallet/login.d.ts.map +1 -1
  71. package/dist/src/wallet/login.js +86 -36
  72. package/dist/src/wallet/login.js.map +1 -1
  73. package/dist/src/wallet/routes.manifest.d.ts +8 -0
  74. package/dist/src/wallet/routes.manifest.d.ts.map +1 -1
  75. package/dist/src/wallet/routes.manifest.js +20 -0
  76. package/dist/src/wallet/routes.manifest.js.map +1 -1
  77. package/dist/src/wallet/send-orchestration.d.ts +11 -9
  78. package/dist/src/wallet/send-orchestration.d.ts.map +1 -1
  79. package/dist/src/wallet/send-orchestration.js +64 -21
  80. package/dist/src/wallet/send-orchestration.js.map +1 -1
  81. package/dist/src/wallet/send.d.ts +15 -0
  82. package/dist/src/wallet/send.d.ts.map +1 -1
  83. package/dist/src/wallet/send.js +66 -3
  84. package/dist/src/wallet/send.js.map +1 -1
  85. package/dist/src/wallet/sign-request.d.ts +36 -0
  86. package/dist/src/wallet/sign-request.d.ts.map +1 -0
  87. package/dist/src/wallet/sign-request.js +10 -0
  88. package/dist/src/wallet/sign-request.js.map +1 -0
  89. package/dist/src/wallet/write-routes.manifest.d.ts +57 -0
  90. package/dist/src/wallet/write-routes.manifest.d.ts.map +1 -0
  91. package/dist/src/wallet/write-routes.manifest.js +79 -0
  92. package/dist/src/wallet/write-routes.manifest.js.map +1 -0
  93. package/package.json +12 -12
package/README.md CHANGED
@@ -18,6 +18,9 @@ picked at login. Nothing forces them to agree - `wallet_status` prints both bind
18
18
  flags a mismatch as a first-class finding, and `wallet_send`'s own lane arbitration (below) refuses to
19
19
  let a mandate on one account authorize a spend on the other, no matter how "helpful" that would be.
20
20
 
21
+ > **Full documentation: https://docs.botanary.xyz/mcp** - install recipes per client, the two lanes,
22
+ > the trust model, and a tool reference generated from this package.
23
+
21
24
  ## Tools
22
25
 
23
26
  `botanary-mcp` advertises a **subset** of its tools at any moment - a small starter set when nothing is
@@ -67,6 +70,15 @@ advertised tool list changes" further down.
67
70
  | `wallet_mandates` | Reads `GET /delegations` + `GET /mandates`: what the agent lane may spend unattended - active delegations with budget info, and any outstanding mandates. |
68
71
  | `wallet_agents` | Reads `GET /agents` + `GET /agents/requests`: connected agents and any pending approval requests they've filed. |
69
72
  | `wallet_api_get` | Read ANY `GET` endpoint in Botanary's frozen OpenAPI contract, authenticated as the owner. **GET-only, deliberately** - see below. |
73
+ | `wallet_api_write` | Call a genuinely administrative write endpoint - claim an agent, mark a notification read, rename an account, edit a pay-sh allowlist, manage conversations - authenticated as the owner. Every route whose response is an unsigned build, or that the contract marks `x-client-signed`, is excluded by construction; a small explicit denylist covers what that mechanical rule cannot see. **Never a fund-moving or authority-granting write** - see below. |
74
+ | `list_sign_kinds` | Reads `GET /sign-kinds`: every sign-request kind this backend currently registers, each with a summary, the routes it builds and relays through, and whether it is available right now. Call this before `wallet_sign_request` to learn what a kind takes. |
75
+ | `wallet_sign_request` | Park a typed, kind-discriminated intent (`POST /sign-requests`) and hand it to the owner to review and sign in their own browser. The one write primitive covering every owner-authorized action that is not `wallet_send`. **Cannot sign, cannot relay** - see below. |
76
+ | `resolve_token` | Resolve a token address or CAIP-19 asset ref to its full identity - symbol, name, decimals, and which source vouches for it. Refuses bare symbols: a symbol is a label a contract picked for itself, and two contracts on one chain can share one, so the product will not guess. Call `list_tokens` when you only have a symbol. |
77
+ | `list_tokens` | Every token this account holds on a chain, with the contract address and CAIP-19 asset ref you need to spend it. This is the discovery command for `wallet_send`, which takes an address and refuses a symbol. When two rows share a symbol, show both and let the user choose; never guess. |
78
+
79
+ ## Why `wallet_send` requires a token address, not a symbol
80
+
81
+ The `wallet_send` tool requires a contract address or CAIP-19 asset ref for the `token` parameter, never a symbol. This is by design: a symbol is a label a contract picks for itself, and two contracts on one chain can legally share the same symbol. The product will not guess which one you meant. Use `resolve_token` to turn a symbol into a full identity, or call `list_tokens` to discover every token this account holds on a chain, each with the address you need.
70
82
 
71
83
  ## Lane arbitration: how `wallet_send` decides who signs
72
84
 
@@ -95,17 +107,183 @@ the browser page itself does against the live backend, and beneath that, on-chai
95
107
  result from this preflight proves nothing by itself, the same discipline `propose_payment`'s own
96
108
  client-side bounds check documents on the agent lane.
97
109
 
98
- ## `wallet_api_get` is GET-only, deliberately - and there is no `api_post`
110
+ ## Waiting for results: handles, streams, and why elicitation is not approval
111
+
112
+ Several tools (`wallet_login`, `wallet_send`, `pair`, `request_approval`, `propose_payment`, `propose_swap`)
113
+ do not return immediately - they need human action, on-chain confirmation, or both. These tools now WAIT
114
+ for completion instead of handing back a reference and walking away.
115
+
116
+ When a tool waits, it:
117
+
118
+ 1. **Reports progress** - periodically sends heartbeats so the client knows it is still alive and waiting,
119
+ never going silent for minutes at a time.
120
+ 2. **Watches the backend's declared deadline** - the server tells the tool how long it is willing to hold the
121
+ operation open. The tool will wait until that deadline, then stop, and the client can join the same wait
122
+ at any time by calling `botanary_wait` with the returned handle.
123
+ 3. **Respects an abort signal** - if the client has to stop (interrupt, timeout, preemption by a newer task),
124
+ it can abort the wait without breaking the backend operation. The handle stays live, and the wait can be
125
+ rejoined from where it left off.
126
+ 4. **Runs a stream when the server supports it** - most operations have a Server-Sent Events stream endpoint
127
+ that delivers updates in real time. When a stream is not available (old backend, network lost), the tool
128
+ automatically falls back to polling, asking the backend "is this operation done?" at regular intervals.
129
+
130
+ ## Handles, and why a handle is not a secret
131
+
132
+ A handle is an opaque reference to an ongoing operation at the backend - a place to rejoin a wait that was
133
+ interrupted. The handle file itself carries **no secret**. Any credential the operation needs (a session
134
+ token, a signer's key, an approval credential) lives in the same keychain chain `wallet_login` uses, and is
135
+ deleted the moment the operation terminates - the handle cannot be replayed from an old transcript.
136
+
137
+ To rejoin a wait: **call `botanary_wait` with the handle** - never re-call the original tool (`wallet_send`,
138
+ `get_pairing_code`, `request_approval`, `propose_payment`, `wallet_sign_request`). Re-calling starts a
139
+ brand-new operation; the wait will not pick up where it left off.
140
+
141
+ `wallet_login` is the one flow that opens **no** handle, so there is nothing to rejoin: a login that drops
142
+ is a login you run again. That is deliberate - resuming one would mean re-reading the freshly minted
143
+ session token, and a session token belongs in the keychain and the `Authorization` header, never in a tool
144
+ result.
145
+
146
+ ## Why elicitation is never an approval
147
+
148
+ When a tool waits through the `wallet_send` browser handoff, it may elicit - show the caller where a
149
+ signature is being requested, with a cancel affordance. **Elicitation is strictly presentational.** It never
150
+ asks for an approval and never authorizes anything. It only tells the caller: "The signature is needed in
151
+ your browser, here is a link or a code to review it."
152
+
153
+ - If the caller cancels the elicitation, the wait stops locally, but the browser tab stays live and the
154
+ owner can still sign it there.
155
+ - If the owner signs in the browser, the elicitation on the model's side gets the result.
156
+ - If the owner rejects it in the browser, the wait gets the rejection and surfaces it as the final result.
157
+
158
+ The only boundary that counts is the one on-chain.
159
+
160
+ ## The write boundary: three primitives, never a generic `api_post`
161
+
162
+ **There is no GENERIC write counterpart, and there must not be one.** A tool that took an arbitrary path
163
+ and body and forwarded it to any mutating endpoint would let a model reach *any* mutation - freeze the
164
+ account, remove a signer, drain a grant - with no typed intent, no review panel, and no lane arbitration.
165
+ That argument hasn't changed. What has changed is that it is no longer served by a single refusal -
166
+ `wallet_api_get` being GET-only and nothing else. It is now served by THREE primitives, each admitting a
167
+ different, narrow slice of what a caller can reach, with the dangerous middle - anything that could move
168
+ funds or grant authority on its own - structurally unreachable by all three:
169
+
170
+ | Primitive | What it reaches | How the boundary holds |
171
+ |---|---|---|
172
+ | `wallet_api_get` | Any documented `GET` | Read-only. There is no body to send, no method but `GET`. |
173
+ | `wallet_sign_request` | Any typed sign-kind | Never signs, never relays - returns a URL the OWNER opens and signs in their own browser. |
174
+ | `wallet_api_write` | A small set of administrative `POST`/`PUT`/`PATCH`/`DELETE` routes | Every route that returns an unsigned build for the owner to sign is excluded from its manifest **by construction** - see below. |
175
+
176
+ ### `wallet_api_get` is GET-only, deliberately
99
177
 
100
178
  Every path is validated against a manifest generated from the frozen OpenAPI contract
101
179
  (`openapi/botanary-v1.yaml`, via `pnpm generate:routes` - see "Development" below) before anything
102
- reaches the network. An undocumented path, or any method other than `GET`, is refused.
103
-
104
- **There is no write counterpart, and there must not be one.** A generic `api_post` would let a model
105
- reach *any* mutation - freeze the account, remove a signer, drain a grant - with no typed intent, no
106
- review panel, and no lane arbitration. Every write instead goes through `wallet_send` (or a future
107
- `wallet_swap`): a typed intent the owner reviews and signs in their own browser, or the agent lane's own
108
- on-chain-bound mandate. `wallet_api_get` is deliberately incapable of being that shortcut.
180
+ reaches the network. An undocumented path, or any method other than `GET`, is refused. `wallet_api_get`
181
+ is deliberately incapable of writing anything, and always will be.
182
+
183
+ ### One parse: the string that is validated is the string that is requested
184
+
185
+ Both path allowlists - `wallet_api_get`'s and `wallet_api_write`'s - share a single canonicalisation
186
+ step (`src/http-path.ts`) that runs BEFORE any manifest is consulted, and both then match and request
187
+ the *same* canonical string. This is not a detail: a path that one layer validates and another layer
188
+ re-parses differently is an allowlist that allows something other than what it approved. `fetch`
189
+ re-parses whatever it is given with the WHATWG URL parser, which resolves `.` and `..` (percent-encoded
190
+ forms included), normalises `\` to `/`, and truncates at `#` - so a regex allowlist that treats those as
191
+ ordinary characters and then rebuilds the request from the caller's raw string is checking one route and
192
+ calling another.
193
+
194
+ So a caller-supplied path is refused unless it is *canonical*: absolute, never beginning `//`, no
195
+ fragment, no empty segment, every segment drawn from unreserved/sub-delim characters or well-formed
196
+ `%XX` escapes that do not decode - through any number of layers - to a separator, a fragment marker or a
197
+ `.`/`..` traversal, and finally a string the URL parser reproduces byte for byte. A `{param}` in a
198
+ manifest template compiles to that same charset, so a path parameter structurally cannot hold a
199
+ separator. The denylists are enforced as refusals rather than as mere omissions, so a denylisted literal
200
+ cannot come back through a parameterised sibling that happens to match it. `src/api-client.ts` re-checks
201
+ the same property immediately before calling `fetch`, as a second layer for callers other than these
202
+ two. A percent-encoded character that is genuinely part of an id (`%3A` for a CAIP-style `:`) passes and
203
+ is transmitted verbatim - never decoded, never re-encoded.
204
+
205
+ ### `wallet_sign_request`: the typed-intent lane
206
+
207
+ It is the write primitive this package has had the longest, and it covers every owner-authorized action
208
+ other than a send (see the tools table above and "Lane arbitration" below for why `wallet_send` stays
209
+ separate). Read closely, it does not weaken the argument above - it satisfies every part of it:
210
+
211
+ - **Typed intent.** `wallet_sign_request` takes a `kind` and a `params` object, never a path and a raw
212
+ body. The backend validates `params` server-side against that kind's own DTO (one shape per kind,
213
+ `SIGN_KIND_DTOS` in the contract) before anything is stored; an unregistered kind, or a body that does
214
+ not match the registered one, is refused before the owner is involved at all. Call `list_sign_kinds`
215
+ first to see every kind currently registered and exactly what it takes.
216
+ - **Review panel.** This tool never builds calldata and never signs. What it returns is a URL - the
217
+ SAME `/sign` handoff `wallet_send`'s browser lane already uses - that the OWNER opens in their own
218
+ browser, where the page builds the operation, simulates it, and asks for their signature. A model
219
+ calling this tool can make the owner see a request; it cannot make anything happen without them.
220
+ - **Lane arbitration.** `wallet_sign_request` has none to weaken, because it has no agent lane to
221
+ arbitrate into: it is the browser handoff, always, for every action it covers. `wallet_send` keeps its
222
+ own arbitration (agent-vs-owner routing) untouched, because send is the one action where that routing
223
+ is load-bearing - see "Lane arbitration" below.
224
+
225
+ So the worst a compromised model achieves through `wallet_sign_request` is ASKING the owner to sign
226
+ something - the same authority a stranger with the owner's phone number has.
227
+
228
+ ### `wallet_api_write`: plain session writes that need no signature
229
+
230
+ Everything left over from the two primitives above is administrative bookkeeping with no fund movement
231
+ and no authority grant of its own: claim an agent, mark a notification read, rename an account, edit a
232
+ pay-sh allowlist, manage conversations. `wallet_api_write` reaches exactly that set, and the property
233
+ that keeps it there is mechanical, not a promise: **every authority action in this backend returns an
234
+ UNSIGNED build for the owner to sign** (`build -> sign -> relay`, the invariant `botanary-be/CLAUDE.md`
235
+ states and `test/no-custody.spec.ts` pins). So a route can be excluded from `WRITE_ROUTES`
236
+ (`src/wallet/write-routes.manifest.ts`, generated by `pnpm generate:write-routes` - see "Development"
237
+ below) using nothing but the contract itself:
238
+
239
+ 1. **Build-shaped response.** Its success response resolves - directly, through an array's `items`, or
240
+ through any `oneOf`/`anyOf`/`allOf` branch - to a component schema named `*Build`: `UserOpBuild`,
241
+ `DelegationBuild`, `GrantBuild`, `ApiBudgetBuild`, and every other one. Freeze, initial account setup,
242
+ guardian install, add-signer, budget commit, delegation/grant creation - all named this way, all
243
+ excluded automatically.
244
+ 2. **`x-client-signed: true`.** The contract's own flag for "hands back or consumes something a client
245
+ must sign" - it catches real gaps signal 1 alone misses, because not every build-shaped response is
246
+ named `*Build` (`POST /account`'s `AccountDeployIntent` embeds an unsigned `deployUserOp`; pay.sh's
247
+ own withdraw-build response is named `PayShWithdrawBuildResponse`, breaking the naming convention by
248
+ one word) and it also catches every RELAY call (`POST /delegations`, pay.sh's own relay and
249
+ manual-sign lanes) - the same category `/userops` is in, just with nothing to *build* because there
250
+ is only something to *relay*.
251
+
252
+ A small explicit denylist covers what neither mechanical signal can see - it exists precisely BECAUSE the
253
+ two rules above are mechanical: a route can pass both (no `*Build` response, no `x-client-signed` flag)
254
+ and still hand back a live session credential, mint session authority for someone else, relay an
255
+ already-signed payload, or move funds through a custodial signer this backend holds itself (the Virtuals
256
+ agent-wallet withdraw/trade routes - the one deliberately custodial exception this backend carries). One
257
+ more entry (`/sign-requests`) is denylisted for a different reason: admitting it would let a caller
258
+ construct an arbitrary sign-request intent through an untyped path, duplicating `wallet_sign_request`'s own
259
+ typed-intent lane rather than going through it. Every entry is justified individually in
260
+ `scripts/generate-write-routes.mjs`'s own header comment and its `DENYLIST` object.
261
+
262
+ **The boundary is two mechanical rules plus this denylist, not one rule** - the numbers, read straight off
263
+ the frozen contract by `pnpm generate:write-routes` (`src/wallet/write-routes.manifest.ts`'s own generated
264
+ banner records them on every run):
265
+
266
+ | | Write operations (`POST`/`PUT`/`PATCH`/`DELETE`) |
267
+ |---|---|
268
+ | Total in the contract | 131 |
269
+ | Excluded - build-shaped response (`*Build`, signal 1) | 57 |
270
+ | Excluded - `x-client-signed: true`, not caught by signal 1 (signal 2) | 9 |
271
+ | Excluded - explicit denylist | 18 (across 17 distinct paths - `/auth/session` denylists both its `POST` and `DELETE`) |
272
+ | **Admitted into `WRITE_ROUTES`** | **47** |
273
+
274
+ The result: `wallet_api_write` can be talked into marking a notification read. It cannot be talked into
275
+ anything that moves a token or grants an agent, a signer, or a device new authority - not because the
276
+ tool refuses to *try*, but because the route to do so was never in its manifest to begin with.
277
+
278
+ **Two admitted routes still refuse at the HTTP layer, and that is a second layer working, not a manifest
279
+ gap.** `/pay-sh/accounts/{accountId}/allowlist` and `/pay-sh/accounts/{accountId}/settings` pass both
280
+ mechanical checks (neither is `*Build`-shaped nor `x-client-signed`) and so ARE in `WRITE_ROUTES` - but
281
+ `wallet_login` mints the same `kind: 'cli'` session `botanary login` does (this package and `botanary-cli`
282
+ share one identity and session store), and the backend's own `NoCliWritesGuard` 403s any write from a
283
+ `kind: 'cli'` session on the pay-sh and agent-wallet controllers, precisely because those routes move a
284
+ Privy-custodied balance or widen an agent wallet's spending fence with no owner signature anywhere in the
285
+ loop. The manifest is the first layer, not the only one; a route being admitted here says "shape-safe to
286
+ attempt," never "guaranteed to succeed."
109
287
 
110
288
  ## Why the advertised tool list changes
111
289
 
@@ -224,8 +402,11 @@ Neither piece is derived *from* the private key, and there's no computation that
224
402
  an obfuscated secret - it was never built out of one.
225
403
 
226
404
  That's what makes the rest of the claim hold: **the code identifies, the signature authenticates.**
227
- Completing a connection is designed to require the agent to sign a server-issued challenge with the key
228
- that never left this machine - proof of possession, not proof of having seen a string. Someone who only
405
+ Completing a connection requires the agent to sign the code together with a timestamp, using the key
406
+ that never left this machine, and submit that signature with its public key - proof of possession, not
407
+ proof of having seen a string. (The signed message is `code|timestamp`; the code is minted locally, so
408
+ this is not a server-issued challenge. `mintSession` is the separate flow that does fetch a server
409
+ nonce before signing.) Someone who only
229
410
  intercepted the code cannot produce that signature, because they don't have the key. The worst they can
230
411
  do is type the code into their *own* Botanary account's "Connected agents" box - which, per the product
231
412
  rule above, gets *them* nothing: a connection with no grant can do nothing, and it takes nothing away
@@ -353,8 +534,18 @@ pnpm generate:routes # regenerate src/wallet/routes.manifest.ts from the siblin
353
534
  # checkout's openapi/botanary-v1.yaml - run this and commit the result whenever
354
535
  # the contract changes; it never runs automatically (a published install has no
355
536
  # sibling openapi/ directory to read it from)
537
+ pnpm generate:write-routes # same thing for src/wallet/write-routes.manifest.ts - see "The write
538
+ # boundary" above for the exclusion rule it applies while doing so
356
539
  ```
357
540
 
541
+ Neither generator runs from `test`, `build` or `prepare`, deliberately - a published `npx botanary-mcp`
542
+ install has no sibling `botanary-be` checkout to read the contract from. The cost of that correct
543
+ decision is that the committed output can rot silently, and it did (GET_ROUTES once sat nine routes
544
+ behind the contract, refusing routes the same branch had shipped). `test/manifest-freshness.spec.ts`
545
+ regenerates both manifests into a scratch directory and byte-compares - it never repairs the file it
546
+ checks - and skips, loudly and with a stated reason, where the sibling contract is absent. Same guard,
547
+ same reasoning as `botanary-fe/tests/api/schema-drift.test.ts`.
548
+
358
549
  `BOTANARY_MCP_HOME` overrides where the non-secret metadata file (and the file-fallback secret, if it's
359
550
  ever in use) live - defaults to `~/.botanary-mcp`. It exists mainly for tests and for running this
360
551
  server inside a container with an isolated home; a normal install never needs to set it.
@@ -379,8 +570,9 @@ What stays out on purpose:
379
570
  The chain is still the only real enforcement either way (see "The bound it reads is a convenience, not
380
571
  the check" above). The wallet lane's own `wallet_send` makes the SAME promise for the mandate lane it
381
572
  can take (see "Lane arbitration" above), and its browser-lane fallback is likewise never a shortcut:
382
- `wallet_api_get` is GET-only with no write counterpart, so every wallet-lane write terminates in the
383
- owner's own browser signature, not in anything this package executes on its own.
573
+ every fund-moving or authority-granting wallet-lane write terminates in the owner's own browser
574
+ signature, never in anything this package executes on its own. `wallet_api_write` reaches a small,
575
+ mechanically-excluded set of administrative writes only - see "The write boundary" above.
384
576
 
385
577
  `src/runtime.ts`'s `AgentRuntime` is the seam every tool in `src/tools.ts` is built on: it owns identity,
386
578
  signing (`store.sign()`/`store.signHash()`), a cached-with-retry agent session, and one method per
File without changes
@@ -2,12 +2,21 @@ import type { AgentRuntime } from './runtime.js';
2
2
  export interface ProposePaymentInput {
3
3
  recipient: string;
4
4
  amount: number;
5
- tokenSymbol: string;
5
+ /** A contract address or CAIP-19 asset ref - never a symbol. See `resolveAsset`'s own doc comment:
6
+ * this package never resolves a token itself, it asks the backend, whose `AssetResolverService` is
7
+ * the one resolution `DelegationService.buildAction` also uses. */
8
+ token: string;
6
9
  chainId: number;
7
10
  }
8
11
  export interface ProposeSwapInput {
9
- tokenIn: string;
10
- tokenOut: string;
12
+ /** The token being SOLD - a contract address or CAIP-19 asset ref, never a symbol. Resolved before
13
+ * anything else so the venue match, the budget check and the build all name the same contract. */
14
+ assetIn: string;
15
+ /** The token being BOUGHT - a contract address or CAIP-19 asset ref, never a symbol. Unbounded by the
16
+ * grant (see `proposeSwap`'s own doc comment); resolved only so the backend's still-symbol-keyed
17
+ * build route (`DelegatedActionDto.tokenOut` - the swap shape was not part of Task A11's widening,
18
+ * see its own doc comment) gets a verified symbol rather than whatever the caller typed. */
19
+ assetOut: string;
11
20
  amountIn: number;
12
21
  chainId: number;
13
22
  maxSlippageBps?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-actions.d.ts","sourceRoot":"","sources":["../../src/agent-actions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAKjD,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA8GxH;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAqIlH"}
1
+ {"version":3,"file":"agent-actions.d.ts","sourceRoot":"","sources":["../../src/agent-actions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAMjD,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf;;wEAEoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B;uGACmG;IACnG,OAAO,EAAE,MAAM,CAAC;IAChB;;;iGAG6F;IAC7F,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAuHxH;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAgJlH"}
@@ -1,6 +1,7 @@
1
- import { describeGrant, findBudgetMeterBySymbol, missingModuleOf } from './agent-grant-helpers.js';
1
+ import { describeGrant, findBudgetMeter, missingModuleOf } from './agent-grant-helpers.js';
2
2
  import { settleRelayedOp } from './wallet/send-orchestration.js';
3
3
  import { setupUrl } from './app-link.js';
4
+ import { resolveAsset } from './wallet/asset.js';
4
5
  /**
5
6
  * Build and relay a payment under this agent's OWN grant. Reads the grant's bounds and permissionId from
6
7
  * the backend (GET /agents/me) FIRST: when there is no grant, the grant is not active, it is on a
@@ -13,7 +14,7 @@ import { setupUrl } from './app-link.js';
13
14
  * chain is what actually enforces the grant.
14
15
  */
15
16
  export async function proposePayment(runtime, input) {
16
- const { recipient, amount, tokenSymbol, chainId } = input;
17
+ const { recipient, amount, token: tokenRef, chainId } = input;
17
18
  const self = await runtime.me();
18
19
  if (!self.grant) {
19
20
  return { proposed: false, reason: 'no_grant', message: `${describeGrant(self)} Nothing was built or sent.` };
@@ -35,12 +36,17 @@ export async function proposePayment(runtime, input) {
35
36
  'was built or sent. Use request_approval if this payment genuinely needs that chain.',
36
37
  };
37
38
  }
38
- const meter = findBudgetMeterBySymbol(grant, tokenSymbol);
39
+ // RESOLVE FIRST - the same discipline `wallet_send`'s own doc comment names: every branch below
40
+ // (budget check, per-action cap, build, human-readable messages) has to name the same contract the
41
+ // op will bind, so nothing downstream re-derives or guesses the asset once this resolves. A backend
42
+ // refusal here (unknown ref, unresolvable address) propagates as a rejection, same as `wallet_send`.
43
+ const asset = await resolveAsset(runtime, chainId, tokenRef, await runtime.ensureSession());
44
+ const meter = findBudgetMeter(grant, asset.assetRef);
39
45
  if (!meter) {
40
46
  return {
41
47
  proposed: false,
42
48
  reason: 'token_not_budgeted',
43
- message: `This grant has no budget for ${tokenSymbol}. Budgeted tokens: ` +
49
+ message: `This grant has no budget for ${asset.symbol}. Budgeted tokens: ` +
44
50
  `${grant.policySet.budgets.map((b) => b.token.symbol).join(', ') || 'none'}. Nothing was ` +
45
51
  'built or sent. Use request_approval instead.',
46
52
  };
@@ -49,17 +55,17 @@ export async function proposePayment(runtime, input) {
49
55
  return {
50
56
  proposed: false,
51
57
  reason: 'over_budget',
52
- message: `This grant has ${meter.remaining} ${tokenSymbol} remaining (of ${meter.limit} total); ` +
53
- `${amount} ${tokenSymbol} would exceed it. Nothing was built or sent. Use request_approval ` +
58
+ message: `This grant has ${meter.remaining} ${asset.symbol} remaining (of ${meter.limit} total); ` +
59
+ `${amount} ${asset.symbol} would exceed it. Nothing was built or sent. Use request_approval ` +
54
60
  'to ask the owner for this specific payment.',
55
61
  };
56
62
  }
57
63
  const perActionMax = grant.policySet.perActionMax;
58
- if (perActionMax && perActionMax.token.symbol.toUpperCase() === tokenSymbol.toUpperCase() && amount > perActionMax.amount) {
64
+ if (perActionMax && perActionMax.token.assetRef === asset.assetRef && amount > perActionMax.amount) {
59
65
  return {
60
66
  proposed: false,
61
67
  reason: 'over_per_action_max',
62
- message: `This grant caps a single action at ${perActionMax.amount} ${tokenSymbol}; ${amount} ` +
68
+ message: `This grant caps a single action at ${perActionMax.amount} ${asset.symbol}; ${amount} ` +
63
69
  'exceeds it. Nothing was built or sent. Use request_approval instead.',
64
70
  };
65
71
  }
@@ -70,7 +76,11 @@ export async function proposePayment(runtime, input) {
70
76
  // itself refuses (403, named reason) a delegation id that does not name this agent.
71
77
  let build;
72
78
  try {
73
- build = await runtime.buildDelegatedAction({ delegationId: grant.id, recipient, amount, token: tokenSymbol });
79
+ // `asset.assetRef` - the RESOLVED identity, not the raw `tokenRef` the caller passed in. Both are
80
+ // accepted by `DelegatedActionDto.token` (an address or a CAIP-19 ref), but the assetRef is what
81
+ // this function already checked the budget against, so sending anything else risks the build
82
+ // resolving a technically-equivalent-but-textually-different reference to a different conclusion.
83
+ build = await runtime.buildDelegatedAction({ delegationId: grant.id, recipient, amount, token: asset.assetRef });
74
84
  }
75
85
  catch (e) {
76
86
  // The one refusal with a remedy the OWNER can act on in a browser and this agent cannot act on
@@ -105,7 +115,7 @@ export async function proposePayment(runtime, input) {
105
115
  // instruction - and the agent's natural next move, resending, would move real money twice. That
106
116
  // whole discipline lives in `settleRelayedOp`, shared with `proposeSwap` so the two can never
107
117
  // drift into describing the same three outcomes differently.
108
- return settleRelayedOp(runtime, opId, build.userOpHash, 'payment', { amount, token: tokenSymbol }, `NOTHING moved: no ${tokenSymbol} left the account, the recipient received nothing, ` +
118
+ return settleRelayedOp(runtime, opId, build.userOpHash, 'payment', { amount, token: asset.symbol }, `NOTHING moved: no ${asset.symbol} left the account, the recipient received nothing, ` +
109
119
  'and the grant budget was not spent.');
110
120
  }
111
121
  /**
@@ -125,7 +135,7 @@ export async function proposePayment(runtime, input) {
125
135
  * the grant.
126
136
  */
127
137
  export async function proposeSwap(runtime, input) {
128
- const { tokenIn, tokenOut, amountIn, chainId, maxSlippageBps } = input;
138
+ const { assetIn, assetOut, amountIn, chainId, maxSlippageBps } = input;
129
139
  // BOUNDS FIRST, exactly as proposePayment does, and for the same reason: the refusals below are
130
140
  // the ones this side can make honestly from backend-reported facts, and making them here means an
131
141
  // out-of-grant swap costs no build, no signature and no relay.
@@ -168,12 +178,17 @@ export async function proposeSwap(runtime, input) {
168
178
  'and token it may swap, or use request_approval for this one swap.',
169
179
  };
170
180
  }
171
- if (venue.token.symbol.toUpperCase() !== tokenIn.toUpperCase()) {
181
+ // RESOLVE the SOLD leg before anything below - the venue match, the allowance ceiling and the budget
182
+ // check all have to name the same contract, exactly the discipline `proposePayment` follows. The
183
+ // BOUGHT leg (`assetOut`) is resolved further down, only once every refusal above it has passed: it
184
+ // costs a network call for no reason if this swap is going to be refused anyway.
185
+ const soldAsset = await resolveAsset(runtime, chainId, assetIn, await runtime.ensureSession());
186
+ if (venue.token.symbol.toUpperCase() !== soldAsset.symbol.toUpperCase()) {
172
187
  return {
173
188
  proposed: false,
174
189
  reason: 'token_not_venue_token',
175
- message: `This grant may only swap ${venue.token.symbol}, not ${tokenIn} - its session pins the ` +
176
- 'sold token exactly, and any other would be refused in validation. Nothing was built or ' +
190
+ message: `This grant may only swap ${venue.token.symbol}, not ${soldAsset.symbol} - its session pins ` +
191
+ 'the sold token exactly, and any other would be refused in validation. Nothing was built or ' +
177
192
  'sent. Use request_approval instead.',
178
193
  };
179
194
  }
@@ -182,23 +197,28 @@ export async function proposeSwap(runtime, input) {
182
197
  proposed: false,
183
198
  reason: 'over_venue_allowance',
184
199
  message: `This grant allows at most ${venue.maxAllowance} ${venue.token.symbol} per swap; ` +
185
- `${amountIn} ${tokenIn} exceeds it. Nothing was built or sent. Use request_approval to ask ` +
186
- 'the owner for this specific swap.',
200
+ `${amountIn} ${soldAsset.symbol} exceeds it. Nothing was built or sent. Use ` +
201
+ 'request_approval to ask the owner for this specific swap.',
187
202
  };
188
203
  }
189
204
  // The grant's ordinary spend meter applies TOO - the venue ceiling caps one swap, the budget caps
190
205
  // the lifetime - so a swap within the ceiling but over what is left is still refused here, with
191
206
  // the backend's own remaining figure rather than a guess.
192
- const meter = findBudgetMeterBySymbol(grant, tokenIn);
207
+ const meter = findBudgetMeter(grant, soldAsset.assetRef);
193
208
  if (meter && amountIn > meter.remaining) {
194
209
  return {
195
210
  proposed: false,
196
211
  reason: 'over_budget',
197
- message: `This grant has ${meter.remaining} ${tokenIn} remaining (of ${meter.limit} total); ` +
198
- `${amountIn} ${tokenIn} would exceed it. Nothing was built or sent. Use request_approval ` +
199
- 'to ask the owner for this specific swap.',
212
+ message: `This grant has ${meter.remaining} ${soldAsset.symbol} remaining (of ${meter.limit} total); ` +
213
+ `${amountIn} ${soldAsset.symbol} would exceed it. Nothing was built or sent. Use ` +
214
+ 'request_approval to ask the owner for this specific swap.',
200
215
  };
201
216
  }
217
+ // Resolved only now, past every refusal that did not need it. `DelegatedActionDto`'s swap shape
218
+ // (`tokenIn`/`tokenOut`) was NOT part of Task A11's widening - see this function's own doc comment -
219
+ // so the backend still wants a SYMBOL for both legs; this resolves the caller's address/asset ref
220
+ // into the contract's own verified symbol rather than sending back whatever string the caller typed.
221
+ const boughtAsset = await resolveAsset(runtime, chainId, assetOut, await runtime.ensureSession());
202
222
  // Within the client-read bounds - build AGAINST THIS AGENT'S OWN GRANT ID (grant.id, from
203
223
  // GET /agents/me), then relay it signed with the grant's own session key. The router is the
204
224
  // BACKEND's to resolve: it quotes the route, checks it against the one router the venue pins, and
@@ -207,8 +227,8 @@ export async function proposeSwap(runtime, input) {
207
227
  try {
208
228
  build = await runtime.buildDelegatedSwap({
209
229
  delegationId: grant.id,
210
- tokenIn,
211
- tokenOut,
230
+ tokenIn: soldAsset.symbol,
231
+ tokenOut: boughtAsset.symbol,
212
232
  amountIn,
213
233
  ...(maxSlippageBps != null ? { maxSlippageBps } : {}),
214
234
  });
@@ -238,7 +258,7 @@ export async function proposeSwap(runtime, input) {
238
258
  return { proposed: true, settled: false, userOpHash: build.userOpHash, relay };
239
259
  // THE RELAY HAS ALREADY SUCCEEDED by this line - see `settleRelayedOp`, which owns the three
240
260
  // outcomes from here and is the SAME code proposePayment settles through.
241
- return settleRelayedOp(runtime, opId, build.userOpHash, 'swap', { amount: amountIn, token: tokenIn }, `NOTHING moved: no ${tokenIn} left the account, no ${tokenOut} was received, ` +
261
+ return settleRelayedOp(runtime, opId, build.userOpHash, 'swap', { amount: amountIn, token: soldAsset.symbol }, `NOTHING moved: no ${soldAsset.symbol} left the account, no ${boughtAsset.symbol} was received, ` +
242
262
  'and the grant budget was not spent.');
243
263
  }
244
264
  //# sourceMappingURL=agent-actions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-actions.js","sourceRoot":"","sources":["../../src/agent-actions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent-actions.js","sourceRoot":"","sources":["../../src/agent-actions.ts"],"names":[],"mappings":"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"}
@@ -16,24 +16,13 @@ export declare function describeGrant(self: AgentSelf): string;
16
16
  *
17
17
  * Callers must supply a REAL assetRef - one that came from `GET /agents/me`'s own grant (a budgeted
18
18
  * token) or from `GET /assets/resolve` (a resolved send/swap target), never a guessed or hand-built
19
- * string. `wallet_send`'s `checkSendBounds` is the caller: its `SendInput.asset` is always the output of
20
- * a real resolve, so this is the ONE place in the wallet lane a budget is matched by identity rather
21
- * than by label.
19
+ * string. `wallet_send`'s `checkSendBounds` (the owner lane) and `propose_payment`/`propose_swap`
20
+ * (`agent-actions.ts`, the agent lane) are both callers, each resolving its caller-named token before
21
+ * ever reaching here - this is the ONLY place a budget is matched, by identity rather than by label,
22
+ * across either lane. `findBudgetMeterBySymbol` used to exist as a SECOND matcher for the agent lane's
23
+ * build route, which validated its token by symbol until Task A11 widened it to accept an address/asset
24
+ * ref too - a second enumeration of the same fact is exactly what `modules/agent/token-decimals.ts`
25
+ * blames for its 10^12 mis-encoding incident, so it was deleted rather than kept in sync by hand.
22
26
  */
23
27
  export declare function findBudgetMeter(grant: AgentGrantView, assetRef: string): SpendMeterView | undefined;
24
- /**
25
- * The spend meter for `tokenSymbol` on this grant, matched by SYMBOL - not `findBudgetMeter`'s assetRef
26
- * match above. Exists ONLY for `propose_payment`/`propose_swap` (`agent-actions.ts`), whose build route
27
- * (`POST /delegations/{delegationId}/actions`, `DelegatedActionDto`) still validates `token`/`tokenIn`/
28
- * `tokenOut` BY SYMBOL - that DTO was not touched by the asset-identity migration, so those two tools
29
- * still take a symbol from their caller and this is the honest match for it.
30
- *
31
- * Deliberately does NOT resolve a symbol to an assetRef and delegate to `findBudgetMeter`: a budgeted
32
- * token whose address this build has no manifest entry for keeps `assetRef: null`
33
- * (`grant-asset-refs.ts`'s own convention, "honestly undecodable, never guessed") - if this delegated
34
- * instead, that null would collide with every other unresolvable token and the meter would go missing
35
- * for a token that IS genuinely budgeted. Matching directly on the row's own `symbol` field, exactly as
36
- * this package always has, has no such failure mode.
37
- */
38
- export declare function findBudgetMeterBySymbol(grant: AgentGrantView, tokenSymbol: string): SpendMeterView | undefined;
39
28
  //# sourceMappingURL=agent-grant-helpers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-grant-helpers.d.ts","sourceRoot":"","sources":["../../src/agent-grant-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9E;4GAC4G;AAC5G,wBAAgB,eAAe,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAIzD;AAED;;gFAEgF;AAChF,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAqBrD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAGnG;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAG9G"}
1
+ {"version":3,"file":"agent-grant-helpers.d.ts","sourceRoot":"","sources":["../../src/agent-grant-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9E;4GAC4G;AAC5G,wBAAgB,eAAe,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAIzD;AAED;;gFAEgF;AAChF,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAqBrD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAGnG"}
@@ -36,30 +36,16 @@ export function describeGrant(self) {
36
36
  *
37
37
  * Callers must supply a REAL assetRef - one that came from `GET /agents/me`'s own grant (a budgeted
38
38
  * token) or from `GET /assets/resolve` (a resolved send/swap target), never a guessed or hand-built
39
- * string. `wallet_send`'s `checkSendBounds` is the caller: its `SendInput.asset` is always the output of
40
- * a real resolve, so this is the ONE place in the wallet lane a budget is matched by identity rather
41
- * than by label.
39
+ * string. `wallet_send`'s `checkSendBounds` (the owner lane) and `propose_payment`/`propose_swap`
40
+ * (`agent-actions.ts`, the agent lane) are both callers, each resolving its caller-named token before
41
+ * ever reaching here - this is the ONLY place a budget is matched, by identity rather than by label,
42
+ * across either lane. `findBudgetMeterBySymbol` used to exist as a SECOND matcher for the agent lane's
43
+ * build route, which validated its token by symbol until Task A11 widened it to accept an address/asset
44
+ * ref too - a second enumeration of the same fact is exactly what `modules/agent/token-decimals.ts`
45
+ * blames for its 10^12 mis-encoding incident, so it was deleted rather than kept in sync by hand.
42
46
  */
43
47
  export function findBudgetMeter(grant, assetRef) {
44
48
  const idx = grant.policySet.budgets.findIndex((b) => b.token.assetRef === assetRef);
45
49
  return idx === -1 ? undefined : grant.spentToDate[idx];
46
50
  }
47
- /**
48
- * The spend meter for `tokenSymbol` on this grant, matched by SYMBOL - not `findBudgetMeter`'s assetRef
49
- * match above. Exists ONLY for `propose_payment`/`propose_swap` (`agent-actions.ts`), whose build route
50
- * (`POST /delegations/{delegationId}/actions`, `DelegatedActionDto`) still validates `token`/`tokenIn`/
51
- * `tokenOut` BY SYMBOL - that DTO was not touched by the asset-identity migration, so those two tools
52
- * still take a symbol from their caller and this is the honest match for it.
53
- *
54
- * Deliberately does NOT resolve a symbol to an assetRef and delegate to `findBudgetMeter`: a budgeted
55
- * token whose address this build has no manifest entry for keeps `assetRef: null`
56
- * (`grant-asset-refs.ts`'s own convention, "honestly undecodable, never guessed") - if this delegated
57
- * instead, that null would collide with every other unresolvable token and the meter would go missing
58
- * for a token that IS genuinely budgeted. Matching directly on the row's own `symbol` field, exactly as
59
- * this package always has, has no such failure mode.
60
- */
61
- export function findBudgetMeterBySymbol(grant, tokenSymbol) {
62
- const idx = grant.policySet.budgets.findIndex((b) => b.token.symbol.toUpperCase() === tokenSymbol.toUpperCase());
63
- return idx === -1 ? undefined : grant.spentToDate[idx];
64
- }
65
51
  //# sourceMappingURL=agent-grant-helpers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-grant-helpers.js","sourceRoot":"","sources":["../../src/agent-grant-helpers.ts"],"names":[],"mappings":"AAEA;4GAC4G;AAC5G,MAAM,UAAU,eAAe,CAAC,CAAU;IACxC,MAAM,OAAO,GAAI,CAAyD,EAAE,OAAO,CAAC;IACpF,MAAM,IAAI,GAAG,OAAO,EAAE,aAAa,CAAC;IACpC,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACnE,CAAC;AAED;;gFAEgF;AAChF,MAAM,UAAU,aAAa,CAAC,IAAe;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,eAAe,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAChF,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,CACL,wCAAwC,OAAO,kDAAkD;YACjG,mGAAmG;YACnG,oFAAoF;YACpF,IAAI,IAAI,CAAC,OAAO,gFAAgF;YAChG,OACE,IAAI,CAAC,cAAc;gBACjB,CAAC,CAAC,OAAO,IAAI,CAAC,cAAc,mEAAmE;oBAC7F,0FAA0F;gBAC5F,CAAC,CAAC,EACN,EAAE,CACH,CAAC;IACJ,CAAC;IACD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;IACrB,MAAM,MAAM,GAAG,CAAC,CAAC,WAAW;SACzB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,iBAAiB,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;SACrH,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO,iBAAiB,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,YAAY,GAAG,MAAM,CAAC,CAAC,CAAC,eAAe,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AACjG,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,eAAe,CAAC,KAAqB,EAAE,QAAgB;IACrE,MAAM,GAAG,GAAG,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;IACpF,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;AACzD,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAqB,EAAE,WAAmB;IAChF,MAAM,GAAG,GAAG,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC;IACjH,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;AACzD,CAAC"}
1
+ {"version":3,"file":"agent-grant-helpers.js","sourceRoot":"","sources":["../../src/agent-grant-helpers.ts"],"names":[],"mappings":"AAEA;4GAC4G;AAC5G,MAAM,UAAU,eAAe,CAAC,CAAU;IACxC,MAAM,OAAO,GAAI,CAAyD,EAAE,OAAO,CAAC;IACpF,MAAM,IAAI,GAAG,OAAO,EAAE,aAAa,CAAC;IACpC,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACnE,CAAC;AAED;;gFAEgF;AAChF,MAAM,UAAU,aAAa,CAAC,IAAe;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,eAAe,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAChF,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,CACL,wCAAwC,OAAO,kDAAkD;YACjG,mGAAmG;YACnG,oFAAoF;YACpF,IAAI,IAAI,CAAC,OAAO,gFAAgF;YAChG,OACE,IAAI,CAAC,cAAc;gBACjB,CAAC,CAAC,OAAO,IAAI,CAAC,cAAc,mEAAmE;oBAC7F,0FAA0F;gBAC5F,CAAC,CAAC,EACN,EAAE,CACH,CAAC;IACJ,CAAC;IACD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;IACrB,MAAM,MAAM,GAAG,CAAC,CAAC,WAAW;SACzB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,iBAAiB,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;SACrH,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO,iBAAiB,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,YAAY,GAAG,MAAM,CAAC,CAAC,CAAC,eAAe,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AACjG,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,eAAe,CAAC,KAAqB,EAAE,QAAgB;IACrE,MAAM,GAAG,GAAG,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;IACpF,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;AACzD,CAAC"}
@@ -48,10 +48,18 @@ export declare class BotanaryApiClient {
48
48
  private readonly fetchImpl;
49
49
  constructor(baseUrl: string, fetchImpl?: typeof fetch);
50
50
  post<T>(path: string, body: unknown, token?: string): Promise<T>;
51
+ /** PUT request - used by wallet_api_write for the manifest's PUT-shaped administrative writes
52
+ * (e.g. `/agent-wallets/{agentId}/caps`). */
53
+ put<T>(path: string, body: unknown, token?: string): Promise<T>;
54
+ /** PATCH request - used by wallet_api_write for the manifest's PATCH-shaped administrative writes
55
+ * (e.g. `/accounts/{id}`). */
56
+ patch<T>(path: string, body: unknown, token?: string): Promise<T>;
51
57
  /** GET has no body - a query string, when one is needed, belongs in `path` itself (callers below never
52
58
  * put a token or anything secret there; see test/no-leak.spec.ts). */
53
59
  get<T>(path: string, token?: string): Promise<T>;
54
- /** DELETE request for logout and cleanup operations. No body, authenticated with optional token. */
60
+ /** DELETE request for logout and cleanup operations, and for the manifest's DELETE-shaped
61
+ * administrative writes (e.g. `/agent/conversations/{conversationId}`). No body, authenticated with
62
+ * optional token. */
55
63
  delete<T>(path: string, token?: string): Promise<T>;
56
64
  }
57
65
  //# sourceMappingURL=api-client.d.ts.map