mppx 0.8.19 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +0 -6
  3. package/dist/Challenge.d.ts +7 -0
  4. package/dist/Challenge.js +32 -6
  5. package/dist/Constants.d.ts +1 -0
  6. package/dist/Constants.js +1 -0
  7. package/dist/Credential.d.ts +11 -5
  8. package/dist/Credential.js +8 -8
  9. package/dist/Errors.d.ts +10 -0
  10. package/dist/Errors.js +12 -0
  11. package/dist/Html.js +1 -1
  12. package/dist/Mcp.d.ts +9 -1
  13. package/dist/Mcp.js +18 -0
  14. package/dist/Method.d.ts +7 -0
  15. package/dist/cli/THIRD-PARTY-LICENSES.txt +1 -1
  16. package/dist/cli/cli.d.ts +2 -2
  17. package/dist/cli/cli.js +134 -134
  18. package/dist/cli/plugins/index.js +13 -13
  19. package/dist/cli/sessions/Manager.js +4 -6
  20. package/dist/cli/sessions/commands.d.ts +1 -1
  21. package/dist/cli/sessions/store.js +13 -19
  22. package/dist/cli/validate/index.d.ts +2 -2
  23. package/dist/client/Mppx.d.ts +39 -2
  24. package/dist/client/Mppx.js +102 -46
  25. package/dist/client/Transport.js +1 -1
  26. package/dist/client/internal/protocols/Mcp.js +2 -1
  27. package/dist/client/internal/protocols/Mpp.d.ts +1 -1
  28. package/dist/client/internal/protocols/Mpp.js +5 -3
  29. package/dist/client/internal/protocols/Protocol.d.ts +3 -1
  30. package/dist/client/internal/protocols/Shared.js +5 -1
  31. package/dist/integrations/x402/Evm.d.ts +29 -0
  32. package/dist/integrations/x402/Evm.js +150 -0
  33. package/dist/integrations/x402/Negotiator.d.ts +36 -0
  34. package/dist/integrations/x402/Negotiator.js +165 -0
  35. package/dist/mcp/client/McpClient.js +22 -10
  36. package/dist/mcp/internal/Credential.d.ts +9 -0
  37. package/dist/mcp/internal/Credential.js +16 -0
  38. package/dist/mcp/server/Transport.d.ts +2 -2
  39. package/dist/mcp/server/Transport.js +11 -6
  40. package/dist/middlewares/express.js +5 -12
  41. package/dist/middlewares/internal/express.d.ts +8 -0
  42. package/dist/middlewares/internal/express.js +24 -0
  43. package/dist/middlewares/internal/node.d.ts +10 -0
  44. package/dist/middlewares/internal/node.js +34 -0
  45. package/dist/proxy/Proxy.js +15 -9
  46. package/dist/server/Mppx.d.ts +8 -0
  47. package/dist/server/Mppx.js +92 -20
  48. package/dist/server/Transport.d.ts +8 -2
  49. package/dist/server/Transport.js +14 -18
  50. package/dist/server/internal/SecretKey.d.ts +3 -0
  51. package/dist/server/internal/SecretKey.js +9 -0
  52. package/dist/server/internal/html/serviceWorker.client.d.ts +1 -1
  53. package/dist/server/internal/html/serviceWorker.client.js +2 -2
  54. package/dist/server/internal/html/serviceWorker.gen.d.ts +1 -1
  55. package/dist/server/internal/html/serviceWorker.gen.js +1 -1
  56. package/dist/stripe/Methods.d.ts +6 -0
  57. package/dist/stripe/Methods.js +3 -1
  58. package/dist/stripe/client/Charge.d.ts +6 -0
  59. package/dist/stripe/client/Methods.d.ts +6 -0
  60. package/dist/stripe/internal/payment-intent.d.ts +7 -0
  61. package/dist/stripe/internal/payment-intent.js +6 -0
  62. package/dist/stripe/server/Charge.d.ts +6 -0
  63. package/dist/stripe/server/Charge.js +8 -3
  64. package/dist/stripe/server/Methods.js +62 -7
  65. package/dist/stripe/server/internal/html.gen.d.ts +1 -1
  66. package/dist/stripe/server/internal/html.gen.js +1 -1
  67. package/dist/tempo/Methods.d.ts +0 -10
  68. package/dist/tempo/Methods.js +3 -12
  69. package/dist/tempo/Tokens.d.ts +13 -0
  70. package/dist/tempo/Tokens.js +13 -0
  71. package/dist/tempo/client/Charge.d.ts +1 -4
  72. package/dist/tempo/client/Charge.js +20 -13
  73. package/dist/tempo/client/Methods.d.ts +0 -10
  74. package/dist/tempo/index.d.ts +1 -0
  75. package/dist/tempo/index.js +1 -0
  76. package/dist/tempo/internal/account.d.ts +15 -6
  77. package/dist/tempo/internal/account.js +17 -26
  78. package/dist/tempo/internal/defaults.d.ts +0 -11
  79. package/dist/tempo/internal/defaults.js +0 -11
  80. package/dist/tempo/internal/fee-payer.d.ts +22 -4
  81. package/dist/tempo/internal/fee-payer.js +12 -31
  82. package/dist/tempo/internal/fee-token.d.ts +2 -0
  83. package/dist/tempo/internal/fee-token.js +7 -0
  84. package/dist/tempo/internal/remote-fee-payer.d.ts +12 -0
  85. package/dist/tempo/internal/remote-fee-payer.js +17 -0
  86. package/dist/tempo/legacy/client/Session.d.ts +0 -7
  87. package/dist/tempo/server/Charge.d.ts +0 -3
  88. package/dist/tempo/server/Charge.js +26 -68
  89. package/dist/tempo/server/Methods.d.ts +4 -18
  90. package/dist/tempo/server/Methods.js +4 -8
  91. package/dist/tempo/server/internal/html.gen.d.ts +1 -1
  92. package/dist/tempo/server/internal/html.gen.js +1 -1
  93. package/dist/tempo/session/client/ChannelOps.d.ts +0 -14
  94. package/dist/tempo/session/client/ChannelOps.js +0 -22
  95. package/dist/tempo/session/client/ChannelStore.d.ts +5 -0
  96. package/dist/tempo/session/client/ChannelStore.js +2 -2
  97. package/dist/tempo/session/client/CredentialState.d.ts +2 -12
  98. package/dist/tempo/session/client/CredentialState.js +75 -73
  99. package/dist/tempo/session/client/Session.d.ts +2 -9
  100. package/dist/tempo/session/client/Session.js +71 -176
  101. package/dist/tempo/session/client/SessionManager.js +7 -27
  102. package/dist/tempo/session/precompile/Chain.d.ts +0 -4
  103. package/dist/tempo/session/precompile/Chain.js +1 -29
  104. package/dist/tempo/session/precompile/Protocol.d.ts +0 -13
  105. package/dist/tempo/session/precompile/Voucher.d.ts +1 -3
  106. package/dist/tempo/session/precompile/Voucher.js +12 -6
  107. package/dist/tempo/session/server/ChannelStore.d.ts +0 -6
  108. package/dist/tempo/session/server/ChannelStore.js +4 -11
  109. package/dist/tempo/session/server/CredentialVerification.d.ts +7 -9
  110. package/dist/tempo/session/server/CredentialVerification.js +118 -184
  111. package/dist/tempo/session/server/RequestState.d.ts +0 -17
  112. package/dist/tempo/session/server/RequestState.js +15 -59
  113. package/dist/tempo/session/server/Session.d.ts +0 -9
  114. package/dist/tempo/session/server/Session.js +13 -39
  115. package/dist/tempo/session/server/Settlement.d.ts +0 -7
  116. package/dist/tempo/session/server/Settlement.js +16 -50
  117. package/dist/viem/Client.d.ts +7 -2
  118. package/dist/viem/Client.js +17 -5
  119. package/dist/x402/Types.d.ts +2 -0
  120. package/dist/x402/Types.js +2 -0
  121. package/dist/x402/mcp.d.ts +20 -0
  122. package/dist/x402/mcp.js +154 -0
  123. package/dist/x402/middlewares/express.d.ts +23 -0
  124. package/dist/x402/middlewares/express.js +49 -0
  125. package/dist/x402/middlewares/hono.d.ts +13 -0
  126. package/dist/x402/middlewares/hono.js +36 -0
  127. package/dist/x402/middlewares/next.d.ts +17 -0
  128. package/dist/x402/middlewares/next.js +58 -0
  129. package/package.json +41 -1
  130. package/dist/tempo/internal/machine-token-charge.d.ts +0 -51
  131. package/dist/tempo/internal/machine-token-charge.js +0 -113
  132. package/dist/tempo/internal/machine-token-session.d.ts +0 -88
  133. package/dist/tempo/internal/machine-token-session.js +0 -173
  134. package/dist/tempo/internal/signature-envelope.d.ts +0 -14
  135. 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, uint96, } from '../precompile/Protocol.js';
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, requireSessionCredentialPayload, } from './CredentialVerification.js';
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, matchPaymentFields, store } = parameters;
50
+ const { amount, channelId, expected, store } = parameters;
73
51
  if (!channelId)
