@one-source/api-mcp 5.4.6 → 5.5.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.
package/dist/mpp.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ export type MppMode = 'charge' | 'session';
2
+ export interface MppSessionHandle {
3
+ /** Payment-aware fetch that drives the voucher-channel lifecycle. */
4
+ fetch: typeof globalThis.fetch;
5
+ /** Whether the session manager initialised and can be selected. */
6
+ available: boolean;
7
+ }
8
+ export interface MppSetupResult {
9
+ enabled: boolean;
10
+ address?: string;
11
+ /** Per-call charge fetch, present whenever MPP is enabled. */
12
+ chargeFetch?: typeof globalThis.fetch;
13
+ /** Voucher-channel session handle. */
14
+ session?: MppSessionHandle;
15
+ }
16
+ export declare function setupMpp(): MppSetupResult;
17
+ /** Whether MPP payment is active (MPP_PRIVATE_KEY set). */
18
+ export declare function isMppEnabled(): boolean;
19
+ /** Payer wallet address, when enabled. */
20
+ export declare function getMppAddress(): string | undefined;
21
+ /** Whether the session channel scheme initialised and can be selected. */
22
+ export declare function isMppSessionAvailable(): boolean;
23
+ /**
24
+ * Cooperatively close the active MPP voucher channel, settling the latest
25
+ * authorized spend on-chain and reclaiming the unspent deposit to the payer
26
+ * wallet. Safe to call when no channel was ever opened (no-op) and idempotent.
27
+ * Swallows errors so a stuck settle can't hang shutdown.
28
+ *
29
+ * We do NOT use `manager.close()`: mppx's legacy manager signs the close at its
30
+ * locally-tracked `spent`, which it derives from the receipt `spent` field. The
31
+ * gateway (mpp-go) reports `spent` as the per-call delta and the running total
32
+ * in `acceptedCumulative`, so mppx's `spent` never advances past the first
33
+ * voucher and the close is rejected ("close cumulativeAmount … below the last
34
+ * accepted voucher"). Instead we sign our own close credential at the manager's
35
+ * `cumulative` (the total we authorized and the gateway accepted) and POST it —
36
+ * validated end-to-end against the live gateway. Track the upstream fix at
37
+ * wevm/mppx; switch back to `manager.close()` once it uses `acceptedCumulative`.
38
+ */
39
+ export declare function closeMppSession(): Promise<void>;
40
+ //# sourceMappingURL=mpp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mpp.d.ts","sourceRoot":"","sources":["../src/mpp.ts"],"names":[],"mappings":"AA4BA,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE3C,MAAM,WAAW,gBAAgB;IAC/B,qEAAqE;IACrE,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAC/B,mEAAmE;IACnE,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,WAAW,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IACtC,sCAAsC;IACtC,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC5B;AA4BD,wBAAgB,QAAQ,IAAI,cAAc,CAmGzC;AAED,2DAA2D;AAC3D,wBAAgB,YAAY,IAAI,OAAO,CAEtC;AAED,0CAA0C;AAC1C,wBAAgB,aAAa,IAAI,MAAM,GAAG,SAAS,CAElD;AAED,0EAA0E;AAC1E,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CA6BrD"}
package/dist/mpp.js ADDED
@@ -0,0 +1,217 @@
1
+ /**
2
+ * MPP (Tempo Machine Payments Protocol) payment setup.
3
+ *
4
+ * When MPP_PRIVATE_KEY is set, builds payment-aware fetch wrappers that handle
5
+ * HTTP 402 `WWW-Authenticate: Payment` challenges from the gateway by signing
6
+ * Tempo payments (USDC.e / pathUSD) via the `mppx` SDK.
7
+ *
8
+ * Two sub-modes, both using the same MPP_PRIVATE_KEY wallet:
9
+ * - `charge` — one signed Tempo payment per call (the default). Local accounts
10
+ * sign in `pull` mode (server broadcasts), so no Tempo RPC is
11
+ * needed — the network/currency/recipient come from the gateway
12
+ * challenge, exactly like x402 `exact`.
13
+ * - `session` — a TIP-1034 voucher channel: the first call opens a channel
14
+ * on-chain (capped by MPP_MAX_DEPOSIT), subsequent calls are
15
+ * signed off-chain as cumulative vouchers, and the unspent
16
+ * deposit is reclaimed by `closeMppSession()` on shutdown.
17
+ *
18
+ * Like x402.ts, this returns the wrapped fetches instead of patching
19
+ * globalThis.fetch (Mppx.create polyfills global by default — we pass
20
+ * polyfill:false), so only the OneSourceClient pays; analytics and other HTTP
21
+ * consumers are unaffected. The unified `payment.ts` orchestrator selects
22
+ * between the charge fetch and the session fetch based on the active mode.
23
+ */
24
+ import { Mppx, tempo, sessionLegacyManager, sessionLegacy } from 'mppx/client';
25
+ import { privateKeyToAccount } from 'viem/accounts';
26
+ import { createPublicClient, http } from 'viem';
27
+ import { tempo as tempoChain } from 'viem/chains';
28
+ // Human-readable cap (in token units) on a session channel's on-chain deposit.
29
+ // Bounds the worst-case locked balance if the process dies before close.
30
+ const DEFAULT_MAX_DEPOSIT = '1';
31
+ let _applied = false;
32
+ let _cachedResult;
33
+ let _enabled = false;
34
+ let _address;
35
+ let _sessionAvailable = false;
36
+ // The mppx session manager, retained so `closeMppSession` can cooperatively
37
+ // settle and reclaim the unspent deposit on shutdown.
38
+ let _sessionManager;
39
+ // The legacy session method + the strip-x402 fetch + the last session request's
40
+ // URL and challenge — used by closeMppSession to sign and POST our own close
41
+ // credential at the locally-authorized cumulative (see closeMppSession).
42
+ let _sessionMethod;
43
+ let _sessionFetchImpl;
44
+ let _lastSessionUrl;
45
+ let _lastSessionChallenge;
46
+ let _sessionClosed = false;
47
+ function maxDeposit() {
48
+ return process.env.MPP_MAX_DEPOSIT?.trim() || DEFAULT_MAX_DEPOSIT;
49
+ }
50
+ export function setupMpp() {
51
+ const rawKey = process.env.MPP_PRIVATE_KEY;
52
+ if (!rawKey)
53
+ return { enabled: false };
54
+ if (_applied && _cachedResult)
55
+ return _cachedResult;
56
+ // Auto-prepend 0x — viem requires it but private keys are not typically stored with it
57
+ const privateKey = rawKey.startsWith('0x')
58
+ ? rawKey
59
+ : `0x${rawKey}`;
60
+ const account = privateKeyToAccount(privateKey);
61
+ // The gateway advertises BOTH x402 (Payment-Required header) and MPP
62
+ // (WWW-Authenticate: Payment) on every 402. mppx's HTTP transport eagerly
63
+ // parses the x402 header too, and its x402 decoder can't read the gateway's
64
+ // (coinbase-style) Payment-Required header — it throws before the MPP
65
+ // challenge is ever used. Strip Payment-Required from 402s so mppx only sees
66
+ // the MPP challenge; the x402 rail is handled separately by x402.ts.
67
+ const stripX402Fetch = async (input, init) => {
68
+ const res = await fetch(input, init);
69
+ if (res.status === 402 && res.headers.has('payment-required')) {
70
+ const headers = new Headers(res.headers);
71
+ headers.delete('payment-required');
72
+ return new Response(res.body, { status: res.status, statusText: res.statusText, headers });
73
+ }
74
+ return res;
75
+ };
76
+ // --- charge method (per-call payment) ---
77
+ // Register only the `charge` intent so this fetch always pays per-call (the
78
+ // bare `tempo()` factory would also register the session intent). polyfill:
79
+ // false keeps globalThis.fetch untouched.
80
+ const chargeClient = Mppx.create({
81
+ methods: [tempo.charge({ account })],
82
+ polyfill: false,
83
+ fetch: stripX402Fetch,
84
+ });
85
+ const chargeFetch = (input, init) => chargeClient.fetch(input, init);
86
+ // --- session method (voucher channel) ---
87
+ // Built eagerly but lazily funded: no on-chain channel opens until the first
88
+ // paid request is made while in session mode. The manager needs a viem client
89
+ // (Tempo chain + RPC) to open/settle the channel. If construction fails, fall
90
+ // back to charge-only rather than crashing the MCP.
91
+ //
92
+ // We use the LEGACY session manager: the gateway (tempoxyz/mpp-go) emits v1
93
+ // session challenges (no `sessionProtocol` marker), which mppx's current
94
+ // `tempo.session.manager` rejects (it requires sessionProtocol v2). The
95
+ // legacy manager accepts `sessionProtocol` undefined|v1. Switch to the v2
96
+ // manager once the gateway advertises sessionProtocol v2.
97
+ let session;
98
+ try {
99
+ const sessionClient = createPublicClient({
100
+ chain: tempoChain,
101
+ transport: http(process.env.MPP_RPC_URL?.trim() || undefined),
102
+ });
103
+ _sessionManager = sessionLegacyManager({
104
+ account,
105
+ client: sessionClient,
106
+ maxDeposit: maxDeposit(),
107
+ fetch: stripX402Fetch,
108
+ });
109
+ // A standalone legacy session method (same account/client) used by
110
+ // closeMppSession to sign our own close credential — see there for why.
111
+ // The method factory takes `getClient` (the `client` shorthand is
112
+ // manager-only).
113
+ _sessionMethod = sessionLegacy({ account, getClient: () => sessionClient });
114
+ _sessionFetchImpl = stripX402Fetch;
115
+ const mgr = _sessionManager;
116
+ // Capture the last session request's URL + parsed challenge so the shutdown
117
+ // close can target the right endpoint and bind to a valid challenge.
118
+ const sessionFetch = async (input, init) => {
119
+ const res = await mgr.fetch(input, init);
120
+ _lastSessionUrl = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url;
121
+ const challenge = res.challenge;
122
+ if (challenge)
123
+ _lastSessionChallenge = challenge;
124
+ return res;
125
+ };
126
+ _sessionAvailable = true;
127
+ session = { fetch: sessionFetch, available: true };
128
+ }
129
+ catch (err) {
130
+ _sessionAvailable = false;
131
+ _sessionManager = undefined;
132
+ console.error(`[onesource-api] warning: MPP session channel unavailable (${err instanceof Error ? err.message : String(err)}); falling back to charge-only`);
133
+ }
134
+ _enabled = true;
135
+ _address = account.address;
136
+ _applied = true;
137
+ _cachedResult = {
138
+ enabled: true,
139
+ address: account.address,
140
+ chargeFetch,
141
+ ...(session ? { session } : {}),
142
+ };
143
+ return _cachedResult;
144
+ }
145
+ /** Whether MPP payment is active (MPP_PRIVATE_KEY set). */
146
+ export function isMppEnabled() {
147
+ return _enabled;
148
+ }
149
+ /** Payer wallet address, when enabled. */
150
+ export function getMppAddress() {
151
+ return _address;
152
+ }
153
+ /** Whether the session channel scheme initialised and can be selected. */
154
+ export function isMppSessionAvailable() {
155
+ return _sessionAvailable;
156
+ }
157
+ /**
158
+ * Cooperatively close the active MPP voucher channel, settling the latest
159
+ * authorized spend on-chain and reclaiming the unspent deposit to the payer
160
+ * wallet. Safe to call when no channel was ever opened (no-op) and idempotent.
161
+ * Swallows errors so a stuck settle can't hang shutdown.
162
+ *
163
+ * We do NOT use `manager.close()`: mppx's legacy manager signs the close at its
164
+ * locally-tracked `spent`, which it derives from the receipt `spent` field. The
165
+ * gateway (mpp-go) reports `spent` as the per-call delta and the running total
166
+ * in `acceptedCumulative`, so mppx's `spent` never advances past the first
167
+ * voucher and the close is rejected ("close cumulativeAmount … below the last
168
+ * accepted voucher"). Instead we sign our own close credential at the manager's
169
+ * `cumulative` (the total we authorized and the gateway accepted) and POST it —
170
+ * validated end-to-end against the live gateway. Track the upstream fix at
171
+ * wevm/mppx; switch back to `manager.close()` once it uses `acceptedCumulative`.
172
+ */
173
+ export async function closeMppSession() {
174
+ if (_sessionClosed)
175
+ return;
176
+ _sessionClosed = true;
177
+ const mgr = _sessionManager;
178
+ if (!mgr?.opened || !_sessionMethod || !_sessionFetchImpl || !_lastSessionUrl || !_lastSessionChallenge) {
179
+ return;
180
+ }
181
+ try {
182
+ const credential = await _sessionMethod.createCredential({
183
+ challenge: _lastSessionChallenge,
184
+ context: {
185
+ action: 'close',
186
+ channelId: mgr.channelId,
187
+ cumulativeAmountRaw: mgr.cumulative.toString(),
188
+ },
189
+ });
190
+ const res = await _sessionFetchImpl(_lastSessionUrl, {
191
+ method: 'POST',
192
+ headers: { Authorization: credential },
193
+ });
194
+ if (!res.ok) {
195
+ const body = await res.text().catch(() => '');
196
+ throw new Error(`gateway returned ${res.status}${body ? `: ${body.slice(0, 160)}` : ''}`);
197
+ }
198
+ }
199
+ catch (err) {
200
+ console.error(`[onesource-api] warning: MPP session close failed (${err instanceof Error ? err.message : String(err)}); unspent deposit is reclaimable later on-chain`);
201
+ }
202
+ }
203
+ /** @internal -- for test teardown only */
204
+ export function resetMpp() {
205
+ _applied = false;
206
+ _cachedResult = undefined;
207
+ _enabled = false;
208
+ _address = undefined;
209
+ _sessionAvailable = false;
210
+ _sessionManager = undefined;
211
+ _sessionMethod = undefined;
212
+ _sessionFetchImpl = undefined;
213
+ _lastSessionUrl = undefined;
214
+ _lastSessionChallenge = undefined;
215
+ _sessionClosed = false;
216
+ }
217
+ //# sourceMappingURL=mpp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mpp.js","sourceRoot":"","sources":["../src/mpp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAChD,OAAO,EAAE,KAAK,IAAI,UAAU,EAAE,MAAM,aAAa,CAAC;AAoBlD,+EAA+E;AAC/E,yEAAyE;AACzE,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEhC,IAAI,QAAQ,GAAG,KAAK,CAAC;AACrB,IAAI,aAAyC,CAAC;AAE9C,IAAI,QAAQ,GAAG,KAAK,CAAC;AACrB,IAAI,QAA4B,CAAC;AACjC,IAAI,iBAAiB,GAAG,KAAK,CAAC;AAC9B,4EAA4E;AAC5E,sDAAsD;AACtD,IAAI,eAAoE,CAAC;AACzE,gFAAgF;AAChF,6EAA6E;AAC7E,yEAAyE;AACzE,IAAI,cAA4D,CAAC;AACjE,IAAI,iBAAsD,CAAC;AAC3D,IAAI,eAAmC,CAAC;AACxC,IAAI,qBAA8B,CAAC;AACnC,IAAI,cAAc,GAAG,KAAK,CAAC;AAE3B,SAAS,UAAU;IACjB,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,mBAAmB,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAC3C,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IACvC,IAAI,QAAQ,IAAI,aAAa;QAAE,OAAO,aAAa,CAAC;IAEpD,uFAAuF;IACvF,MAAM,UAAU,GAAkB,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;QACvD,CAAC,CAAE,MAAwB;QAC3B,CAAC,CAAE,KAAK,MAAM,EAAoB,CAAC;IAErC,MAAM,OAAO,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;IAEhD,qEAAqE;IACrE,0EAA0E;IAC1E,4EAA4E;IAC5E,sEAAsE;IACtE,6EAA6E;IAC7E,qEAAqE;IACrE,MAAM,cAAc,GAA4B,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACpE,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACrC,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC9D,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACzC,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;YACnC,OAAO,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;QAC7F,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;IAEF,2CAA2C;IAC3C,4EAA4E;IAC5E,4EAA4E;IAC5E,0CAA0C;IAC1C,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC;QAC/B,OAAO,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QACpC,QAAQ,EAAE,KAAK;QACf,KAAK,EAAE,cAAc;KACtB,CAAC,CAAC;IACH,MAAM,WAAW,GAA4B,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAC3D,YAAY,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAElC,2CAA2C;IAC3C,6EAA6E;IAC7E,8EAA8E;IAC9E,8EAA8E;IAC9E,oDAAoD;IACpD,EAAE;IACF,4EAA4E;IAC5E,yEAAyE;IACzE,wEAAwE;IACxE,0EAA0E;IAC1E,0DAA0D;IAC1D,IAAI,OAAqC,CAAC;IAC1C,IAAI,CAAC;QACH,MAAM,aAAa,GAAG,kBAAkB,CAAC;YACvC,KAAK,EAAE,UAAU;YACjB,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;SAC9D,CAAC,CAAC;QACH,eAAe,GAAG,oBAAoB,CAAC;YACrC,OAAO;YACP,MAAM,EAAE,aAAa;YACrB,UAAU,EAAE,UAAU,EAAE;YACxB,KAAK,EAAE,cAAc;SACtB,CAAC,CAAC;QACH,mEAAmE;QACnE,wEAAwE;QACxE,kEAAkE;QAClE,iBAAiB;QACjB,cAAc,GAAG,aAAa,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,aAAa,EAAE,CAAC,CAAC;QAC5E,iBAAiB,GAAG,cAAc,CAAC;QACnC,MAAM,GAAG,GAAG,eAAe,CAAC;QAC5B,4EAA4E;QAC5E,qEAAqE;QACrE,MAAM,YAAY,GAA4B,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YAClE,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,KAA0B,EAAE,IAAI,CAAC,CAAC;YAC9D,eAAe,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,YAAY,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAE,KAAiB,CAAC,GAAG,CAAC;YACjH,MAAM,SAAS,GAAI,GAA0C,CAAC,SAAS,CAAC;YACxE,IAAI,SAAS;gBAAE,qBAAqB,GAAG,SAAS,CAAC;YACjD,OAAO,GAAG,CAAC;QACb,CAAC,CAAC;QACF,iBAAiB,GAAG,IAAI,CAAC;QACzB,OAAO,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACrD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,iBAAiB,GAAG,KAAK,CAAC;QAC1B,eAAe,GAAG,SAAS,CAAC;QAC5B,OAAO,CAAC,KAAK,CACX,6DAA6D,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,gCAAgC,CAC9I,CAAC;IACJ,CAAC;IAED,QAAQ,GAAG,IAAI,CAAC;IAChB,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAC3B,QAAQ,GAAG,IAAI,CAAC;IAChB,aAAa,GAAG;QACd,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,WAAW;QACX,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChC,CAAC;IACF,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,YAAY;IAC1B,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,aAAa;IAC3B,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,qBAAqB;IACnC,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,cAAc;QAAE,OAAO;IAC3B,cAAc,GAAG,IAAI,CAAC;IACtB,MAAM,GAAG,GAAG,eAAe,CAAC;IAC5B,IAAI,CAAC,GAAG,EAAE,MAAM,IAAI,CAAC,cAAc,IAAI,CAAC,iBAAiB,IAAI,CAAC,eAAe,IAAI,CAAC,qBAAqB,EAAE,CAAC;QACxG,OAAO;IACT,CAAC;IACD,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,gBAAgB,CAAC;YACvD,SAAS,EAAE,qBAAqB;YAChC,OAAO,EAAE;gBACP,MAAM,EAAE,OAAO;gBACf,SAAS,EAAE,GAAG,CAAC,SAAS;gBACxB,mBAAmB,EAAE,GAAG,CAAC,UAAU,CAAC,QAAQ,EAAE;aAC/C;SACuD,CAAC,CAAC;QAC5D,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,eAAe,EAAE;YACnD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,EAAE;SACvC,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAC9C,MAAM,IAAI,KAAK,CAAC,oBAAoB,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5F,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CACX,sDAAsD,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,kDAAkD,CACzJ,CAAC;IACJ,CAAC;AACH,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,QAAQ;IACtB,QAAQ,GAAG,KAAK,CAAC;IACjB,aAAa,GAAG,SAAS,CAAC;IAC1B,QAAQ,GAAG,KAAK,CAAC;IACjB,QAAQ,GAAG,SAAS,CAAC;IACrB,iBAAiB,GAAG,KAAK,CAAC;IAC1B,eAAe,GAAG,SAAS,CAAC;IAC5B,cAAc,GAAG,SAAS,CAAC;IAC3B,iBAAiB,GAAG,SAAS,CAAC;IAC9B,eAAe,GAAG,SAAS,CAAC;IAC5B,qBAAqB,GAAG,SAAS,CAAC;IAClC,cAAc,GAAG,KAAK,CAAC;AACzB,CAAC"}
@@ -0,0 +1,48 @@
1
+ export type PaymentRailMode = 'x402-exact' | 'x402-batch' | 'mpp-charge' | 'mpp-session';
2
+ export type AuthMethod = 'x402' | 'mpp' | 'none';
3
+ export interface PaymentSetupResult {
4
+ /** Whether any payment rail is active (a wallet key is set). */
5
+ enabled: boolean;
6
+ /** Primary rail, for analytics / wallet-id reporting. */
7
+ authMethod: AuthMethod;
8
+ x402Address?: string;
9
+ mppAddress?: string;
10
+ /** Unified dispatch fetch, present when a rail is enabled. */
11
+ fetch?: typeof globalThis.fetch;
12
+ }
13
+ export interface PaymentModeInfo {
14
+ /** Whether any payment rail is active. */
15
+ enabled: boolean;
16
+ /** Current active rail+mode. */
17
+ mode: PaymentRailMode;
18
+ x402: {
19
+ enabled: boolean;
20
+ address?: string;
21
+ batchAvailable: boolean;
22
+ };
23
+ mpp: {
24
+ enabled: boolean;
25
+ address?: string;
26
+ sessionAvailable: boolean;
27
+ };
28
+ /** Modes that can be switched to right now (their rail is enabled/available). */
29
+ availableModes: PaymentRailMode[];
30
+ }
31
+ export declare function setupPayments(): PaymentSetupResult;
32
+ /** Current active rail+mode. */
33
+ export declare function getPaymentMode(): PaymentRailMode;
34
+ /**
35
+ * Switch the active rail+mode for subsequent calls. No-op (returns the unchanged
36
+ * mode) when the target rail's key isn't set or its sub-mode is unavailable
37
+ * (x402 batch scheme failed to init, or MPP session channel failed to init).
38
+ */
39
+ export declare function setPaymentMode(mode: PaymentRailMode): PaymentRailMode;
40
+ /** Snapshot of unified payment state for the 1s_payment_mode tool. */
41
+ export declare function getPaymentModeInfo(): PaymentModeInfo;
42
+ /**
43
+ * Settle and reclaim any open MPP voucher channel. Called on shutdown; no-op
44
+ * for the x402 rail (its batch residual is reclaimed via 1s_refund or the
45
+ * gateway's idle auto-refund). Idempotent.
46
+ */
47
+ export declare function closePaymentSession(): Promise<void>;
48
+ //# sourceMappingURL=payment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payment.d.ts","sourceRoot":"","sources":["../src/payment.ts"],"names":[],"mappings":"AA4BA,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG,YAAY,GAAG,YAAY,GAAG,aAAa,CAAC;AAEzF,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;AAEjD,MAAM,WAAW,kBAAkB;IACjC,gEAAgE;IAChE,OAAO,EAAE,OAAO,CAAC;IACjB,yDAAyD;IACzD,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,0CAA0C;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,gCAAgC;IAChC,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,OAAO,CAAA;KAAE,CAAC;IACtE,GAAG,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,OAAO,CAAA;KAAE,CAAC;IACvE,iFAAiF;IACjF,cAAc,EAAE,eAAe,EAAE,CAAC;CACnC;AA6BD,wBAAgB,aAAa,IAAI,kBAAkB,CA0ClD;AAED,gCAAgC;AAChC,wBAAgB,cAAc,IAAI,eAAe,CAEhD;AAgBD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,eAAe,GAAG,eAAe,CAwBrE;AAED,sEAAsE;AACtE,wBAAgB,kBAAkB,IAAI,eAAe,CASpD;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAEzD"}
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Unified payment orchestrator.
3
+ *
4
+ * The MCP can pay the gateway over two rails, each with two sub-modes:
5
+ * - x402 (USDC on Base): `x402-exact` | `x402-batch`
6
+ * - MPP (Tempo USDC.e /pathUSD): `mpp-charge` | `mpp-session`
7
+ *
8
+ * This module owns the single active mode and returns ONE dispatch fetch that
9
+ * routes each request to the matching rail's payment-aware fetch. The
10
+ * `1s_payment_mode` tool flips the mode in-session via {@link setPaymentMode}.
11
+ *
12
+ * The per-rail wiring lives in x402.ts and mpp.ts; this file only composes them
13
+ * and holds the unified selector, so the money-critical x402 path stays
14
+ * isolated and unchanged.
15
+ */
16
+ import { setupX402, setPaymentMode as setX402Mode, getPaymentModeInfo as getX402Info, } from './x402.js';
17
+ import { setupMpp, isMppEnabled, getMppAddress, isMppSessionAvailable, closeMppSession, } from './mpp.js';
18
+ let _applied = false;
19
+ let _cachedResult;
20
+ let _mode = 'x402-exact';
21
+ let _x402Fetch;
22
+ let _mppChargeFetch;
23
+ let _mppSessionFetch;
24
+ // Resolve the initial unified mode. Precedence: ONESOURCE_PAYMENT_MODE (if its
25
+ // rail is enabled) > x402 (key present, X402_PAYMENT_MODE picks the sub-mode) >
26
+ // mpp (MPP_PAYMENT_MODE picks the sub-mode). When both keys are set, x402 is the
27
+ // initial primary — both rails stay switchable via setPaymentMode.
28
+ function initialMode(x402Enabled, mppEnabled) {
29
+ const all = ['x402-exact', 'x402-batch', 'mpp-charge', 'mpp-session'];
30
+ const requested = process.env.ONESOURCE_PAYMENT_MODE?.trim().toLowerCase();
31
+ if (requested && all.includes(requested)) {
32
+ if (requested.startsWith('x402-') && x402Enabled)
33
+ return requested;
34
+ if (requested.startsWith('mpp-') && mppEnabled)
35
+ return requested;
36
+ }
37
+ if (x402Enabled) {
38
+ return process.env.X402_PAYMENT_MODE?.trim().toLowerCase() === 'batch' ? 'x402-batch' : 'x402-exact';
39
+ }
40
+ if (mppEnabled) {
41
+ return process.env.MPP_PAYMENT_MODE?.trim().toLowerCase() === 'session' ? 'mpp-session' : 'mpp-charge';
42
+ }
43
+ return 'x402-exact';
44
+ }
45
+ export function setupPayments() {
46
+ if (_applied && _cachedResult)
47
+ return _cachedResult;
48
+ const x402 = setupX402();
49
+ const mpp = setupMpp();
50
+ _x402Fetch = x402.enabled ? x402.fetch : undefined;
51
+ _mppChargeFetch = mpp.enabled ? mpp.chargeFetch : undefined;
52
+ _mppSessionFetch = mpp.enabled ? mpp.session?.fetch : undefined;
53
+ const enabled = Boolean(x402.enabled || mpp.enabled);
54
+ const authMethod = x402.enabled ? 'x402' : mpp.enabled ? 'mpp' : 'none';
55
+ _mode = initialMode(x402.enabled, mpp.enabled);
56
+ // Keep x402's internal scheme in sync with the unified mode at startup.
57
+ if (_mode === 'x402-batch')
58
+ setX402Mode('batch');
59
+ else if (_mode === 'x402-exact')
60
+ setX402Mode('exact');
61
+ // Dispatcher: route each request through the active rail's fetch. Reads
62
+ // `_mode` live so in-session switches take effect immediately. Falls back to
63
+ // any enabled fetch if the active one is somehow missing (defensive).
64
+ const dispatchFetch = (input, init) => {
65
+ const active = _mode === 'mpp-charge'
66
+ ? _mppChargeFetch
67
+ : _mode === 'mpp-session'
68
+ ? _mppSessionFetch
69
+ : _x402Fetch;
70
+ const f = active ?? _x402Fetch ?? _mppChargeFetch ?? _mppSessionFetch;
71
+ if (!f)
72
+ return fetch(input, init);
73
+ return f(input, init);
74
+ };
75
+ _applied = true;
76
+ _cachedResult = {
77
+ enabled,
78
+ authMethod,
79
+ ...(x402.address ? { x402Address: x402.address } : {}),
80
+ ...(mpp.address ? { mppAddress: mpp.address } : {}),
81
+ ...(enabled ? { fetch: dispatchFetch } : {}),
82
+ };
83
+ return _cachedResult;
84
+ }
85
+ /** Current active rail+mode. */
86
+ export function getPaymentMode() {
87
+ return _mode;
88
+ }
89
+ function availableModes() {
90
+ const modes = [];
91
+ const x = getX402Info();
92
+ if (x.enabled) {
93
+ modes.push('x402-exact');
94
+ if (x.batchAvailable)
95
+ modes.push('x402-batch');
96
+ }
97
+ if (isMppEnabled()) {
98
+ modes.push('mpp-charge');
99
+ if (isMppSessionAvailable())
100
+ modes.push('mpp-session');
101
+ }
102
+ return modes;
103
+ }
104
+ /**
105
+ * Switch the active rail+mode for subsequent calls. No-op (returns the unchanged
106
+ * mode) when the target rail's key isn't set or its sub-mode is unavailable
107
+ * (x402 batch scheme failed to init, or MPP session channel failed to init).
108
+ */
109
+ export function setPaymentMode(mode) {
110
+ const x = getX402Info();
111
+ switch (mode) {
112
+ case 'x402-exact':
113
+ if (!x.enabled)
114
+ return _mode;
115
+ setX402Mode('exact');
116
+ _mode = 'x402-exact';
117
+ return _mode;
118
+ case 'x402-batch':
119
+ if (!x.enabled || !x.batchAvailable)
120
+ return _mode;
121
+ setX402Mode('batch');
122
+ _mode = 'x402-batch';
123
+ return _mode;
124
+ case 'mpp-charge':
125
+ if (!isMppEnabled())
126
+ return _mode;
127
+ _mode = 'mpp-charge';
128
+ return _mode;
129
+ case 'mpp-session':
130
+ if (!isMppEnabled() || !isMppSessionAvailable())
131
+ return _mode;
132
+ _mode = 'mpp-session';
133
+ return _mode;
134
+ default:
135
+ return _mode;
136
+ }
137
+ }
138
+ /** Snapshot of unified payment state for the 1s_payment_mode tool. */
139
+ export function getPaymentModeInfo() {
140
+ const x = getX402Info();
141
+ return {
142
+ enabled: x.enabled || isMppEnabled(),
143
+ mode: _mode,
144
+ x402: { enabled: x.enabled, address: x.address, batchAvailable: x.batchAvailable },
145
+ mpp: { enabled: isMppEnabled(), address: getMppAddress(), sessionAvailable: isMppSessionAvailable() },
146
+ availableModes: availableModes(),
147
+ };
148
+ }
149
+ /**
150
+ * Settle and reclaim any open MPP voucher channel. Called on shutdown; no-op
151
+ * for the x402 rail (its batch residual is reclaimed via 1s_refund or the
152
+ * gateway's idle auto-refund). Idempotent.
153
+ */
154
+ export async function closePaymentSession() {
155
+ await closeMppSession();
156
+ }
157
+ /** @internal -- for test teardown only */
158
+ export function resetPayments() {
159
+ _applied = false;
160
+ _cachedResult = undefined;
161
+ _mode = 'x402-exact';
162
+ _x402Fetch = undefined;
163
+ _mppChargeFetch = undefined;
164
+ _mppSessionFetch = undefined;
165
+ }
166
+ //# sourceMappingURL=payment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payment.js","sourceRoot":"","sources":["../src/payment.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"payment-mode.d.ts","sourceRoot":"","sources":["../../../src/tools/chain/payment-mode.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAoB9C,eAAO,MAAM,IAAI,EAAE,OA2ClB,CAAC"}
1
+ {"version":3,"file":"payment-mode.d.ts","sourceRoot":"","sources":["../../../src/tools/chain/payment-mode.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAoC9C,eAAO,MAAM,IAAI,EAAE,OAuElB,CAAC"}
@@ -1,54 +1,91 @@
1
1
  /**
2
- * 1s_payment_mode — view or switch the x402 payment scheme for this session.
2
+ * 1s_payment_mode — view or switch the payment rail + mode for this session.
3
+ *
4
+ * Two rails, each with two modes:
5
+ * - x402 (USDC on Base): x402-exact | x402-batch
6
+ * - MPP (Tempo USDC.e / pathUSD): mpp-charge | mpp-session
3
7
  */
4
8
  import { z } from 'zod';
5
- import { getPaymentModeInfo, setPaymentMode } from '../../x402.js';
9
+ import { getPaymentModeInfo, setPaymentMode } from '../../payment.js';
6
10
  function describe(mode, address) {
7
11
  const wallet = address ? ` Paying wallet: ${address}.` : '';
8
- if (mode === 'batch') {
9
- return (`Payment mode: batch (payment channel).${wallet} ` +
10
- 'The first paid call opens a channel with one on-chain deposit (price × deposit multiplier); ' +
11
- 'subsequent calls are signed off-chain as cumulative vouchers and settled together with a single claim. ' +
12
- 'Best for a burst of calls. Switching back to exact leaves any unspent channel balance locked until the on-chain withdraw delay (~1 day on mainnet).');
12
+ switch (mode) {
13
+ case 'x402-batch':
14
+ return (`Payment mode: x402-batch (payment channel on Base).${wallet} ` +
15
+ 'The first paid call opens a channel with one on-chain USDC deposit (price × deposit multiplier); ' +
16
+ 'subsequent calls are signed off-chain as cumulative vouchers and settled with a single claim. ' +
17
+ 'Best for a burst of calls. Switching away leaves any unspent channel balance locked until the on-chain withdraw delay (~1 day on mainnet) — use 1s_refund to reclaim it sooner.');
18
+ case 'mpp-charge':
19
+ return (`Payment mode: mpp-charge (per-call on Tempo).${wallet} ` +
20
+ 'Each paid call signs and settles one Tempo payment (USDC.e or pathUSD, per the gateway challenge). ' +
21
+ 'Switch to mpp-session for a voucher channel that is cheaper across many calls.');
22
+ case 'mpp-session':
23
+ return (`Payment mode: mpp-session (voucher channel on Tempo).${wallet} ` +
24
+ 'The first paid call opens a TIP-1034 channel on-chain (capped by MPP_MAX_DEPOSIT); ' +
25
+ 'subsequent calls are signed off-chain as cumulative vouchers. ' +
26
+ 'The unspent deposit is settled and reclaimed automatically when the server shuts down cleanly; ' +
27
+ 'a hard kill leaves it locked until reclaimed on-chain later.');
28
+ default:
29
+ return (`Payment mode: x402-exact (per-call on Base).${wallet} ` +
30
+ 'Each paid call signs and settles one USDC payment on Base. ' +
31
+ 'Switch to x402-batch (Base channel) or mpp-charge / mpp-session (Tempo) for cheaper bursts.');
13
32
  }
14
- return (`Payment mode: exact (per-call).${wallet} ` +
15
- 'Each paid call signs and settles one USDC payment on Base. ' +
16
- 'Switch to batch with { "mode": "batch" } to open a payment channel — cheaper for many calls in a session.');
17
33
  }
18
34
  export const tool = {
19
35
  name: '1s_payment_mode',
20
- description: 'View or switch how this session pays for x402 calls. ' +
21
- 'Two schemes: "exact" (default) signs one USDC payment per call; ' +
22
- '"batch" opens a payment channel — one on-chain deposit funds many off-chain calls, settled with a single claim (cheaper for a burst of calls, but locks the deposit residual until an on-chain withdraw delay). ' +
23
- 'Both use the same wallet. Call with no arguments to see the current mode. ' +
24
- 'Only applies when paying via x402 (X402_PRIVATE_KEY set); with an API key, calls are covered by your plan.',
36
+ description: 'View or switch how this session pays for metered calls. ' +
37
+ 'Two rails, each with two modes: x402-exact (per-call USDC on Base, default), ' +
38
+ 'x402-batch (Base payment channel — one deposit funds many off-chain calls), ' +
39
+ 'mpp-charge (per-call on Tempo, USDC.e/pathUSD), and mpp-session (Tempo voucher channel). ' +
40
+ 'Channel modes are cheaper for a burst of calls but lock a deposit until the channel is closed/refunded. ' +
41
+ 'Each rail uses its own wallet (X402_PRIVATE_KEY on Base / MPP_PRIVATE_KEY on Tempo). ' +
42
+ 'Call with no arguments to see the current mode and which modes are available. ' +
43
+ 'Only applies when paying via a wallet; with an API key, calls are covered by your plan.',
25
44
  category: 'chain',
26
45
  schema: {
27
46
  mode: z
28
- .enum(['exact', 'batch'])
47
+ .enum(['x402-exact', 'x402-batch', 'mpp-charge', 'mpp-session'])
29
48
  .optional()
30
- .describe('Payment scheme to switch to. Omit to report the current mode without changing it.'),
49
+ .describe('Payment rail + mode to switch to. Omit to report the current mode without changing it.'),
31
50
  },
32
51
  handler: async (input) => {
33
52
  const requested = input.mode;
34
53
  const before = getPaymentModeInfo();
35
54
  if (!before.enabled) {
36
- return ('x402 payment is not active in this session, so there is no payment scheme to switch. ' +
37
- 'Payment mode (exact vs batch) only applies when paying per-call via x402 set X402_PRIVATE_KEY to a funded Base wallet. ' +
38
- 'With an API key (ONESOURCE_API_KEY), calls are covered by your plan and no x402 payment is made.');
55
+ return ('No payment wallet is active in this session, so there is no payment mode to switch. ' +
56
+ 'Set X402_PRIVATE_KEY (a funded Base wallet) to pay via x402, or MPP_PRIVATE_KEY (a funded Tempo wallet) to pay via MPP. ' +
57
+ 'With an API key (ONESOURCE_API_KEY), calls are covered by your plan and no wallet payment is made.');
39
58
  }
40
59
  if (requested) {
41
- const applied = setPaymentMode(requested);
42
- if (requested === 'batch' && !before.batchAvailable) {
43
- return (`Batch mode is unavailable in this session — the channel scheme failed to initialise — so the mode stays "${applied}". ` +
44
- 'Check X402_RPC_URL, then restart the server.');
60
+ // Rail not enabled (its wallet key isn't set).
61
+ const railEnabled = requested.startsWith('x402-') ? before.x402.enabled : before.mpp.enabled;
62
+ if (!railEnabled) {
63
+ const envVar = requested.startsWith('x402-') ? 'X402_PRIVATE_KEY (funded Base wallet)' : 'MPP_PRIVATE_KEY (funded Tempo wallet)';
64
+ return (`Cannot switch to ${requested} — that rail is not active in this session. Set ${envVar} and restart. ` +
65
+ `Available modes right now: ${before.availableModes.join(', ')}.`);
45
66
  }
46
- if (applied === requested) {
47
- return `Switched to ${applied} mode. ${describe(applied, before.address)}`;
67
+ const applied = setPaymentMode(requested);
68
+ // Sub-mode unavailable (channel scheme failed to initialise).
69
+ if (applied !== requested) {
70
+ if (requested === 'x402-batch' && !before.x402.batchAvailable) {
71
+ return (`x402-batch is unavailable in this session — the channel scheme failed to initialise — so the mode stays "${applied}". ` +
72
+ 'Check X402_RPC_URL, then restart the server.');
73
+ }
74
+ if (requested === 'mpp-session' && !before.mpp.sessionAvailable) {
75
+ return (`mpp-session is unavailable in this session — the Tempo channel failed to initialise — so the mode stays "${applied}". ` +
76
+ 'Check MPP_RPC_URL, then restart the server.');
77
+ }
78
+ return `Could not switch to ${requested}; mode stays "${applied}". Available modes: ${before.availableModes.join(', ')}.`;
48
79
  }
80
+ const address = applied.startsWith('x402-') ? before.x402.address : before.mpp.address;
81
+ return `Switched to ${applied}. ${describe(applied, address)}`;
49
82
  }
50
83
  const info = getPaymentModeInfo();
51
- return describe(info.mode, info.address);
84
+ const address = info.mode.startsWith('x402-') ? info.x402.address : info.mpp.address;
85
+ return (`${describe(info.mode, address)} ` +
86
+ `Available modes: ${info.availableModes.join(', ')}.` +
87
+ (info.x402.enabled ? ` x402 wallet: ${info.x402.address}.` : '') +
88
+ (info.mpp.enabled ? ` MPP wallet: ${info.mpp.address}.` : ''));
52
89
  },
53
90
  };
54
91
  //# sourceMappingURL=payment-mode.js.map