@routedock/routedock 0.3.0 → 0.4.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 (58) hide show
  1. package/README.md +113 -12
  2. package/dist/{MppSessionHandler-1EL8QBAn.d.cts → MppSessionHandler-3QfCHI5x.d.ts} +40 -2
  3. package/dist/{MppSessionHandler-Bq4S-JTE.d.ts → MppSessionHandler-xu4Kxu6N.d.cts} +40 -2
  4. package/dist/{ProviderRegistry-CA_TdREG.d.ts → ProviderRegistry-D9KqyuH-.d.cts} +16 -36
  5. package/dist/{ProviderRegistry-D-0rqK0N.d.cts → ProviderRegistry-DVi2uzgk.d.ts} +16 -36
  6. package/dist/{RouteDockClient-go9aopfF.d.cts → RouteDockClient-6rmgkbYb.d.cts} +124 -142
  7. package/dist/{RouteDockClient-Bh86bVly.d.ts → RouteDockClient-CnAkxwrW.d.ts} +124 -142
  8. package/dist/{SessionReconciler-Bw-PoBVl.d.ts → SessionReconciler-Cce9MXO1.d.ts} +10 -3
  9. package/dist/{SessionReconciler-Cz2nuOlJ.d.cts → SessionReconciler-Dpe9qXdD.d.cts} +10 -3
  10. package/dist/{SessionStore-BaYiegP0.d.ts → SessionStore-DkLBxFQu.d.cts} +28 -3
  11. package/dist/{SessionStore-B4-Hi4H8.d.cts → SessionStore-_ZkoBzFY.d.ts} +28 -3
  12. package/dist/SpendStore-BUclV02i.d.ts +73 -0
  13. package/dist/SpendStore-s_dfcemj.d.cts +73 -0
  14. package/dist/client.cjs +767 -487
  15. package/dist/client.d.cts +80 -10
  16. package/dist/client.d.ts +80 -10
  17. package/dist/client.js +733 -468
  18. package/dist/index.cjs +1295 -590
  19. package/dist/index.d.cts +13 -10
  20. package/dist/index.d.ts +13 -10
  21. package/dist/index.js +1247 -559
  22. package/dist/logger-DVa7VT4c.d.cts +41 -0
  23. package/dist/logger-DVa7VT4c.d.ts +41 -0
  24. package/dist/network.cjs +57 -0
  25. package/dist/network.d.cts +72 -0
  26. package/dist/network.d.ts +72 -0
  27. package/dist/network.js +49 -0
  28. package/dist/node.cjs +166 -0
  29. package/dist/node.d.cts +77 -0
  30. package/dist/node.d.ts +77 -0
  31. package/dist/node.js +159 -0
  32. package/dist/provider/fastify.cjs +847 -62
  33. package/dist/provider/fastify.d.cts +10 -3
  34. package/dist/provider/fastify.d.ts +10 -3
  35. package/dist/provider/fastify.js +848 -63
  36. package/dist/provider/hono.cjs +936 -60
  37. package/dist/provider/hono.d.cts +23 -8
  38. package/dist/provider/hono.d.ts +23 -8
  39. package/dist/provider/hono.js +937 -61
  40. package/dist/provider.cjs +894 -70
  41. package/dist/provider.d.cts +9 -8
  42. package/dist/provider.d.ts +9 -8
  43. package/dist/provider.js +895 -72
  44. package/dist/react.cjs +736 -436
  45. package/dist/react.d.cts +7 -5
  46. package/dist/react.d.ts +7 -5
  47. package/dist/react.js +725 -425
  48. package/dist/{routedockMiddleware-57gUaEMf.d.ts → routedockMiddleware-Cq9HOJEa.d.ts} +9 -2
  49. package/dist/{routedockMiddleware-DlyLrxp7.d.cts → routedockMiddleware-CxsWkSKa.d.cts} +9 -2
  50. package/dist/schema.cjs +7 -0
  51. package/dist/schema.js +7 -0
  52. package/dist/{sign-AKH67sft.d.cts → sign-Bq08SeFq.d.ts} +2 -2
  53. package/dist/{sign-BEq-OsSq.d.ts → sign-DqGE0Plv.d.cts} +2 -2
  54. package/dist/testing.d.cts +4 -3
  55. package/dist/testing.d.ts +4 -3
  56. package/dist/{logger-D8_Q2ytp.d.cts → types-DXaS5Wip.d.cts} +85 -47
  57. package/dist/{logger-D8_Q2ytp.d.ts → types-DXaS5Wip.d.ts} +85 -47
  58. package/package.json +50 -4