74
52
  return undefined;
75
- const channel = parameters.channel ?? (await store.getChannel(ChannelStore.normalizeChannelId(channelId)));
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
- // The snapshot is an optional reuse hint: a failing matcher (for example a
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, matchSnapshotPaymentFields, parameterChainId, parameterEscrowContract, parameterFeePayer, request, resolveChannelId, source, store, } = parameters;
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
- // A close credential names the channel it settles; advertising that channel's
209
- // snapshot on the retry challenge lets clients without a configured
210
- // `resolveChannelId` learn the exact capture amount a machine-token close
211
- // voucher must match. Only trusted once the voucher signature verifies, and
212
- // matched with close semantics so retired routes stay closable.
213
- const verifiedClose = await verifiedCloseCredentialChannel(credential, store);
214
- const channelId = verifiedClose?.channelId ??
215
- (await resolveSessionChannelId({
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, isAddressEqual } from 'viem';
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';
@@ -130,10 +129,13 @@ async function verifyBootstrapCredential(parameters) {
130
129
  });
131
130
  Expires.assert(credential.challenge.expires, credential.challenge.id);
132
131
  assertBootstrapChallengeMatches(challenge, credential.challenge);
132
+ const payload = Methods.charge.schema.credential.payload.safeParse(credential.payload);
133
+ if (!payload.success)
134
+ throw new Errors.InvalidPayloadError();
133
135
  return charge.verify({
134
136
  credential: {
135
137
  ...credential,
136
- payload: Methods.charge.schema.credential.payload.parse(credential.payload),
138
+ payload: payload.data,
137
139
  },
138
140
  request: rawRequest,
139
141
  });
@@ -160,7 +162,7 @@ async function handleBootstrapPreflight(parameters) {
160
162
  });
