mppx 0.8.19 → 0.9.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/CHANGELOG.md +16 -0
- package/README.md +0 -6
- package/dist/Challenge.d.ts +7 -0
- package/dist/Challenge.js +32 -6
- package/dist/Constants.d.ts +1 -0
- package/dist/Constants.js +1 -0
- package/dist/Credential.d.ts +11 -5
- package/dist/Credential.js +8 -8
- package/dist/Html.js +1 -1
- package/dist/cli/THIRD-PARTY-LICENSES.txt +1 -1
- package/dist/cli/cli.d.ts +2 -2
- package/dist/cli/cli.js +134 -134
- package/dist/cli/plugins/index.js +13 -13
- package/dist/cli/sessions/Manager.js +4 -6
- package/dist/cli/sessions/commands.d.ts +1 -1
- package/dist/cli/sessions/store.js +13 -19
- package/dist/cli/validate/index.d.ts +2 -2
- package/dist/client/Mppx.d.ts +39 -2
- package/dist/client/Mppx.js +102 -46
- package/dist/client/Transport.js +1 -1
- package/dist/client/internal/protocols/Mpp.d.ts +1 -1
- package/dist/client/internal/protocols/Mpp.js +5 -3
- package/dist/client/internal/protocols/Protocol.d.ts +3 -1
- package/dist/client/internal/protocols/Shared.js +5 -1
- package/dist/integrations/x402/Evm.d.ts +29 -0
- package/dist/integrations/x402/Evm.js +150 -0
- package/dist/integrations/x402/Negotiator.d.ts +36 -0
- package/dist/integrations/x402/Negotiator.js +165 -0
- package/dist/mcp/internal/Credential.d.ts +9 -0
- package/dist/mcp/internal/Credential.js +16 -0
- package/dist/mcp/server/Transport.js +2 -4
- package/dist/middlewares/express.js +5 -12
- package/dist/middlewares/internal/express.d.ts +8 -0
- package/dist/middlewares/internal/express.js +24 -0
- package/dist/middlewares/internal/node.d.ts +10 -0
- package/dist/middlewares/internal/node.js +34 -0
- package/dist/proxy/Proxy.js +15 -9
- package/dist/server/Mppx.d.ts +2 -0
- package/dist/server/Mppx.js +17 -14
- package/dist/server/Transport.d.ts +8 -2
- package/dist/server/Transport.js +6 -3
- package/dist/server/internal/SecretKey.d.ts +3 -0
- package/dist/server/internal/SecretKey.js +9 -0
- package/dist/server/internal/html/serviceWorker.client.d.ts +1 -1
- package/dist/server/internal/html/serviceWorker.client.js +2 -2
- package/dist/server/internal/html/serviceWorker.gen.d.ts +1 -1
- package/dist/server/internal/html/serviceWorker.gen.js +1 -1
- package/dist/stripe/server/internal/html.gen.d.ts +1 -1
- package/dist/stripe/server/internal/html.gen.js +1 -1
- package/dist/tempo/Methods.d.ts +0 -10
- package/dist/tempo/Methods.js +3 -12
- package/dist/tempo/client/Charge.d.ts +0 -3
- package/dist/tempo/client/Charge.js +3 -13
- package/dist/tempo/client/Methods.d.ts +0 -10
- package/dist/tempo/internal/account.d.ts +15 -6
- package/dist/tempo/internal/account.js +17 -26
- package/dist/tempo/internal/defaults.d.ts +0 -11
- package/dist/tempo/internal/defaults.js +0 -11
- package/dist/tempo/internal/fee-payer.d.ts +21 -3
- package/dist/tempo/internal/fee-payer.js +10 -19
- package/dist/tempo/internal/remote-fee-payer.d.ts +12 -0
- package/dist/tempo/internal/remote-fee-payer.js +17 -0
- package/dist/tempo/legacy/client/Session.d.ts +0 -7
- package/dist/tempo/server/Charge.d.ts +0 -3
- package/dist/tempo/server/Charge.js +26 -68
- package/dist/tempo/server/Methods.d.ts +4 -18
- package/dist/tempo/server/Methods.js +4 -8
- package/dist/tempo/server/internal/html.gen.d.ts +1 -1
- package/dist/tempo/server/internal/html.gen.js +1 -1
- package/dist/tempo/session/client/ChannelOps.d.ts +0 -14
- package/dist/tempo/session/client/ChannelOps.js +0 -22
- package/dist/tempo/session/client/ChannelStore.d.ts +5 -0
- package/dist/tempo/session/client/ChannelStore.js +2 -2
- package/dist/tempo/session/client/CredentialState.d.ts +2 -12
- package/dist/tempo/session/client/CredentialState.js +75 -73
- package/dist/tempo/session/client/Session.d.ts +2 -9
- package/dist/tempo/session/client/Session.js +71 -176
- package/dist/tempo/session/client/SessionManager.js +9 -28
- package/dist/tempo/session/precompile/Chain.d.ts +0 -4
- package/dist/tempo/session/precompile/Chain.js +1 -29
- package/dist/tempo/session/precompile/Protocol.d.ts +0 -13
- package/dist/tempo/session/precompile/Voucher.d.ts +1 -3
- package/dist/tempo/session/precompile/Voucher.js +12 -6
- package/dist/tempo/session/server/ChannelStore.d.ts +0 -6
- package/dist/tempo/session/server/ChannelStore.js +4 -11
- package/dist/tempo/session/server/CredentialVerification.d.ts +7 -9
- package/dist/tempo/session/server/CredentialVerification.js +118 -184
- package/dist/tempo/session/server/RequestState.d.ts +0 -17
- package/dist/tempo/session/server/RequestState.js +15 -59
- package/dist/tempo/session/server/Session.d.ts +0 -9
- package/dist/tempo/session/server/Session.js +8 -37
- package/dist/tempo/session/server/Settlement.d.ts +0 -7
- package/dist/tempo/session/server/Settlement.js +16 -50
- package/dist/viem/Client.d.ts +7 -2
- package/dist/viem/Client.js +17 -5
- package/dist/x402/Types.d.ts +2 -0
- package/dist/x402/Types.js +2 -0
- package/dist/x402/mcp.d.ts +20 -0
- package/dist/x402/mcp.js +153 -0
- package/dist/x402/middlewares/express.d.ts +23 -0
- package/dist/x402/middlewares/express.js +49 -0
- package/dist/x402/middlewares/hono.d.ts +13 -0
- package/dist/x402/middlewares/hono.js +36 -0
- package/dist/x402/middlewares/next.d.ts +17 -0
- package/dist/x402/middlewares/next.js +58 -0
- package/package.json +41 -1
- package/dist/tempo/internal/machine-token-charge.d.ts +0 -51
- package/dist/tempo/internal/machine-token-charge.js +0 -113
- package/dist/tempo/internal/machine-token-session.d.ts +0 -88
- package/dist/tempo/internal/machine-token-session.js +0 -173
- package/dist/tempo/internal/signature-envelope.d.ts +0 -14
- package/dist/tempo/internal/signature-envelope.js +0 -28
|
@@ -3,10 +3,9 @@ import * as Constants from '../../../Constants.js';
|
|
|
3
3
|
import { VerificationFailedError } from '../../../Errors.js';
|
|
4
4
|
import * as Methods from '../../Methods.js';
|
|
5
5
|
import { captureRequestBodyProbe, isSessionContentRequest, } from '../../server/internal/request-body.js';
|
|
6
|
-
import { tip20ChannelEscrow
|
|
7
|
-
import * as Voucher from '../precompile/Voucher.js';
|
|
6
|
+
import { tip20ChannelEscrow } from '../precompile/Protocol.js';
|
|
8
7
|
import * as ChannelStore from './ChannelStore.js';
|
|
9
|
-
import { requireSessionCredentialAction
|
|
8
|
+
import { requireSessionCredentialAction } from './CredentialVerification.js';
|
|
10
9
|
import { resolveCredentialFeePayer, resolveRequestFeePayer, } from './Settlement.js';
|
|
11
10
|
/** Normalizes a session channel ID hint when one is present. */
|
|
12
11
|
export function normalizeSessionChannelId(value) {
|
|
@@ -30,27 +29,6 @@ function normalizeResolvedSessionChannelId(value) {
|
|
|
30
29
|
return undefined;
|
|
31
30
|
return ChannelStore.normalizeChannelId(value);
|
|
32
31
|
}
|
|
33
|
-
/** Returns a close credential's channel once its voucher signature verifies. */
|
|
34
|
-
async function verifiedCloseCredentialChannel(credential, store) {
|
|
35
|
-
try {
|
|
36
|
-
const payload = requireSessionCredentialPayload(credential?.payload);
|
|
37
|
-
if (payload.action !== 'close')
|
|
38
|
-
return undefined;
|
|
39
|
-
const channelId = payload.channelId;
|
|
40
|
-
const channel = await store.getChannel(channelId);
|
|
41
|
-
if (!channel || !ChannelStore.isPrecompileState(channel))
|
|
42
|
-
return undefined;
|
|
43
|
-
const verified = Voucher.verifyVoucher(channel.escrowContract, channel.chainId, {
|
|
44
|
-
channelId,
|
|
45
|
-
cumulativeAmount: uint96(BigInt(payload.cumulativeAmount)),
|
|
46
|
-
signature: payload.signature,
|
|
47
|
-
}, channel.authorizedSigner);
|
|
48
|
-
return verified ? { channelId, channel } : undefined;
|
|
49
|
-
}
|
|
50
|
-
catch {
|
|
51
|
-
return undefined;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
32
|
/** Resolves the channel ID used to build server-side session bootstrap hints. */
|
|
55
33
|
export async function resolveSessionChannelId(parameters) {
|
|
56
34
|
const { capturedRequest, credential, request, resolveChannelId, source, store } = parameters;
|
|
@@ -69,10 +47,10 @@ export async function resolveSessionChannelId(parameters) {
|
|
|
69
47
|
}
|
|
70
48
|
/** Builds server bootstrap hints for a reusable precompile session channel. */
|
|
71
49
|
export async function resolveSessionSnapshot(parameters) {
|
|
72
|
-
const { amount, channelId, expected,
|
|
50
|
+
const { amount, channelId, expected, store } = parameters;
|
|
73
51
|
if (!channelId)
|
|
74
52
|
return undefined;
|
|
75
|
-
const channel =
|
|
53
|
+
const channel = await store.getChannel(ChannelStore.normalizeChannelId(channelId));
|
|
76
54
|
if (!channel || !ChannelStore.isPrecompileState(channel))
|
|
77
55
|
return undefined;
|
|
78
56
|
if (channel.finalized)
|
|
@@ -83,18 +61,8 @@ export async function resolveSessionSnapshot(parameters) {
|
|
|
83
61
|
return undefined;
|
|
84
62
|
if (channel.highestVoucher.cumulativeAmount !== channel.highestVoucherAmount)
|
|
85
63
|
return undefined;
|
|
86
|
-
if (expected && !matchesSnapshotPaymentFields(channel, expected))
|
|
87
|
-
|
|
88
|
-
// transient RPC error during the route check) must omit the hint rather
|
|
89
|
-
// than fail challenge issuance or bootstrap preflight.
|
|
90
|
-
let matched = false;
|
|
91
|
-
try {
|
|
92
|
-
matched = (await matchPaymentFields?.(channel, expected)) ?? false;
|
|
93
|
-
}
|
|
94
|
-
catch { }
|
|
95
|
-
if (!matched)
|
|
96
|
-
return undefined;
|
|
97
|
-
}
|
|
64
|
+
if (expected && !matchesSnapshotPaymentFields(channel, expected))
|
|
65
|
+
return undefined;
|
|
98
66
|
const requiredCumulative = channel.spent + amount;
|
|
99
67
|
return {
|
|
100
68
|
acceptedCumulative: channel.highestVoucherAmount.toString(),
|
|
@@ -149,7 +117,6 @@ function isCanonicalSessionMethodDetails(value) {
|
|
|
149
117
|
(value.feePayer === undefined || typeof value.feePayer === 'boolean') &&
|
|
150
118
|
(value.feeToken === undefined ||
|
|
151
119
|
(typeof value.feeToken === 'string' && isAddress(value.feeToken, { strict: false }))) &&
|
|
152
|
-
(value.machineTokenEnabled === undefined || typeof value.machineTokenEnabled === 'boolean') &&
|
|
153
120
|
(value.minVoucherDelta === undefined || typeof value.minVoucherDelta === 'string') &&
|
|
154
121
|
(value.operator === undefined ||
|
|
155
122
|
(typeof value.operator === 'string' && isAddress(value.operator, { strict: false }))) &&
|
|
@@ -191,7 +158,7 @@ export async function resolveRequestChainId(parameters) {
|
|
|
191
158
|
}
|
|
192
159
|
/** Resolves request-time TIP-1034 details and server bootstrap hints for a challenge. */
|
|
193
160
|
export async function resolveSessionPaymentRequest(parameters) {
|
|
194
|
-
const { capturedRequest, credential, decimals, defaultFeePayer, getClient,
|
|
161
|
+
const { capturedRequest, credential, decimals, defaultFeePayer, getClient, parameterChainId, parameterEscrowContract, parameterFeePayer, request, resolveChannelId, source, store, } = parameters;
|
|
195
162
|
const chainId = await resolveRequestChainId({
|
|
196
163
|
getClient,
|
|
197
164
|
parameterChainId,
|
|
@@ -205,24 +172,16 @@ export async function resolveSessionPaymentRequest(parameters) {
|
|
|
205
172
|
const escrowContract = resolveRequestEscrowContract(request.escrowContract, parameterEscrowContract);
|
|
206
173
|
const operator = resolveRequestOperator(request.operator);
|
|
207
174
|
const requestAmount = parseUnits(request.amount, decimals);
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
capturedRequest,
|
|
217
|
-
credential,
|
|
218
|
-
request,
|
|
219
|
-
resolveChannelId,
|
|
220
|
-
source,
|
|
221
|
-
store,
|
|
222
|
-
}));
|
|
175
|
+
const channelId = await resolveSessionChannelId({
|
|
176
|
+
capturedRequest,
|
|
177
|
+
credential,
|
|
178
|
+
request,
|
|
179
|
+
resolveChannelId,
|
|
180
|
+
source,
|
|
181
|
+
store,
|
|
182
|
+
});
|
|
223
183
|
const sessionSnapshot = await resolveSessionSnapshot({
|
|
224
184
|
amount: capturedRequest && !isSessionContentRequest(capturedRequest) ? 0n : requestAmount,
|
|
225
|
-
channel: verifiedClose?.channel,
|
|
226
185
|
channelId,
|
|
227
186
|
expected: {
|
|
228
187
|
chainId,
|
|
@@ -230,9 +189,6 @@ export async function resolveSessionPaymentRequest(parameters) {
|
|
|
230
189
|
escrowContract,
|
|
231
190
|
recipient: readChallengeAddress(request.recipient, 'recipient'),
|
|
232
191
|
},
|
|
233
|
-
matchPaymentFields: matchSnapshotPaymentFields && (verifiedClose || request.machineTokenEnabled)
|
|
234
|
-
? (channel, expected) => matchSnapshotPaymentFields(channel, expected, verifiedClose ? { action: 'close' } : undefined)
|
|
235
|
-
: undefined,
|
|
236
192
|
store,
|
|
237
193
|
});
|
|
238
194
|
const { operator: _operator, ...requestWithoutOperator } = request;
|
|
@@ -36,7 +36,6 @@ export declare function session<const parameters extends session.Parameters>(p?:
|
|
|
36
36
|
credential: {
|
|
37
37
|
payload: import("zod/mini").ZodMiniDiscriminatedUnion<[import("zod/mini").ZodMiniObject<{
|
|
38
38
|
action: import("zod/mini").ZodMiniLiteral<"open">;
|
|
39
|
-
authorizationSignature: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
40
39
|
authorizedSigner: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
41
40
|
channelId: import("zod/mini").ZodMiniString<string>;
|
|
42
41
|
cumulativeAmount: import("zod/mini").ZodMiniString<string>;
|
|
@@ -53,18 +52,15 @@ export declare function session<const parameters extends session.Parameters>(p?:
|
|
|
53
52
|
type: import("zod/mini").ZodMiniLiteral<"transaction">;
|
|
54
53
|
}, import("zod/v4/core").$strip>, import("zod/mini").ZodMiniObject<{
|
|
55
54
|
action: import("zod/mini").ZodMiniLiteral<"voucher">;
|
|
56
|
-
authorizationSignature: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
57
55
|
channelId: import("zod/mini").ZodMiniString<string>;
|
|
58
56
|
cumulativeAmount: import("zod/mini").ZodMiniString<string>;
|
|
59
57
|
descriptor: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniCustom<import("../precompile/Protocol.js").ChannelDescriptor, import("../precompile/Protocol.js").ChannelDescriptor>>;
|
|
60
58
|
signature: import("zod/mini").ZodMiniString<string>;
|
|
61
59
|
}, import("zod/v4/core").$strip>, import("zod/mini").ZodMiniObject<{
|
|
62
60
|
action: import("zod/mini").ZodMiniLiteral<"close">;
|
|
63
|
-
authorizationSignature: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
64
61
|
channelId: import("zod/mini").ZodMiniString<string>;
|
|
65
62
|
cumulativeAmount: import("zod/mini").ZodMiniString<string>;
|
|
66
63
|
descriptor: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniCustom<import("../precompile/Protocol.js").ChannelDescriptor, import("../precompile/Protocol.js").ChannelDescriptor>>;
|
|
67
|
-
refundSignature: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
68
64
|
signature: import("zod/mini").ZodMiniString<string>;
|
|
69
65
|
}, import("zod/v4/core").$strip>], "action">;
|
|
70
66
|
};
|
|
@@ -77,7 +73,6 @@ export declare function session<const parameters extends session.Parameters>(p?:
|
|
|
77
73
|
escrowContract: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
78
74
|
feePayer: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniPipe<import("zod/mini").ZodMiniUnion<readonly [import("zod/mini").ZodMiniBoolean<boolean>, import("zod/mini").ZodMiniCustom<import("viem").Account, import("viem").Account>]>, import("zod/mini").ZodMiniTransform<boolean, boolean | import("viem").Account>>>;
|
|
79
75
|
feeToken: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
80
|
-
machineTokenEnabled: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniBoolean<boolean>>;
|
|
81
76
|
minVoucherDelta: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
82
77
|
operator: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
83
78
|
recipient: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
@@ -101,7 +96,6 @@ export declare function session<const parameters extends session.Parameters>(p?:
|
|
|
101
96
|
chainId?: number | undefined;
|
|
102
97
|
feePayer?: boolean | undefined;
|
|
103
98
|
feeToken?: string | undefined;
|
|
104
|
-
machineTokenEnabled?: boolean | undefined;
|
|
105
99
|
operator?: string | undefined;
|
|
106
100
|
sessionProtocol?: "v1" | "v2" | undefined;
|
|
107
101
|
sessionSnapshot?: import("../Snapshot.js").SessionSnapshot | undefined;
|
|
@@ -115,7 +109,6 @@ export declare function session<const parameters extends session.Parameters>(p?:
|
|
|
115
109
|
escrowContract?: string | undefined;
|
|
116
110
|
feePayer?: boolean | undefined;
|
|
117
111
|
feeToken?: string | undefined;
|
|
118
|
-
machineTokenEnabled?: boolean | undefined;
|
|
119
112
|
minVoucherDelta?: string | undefined;
|
|
120
113
|
operator?: string | undefined;
|
|
121
114
|
recipient?: string | undefined;
|
|
@@ -185,8 +178,6 @@ export declare namespace session {
|
|
|
185
178
|
settlementSchedule?: SettlementSchedule | undefined;
|
|
186
179
|
/** Optional fee token for management and server-driven settle/close transactions. */
|
|
187
180
|
feeToken?: Address | undefined;
|
|
188
|
-
/** Enables first-party machine-token funding when the configured deployment is available. */
|
|
189
|
-
machineTokenEnabled?: boolean | undefined;
|
|
190
181
|
} & Account.resolve.Parameters & Client.getResolver.Parameters & Defaults & Method.ComposableHooks<typeof Methods.session>;
|
|
191
182
|
/** Defaults derived from `session()` parameters for handler type inference. */
|
|
192
183
|
type DeriveDefaults<parameters extends Parameters> = types.DeriveDefaults<parameters, Defaults, {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* and one-shot settlement. Each incoming request carries a session credential
|
|
6
6
|
* with a cumulative voucher that the server validates and records.
|
|
7
7
|
*/
|
|
8
|
-
import { isAddress
|
|
8
|
+
import { isAddress } from 'viem';
|
|
9
9
|
import { tempo as tempo_chain } from 'viem/chains';
|
|
10
10
|
import * as Challenge from '../../../Challenge.js';
|
|
11
11
|
import * as Constants from '../../../Constants.js';
|
|
@@ -16,7 +16,6 @@ import * as Store from '../../../Store.js';
|
|
|
16
16
|
import * as Client from '../../../viem/Client.js';
|
|
17
17
|
import * as Account from '../../internal/account.js';
|
|
18
18
|
import * as defaults from '../../internal/defaults.js';
|
|
19
|
-
import * as MachineTokenSession from '../../internal/machine-token-session.js';
|
|
20
19
|
import * as Methods from '../../Methods.js';
|
|
21
20
|
import * as ChargeServer from '../../server/Charge.js';
|
|
22
21
|
import * as Transport from '../../server/internal/transport.js';
|
|
@@ -179,9 +178,6 @@ async function handleBootstrapPreflight(parameters) {
|
|
|
179
178
|
escrowContract: resolveBootstrapEscrowContract(parameters.paymentRequest, parameters.parameterEscrowContract),
|
|
180
179
|
recipient: readBootstrapAddress(request.recipient, 'recipient'),
|
|
181
180
|
},
|
|
182
|
-
matchPaymentFields: parameters.paymentRequest.machineTokenEnabled
|
|
183
|
-
? parameters.matchSnapshotPaymentFields
|
|
184
|
-
: undefined,
|
|
185
181
|
store: parameters.store,
|
|
186
182
|
});
|
|
187
183
|
const headers = new Headers({ 'Cache-Control': 'no-store' });
|
|
@@ -194,33 +190,19 @@ async function handleBootstrapPreflight(parameters) {
|
|
|
194
190
|
/** Creates a server-side TIP20EscrowChannel precompile session payment method. */
|
|
195
191
|
export function session(p) {
|
|
196
192
|
const parameters = p;
|
|
197
|
-
const { amount, channelStateTtl = 5_000, currency = defaults.resolveCurrency(parameters), decimals = defaults.decimals,
|
|
193
|
+
const { amount, channelStateTtl = 5_000, currency = defaults.resolveCurrency(parameters), decimals = defaults.decimals, operator, store: rawStore = Store.memory(), suggestedDeposit, unitType, } = parameters;
|
|
198
194
|
const settlementSchedule = resolveSettlementSchedule(parameters.settlementSchedule, decimals);
|
|
199
195
|
const onSessionSettlement = parameters.onSessionSettlement;
|
|
200
196
|
const store = ChannelStore.fromStore(rawStore);
|
|
201
197
|
const lastOnChainVerified = new Map();
|
|
202
|
-
const { account, feePayer,
|
|
203
|
-
const configuredFeePayer = feePayer ??
|
|
204
|
-
const settlementFeePayer = feePayer ?? (feePayerUrl ? true : undefined);
|
|
198
|
+
const { account, feePayer, remoteFeePayer, recipient } = Account.resolve(parameters);
|
|
199
|
+
const configuredFeePayer = feePayer ?? (remoteFeePayer || parameters.feePayer === true ? true : undefined);
|
|
205
200
|
const getClient = Client.getResolver({
|
|
206
201
|
chain: tempo_chain,
|
|
207
|
-
|
|
202
|
+
remoteFeePayer,
|
|
208
203
|
getClient: parameters.getClient,
|
|
209
204
|
rpcUrl: defaults.rpcUrl,
|
|
210
205
|
});
|
|
211
|
-
const matchSnapshotPaymentFields = async (channel, expected, options) => {
|
|
212
|
-
if (channel.chainId !== expected.chainId ||
|
|
213
|
-
!isAddressEqual(channel.escrowContract, expected.escrowContract) ||
|
|
214
|
-
!isAddressEqual(expected.escrowContract, tip20ChannelEscrow))
|
|
215
|
-
return false;
|
|
216
|
-
return !!(await MachineTokenSession.matchRoute(await getClient({ chainId: expected.chainId }), {
|
|
217
|
-
active: options?.action !== 'close',
|
|
218
|
-
chainId: expected.chainId,
|
|
219
|
-
descriptor: channel.descriptor,
|
|
220
|
-
merchant: expected.recipient,
|
|
221
|
-
targetToken: expected.currency,
|
|
222
|
-
}));
|
|
223
|
-
};
|
|
224
206
|
const settleScheduled = async (channel) => {
|
|
225
207
|
if (!isSettlementDue(channel, settlementSchedule))
|
|
226
208
|
return undefined;
|
|
@@ -228,7 +210,7 @@ export function session(p) {
|
|
|
228
210
|
account,
|
|
229
211
|
channel,
|
|
230
212
|
client: await getClient({ chainId: channel.chainId }),
|
|
231
|
-
...(
|
|
213
|
+
...(configuredFeePayer ? { feePayer: configuredFeePayer } : {}),
|
|
232
214
|
feePayerPolicy: parameters.feePayerPolicy,
|
|
233
215
|
feeToken: parameters.feeToken,
|
|
234
216
|
onSessionSettlement,
|
|
@@ -350,7 +332,6 @@ export function session(p) {
|
|
|
350
332
|
amount,
|
|
351
333
|
currency,
|
|
352
334
|
decimals,
|
|
353
|
-
machineTokenEnabled,
|
|
354
335
|
operator,
|
|
355
336
|
recipient,
|
|
356
337
|
suggestedDeposit,
|
|
@@ -371,7 +352,6 @@ export function session(p) {
|
|
|
371
352
|
defaultRecipient: recipient,
|
|
372
353
|
expires,
|
|
373
354
|
getClient,
|
|
374
|
-
matchSnapshotPaymentFields,
|
|
375
355
|
parameterChainId: parameters.chainId,
|
|
376
356
|
parameterEscrowContract: parameters.escrowContract,
|
|
377
357
|
paymentRequest: options,
|
|
@@ -389,25 +369,16 @@ export function session(p) {
|
|
|
389
369
|
decimals,
|
|
390
370
|
defaultFeePayer: feePayer,
|
|
391
371
|
getClient,
|
|
392
|
-
matchSnapshotPaymentFields,
|
|
393
372
|
parameterChainId: parameters.chainId,
|
|
394
373
|
parameterEscrowContract: parameters.escrowContract,
|
|
395
|
-
parameterFeePayer:
|
|
374
|
+
parameterFeePayer: configuredFeePayer,
|
|
396
375
|
request,
|
|
397
376
|
resolveChannelId: parameters.resolveChannelId,
|
|
398
377
|
store,
|
|
399
378
|
});
|
|
400
|
-
// Only advertise the capability when this logical session can use a
|
|
401
|
-
// configured unified router on the canonical escrow.
|
|
402
|
-
const { machineTokenEnabled: requestedMachineTokenEnabled, ...requestWithoutMachineToken } = resolvedRequest;
|
|
403
|
-
const machineSessionSupported = MachineTokenSession.isSupported(resolvedRequest.chainId) &&
|
|
404
|
-
isAddressEqual(resolvedRequest.escrowContract, tip20ChannelEscrow);
|
|
405
379
|
return {
|
|
406
|
-
...
|
|
380
|
+
...resolvedRequest,
|
|
407
381
|
feeToken: parameters.feeToken,
|
|
408
|
-
...(requestedMachineTokenEnabled && machineSessionSupported
|
|
409
|
-
? { machineTokenEnabled: true }
|
|
410
|
-
: {}),
|
|
411
382
|
sessionProtocol: Constants.SessionProtocols.v2,
|
|
412
383
|
};
|
|
413
384
|
},
|
|
@@ -198,13 +198,6 @@ export declare function getClientAccount(client: {
|
|
|
198
198
|
}): viem_Account | undefined;
|
|
199
199
|
/** Validates that the transaction sender is the channel payee or nonzero operator. */
|
|
200
200
|
export declare function assertSettlementSender(parameters: SettlementSenderParameters): void;
|
|
201
|
-
/**
|
|
202
|
-
* Assembles transaction options for settle/close transactions. Machine
|
|
203
|
-
* channels pin PathUSD (or an explicit override); direct channels leave the
|
|
204
|
-
* fee token unset so balance-aware selection can pick a funded candidate.
|
|
205
|
-
* The rail comes from the caller so fee pinning always matches dispatch.
|
|
206
|
-
*/
|
|
207
|
-
export declare function resolveChannelTransactionOptions(channel: Pick<ChannelStore.StoredPrecompileChannel, 'chainId' | 'token'>, options: SettlementTransactionOptions | undefined, account: viem_Account | undefined, machineRouter: Address | undefined): Chain.ChannelTransactionOptions | undefined;
|
|
208
201
|
/** Applies automatic settlement when the server-owned schedule is due. */
|
|
209
202
|
export declare function maybeSettleScheduled(parameters: MaybeSettleScheduledParameters): Promise<Hex | undefined>;
|
|
210
203
|
/** Settles the highest accepted voucher for a precompile-backed session channel. */
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { isAddress, isAddressEqual, parseUnits, zeroAddress, } from 'viem';
|
|
2
2
|
import { BadRequestError, ChannelClosedError, ChannelNotFoundError, InsufficientBalanceError, VerificationFailedError, } from '../../../Errors.js';
|
|
3
|
-
import * as MachineTokenSession from '../../internal/machine-token-session.js';
|
|
4
3
|
import { isSessionContentRequest } from '../../server/internal/request-body.js';
|
|
5
4
|
import * as Chain from '../precompile/Chain.js';
|
|
6
5
|
import { readSettledReceiptFields } from '../precompile/Chain.js';
|
|
@@ -183,30 +182,6 @@ export function assertSettlementSender(parameters) {
|
|
|
183
182
|
' If using an access key, pass a Tempo access-key account whose address is the payee/operator wallet, not the raw delegated key address.',
|
|
184
183
|
});
|
|
185
184
|
}
|
|
186
|
-
/**
|
|
187
|
-
* Assembles transaction options for settle/close transactions. Machine
|
|
188
|
-
* channels pin PathUSD (or an explicit override); direct channels leave the
|
|
189
|
-
* fee token unset so balance-aware selection can pick a funded candidate.
|
|
190
|
-
* The rail comes from the caller so fee pinning always matches dispatch.
|
|
191
|
-
*/
|
|
192
|
-
export function resolveChannelTransactionOptions(channel, options, account, machineRouter) {
|
|
193
|
-
if (!account)
|
|
194
|
-
return undefined;
|
|
195
|
-
const feeToken = options?.feeToken ??
|
|
196
|
-
(machineRouter
|
|
197
|
-
? MachineTokenSession.resolveFeeToken({
|
|
198
|
-
chainId: channel.chainId,
|
|
199
|
-
paymentToken: channel.token,
|
|
200
|
-
})
|
|
201
|
-
: undefined);
|
|
202
|
-
return {
|
|
203
|
-
account,
|
|
204
|
-
...(options?.feePayer ? { feePayer: options.feePayer } : {}),
|
|
205
|
-
...(options?.feePayerPolicy ? { feePayerPolicy: options.feePayerPolicy } : {}),
|
|
206
|
-
...(feeToken ? { feeToken } : {}),
|
|
207
|
-
candidateFeeTokens: options?.candidateFeeTokens ?? [feeToken ?? channel.token],
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
185
|
/** Applies automatic settlement when the server-owned schedule is due. */
|
|
211
186
|
export async function maybeSettleScheduled(parameters) {
|
|
212
187
|
const { channel, schedule, store } = parameters;
|
|
@@ -237,32 +212,23 @@ export async function settle(store_, client, channelId_, options) {
|
|
|
237
212
|
throw new VerificationFailedError({ reason: 'no voucher to settle' });
|
|
238
213
|
const escrow = options?.escrowContract ?? channel.escrowContract;
|
|
239
214
|
const account = options?.account ?? getClientAccount(client);
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
channelId,
|
|
248
|
-
operator: channel.operator,
|
|
249
|
-
payee: channel.payee,
|
|
250
|
-
sender: account?.address,
|
|
251
|
-
});
|
|
215
|
+
assertSettlementSender({
|
|
216
|
+
operation: 'settle',
|
|
217
|
+
channelId,
|
|
218
|
+
operator: channel.operator,
|
|
219
|
+
payee: channel.payee,
|
|
220
|
+
sender: account?.address,
|
|
221
|
+
});
|
|
252
222
|
const amount = uint96(channel.highestVoucher.cumulativeAmount);
|
|
253
|
-
const
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
}
|
|
263
|
-
else {
|
|
264
|
-
txHash = await Chain.settleOnChain(client, channel.descriptor, amount, channel.highestVoucher.signature, escrow, transactionOptions);
|
|
265
|
-
}
|
|
223
|
+
const txHash = await Chain.settleOnChain(client, channel.descriptor, amount, channel.highestVoucher.signature, escrow, account
|
|
224
|
+
? {
|
|
225
|
+
account,
|
|
226
|
+
...(options?.feePayer ? { feePayer: options.feePayer } : {}),
|
|
227
|
+
...(options?.feePayerPolicy ? { feePayerPolicy: options.feePayerPolicy } : {}),
|
|
228
|
+
...(options?.feeToken ? { feeToken: options.feeToken } : {}),
|
|
229
|
+
candidateFeeTokens: options?.candidateFeeTokens ?? [channel.token],
|
|
230
|
+
}
|
|
231
|
+
: undefined);
|
|
266
232
|
const receipt = await Chain.waitForSuccessfulReceipt(client, txHash);
|
|
267
233
|
const settled = readSettledReceiptFields(Chain.getChannelEvent(receipt, 'Settled', channelId));
|
|
268
234
|
const { newSettled } = settled;
|
package/dist/viem/Client.d.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { type Chain, type Client } from 'viem';
|
|
2
2
|
import type { MaybePromise } from '../internal/types.js';
|
|
3
|
+
import * as RemoteFeePayer from '../tempo/internal/remote-fee-payer.js';
|
|
4
|
+
/** Creates an HTTP transport for a configured remote fee-payer service. */
|
|
5
|
+
export declare function remoteFeePayerTransport(config: RemoteFeePayer.Config, options?: {
|
|
6
|
+
retryCount?: number | undefined;
|
|
7
|
+
}): import("viem").HttpTransport<undefined, false>;
|
|
3
8
|
export declare function getResolver(parameters: getResolver.Parameters & {
|
|
4
9
|
/** Default chain to use if not provided. */
|
|
5
10
|
chain?: Chain | undefined;
|
|
6
|
-
/**
|
|
7
|
-
|
|
11
|
+
/** Remote fee-payer configuration. When set, the transport is wrapped with `withFeePayer`. */
|
|
12
|
+
remoteFeePayer?: RemoteFeePayer.Config | undefined;
|
|
8
13
|
/** RPC URLs keyed by chain ID. */
|
|
9
14
|
rpcUrl?: ({
|
|
10
15
|
[chainId: number]: string;
|
package/dist/viem/Client.js
CHANGED
|
@@ -1,28 +1,38 @@
|
|
|
1
1
|
import { createClient, createTransport, custom, http } from 'viem';
|
|
2
2
|
import { withFeePayer } from 'viem/tempo';
|
|
3
3
|
import { tempo as tempoMainnetChain, tempoModerato } from 'viem/tempo/chains';
|
|
4
|
+
import * as RemoteFeePayer from '../tempo/internal/remote-fee-payer.js';
|
|
4
5
|
const knownTempoChains = {
|
|
5
6
|
[tempoMainnetChain.id]: tempoMainnetChain,
|
|
6
7
|
[tempoModerato.id]: tempoModerato,
|
|
7
8
|
};
|
|
9
|
+
/** Creates an HTTP transport for a configured remote fee-payer service. */
|
|
10
|
+
export function remoteFeePayerTransport(config, options = {}) {
|
|
11
|
+
return http(config.url, {
|
|
12
|
+
fetchOptions: { headers: RemoteFeePayer.resolveHeaders(config) },
|
|
13
|
+
...options,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
8
16
|
export function getResolver(parameters) {
|
|
9
|
-
const { chain,
|
|
17
|
+
const { chain, getClient, remoteFeePayer, rpcUrl } = parameters;
|
|
10
18
|
if (getClient) {
|
|
11
19
|
// When a default chain with serializers is provided (e.g. Tempo chain config),
|
|
12
20
|
// ensure user-provided clients inherit those serializers. Without this, clients
|
|
13
21
|
// created without the Tempo chain config will use the default viem serializer,
|
|
14
22
|
// causing errors like "maxFeePerGas is not a valid Legacy Transaction attribute".
|
|
15
|
-
if (!chain?.serializers && !
|
|
23
|
+
if (!chain?.serializers && !remoteFeePayer)
|
|
16
24
|
return getClient;
|
|
17
25
|
return async (params) => {
|
|
18
26
|
const client = await getClient(params);
|
|
19
27
|
let resolvedClient = client;
|
|
20
28
|
// Wrap the client's transport with `withFeePayer` when a fee payer URL is provided.
|
|
21
|
-
if (
|
|
29
|
+
if (remoteFeePayer && client.transport.key !== 'feePayer') {
|
|
22
30
|
const request = client.request.bind(client);
|
|
23
31
|
// The supplied client already owns retries. Keep the relay middleware retry-free so
|
|
24
32
|
// failures are not retried once per nested transport layer.
|
|
25
|
-
const feePayerTransport = withFeePayer(custom({ request: (args) => request(args) }, { retryCount: 0 }),
|
|
33
|
+
const feePayerTransport = withFeePayer(custom({ request: (args) => request(args) }, { retryCount: 0 }), remoteFeePayerTransport(remoteFeePayer, {
|
|
34
|
+
retryCount: client.transport.retryCount,
|
|
35
|
+
}))({
|
|
26
36
|
account: client.account,
|
|
27
37
|
chain: client.chain,
|
|
28
38
|
pollingInterval: client.pollingInterval,
|
|
@@ -56,7 +66,9 @@ export function getResolver(parameters) {
|
|
|
56
66
|
const url = rpcUrl[resolvedChainId];
|
|
57
67
|
if (!url)
|
|
58
68
|
throw new Error(`No \`rpcUrl\` configured for \`chainId\` (${resolvedChainId}).`);
|
|
59
|
-
const transport =
|
|
69
|
+
const transport = remoteFeePayer
|
|
70
|
+
? withFeePayer(http(url), remoteFeePayerTransport(remoteFeePayer))
|
|
71
|
+
: http(url);
|
|
60
72
|
return createClient({
|
|
61
73
|
chain: (knownTempoChains[resolvedChainId] ?? { ...chain, id: resolvedChainId }),
|
|
62
74
|
transport,
|
package/dist/x402/Types.d.ts
CHANGED
|
@@ -26,6 +26,8 @@ export type EvmNetwork = `${typeof evmNetworkPrefix}${number}`;
|
|
|
26
26
|
export declare const paymentRequiredHeader = "PAYMENT-REQUIRED";
|
|
27
27
|
/** HTTP header carrying a base64-encoded x402 payment payload. */
|
|
28
28
|
export declare const paymentSignatureHeader = "PAYMENT-SIGNATURE";
|
|
29
|
+
/** Legacy HTTP header carrying an x402 v1 payment payload. */
|
|
30
|
+
export declare const legacyPaymentSignatureHeader = "X-PAYMENT";
|
|
29
31
|
/** HTTP header carrying a base64-encoded x402 settlement response. */
|
|
30
32
|
export declare const paymentResponseHeader = "PAYMENT-RESPONSE";
|
|
31
33
|
/** Describes the protected resource in x402 v2 payment-required responses. */
|
package/dist/x402/Types.js
CHANGED
|
@@ -14,6 +14,8 @@ export const syntheticChallengeIdPrefix = 'x402:';
|
|
|
14
14
|
export const paymentRequiredHeader = 'PAYMENT-REQUIRED';
|
|
15
15
|
/** HTTP header carrying a base64-encoded x402 payment payload. */
|
|
16
16
|
export const paymentSignatureHeader = 'PAYMENT-SIGNATURE';
|
|
17
|
+
/** Legacy HTTP header carrying an x402 v1 payment payload. */
|
|
18
|
+
export const legacyPaymentSignatureHeader = 'X-PAYMENT';
|
|
17
19
|
/** HTTP header carrying a base64-encoded x402 settlement response. */
|
|
18
20
|
export const paymentResponseHeader = 'PAYMENT-RESPONSE';
|
|
19
21
|
const nonEmptyString = z.string().check(z.minLength(1));
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { x402ResourceServer } from '@x402/core/server';
|
|
2
|
+
import { type MCPToolCallback, type PaymentWrappedHandler, type PaymentWrapperConfig } from '@x402/mcp';
|
|
3
|
+
import * as Negotiator from '../integrations/x402/Negotiator.js';
|
|
4
|
+
type ToolResource = NonNullable<PaymentWrapperConfig['resource']> & {
|
|
5
|
+
url: `mcp://tool/${string}`;
|
|
6
|
+
};
|
|
7
|
+
/** Configuration for {@link mpp}. A canonical MCP tool URL is required as its identity. */
|
|
8
|
+
export type Config = Omit<PaymentWrapperConfig, 'resource'> & Pick<Negotiator.Config, 'realm' | 'secretKey'> & {
|
|
9
|
+
resource: ToolResource;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Creates an MCP tool wrapper that accepts both MPP and x402 payment metadata.
|
|
13
|
+
*
|
|
14
|
+
* Existing x402 credentials and lifecycle hooks continue through `@x402/mcp`.
|
|
15
|
+
* MPP credentials reuse the same x402 requirements, verifier, and facilitator;
|
|
16
|
+
* x402-only hooks in `PaymentWrapperConfig.hooks` therefore run only on x402 calls.
|
|
17
|
+
*/
|
|
18
|
+
export declare function mpp(resourceServer: x402ResourceServer, config: Config): <arguments_ extends Record<string, unknown>>(handler: PaymentWrappedHandler<arguments_>) => MCPToolCallback<arguments_>;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=mcp.d.ts.map
|