package/README.md CHANGED
@@ -1,17 +1,21 @@
1
- # @routedock/sdk
1
+ # @routedock/routedock
2
2
 
3
3
  Unified payment execution layer for autonomous agents on Stellar. One SDK for x402, MPP charge, and MPP session — mode selected automatically from the provider's `routedock.json` manifest.
4
4
 
5
+ ## Requirements
6
+
7
+ Node.js **22 or newer**, matching the supported runtime of all RouteDock npm packages.
8
+
5
9
  ## Install
6
10
 
7
11
  ```bash
8
- npm install @routedock/sdk
12
+ npm install @routedock/routedock
9
13
  ```
10
14
 
11
15
  ## Agent Usage
12
16
 
13
17
  ```ts
14
- import { RouteDockClient } from '@routedock/sdk/client'
18
+ import { RouteDockClient } from '@routedock/routedock/client'
15
19
  import { Keypair } from '@stellar/stellar-sdk'
16
20
 
17
21
  const client = new RouteDockClient({
@@ -35,6 +39,47 @@ for await (const update of session.stream()) {
35
39
  await session.close() // triggers on-chain settlement
36
40
  ```
37
41
 
42
+ ### POST endpoints and custom headers
43
+
44
+ `pay()` sends a `GET` with no body by default. For endpoints that take input,
45
+ pass `request` with the method, headers and body to send:
46
+
47
+ ```ts
48
+ const result = await client.pay('https://provider.example.com/infer', {
49
+ request: {
50
+ method: 'POST',
51
+ headers: { 'content-type': 'application/json', 'x-trace-id': 'trace-123' },
52
+ body: JSON.stringify({ prompt: 'Explain MPP charge in one sentence' }),
53
+ },
54
+ })
55
+ ```
56
+
57
+ The same request is replayed on the unpaid 402 probe, the paid request and any
58
+ retry, so the body is buffered once (streams are drained up front). Payment
59
+ headers set by the SDK — `PAYMENT-SIGNATURE`/`X-PAYMENT` for x402 and
60
+ `Authorization` for MPP — always win over a caller header with the same name.
61
+ The method also scopes the per-endpoint sunset check, so a sunset `GET /infer`
62
+ no longer blocks an active `POST /infer`.
63
+
64
+ Sessions accept the same field per stream:
65
+
66
+ ```ts
67
+ for await (const update of session.stream({
68
+ request: { method: 'POST', body: JSON.stringify({ channel: 'XLM/USDC' }) },
69
+ })) {
70
+ console.log(update)
71
+ }
72
+ ```
73
+
74
+ ### Spend cap and other assets
75
+
76
+ The cap is a single USDC total. If the asset selected for a payment is not
77
+ `spendCap.asset` (for example a provider that prices in XLM), `pay()` and
78
+ `openSession()` throw `RouteDockPolicyRejectError` with reason
79
+ `local_cap_asset_mismatch` before anything is paid, and nothing is added to the
80
+ USDC total. USDC-only providers are unaffected. See
81
+ `docs/MULTI_ASSET_SUPPORT.md`.
82
+
38
83
  ### Durable spend cap
39
84
 
40
85
  The `spendCap` is enforced via a pluggable `SpendStore` (`read()` / `write()`).
@@ -44,7 +89,7 @@ production, inject a persistent implementation so a crash or restart can't reset
44
89
  the accumulator and bypass the cap:
45
90
 
46
91
  ```ts
47
- import { RouteDockClient, type SpendStore, type DailySpend } from '@routedock/sdk/client'
92
+ import { RouteDockClient, type SpendStore, type DailySpend } from '@routedock/routedock/client'
48
93
 
49
94
  const redisSpendStore: SpendStore = {
50
95
  async read(): Promise<DailySpend | null> {
@@ -64,11 +109,42 @@ const client = new RouteDockClient({
64
109
  })
65
110
  ```
66
111
 