161
163
  }
162
164
  catch (error) {
163
- return respondBootstrapChallenge(challenge, error instanceof Errors.PaymentError ? error : new Errors.VerificationFailedError());
165
+ return respondBootstrapChallenge(challenge, error instanceof Errors.PaymentError ? error : new Errors.InternalPaymentError());
164
166
  }
165
167
  const channelId = await resolveSessionChannelId({
166
168
  capturedRequest: parameters.capturedRequest,
@@ -179,9 +181,6 @@ async function handleBootstrapPreflight(parameters) {
179
181
  escrowContract: resolveBootstrapEscrowContract(parameters.paymentRequest, parameters.parameterEscrowContract),
180
182
  recipient: readBootstrapAddress(request.recipient, 'recipient'),
181
183
  },
182
- matchPaymentFields: parameters.paymentRequest.machineTokenEnabled
183
- ? parameters.matchSnapshotPaymentFields
184
- : undefined,
185
184
  store: parameters.store,
186
185
  });
187
186
  const headers = new Headers({ 'Cache-Control': 'no-store' });
@@ -194,33 +193,19 @@ async function handleBootstrapPreflight(parameters) {
194
193
  /** Creates a server-side TIP20EscrowChannel precompile session payment method. */
195
194
  export function session(p) {
196
195
  const parameters = p;
197
- const { amount, channelStateTtl = 5_000, currency = defaults.resolveCurrency(parameters), decimals = defaults.decimals, machineTokenEnabled, operator, store: rawStore = Store.memory(), suggestedDeposit, unitType, } = parameters;
196
+ const { amount, channelStateTtl = 5_000, currency = defaults.resolveCurrency(parameters), decimals = defaults.decimals, operator, store: rawStore = Store.memory(), suggestedDeposit, unitType, } = parameters;
198
197
  const settlementSchedule = resolveSettlementSchedule(parameters.settlementSchedule, decimals);
199
198
  const onSessionSettlement = parameters.onSessionSettlement;
200
199
  const store = ChannelStore.fromStore(rawStore);
201
200
  const lastOnChainVerified = new Map();
202
- const { account, feePayer, feePayerUrl, recipient } = Account.resolve(parameters);
203
- const configuredFeePayer = feePayer ?? feePayerUrl;
204
- const settlementFeePayer = feePayer ?? (feePayerUrl ? true : undefined);
201
+ const { account, feePayer, remoteFeePayer, recipient } = Account.resolve(parameters);
202
+ const configuredFeePayer = feePayer ?? (remoteFeePayer || parameters.feePayer === true ? true : undefined);
205
203
  const getClient = Client.getResolver({
206
204
  chain: tempo_chain,
207
- feePayerUrl,
205
+ remoteFeePayer,
208
206
  getClient: parameters.getClient,
209
207
  rpcUrl: defaults.rpcUrl,
210
208
  });
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
209
  const settleScheduled = async (channel) => {
225
210
  if (!isSettlementDue(channel, settlementSchedule))
226
211
  return undefined;
@@ -228,7 +213,7 @@ export function session(p) {
228
213
  account,
229
214
  channel,
230
215
  client: await getClient({ chainId: channel.chainId }),
231
- ...(settlementFeePayer ? { feePayer: settlementFeePayer } : {}),
216
+ ...(configuredFeePayer ? { feePayer: configuredFeePayer } : {}),
232
217
  feePayerPolicy: parameters.feePayerPolicy,
233
218
  feeToken: parameters.feeToken,
234
219
  onSessionSettlement,
@@ -350,7 +335,6 @@ export function session(p) {
350
335
  amount,
351
336
  currency,
352
337
  decimals,
353
- machineTokenEnabled,
354
338
  operator,
355
339
  recipient,
356
340
  suggestedDeposit,
@@ -371,7 +355,6 @@ export function session(p) {
371
355
  defaultRecipient: recipient,
372
356
  expires,
373
357
  getClient,
374
- matchSnapshotPaymentFields,
375
358
  parameterChainId: parameters.chainId,
376
359
  parameterEscrowContract: parameters.escrowContract,
377
360
  paymentRequest: options,
@@ -389,25 +372,16 @@ export function session(p) {
389
372
  decimals,
390
373
  defaultFeePayer: feePayer,
391
374
  getClient,
392
- matchSnapshotPaymentFields,
393
375
  parameterChainId: parameters.chainId,
394
376
  parameterEscrowContract: parameters.escrowContract,
395
- parameterFeePayer: parameters.feePayer,
377
+ parameterFeePayer: configuredFeePayer,
396
378
  request,
397
379
  resolveChannelId: parameters.resolveChannelId,
398
380
  store,
399
381
  });
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
382
  return {
406
- ...requestWithoutMachineToken,
383
+ ...resolvedRequest,
407
384
  feeToken: parameters.feeToken,
408
- ...(requestedMachineTokenEnabled && machineSessionSupported
409
- ? { machineTokenEnabled: true }
410
- : {}),
411
385
  sessionProtocol: Constants.SessionProtocols.v2,
412
386
  };
413
387
  },
@@ -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
- const machineRouter = MachineTokenSession.matchDeployment({
241
- chainId: channel.chainId,
242
- descriptor: channel.descriptor,
243
- })?.swap;
244
- if (!machineRouter || !account)
245
- assertSettlementSender({
246
- operation: 'settle',
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 transactionOptions = resolveChannelTransactionOptions(channel, options, account, machineRouter);
254
- let txHash;
255
- if (machineRouter) {
256
- const authorizationSignature = channel.highestVoucher.authorizationSignature;
257
- if (!authorizationSignature)
258
- throw new VerificationFailedError({
259
- reason: 'machine-token voucher is missing its router authorization',
260
- });
261
- txHash = await Chain.settleMachineSessionOnChain(client, channel.descriptor, amount, channel.highestVoucher.signature, authorizationSignature, machineRouter, transactionOptions);
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;
@@ -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
- /** Fee payer relay URL. When set, the transport is wrapped with `withFeePayer`. */
7
- feePayerUrl?: string | undefined;
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;
@@ -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, feePayerUrl, getClient, rpcUrl } = parameters;
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 && !feePayerUrl)
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 (feePayerUrl && client.transport.key !== 'feePayer') {
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 }), http(feePayerUrl, { retryCount: client.transport.retryCount }))({
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 = feePayerUrl ? withFeePayer(http(url), http(feePayerUrl)) : http(url);
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,
@@ -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. */
@@ -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