@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/LICENSE +21 -21
- package/README.md +170 -155
- package/README.npm.md +170 -155
- package/README.repo.md +221 -201
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +13 -10
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +9 -7
- package/dist/client.js.map +1 -1
- package/dist/mpp.d.ts +40 -0
- package/dist/mpp.d.ts.map +1 -0
- package/dist/mpp.js +217 -0
- package/dist/mpp.js.map +1 -0
- package/dist/payment.d.ts +48 -0
- package/dist/payment.d.ts.map +1 -0
- package/dist/payment.js +166 -0
- package/dist/payment.js.map +1 -0
- package/dist/tools/chain/payment-mode.d.ts.map +1 -1
- package/dist/tools/chain/payment-mode.js +64 -27
- package/dist/tools/chain/payment-mode.js.map +1 -1
- package/dist/tools/chain/refund.d.ts.map +1 -1
- package/dist/tools/chain/refund.js +7 -5
- package/dist/tools/chain/refund.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +14 -3
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
|
package/dist/mpp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mpp.js","sourceRoot":"","sources":["../src/mpp.ts"],"names":[],"mappings":"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"}
|
|
@@ -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"}
|
package/dist/payment.js
ADDED
|
@@ -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":"
|
|
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
|
|
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 '../../
|
|
9
|
+
import { getPaymentModeInfo, setPaymentMode } from '../../payment.js';
|
|
6
10
|
function describe(mode, address) {
|
|
7
11
|
const wallet = address ? ` Paying wallet: ${address}.` : '';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
|
21
|
-
'Two
|
|
22
|
-
'
|
|
23
|
-
'
|
|
24
|
-
'
|
|
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
|
|
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 ('
|
|
37
|
-
'
|
|
38
|
-
'With an API key (ONESOURCE_API_KEY), calls are covered by your plan and no
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
47
|
-
|
|
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
|
-
|
|
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
|