112
+ On Node you can use the file-backed store instead. It depends on `node:fs`, so it
113
+ lives in a Node-only entry point and is **not** exported from `/client`:
114
+
115
+ ```ts
116
+ import { RouteDockClient } from '@routedock/routedock/client'
117
+ import { FileSpendStore } from '@routedock/routedock/node' // Node only (node:fs)
118
+
119
+ const client = new RouteDockClient({
120
+ // ...
121
+ spendStore: new FileSpendStore('~/.routedock/spend.json'),
122
+ })
123
+ ```
124
+
125
+ **Sharing one store between processes.** The client serializes its own
126
+ read → check → write, but that only protects one `RouteDockClient`. If two
127
+ processes can use the same store (the MCP server and the example agent both
128
+ default to `~/.routedock/spend.json`), a plain `read()` / `write()` store can
129
+ lose updates and let the cap be exceeded. A shared store must implement the
130
+ optional atomic `update(fn)` method, which the client uses automatically.
131
+ `FileSpendStore` implements it with an exclusive lock file
132
+ (`<file>.lock`, stale locks from crashed processes are broken after 10 s):
133
+
134
+ ```ts
135
+ const store: SpendStore = {
136
+ read, write,
137
+ // fn(prev) returns the next state, or undefined to leave it unchanged.
138
+ // Make the read, fn and write atomic (a transaction, CAS loop, lock, ...).
139
+ async update(fn) { /* ... */ },
140
+ }
141
+ ```
142
+
67
143
  ## Provider Usage
68
144
 
69
145
  ```ts
70
146
  import express from 'express'
71
- import { routedock } from '@routedock/sdk/provider'
147
+ import { routedock } from '@routedock/routedock/provider'
72
148
 
73
149
  const app = express()
74
150
 
@@ -441,6 +517,26 @@ import from `@routedock/routedock/provider` in a Workers snippet — that's the
441
517
  Node-only Express entry point and pulls in dependencies (like `express`) that
442
518
  don't run on Workers.
443
519
 
520
+ ### Runtime-neutral entry points
521
+
522
+ `@routedock/routedock/client`, `/react` and `/provider/hono` use only
523
+ Web-standard APIs. They run in browsers, Cloudflare Workers (no `nodejs_compat`
524
+ needed for this package), Bun, Deno and Node, and contain no `node:*` imports or
525
+ `Buffer` references. CI enforces this (`node scripts/check-runtime-neutral.mjs`)
526
+ against the built output.
527
+
528
+ Anything that needs Node built-ins is kept out of those entries:
529
+
530
+ | Import | Runtime | Notes |
531
+ | --- | --- | --- |
532
+ | `@routedock/routedock/client`, `/react`, `/provider/hono` | any | runtime-neutral |
533
+ | `@routedock/routedock/node` | Node only | `FileSpendStore` (`node:fs`) |
534
+ | `@routedock/routedock/provider`, `/provider/fastify` | Node only | Express/Fastify adapters |
535
+ | `@routedock/routedock` | Node | full SDK, includes `FileSpendStore` |
536
+
537
+ Third-party dependencies are outside this guarantee: for example `mppx` imports
538
+ `node:util`, so a Worker that uses it can still need `nodejs_compat`.
539
+
444
540
  ## React Integration
445
541
 
446
542
  > **Warning:** These hooks create a RouteDockClient in the browser, so the wallet secret and any commitmentSecret are readable by anyone who loads the page.
@@ -451,10 +547,10 @@ don't run on Workers.
451
547
  >
452
548
  > For production or mainnet, keep RouteDockClient on the server (a route handler or server action) and read the key from a non-public variable such as `AGENT_SECRET`, as the Agent Usage section does.
453
549
 
454
- `@routedock/sdk/react` provides hooks for client construction, payments, sessions, and live tx log subscription. Wrap your app with `RouteDockProvider`:
550
+ `@routedock/routedock/react` provides hooks for client construction, payments, sessions, and live tx log subscription. Wrap your app with `RouteDockProvider`:
455
551
 
456
552
  ```tsx
457
- import { RouteDockProvider, useRouteDockClient } from '@routedock/sdk/react'
553
+ import { RouteDockProvider, useRouteDockClient } from '@routedock/routedock/react'
458
554
  import { createClient } from '@supabase/supabase-js'
459
555
 
460
556
  // Dedicated throwaway testnet key. Never a funded or mainnet key.
