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.
Files changed (112) hide show
  1. package/CHANGELOG.md +16 -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/Html.js +1 -1
  10. package/dist/cli/THIRD-PARTY-LICENSES.txt +1 -1
  11. package/dist/cli/cli.d.ts +2 -2
  12. package/dist/cli/cli.js +134 -134
  13. package/dist/cli/plugins/index.js +13 -13
  14. package/dist/cli/sessions/Manager.js +4 -6
  15. package/dist/cli/sessions/commands.d.ts +1 -1
  16. package/dist/cli/sessions/store.js +13 -19
  17. package/dist/cli/validate/index.d.ts +2 -2
  18. package/dist/client/Mppx.d.ts +39 -2
  19. package/dist/client/Mppx.js +102 -46
  20. package/dist/client/Transport.js +1 -1
  21. package/dist/client/internal/protocols/Mpp.d.ts +1 -1
  22. package/dist/client/internal/protocols/Mpp.js +5 -3
  23. package/dist/client/internal/protocols/Protocol.d.ts +3 -1
  24. package/dist/client/internal/protocols/Shared.js +5 -1
  25. package/dist/integrations/x402/Evm.d.ts +29 -0
  26. package/dist/integrations/x402/Evm.js +150 -0
  27. package/dist/integrations/x402/Negotiator.d.ts +36 -0
  28. package/dist/integrations/x402/Negotiator.js +165 -0
  29. package/dist/mcp/internal/Credential.d.ts +9 -0
  30. package/dist/mcp/internal/Credential.js +16 -0
  31. package/dist/mcp/server/Transport.js +2 -4
  32. package/dist/middlewares/express.js +5 -12
  33. package/dist/middlewares/internal/express.d.ts +8 -0
  34. package/dist/middlewares/internal/express.js +24 -0
  35. package/dist/middlewares/internal/node.d.ts +10 -0
  36. package/dist/middlewares/internal/node.js +34 -0
  37. package/dist/proxy/Proxy.js +15 -9
  38. package/dist/server/Mppx.d.ts +2 -0
  39. package/dist/server/Mppx.js +17 -14
  40. package/dist/server/Transport.d.ts +8 -2
  41. package/dist/server/Transport.js +6 -3
  42. package/dist/server/internal/SecretKey.d.ts +3 -0
  43. package/dist/server/internal/SecretKey.js +9 -0
  44. package/dist/server/internal/html/serviceWorker.client.d.ts +1 -1
  45. package/dist/server/internal/html/serviceWorker.client.js +2 -2
  46. package/dist/server/internal/html/serviceWorker.gen.d.ts +1 -1
  47. package/dist/server/internal/html/serviceWorker.gen.js +1 -1
  48. package/dist/stripe/server/internal/html.gen.d.ts +1 -1
  49. package/dist/stripe/server/internal/html.gen.js +1 -1
  50. package/dist/tempo/Methods.d.ts +0 -10
  51. package/dist/tempo/Methods.js +3 -12
  52. package/dist/tempo/client/Charge.d.ts +0 -3
  53. package/dist/tempo/client/Charge.js +3 -13
  54. package/dist/tempo/client/Methods.d.ts +0 -10
  55. package/dist/tempo/internal/account.d.ts +15 -6
  56. package/dist/tempo/internal/account.js +17 -26
  57. package/dist/tempo/internal/defaults.d.ts +0 -11
  58. package/dist/tempo/internal/defaults.js +0 -11
  59. package/dist/tempo/internal/fee-payer.d.ts +21 -3
  60. package/dist/tempo/internal/fee-payer.js +10 -19
  61. package/dist/tempo/internal/remote-fee-payer.d.ts +12 -0
  62. package/dist/tempo/internal/remote-fee-payer.js +17 -0
  63. package/dist/tempo/legacy/client/Session.d.ts +0 -7
  64. package/dist/tempo/server/Charge.d.ts +0 -3
  65. package/dist/tempo/server/Charge.js +26 -68
  66. package/dist/tempo/server/Methods.d.ts +4 -18
  67. package/dist/tempo/server/Methods.js +4 -8
  68. package/dist/tempo/server/internal/html.gen.d.ts +1 -1
  69. package/dist/tempo/server/internal/html.gen.js +1 -1
  70. package/dist/tempo/session/client/ChannelOps.d.ts +0 -14
  71. package/dist/tempo/session/client/ChannelOps.js +0 -22
  72. package/dist/tempo/session/client/ChannelStore.d.ts +5 -0
  73. package/dist/tempo/session/client/ChannelStore.js +2 -2
  74. package/dist/tempo/session/client/CredentialState.d.ts +2 -12
  75. package/dist/tempo/session/client/CredentialState.js +75 -73
  76. package/dist/tempo/session/client/Session.d.ts +2 -9
  77. package/dist/tempo/session/client/Session.js +71 -176
  78. package/dist/tempo/session/client/SessionManager.js +9 -28
  79. package/dist/tempo/session/precompile/Chain.d.ts +0 -4
  80. package/dist/tempo/session/precompile/Chain.js +1 -29
  81. package/dist/tempo/session/precompile/Protocol.d.ts +0 -13
  82. package/dist/tempo/session/precompile/Voucher.d.ts +1 -3
  83. package/dist/tempo/session/precompile/Voucher.js +12 -6
  84. package/dist/tempo/session/server/ChannelStore.d.ts +0 -6
  85. package/dist/tempo/session/server/ChannelStore.js +4 -11
  86. package/dist/tempo/session/server/CredentialVerification.d.ts +7 -9
  87. package/dist/tempo/session/server/CredentialVerification.js +118 -184
  88. package/dist/tempo/session/server/RequestState.d.ts +0 -17
  89. package/dist/tempo/session/server/RequestState.js +15 -59
  90. package/dist/tempo/session/server/Session.d.ts +0 -9
  91. package/dist/tempo/session/server/Session.js +8 -37
  92. package/dist/tempo/session/server/Settlement.d.ts +0 -7
  93. package/dist/tempo/session/server/Settlement.js +16 -50
  94. package/dist/viem/Client.d.ts +7 -2
  95. package/dist/viem/Client.js +17 -5
  96. package/dist/x402/Types.d.ts +2 -0
  97. package/dist/x402/Types.js +2 -0
  98. package/dist/x402/mcp.d.ts +20 -0
  99. package/dist/x402/mcp.js +153 -0
  100. package/dist/x402/middlewares/express.d.ts +23 -0
  101. package/dist/x402/middlewares/express.js +49 -0
  102. package/dist/x402/middlewares/hono.d.ts +13 -0
  103. package/dist/x402/middlewares/hono.js +36 -0
  104. package/dist/x402/middlewares/next.d.ts +17 -0
  105. package/dist/x402/middlewares/next.js +58 -0
  106. package/package.json +41 -1
  107. package/dist/tempo/internal/machine-token-charge.d.ts +0 -51
  108. package/dist/tempo/internal/machine-token-charge.js +0 -113
  109. package/dist/tempo/internal/machine-token-session.d.ts +0 -88
  110. package/dist/tempo/internal/machine-token-session.js +0 -173
  111. package/dist/tempo/internal/signature-envelope.d.ts +0 -14
  112. 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';
@@ -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, machineTokenEnabled, operator, store: rawStore = Store.memory(), suggestedDeposit, unitType, } = parameters;
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, feePayerUrl, recipient } = Account.resolve(parameters);
203
- const configuredFeePayer = feePayer ?? feePayerUrl;
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
- feePayerUrl,
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
- ...(settlementFeePayer ? { feePayer: settlementFeePayer } : {}),
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: parameters.feePayer,
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
- ...requestWithoutMachineToken,
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
- 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