@@ -482,7 +578,7 @@ function App({ children }: { children: React.ReactNode }) {
482
578
 
483
579
  ```ts
484
580
  // app/api/price/route.ts (runs on the server only)
485
- import { RouteDockClient } from '@routedock/sdk/client'
581
+ import { RouteDockClient } from '@routedock/routedock/client'
486
582
 
487
583
  const client = new RouteDockClient({
488
584
  wallet: process.env.AGENT_SECRET!,
@@ -499,7 +595,7 @@ export async function POST() {
499
595
  ### `usePay(url, options?)`
500
596
 
501
597
  ```tsx
502
- import { usePay } from '@routedock/sdk/react'
598
+ import { usePay } from '@routedock/routedock/react'
503
599
 
504
600
  function PriceButton() {
505
601
  const { pay, result, loading, error } = usePay('https://provider.example.com/price')
@@ -516,7 +612,7 @@ function PriceButton() {
516
612
 
517
613
  ```tsx
518
614
  import { useEffect } from 'react'
519
- import { useSession } from '@routedock/sdk/react'
615
+ import { useSession } from '@routedock/routedock/react'
520
616
 
521
617
  function StreamingFeed() {
522
618
  const { open, close, status, vouchers, cumulative } = useSession(
@@ -537,7 +633,7 @@ The hook automatically fires `session.close()` in the background on unmount when
537
633
  ### `useTxLog(filter?)`
538
634
 
539
635
  ```tsx
540
- import { useTxLog } from '@routedock/sdk/react'
636
+ import { useTxLog } from '@routedock/routedock/react'
541
637
 
542
638
  function ActivityFeed({ channelId }: { channelId: string }) {
543
639
  const txLog = useTxLog({ channelId, limit: 25 })
@@ -572,8 +668,9 @@ import {
572
668
  RouteDockError,
573
669
  RouteDockFacilitatorError,
574
670
  RouteDockManifestError,
671
+ RouteDockPaymentRejectedError,
575
672
  RouteDockPolicyRejectError,
576
- } from '@routedock/sdk/client'
673
+ } from '@routedock/routedock/client'
577
674
 
578
675
  const client = new RouteDockClient({
579
676
  wallet: process.env.AGENT_SECRET!,
@@ -587,6 +684,9 @@ try {
587
684
  } catch (err) {
588
685
  if (err instanceof RouteDockPolicyRejectError) {
589
686
  console.error('Spend cap exceeded:', err.reason)
687
+ } else if (err instanceof RouteDockPaymentRejectedError) {
688
+ // The provider refused the signed payment; `reason` is its explanation.
689
+ console.error(`Payment rejected (HTTP ${err.status}):`, err.reason ?? err.providerError)
590
690
  } else if (err instanceof RouteDockFacilitatorError) {
591
691
  console.error(`Facilitator HTTP ${err.status} (retryable=${err.retryable})`)
592
692
  } else if (err instanceof RouteDockManifestError) {
@@ -604,6 +704,7 @@ try {
604
704
  | `RouteDockManifestError` | no | Invalid manifest, missing pricing fields |
605
705
  | `RouteDockNoSupportedModeError` | no | Provider has no compatible payment mode |
606
706
  | `RouteDockFacilitatorError` | yes | Facilitator/provider 429 or 5xx |
707
+ | `RouteDockPaymentRejectedError` | no | Provider refused the signed paid request (HTTP 401/402/other 4xx); `status` and `reason` carry why |
607
708
  | `RouteDockNetworkError` | yes | Timeouts, connection failures |
608
709
  | `RouteDockSignatureError` | no | Signing or commitment failure |
609
710
  | `RouteDockVoucherMonotonicityError` | no | Non-increasing voucher amount |
@@ -1,6 +1,7 @@
1
- import { g as RouteDockLogger, h as RouteDockManifest } from './logger-D8_Q2ytp.cjs';
1
+ import { b as RouteDockLogger } from './logger-DVa7VT4c.js';
2
2
  import { RequestHandler } from 'express';
3
3
  import { Store } from 'mppx';
4
+ import { R as RouteDockManifest } from './types-DXaS5Wip.js';
4
5
 
5
6
  /**
6
7
  * Idempotency store for payment settlement.
@@ -99,6 +100,20 @@ type SettlementReplayCheck = {
99
100
  } | {
100
101
  kind: 'spent';
101
102
  };
103
+ /**
104
+ * Record a settlement so a retry of the same payment is deduped.
105
+ *
106
+ * Call this only AFTER the payment has settled. By then the funds have moved,
107
+ * so a failing store write must not turn a paid request into a 500: the
108
+ * failure is logged and reported through `onCallbackError(err, 'seenTxStore.set')`
109
+ * and the request carries on to `onSettled` and the route. Never throws.
110
+ */
111
+ declare function recordSettlement(store: SeenTxStore, key: string, record: SettlementRecord, ctx: {
112
+ logger: RouteDockLogger;
113
+ /** Log prefix, e.g. `[x402]` or `[mpp-charge]`. */
114
+ label: string;
115
+ onCallbackError?: ((err: unknown, cb: string) => void) | undefined;
116
+ }): Promise<void>;
102
117
  /**
103
118
  * Decide what a payment bearing `key` should do.
104
119
  *
@@ -159,6 +174,22 @@ declare class InMemorySeenTxStore implements SeenTxStore {
159
174
  */
160
175
  declare function paymentIdempotencyKey(getHeader: (name: string) => string | undefined, scope: SettlementScope): Promise<string | null>;
161
176
 
177
+ /**
178
+ * Explicit provider configuration for recording `session_settled` on the
179
+ * agent vault after a clean mpp-session close.
180
+ *
181
+ * This replaced the old `process.env.AGENT_VAULT_CONTRACT` read inside the
182
+ * provider handlers: Workers have no `process.env` without `nodejs_compat`,
183
+ * and the docs told operators to set `AGENT_VAULT_CONTRACT_ID`, which the SDK
184
+ * never read. Passing the contract in as an option works on every runtime.
185
+ */
186
+ interface VaultSettlementConfig {
187
+ /** Agent vault contract id (C...) whose `record_session_settlement` entry point records the session. */
188
+ contract: string;
189
+ /** Soroban RPC endpoint override; defaults to the public endpoint for the configured network. */
190
+ rpcUrl?: string;
191
+ }
192
+
162
193
  /** Store shape extended with optional atomic update operation. */
163
194
  type ChannelStore = Store.Store & {
164
195
  update?: (key: string, fn: (prev: unknown) => unknown) => Promise<unknown>;
@@ -209,7 +240,14 @@ interface MppSessionHandlerOptions {
209
240
  idleTimeoutMs?: number;
210
241
  /** Log sink for internal error paths. Defaults to a console-backed logger. */
211
242
  logger?: RouteDockLogger;
243
+ /**
244
+ * Record `session_settled` on the agent vault after each clean close.
245
+ * `contract` is the vault's C... id; `rpcUrl` overrides the default Soroban
246
+ * RPC endpoint for the configured network. Falls back to the deprecated
247
+ * `AGENT_VAULT_CONTRACT`/`AGENT_VAULT_CONTRACT_ID` env vars when unset.
248
+ */
249
+ vaultSettlement?: VaultSettlementConfig;
212
250
  }
213
251
  declare function createMppSessionHandler(opts: MppSessionHandlerOptions): RequestHandler;
214
252
 
215
- export { type ChannelStore as C, InMemorySeenTxStore as I, MAX_SETTLEMENT_REPLAYS as M, type OrphanedSessionInfo as O, type SeenTxStore as S, type VoucherStoreValue as V, type SettlementRecord as a, type InMemorySeenTxStoreOptions as b, type MppSessionHandlerOptions as c, type OrphanReason as d, SETTLEMENT_REPLAY_WINDOW_MS as e, type SettlementReplayCheck as f, type SettlementScope as g, checkSettlementReplay as h, createMppSessionHandler as i, isVoucherStoreValue as j, paymentIdempotencyKey as p };
253
+ export { type ChannelStore as C, InMemorySeenTxStore as I, MAX_SETTLEMENT_REPLAYS as M, type OrphanedSessionInfo as O, type SeenTxStore as S, type VaultSettlementConfig as V, type SettlementRecord as a, type InMemorySeenTxStoreOptions as b, type MppSessionHandlerOptions as c, type OrphanReason as d, SETTLEMENT_REPLAY_WINDOW_MS as e, type SettlementReplayCheck as f, type SettlementScope as g, type VoucherStoreValue as h, checkSettlementReplay as i, createMppSessionHandler as j, isVoucherStoreValue as k, paymentIdempotencyKey as p, recordSettlement as r };
@@ -1,6 +1,7 @@
1
- import { g as RouteDockLogger, h as RouteDockManifest } from './logger-D8_Q2ytp.js';
1
+ import { b as RouteDockLogger } from './logger-DVa7VT4c.cjs';
2
2
  import { RequestHandler } from 'express';
3
3
  import { Store } from 'mppx';
4
+ import { R as RouteDockManifest } from './types-DXaS5Wip.cjs';
4
5
 
5
6
  /**
6
7
  * Idempotency store for payment settlement.
@@ -99,6 +100,20 @@ type SettlementReplayCheck = {
99
100
  } | {
100
101
  kind: 'spent';
101
102
  };
103
+ /**
104
+ * Record a settlement so a retry of the same payment is deduped.
105
+ *
106
+ * Call this only AFTER the payment has settled. By then the funds have moved,
107
+ * so a failing store write must not turn a paid request into a 500: the
108
+ * failure is logged and reported through `onCallbackError(err, 'seenTxStore.set')`
109
+ * and the request carries on to `onSettled` and the route. Never throws.
110
+ */
111
+ declare function recordSettlement(store: SeenTxStore, key: string, record: SettlementRecord, ctx: {
112
+ logger: RouteDockLogger;
113
+ /** Log prefix, e.g. `[x402]` or `[mpp-charge]`. */
114
+ label: string;
115
+ onCallbackError?: ((err: unknown, cb: string) => void) | undefined;
116
+ }): Promise<void>;
102
117
  /**
103
118
  * Decide what a payment bearing `key` should do.
104
119
  *
@@ -159,6 +174,22 @@ declare class InMemorySeenTxStore implements SeenTxStore {
159
174
  */
160
175
  declare function paymentIdempotencyKey(getHeader: (name: string) => string | undefined, scope: SettlementScope): Promise<string | null>;
161
176
 
177
+ /**
178
+ * Explicit provider configuration for recording `session_settled` on the
179
+ * agent vault after a clean mpp-session close.
180
+ *
181
+ * This replaced the old `process.env.AGENT_VAULT_CONTRACT` read inside the
182
+ * provider handlers: Workers have no `process.env` without `nodejs_compat`,
183
+ * and the docs told operators to set `AGENT_VAULT_CONTRACT_ID`, which the SDK
184
+ * never read. Passing the contract in as an option works on every runtime.
185
+ */
186
+ interface VaultSettlementConfig {
187
+ /** Agent vault contract id (C...) whose `record_session_settlement` entry point records the session. */
188
+ contract: string;
189
+ /** Soroban RPC endpoint override; defaults to the public endpoint for the configured network. */
190
+ rpcUrl?: string;
191
+ }
192
+
162
193
  /** Store shape extended with optional atomic update operation. */
163
194
  type ChannelStore = Store.Store & {
164
195
  update?: (key: string, fn: (prev: unknown) => unknown) => Promise<unknown>;
@@ -209,7 +240,14 @@ interface MppSessionHandlerOptions {
209
240
  idleTimeoutMs?: number;
210
241
  /** Log sink for internal error paths. Defaults to a console-backed logger. */
211
242
  logger?: RouteDockLogger;
243
+ /**
244
+ * Record `session_settled` on the agent vault after each clean close.
245
+ * `contract` is the vault's C... id; `rpcUrl` overrides the default Soroban
246
+ * RPC endpoint for the configured network. Falls back to the deprecated
247
+ * `AGENT_VAULT_CONTRACT`/`AGENT_VAULT_CONTRACT_ID` env vars when unset.
248
+ */
249
+ vaultSettlement?: VaultSettlementConfig;
212
250
  }
213
251
  declare function createMppSessionHandler(opts: MppSessionHandlerOptions): RequestHandler;
214
252
 
215
- export { type ChannelStore as C, InMemorySeenTxStore as I, MAX_SETTLEMENT_REPLAYS as M, type OrphanedSessionInfo as O, type SeenTxStore as S, type VoucherStoreValue as V, type SettlementRecord as a, type InMemorySeenTxStoreOptions as b, type MppSessionHandlerOptions as c, type OrphanReason as d, SETTLEMENT_REPLAY_WINDOW_MS as e, type SettlementReplayCheck as f, type SettlementScope as g, checkSettlementReplay as h, createMppSessionHandler as i, isVoucherStoreValue as j, paymentIdempotencyKey as p };
253
+ export { type ChannelStore as C, InMemorySeenTxStore as I, MAX_SETTLEMENT_REPLAYS as M, type OrphanedSessionInfo as O, type SeenTxStore as S, type VaultSettlementConfig as V, type SettlementRecord as a, type InMemorySeenTxStoreOptions as b, type MppSessionHandlerOptions as c, type OrphanReason as d, SETTLEMENT_REPLAY_WINDOW_MS as e, type SettlementReplayCheck as f, type SettlementScope as g, type VoucherStoreValue as h, checkSettlementReplay as i, createMppSessionHandler as j, isVoucherStoreValue as k, paymentIdempotencyKey as p, recordSettlement as r };
@@ -1,8 +1,7 @@
1
1
  import { usdcToStroops } from '@routedock/nulth-sdk';
2
- import { l as SpendStore, a as DailySpend, R as RetryPolicy } from './RouteDockClient-Bh86bVly.js';
3
- import { ClientStellarSigner } from '@x402/stellar';
4
- import { h as RouteDockManifest, c as PaymentResult } from './logger-D8_Q2ytp.js';
2
+ import { R as RouteDockManifest, c as PaymentRequest, d as PaymentResult } from './types-DXaS5Wip.cjs';
5
3
  import { Keypair } from '@stellar/stellar-sdk';
4
+ import { R as RetryPolicy } from './RouteDockClient-6rmgkbYb.cjs';
6
5
  import { SupabaseClient } from '@supabase/supabase-js';
7
6
 
8
7
  /**
@@ -20,46 +19,27 @@ import { SupabaseClient } from '@supabase/supabase-js';
20
19
  declare const usdcToUnits: typeof usdcToStroops;
21
20
 
22
21
  /**
23
- * File-backed durable {@link SpendStore}.
22
+ * Validate semantic constraints for manifest fields beyond JSON schema syntax.
23
+ * Enforces:
24
+ * - All keys in `latency_hints` must be a subset of declared `regions`.
25
+ * - If `assets` is defined, it must be a non-empty array whose first entry
26
+ * (`assets[0]`) matches the root-level `asset` and `asset_contract`.
27
+ * - Every mode in `modes` has a matching `pricing` entry, so `pay()` and
28
+ * `estimateCost()` never read a missing price.
29
+ * - Every entry in `deprecated_modes` is also listed in `modes`.
30
+ * - Every price (`amount`, `rate`, `min_deposit`) is a decimal the SDK can
31
+ * convert to base units (non-negative, at most 7 fractional digits).
24
32
  *
25
- * Persists the daily spend accumulator to a JSON file on disk, preserving
26
- * cumulative spending totals across process restarts, crashes, and redeploys.
27
- *
28
- * ### Error semantics
29
- * - File absent (ENOENT): returns null — legitimately no spend recorded yet.
30
- * - File present but unreadable or malformed: throws — a safety control must
31
- * fail closed, not assume nothing was spent.
32
- *
33
- * ### Write atomicity
34
- * Writes go to `<filePath>.tmp` first, then `fs.rename` onto the target.
35
- * `rename` is atomic within a filesystem, so there is no window where the
36
- * target file is truncated but not yet fully written.
33
+ * Every failure is a {@link RouteDockManifestError}.
37
34
  */
38
- declare class FileSpendStore implements SpendStore {
39
- readonly filePath: string;
40
- constructor(filePath: string);
41
- read(): Promise<DailySpend | null>;
42
- write(state: DailySpend): Promise<void>;
43
- }
44
-
45
- type Network = 'testnet' | 'mainnet';
46
- declare class X402Client {
47
- private readonly network;
48
- private readonly retryPolicy?;
49
- private readonly httpClient;
50
- private readonly signer;
51
- constructor(secretKeyOrSigner: string | ClientStellarSigner, network: Network, retryPolicy?: RetryPolicy | undefined);
52
- /** Replace signer (e.g. swap to Nulth ZK account payer before pay) */
53
- withSigner(signer: ClientStellarSigner): X402Client;
54
- pay(url: string, manifest: RouteDockManifest): Promise<PaymentResult>;
55
- }
35
+ declare function assertManifestValid(manifest: RouteDockManifest, baseUrl?: string): void;
56
36
 
57
37
  declare class MppChargeClient {
58
38
  private readonly keypair;
59
39
  private readonly network;
60
40
  private readonly retryPolicy?;
61
41
  constructor(keypair: Keypair, network: 'testnet' | 'mainnet', retryPolicy?: RetryPolicy | undefined);
62
- pay(url: string, manifest: RouteDockManifest): Promise<PaymentResult>;
42
+ pay(url: string, manifest: RouteDockManifest, request?: PaymentRequest): Promise<PaymentResult>;
63
43
  }
64
44
 
65
45
  interface OnChainProviderInfo {
@@ -139,4 +119,4 @@ declare class ProviderRegistry {
139
119
  fetchProviderManifest(record: ProviderRecord): Promise<RouteDockManifest>;
140
120
  }
141
121
 
142
- export { FileSpendStore as F, MppChargeClient as M, type OnChainProviderInfo as O, type ProviderRecord as P, X402Client as X, OnChainRegistry as a, ProviderRegistry as b, type ProviderRegistryConfig as c, usdcToUnits as u };
122
+ export { MppChargeClient as M, type OnChainProviderInfo as O, type ProviderRecord as P, OnChainRegistry as a, ProviderRegistry as b, type ProviderRegistryConfig as c, assertManifestValid as d, usdcToUnits as u };
@@ -1,8 +1,7 @@
1
1
  import { usdcToStroops } from '@routedock/nulth-sdk';
2
- import { l as SpendStore, a as DailySpend, R as RetryPolicy } from './RouteDockClient-go9aopfF.cjs';
3
- import { ClientStellarSigner } from '@x402/stellar';
4
- import { h as RouteDockManifest, c as PaymentResult } from './logger-D8_Q2ytp.cjs';
2
+ import { R as RouteDockManifest, c as PaymentRequest, d as PaymentResult } from './types-DXaS5Wip.js';
5
3
  import { Keypair } from '@stellar/stellar-sdk';
4
+ import { R as RetryPolicy } from './RouteDockClient-CnAkxwrW.js';
6
5
  import { SupabaseClient } from '@supabase/supabase-js';
7
6
 
8
7
  /**
@@ -20,46 +19,27 @@ import { SupabaseClient } from '@supabase/supabase-js';
20
19
  declare const usdcToUnits: typeof usdcToStroops;
21
20
 
22
21
  /**
23
- * File-backed durable {@link SpendStore}.
22
+ * Validate semantic constraints for manifest fields beyond JSON schema syntax.
23
+ * Enforces:
24
+ * - All keys in `latency_hints` must be a subset of declared `regions`.
25
+ * - If `assets` is defined, it must be a non-empty array whose first entry
26
+ * (`assets[0]`) matches the root-level `asset` and `asset_contract`.
27
+ * - Every mode in `modes` has a matching `pricing` entry, so `pay()` and
28
+ * `estimateCost()` never read a missing price.
29
+ * - Every entry in `deprecated_modes` is also listed in `modes`.
30
+ * - Every price (`amount`, `rate`, `min_deposit`) is a decimal the SDK can
31
+ * convert to base units (non-negative, at most 7 fractional digits).
24
32
  *
25
- * Persists the daily spend accumulator to a JSON file on disk, preserving
26
- * cumulative spending totals across process restarts, crashes, and redeploys.
27
- *
28
- * ### Error semantics
29
- * - File absent (ENOENT): returns null — legitimately no spend recorded yet.
30
- * - File present but unreadable or malformed: throws — a safety control must
31
- * fail closed, not assume nothing was spent.
32
- *
33
- * ### Write atomicity
34
- * Writes go to `<filePath>.tmp` first, then `fs.rename` onto the target.
35
- * `rename` is atomic within a filesystem, so there is no window where the
36
- * target file is truncated but not yet fully written.
33
+ * Every failure is a {@link RouteDockManifestError}.
37
34
  */
38
- declare class FileSpendStore implements SpendStore {
39
- readonly filePath: string;
40
- constructor(filePath: string);
41
- read(): Promise<DailySpend | null>;
42
- write(state: DailySpend): Promise<void>;
43
- }
44
-
45
- type Network = 'testnet' | 'mainnet';
46
- declare class X402Client {
47
- private readonly network;
48
- private readonly retryPolicy?;
49
- private readonly httpClient;
50
- private readonly signer;
51
- constructor(secretKeyOrSigner: string | ClientStellarSigner, network: Network, retryPolicy?: RetryPolicy | undefined);
52
- /** Replace signer (e.g. swap to Nulth ZK account payer before pay) */
53
- withSigner(signer: ClientStellarSigner): X402Client;
54
- pay(url: string, manifest: RouteDockManifest): Promise<PaymentResult>;
55
- }
35
+ declare function assertManifestValid(manifest: RouteDockManifest, baseUrl?: string): void;
56
36
 
57
37
  declare class MppChargeClient {
58
38
  private readonly keypair;
59
39
  private readonly network;
60
40
  private readonly retryPolicy?;
61
41
  constructor(keypair: Keypair, network: 'testnet' | 'mainnet', retryPolicy?: RetryPolicy | undefined);
62
- pay(url: string, manifest: RouteDockManifest): Promise<PaymentResult>;
42
+ pay(url: string, manifest: RouteDockManifest, request?: PaymentRequest): Promise<PaymentResult>;
63
43
  }
64
44
 
65
45
  interface OnChainProviderInfo {
@@ -139,4 +119,4 @@ declare class ProviderRegistry {
139
119
  fetchProviderManifest(record: ProviderRecord): Promise<RouteDockManifest>;
140
120
  }
141
121
 
142
- export { FileSpendStore as F, MppChargeClient as M, type OnChainProviderInfo as O, type ProviderRecord as P, X402Client as X, OnChainRegistry as a, ProviderRegistry as b, type ProviderRegistryConfig as c, usdcToUnits as u };
122
+ export { MppChargeClient as M, type OnChainProviderInfo as O, type ProviderRecord as P, OnChainRegistry as a, ProviderRegistry as b, type ProviderRegistryConfig as c, assertManifestValid as d, usdcToUnits as u };