@t402/evm 2.2.0 → 2.3.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 (83) hide show
  1. package/dist/cjs/exact/client/index.d.ts +2 -2
  2. package/dist/cjs/exact/client/index.js +4 -2
  3. package/dist/cjs/exact/client/index.js.map +1 -1
  4. package/dist/cjs/exact/facilitator/index.d.ts +1 -1
  5. package/dist/cjs/exact/facilitator/index.js +40 -4
  6. package/dist/cjs/exact/facilitator/index.js.map +1 -1
  7. package/dist/cjs/exact/server/index.d.ts +1 -1
  8. package/dist/cjs/exact/server/index.js +301 -33
  9. package/dist/cjs/exact/server/index.js.map +1 -1
  10. package/dist/cjs/exact/v1/client/index.d.ts +1 -1
  11. package/dist/cjs/exact/v1/client/index.js +3 -1
  12. package/dist/cjs/exact/v1/client/index.js.map +1 -1
  13. package/dist/cjs/exact/v1/facilitator/index.d.ts +1 -1
  14. package/dist/cjs/exact/v1/facilitator/index.js +21 -2
  15. package/dist/cjs/exact/v1/facilitator/index.js.map +1 -1
  16. package/dist/cjs/index.d.ts +606 -352
  17. package/dist/cjs/index.js +1436 -268
  18. package/dist/cjs/index.js.map +1 -1
  19. package/dist/{esm/scheme-yqGaK9rK.d.mts → cjs/scheme-B4rXSKCN.d.ts} +18 -16
  20. package/dist/cjs/scheme-CIar5W2B.d.ts +200 -0
  21. package/dist/cjs/{scheme-OojTBKAz.d.ts → scheme-CjijeY7y.d.ts} +1 -1
  22. package/dist/{esm/signer-BkcAzwYi.d.mts → cjs/signer-DcavxxZt.d.ts} +1 -18
  23. package/dist/cjs/upto/client/index.d.ts +61 -0
  24. package/dist/cjs/upto/client/index.js +154 -0
  25. package/dist/cjs/upto/client/index.js.map +1 -0
  26. package/dist/cjs/upto/index.d.ts +111 -0
  27. package/dist/cjs/upto/index.js +1030 -0
  28. package/dist/cjs/upto/index.js.map +1 -0
  29. package/dist/cjs/v1/index.d.ts +1 -1
  30. package/dist/cjs/v1/index.js +3 -1
  31. package/dist/cjs/v1/index.js.map +1 -1
  32. package/dist/esm/{chunk-ACDQ5QNT.mjs → chunk-4FBTQTNM.mjs} +27 -5
  33. package/dist/esm/chunk-4FBTQTNM.mjs.map +1 -0
  34. package/dist/esm/chunk-IWSDEZKI.mjs +477 -0
  35. package/dist/esm/chunk-IWSDEZKI.mjs.map +1 -0
  36. package/dist/esm/{chunk-LGSG73NJ.mjs → chunk-LM5RZBVP.mjs} +9 -4
  37. package/dist/esm/{chunk-LGSG73NJ.mjs.map → chunk-LM5RZBVP.mjs.map} +1 -1
  38. package/dist/esm/chunk-NSSMTXJJ.mjs +8 -0
  39. package/dist/esm/chunk-NSSMTXJJ.mjs.map +1 -0
  40. package/dist/esm/chunk-SJ52GTJJ.mjs +411 -0
  41. package/dist/esm/chunk-SJ52GTJJ.mjs.map +1 -0
  42. package/dist/esm/chunk-SURTCHSX.mjs +129 -0
  43. package/dist/esm/chunk-SURTCHSX.mjs.map +1 -0
  44. package/dist/esm/chunk-SYVPLXYV.mjs +26 -0
  45. package/dist/esm/chunk-SYVPLXYV.mjs.map +1 -0
  46. package/dist/esm/{chunk-XYKAO6KJ.mjs → chunk-Y4U7Q543.mjs} +2 -25
  47. package/dist/esm/chunk-Y4U7Q543.mjs.map +1 -0
  48. package/dist/esm/{chunk-JBWWBRYY.mjs → chunk-ZWEYARER.mjs} +9 -4
  49. package/dist/esm/{chunk-JBWWBRYY.mjs.map → chunk-ZWEYARER.mjs.map} +1 -1
  50. package/dist/esm/exact/client/index.d.mts +2 -2
  51. package/dist/esm/exact/client/index.mjs +6 -4
  52. package/dist/esm/exact/client/index.mjs.map +1 -1
  53. package/dist/esm/exact/facilitator/index.d.mts +1 -1
  54. package/dist/esm/exact/facilitator/index.mjs +26 -5
  55. package/dist/esm/exact/facilitator/index.mjs.map +1 -1
  56. package/dist/esm/exact/server/index.d.mts +1 -1
  57. package/dist/esm/exact/server/index.mjs +29 -30
  58. package/dist/esm/exact/server/index.mjs.map +1 -1
  59. package/dist/esm/exact/v1/client/index.d.mts +1 -1
  60. package/dist/esm/exact/v1/client/index.mjs +4 -2
  61. package/dist/esm/exact/v1/facilitator/index.d.mts +1 -1
  62. package/dist/esm/exact/v1/facilitator/index.mjs +4 -2
  63. package/dist/esm/index.d.mts +606 -352
  64. package/dist/esm/index.mjs +626 -138
  65. package/dist/esm/index.mjs.map +1 -1
  66. package/dist/{cjs/scheme-yqGaK9rK.d.ts → esm/scheme-B4rXSKCN.d.mts} +18 -16
  67. package/dist/esm/scheme-DATfd6oM.d.mts +200 -0
  68. package/dist/esm/{scheme-D4mOqq9l.d.mts → scheme-Ddb0dG_F.d.mts} +1 -1
  69. package/dist/{cjs/signer-BkcAzwYi.d.ts → esm/signer-DcavxxZt.d.mts} +1 -18
  70. package/dist/esm/upto/client/index.d.mts +61 -0
  71. package/dist/esm/upto/client/index.mjs +11 -0
  72. package/dist/esm/upto/client/index.mjs.map +1 -0
  73. package/dist/esm/upto/index.d.mts +111 -0
  74. package/dist/esm/upto/index.mjs +26 -0
  75. package/dist/esm/upto/index.mjs.map +1 -0
  76. package/dist/esm/v1/index.d.mts +1 -1
  77. package/dist/esm/v1/index.mjs +5 -3
  78. package/package.json +30 -6
  79. package/dist/cjs/scheme-C6uD7PdY.d.ts +0 -130
  80. package/dist/esm/chunk-ACDQ5QNT.mjs.map +0 -1
  81. package/dist/esm/chunk-OEXW2OK2.mjs +0 -251
  82. package/dist/esm/chunk-OEXW2OK2.mjs.map +0 -1
  83. package/dist/esm/chunk-XYKAO6KJ.mjs.map +0 -1
@@ -0,0 +1,411 @@
1
+ import {
2
+ TOKEN_REGISTRY,
3
+ getDefaultToken,
4
+ getTokenByAddress,
5
+ getTokenConfig
6
+ } from "./chunk-IWSDEZKI.mjs";
7
+ import {
8
+ isUptoEIP2612Payload,
9
+ permitTypes
10
+ } from "./chunk-SURTCHSX.mjs";
11
+ import {
12
+ __publicField
13
+ } from "./chunk-NSSMTXJJ.mjs";
14
+
15
+ // src/upto/server/scheme.ts
16
+ import {
17
+ UPTO_DEFAULTS
18
+ } from "@t402/core/types";
19
+ var UptoEvmServerScheme = class {
20
+ /**
21
+ * Creates a new UptoEvmServerScheme instance.
22
+ *
23
+ * @param config - Optional configuration options for the scheme
24
+ */
25
+ constructor(config = {}) {
26
+ __publicField(this, "scheme", "upto");
27
+ __publicField(this, "moneyParsers", []);
28
+ __publicField(this, "config");
29
+ this.config = config;
30
+ }
31
+ /**
32
+ * Get all supported networks
33
+ *
34
+ * @returns Array of network identifiers in CAIP-2 format
35
+ */
36
+ static getSupportedNetworks() {
37
+ return Object.keys(TOKEN_REGISTRY);
38
+ }
39
+ /**
40
+ * Check if a network is supported
41
+ *
42
+ * @param network - The network identifier to check
43
+ * @returns True if the network is supported
44
+ */
45
+ static isNetworkSupported(network) {
46
+ return network in TOKEN_REGISTRY;
47
+ }
48
+ /**
49
+ * Register a custom money parser in the parser chain.
50
+ *
51
+ * @param parser - Custom function to convert amount to AssetAmount
52
+ * @returns The server instance for chaining
53
+ */
54
+ registerMoneyParser(parser) {
55
+ this.moneyParsers.push(parser);
56
+ return this;
57
+ }
58
+ /**
59
+ * Parses a price into an asset amount for maxAmount.
60
+ *
61
+ * @param price - The price to parse (represents maxAmount)
62
+ * @param network - The network to use
63
+ * @returns Promise resolving to the parsed asset amount
64
+ */
65
+ async parsePrice(price, network) {
66
+ if (typeof price === "object" && price !== null && "amount" in price) {
67
+ if (!price.asset) {
68
+ const token2 = this.getPreferredToken(network);
69
+ return { amount: price.amount, asset: token2.address };
70
+ }
71
+ return price;
72
+ }
73
+ const decimalAmount = this.parseToDecimal(price);
74
+ for (const parser of this.moneyParsers) {
75
+ const result = await parser(decimalAmount, network);
76
+ if (result !== null) {
77
+ return result;
78
+ }
79
+ }
80
+ const token = this.getPreferredToken(network);
81
+ const amount = Math.floor(decimalAmount * 10 ** token.decimals).toString();
82
+ return {
83
+ amount,
84
+ asset: token.address
85
+ };
86
+ }
87
+ /**
88
+ * Enhance payment requirements for the upto scheme.
89
+ *
90
+ * @param paymentRequirements - Base payment requirements
91
+ * @param supportedKind - The supported kind from facilitator
92
+ * @param supportedKind.t402Version - T402 protocol version
93
+ * @param supportedKind.scheme - Payment scheme
94
+ * @param supportedKind.network - Network identifier
95
+ * @param supportedKind.extra - Extra configuration
96
+ * @param facilitatorExtensions - Extensions supported by the facilitator
97
+ * @returns Enhanced payment requirements for upto scheme
98
+ */
99
+ async enhancePaymentRequirements(paymentRequirements, supportedKind, facilitatorExtensions) {
100
+ void facilitatorExtensions;
101
+ const network = supportedKind.network;
102
+ const token = getTokenByAddress(network, paymentRequirements.asset);
103
+ if (!token) {
104
+ throw new Error(`Unknown token ${paymentRequirements.asset} on ${network}`);
105
+ }
106
+ const extra = {
107
+ // EIP-712 domain (required for permit signing)
108
+ name: token.name,
109
+ version: token.version,
110
+ // Router address (optional - if set, permits go to router)
111
+ ...this.config.routerAddress && { routerAddress: this.config.routerAddress },
112
+ // Billing unit info (optional)
113
+ ...this.config.defaultUnit && { unit: this.config.defaultUnit },
114
+ ...this.config.defaultUnitPrice && { unitPrice: this.config.defaultUnitPrice },
115
+ // Upto-specific fields
116
+ maxAmount: paymentRequirements.amount,
117
+ minAmount: UPTO_DEFAULTS.MIN_AMOUNT,
118
+ // Merge any facilitator extra
119
+ ...supportedKind.extra
120
+ };
121
+ return {
122
+ ...paymentRequirements,
123
+ scheme: "upto",
124
+ extra
125
+ };
126
+ }
127
+ /**
128
+ * Get the preferred token for a network.
129
+ *
130
+ * @param network - The network identifier
131
+ * @returns Token configuration
132
+ * @throws Error if no token is found for the network
133
+ */
134
+ getPreferredToken(network) {
135
+ if (this.config.preferredToken) {
136
+ const token = getTokenConfig(network, this.config.preferredToken);
137
+ if (token) return token;
138
+ }
139
+ const defaultToken = getDefaultToken(network);
140
+ if (!defaultToken) {
141
+ throw new Error(`No token configured for network ${network}`);
142
+ }
143
+ return defaultToken;
144
+ }
145
+ /**
146
+ * Parse price to decimal value.
147
+ *
148
+ * @param price - Price string or number
149
+ * @returns Decimal amount
150
+ */
151
+ parseToDecimal(price) {
152
+ if (typeof price === "number") {
153
+ return price;
154
+ }
155
+ const cleaned = price.replace(/[$,]/g, "").trim();
156
+ const parsed = parseFloat(cleaned);
157
+ if (isNaN(parsed)) {
158
+ throw new Error(`Invalid price format: ${price}`);
159
+ }
160
+ return parsed;
161
+ }
162
+ };
163
+ function createUptoEvmServerScheme(config) {
164
+ return new UptoEvmServerScheme(config);
165
+ }
166
+
167
+ // src/upto/facilitator/scheme.ts
168
+ import { getAddress, encodeFunctionData, parseAbi } from "viem";
169
+ var T402_UPTO_ROUTER_ABI = parseAbi([
170
+ "function executeUptoTransfer(address token, address from, address to, uint256 maxAmount, uint256 settleAmount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external",
171
+ "function isFacilitator(address facilitator) external view returns (bool)",
172
+ "function checkPermitValidity(address token, address from, uint256 maxAmount) external view returns (bool valid, uint256 balance)"
173
+ ]);
174
+ var UptoEvmFacilitatorScheme = class {
175
+ /**
176
+ * Creates a new UptoEvmFacilitatorScheme instance.
177
+ *
178
+ * @param signer - The EVM signer for facilitator operations
179
+ * @param config - Optional configuration
180
+ */
181
+ constructor(signer, config) {
182
+ this.signer = signer;
183
+ __publicField(this, "scheme", "upto");
184
+ __publicField(this, "caipFamily", "eip155:*");
185
+ __publicField(this, "config");
186
+ this.config = config ?? {};
187
+ }
188
+ /**
189
+ * Get mechanism-specific extra data for the supported kinds endpoint.
190
+ *
191
+ * @param network - The network identifier
192
+ * @returns Extra data including router address if configured
193
+ */
194
+ getExtra(network) {
195
+ const routerAddress = this.config.routerAddresses?.[network];
196
+ if (routerAddress) {
197
+ return { routerAddress };
198
+ }
199
+ return void 0;
200
+ }
201
+ /**
202
+ * Get signer addresses used by this facilitator.
203
+ *
204
+ * @param _ - The network identifier (unused for EVM)
205
+ * @returns Array of facilitator wallet addresses
206
+ */
207
+ getSigners(_) {
208
+ return [...this.signer.getAddresses()];
209
+ }
210
+ /**
211
+ * Verifies an upto payment payload.
212
+ *
213
+ * @param payload - The payment payload to verify
214
+ * @param requirements - The payment requirements
215
+ * @returns Promise resolving to verification response
216
+ */
217
+ async verify(payload, requirements) {
218
+ const uptoPayload = payload.payload;
219
+ if (!uptoPayload || !isUptoEIP2612Payload(uptoPayload)) {
220
+ return {
221
+ isValid: false,
222
+ invalidReason: "invalid_payload_structure",
223
+ payer: void 0
224
+ };
225
+ }
226
+ if (payload.accepted.scheme !== "upto" || requirements.scheme !== "upto") {
227
+ return {
228
+ isValid: false,
229
+ invalidReason: "unsupported_scheme",
230
+ payer: uptoPayload.authorization.owner
231
+ };
232
+ }
233
+ if (!requirements.extra?.name || !requirements.extra?.version) {
234
+ return {
235
+ isValid: false,
236
+ invalidReason: "missing_eip712_domain",
237
+ payer: uptoPayload.authorization.owner
238
+ };
239
+ }
240
+ const maxAmount = requirements.extra?.maxAmount;
241
+ if (!maxAmount) {
242
+ return {
243
+ isValid: false,
244
+ invalidReason: "missing_maxAmount",
245
+ payer: uptoPayload.authorization.owner
246
+ };
247
+ }
248
+ if (payload.accepted.network !== requirements.network) {
249
+ return {
250
+ isValid: false,
251
+ invalidReason: "network_mismatch",
252
+ payer: uptoPayload.authorization.owner
253
+ };
254
+ }
255
+ const deadline = parseInt(uptoPayload.authorization.deadline);
256
+ const now = Math.floor(Date.now() / 1e3);
257
+ if (deadline <= now) {
258
+ return {
259
+ isValid: false,
260
+ invalidReason: "permit_expired",
261
+ payer: uptoPayload.authorization.owner
262
+ };
263
+ }
264
+ if (uptoPayload.authorization.value !== maxAmount) {
265
+ return {
266
+ isValid: false,
267
+ invalidReason: "amount_mismatch",
268
+ payer: uptoPayload.authorization.owner
269
+ };
270
+ }
271
+ const chainId = parseInt(requirements.network.split(":")[1]);
272
+ const permitTypedData = {
273
+ types: permitTypes,
274
+ primaryType: "Permit",
275
+ domain: {
276
+ name: requirements.extra.name,
277
+ version: requirements.extra.version,
278
+ chainId,
279
+ verifyingContract: getAddress(requirements.asset)
280
+ },
281
+ message: {
282
+ owner: getAddress(uptoPayload.authorization.owner),
283
+ spender: getAddress(uptoPayload.authorization.spender),
284
+ value: BigInt(uptoPayload.authorization.value),
285
+ nonce: BigInt(uptoPayload.authorization.nonce),
286
+ deadline: BigInt(uptoPayload.authorization.deadline)
287
+ }
288
+ };
289
+ const signature = `0x${uptoPayload.signature.r.slice(2)}${uptoPayload.signature.s.slice(2)}${uptoPayload.signature.v.toString(16).padStart(2, "0")}`;
290
+ try {
291
+ const isValid = await this.signer.verifyTypedData({
292
+ address: uptoPayload.authorization.owner,
293
+ ...permitTypedData,
294
+ signature
295
+ });
296
+ if (!isValid) {
297
+ return {
298
+ isValid: false,
299
+ invalidReason: "invalid_signature",
300
+ payer: uptoPayload.authorization.owner
301
+ };
302
+ }
303
+ } catch (error) {
304
+ return {
305
+ isValid: false,
306
+ invalidReason: `signature_verification_failed: ${error instanceof Error ? error.message : "unknown"}`,
307
+ payer: uptoPayload.authorization.owner
308
+ };
309
+ }
310
+ return {
311
+ isValid: true,
312
+ payer: uptoPayload.authorization.owner
313
+ };
314
+ }
315
+ /**
316
+ * Settles an upto payment by calling the T402UptoRouter contract.
317
+ *
318
+ * @param payload - The verified payment payload
319
+ * @param requirements - The payment requirements
320
+ * @returns Promise resolving to settlement response
321
+ */
322
+ async settle(payload, requirements) {
323
+ const uptoPayload = payload.payload;
324
+ const maxAmount = requirements.extra?.maxAmount;
325
+ const minAmount = requirements.extra?.minAmount;
326
+ const routerAddress = requirements.extra?.routerAddress;
327
+ if (!maxAmount) {
328
+ return {
329
+ success: false,
330
+ errorReason: "maxAmount not found in payment requirements",
331
+ transaction: "",
332
+ network: requirements.network,
333
+ payer: uptoPayload.authorization.owner
334
+ };
335
+ }
336
+ const settleAmount = maxAmount;
337
+ if (minAmount && BigInt(settleAmount) < BigInt(minAmount)) {
338
+ return {
339
+ success: false,
340
+ errorReason: `Settle amount ${settleAmount} below minimum ${minAmount}`,
341
+ transaction: "",
342
+ network: requirements.network,
343
+ payer: uptoPayload.authorization.owner
344
+ };
345
+ }
346
+ if (!routerAddress) {
347
+ return {
348
+ success: false,
349
+ errorReason: "Router address not configured",
350
+ transaction: "",
351
+ network: requirements.network,
352
+ payer: uptoPayload.authorization.owner
353
+ };
354
+ }
355
+ try {
356
+ const txHash = await this.signer.sendTransaction({
357
+ to: getAddress(routerAddress),
358
+ data: encodeFunctionData({
359
+ abi: T402_UPTO_ROUTER_ABI,
360
+ functionName: "executeUptoTransfer",
361
+ args: [
362
+ getAddress(requirements.asset),
363
+ getAddress(uptoPayload.authorization.owner),
364
+ getAddress(requirements.payTo),
365
+ BigInt(maxAmount),
366
+ BigInt(settleAmount),
367
+ BigInt(uptoPayload.authorization.deadline),
368
+ uptoPayload.signature.v,
369
+ uptoPayload.signature.r,
370
+ uptoPayload.signature.s
371
+ ]
372
+ })
373
+ });
374
+ const receipt = await this.signer.waitForTransactionReceipt({ hash: txHash });
375
+ if (receipt.status !== "success") {
376
+ return {
377
+ success: false,
378
+ errorReason: "transaction_reverted",
379
+ transaction: txHash,
380
+ network: requirements.network,
381
+ payer: uptoPayload.authorization.owner
382
+ };
383
+ }
384
+ return {
385
+ success: true,
386
+ transaction: txHash,
387
+ network: requirements.network,
388
+ payer: uptoPayload.authorization.owner
389
+ };
390
+ } catch (error) {
391
+ return {
392
+ success: false,
393
+ errorReason: `Settlement failed: ${error instanceof Error ? error.message : "unknown"}`,
394
+ transaction: "",
395
+ network: requirements.network,
396
+ payer: uptoPayload.authorization.owner
397
+ };
398
+ }
399
+ }
400
+ };
401
+ function createUptoEvmFacilitatorScheme(signer, config) {
402
+ return new UptoEvmFacilitatorScheme(signer, config);
403
+ }
404
+
405
+ export {
406
+ UptoEvmServerScheme,
407
+ createUptoEvmServerScheme,
408
+ UptoEvmFacilitatorScheme,
409
+ createUptoEvmFacilitatorScheme
410
+ };
411
+ //# sourceMappingURL=chunk-SJ52GTJJ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/upto/server/scheme.ts","../../src/upto/facilitator/scheme.ts"],"sourcesContent":["import {\n AssetAmount,\n Network,\n PaymentRequirements,\n Price,\n SchemeNetworkServer,\n MoneyParser,\n UPTO_DEFAULTS,\n} from \"@t402/core/types\";\nimport {\n getDefaultToken,\n getTokenConfig,\n getTokenByAddress,\n TokenConfig,\n TOKEN_REGISTRY,\n} from \"../../tokens.js\";\n\n/**\n * Configuration options for UptoEvmServerScheme\n */\nexport interface UptoEvmServerSchemeConfig {\n /** Preferred token symbol (e.g., \"USDT0\", \"USDC\"). Defaults to network's highest priority token. */\n preferredToken?: string;\n\n /** Router contract address for upto payments. If not set, payTo address is used as spender. */\n routerAddress?: string;\n\n /** Default billing unit */\n defaultUnit?: string;\n\n /** Default unit price in smallest denomination */\n defaultUnitPrice?: string;\n}\n\n/**\n * EVM server implementation for the Up-To payment scheme.\n *\n * Enables usage-based billing by creating payment requirements\n * that authorize up to a maximum amount, with actual settlement\n * determined by usage.\n *\n * @example\n * ```typescript\n * import { UptoEvmServerScheme } from \"@t402/evm/upto/server\";\n *\n * const scheme = new UptoEvmServerScheme({\n * routerAddress: \"0x...\", // T402UptoRouter contract\n * defaultUnit: \"token\",\n * defaultUnitPrice: \"100\", // $0.0001 per token\n * });\n *\n * server.registerScheme(\"eip155:8453\", scheme);\n * ```\n */\nexport class UptoEvmServerScheme implements SchemeNetworkServer {\n readonly scheme = \"upto\";\n private moneyParsers: MoneyParser[] = [];\n private config: UptoEvmServerSchemeConfig;\n\n /**\n * Creates a new UptoEvmServerScheme instance.\n *\n * @param config - Optional configuration options for the scheme\n */\n constructor(config: UptoEvmServerSchemeConfig = {}) {\n this.config = config;\n }\n\n /**\n * Get all supported networks\n *\n * @returns Array of network identifiers in CAIP-2 format\n */\n static getSupportedNetworks(): string[] {\n return Object.keys(TOKEN_REGISTRY);\n }\n\n /**\n * Check if a network is supported\n *\n * @param network - The network identifier to check\n * @returns True if the network is supported\n */\n static isNetworkSupported(network: string): boolean {\n return network in TOKEN_REGISTRY;\n }\n\n /**\n * Register a custom money parser in the parser chain.\n *\n * @param parser - Custom function to convert amount to AssetAmount\n * @returns The server instance for chaining\n */\n registerMoneyParser(parser: MoneyParser): UptoEvmServerScheme {\n this.moneyParsers.push(parser);\n return this;\n }\n\n /**\n * Parses a price into an asset amount for maxAmount.\n *\n * @param price - The price to parse (represents maxAmount)\n * @param network - The network to use\n * @returns Promise resolving to the parsed asset amount\n */\n async parsePrice(price: Price, network: Network): Promise<AssetAmount> {\n // If already an AssetAmount, return it directly\n if (typeof price === \"object\" && price !== null && \"amount\" in price) {\n if (!price.asset) {\n const token = this.getPreferredToken(network);\n return { amount: price.amount, asset: token.address };\n }\n return price as AssetAmount;\n }\n\n // Parse string/number price to decimal\n const decimalAmount = this.parseToDecimal(price);\n\n // Try custom parsers first\n for (const parser of this.moneyParsers) {\n const result = await parser(decimalAmount, network);\n if (result !== null) {\n return result;\n }\n }\n\n // Default: convert to token's smallest denomination\n const token = this.getPreferredToken(network);\n const amount = Math.floor(decimalAmount * 10 ** token.decimals).toString();\n\n return {\n amount,\n asset: token.address,\n };\n }\n\n /**\n * Enhance payment requirements for the upto scheme.\n *\n * @param paymentRequirements - Base payment requirements\n * @param supportedKind - The supported kind from facilitator\n * @param supportedKind.t402Version - T402 protocol version\n * @param supportedKind.scheme - Payment scheme\n * @param supportedKind.network - Network identifier\n * @param supportedKind.extra - Extra configuration\n * @param facilitatorExtensions - Extensions supported by the facilitator\n * @returns Enhanced payment requirements for upto scheme\n */\n async enhancePaymentRequirements(\n paymentRequirements: PaymentRequirements,\n supportedKind: {\n t402Version: number;\n scheme: string;\n network: Network;\n extra?: Record<string, unknown>;\n },\n facilitatorExtensions: string[],\n ): Promise<PaymentRequirements> {\n // Mark unused parameter to satisfy linter\n void facilitatorExtensions;\n\n const network = supportedKind.network;\n const token = getTokenByAddress(network, paymentRequirements.asset as `0x${string}`);\n\n if (!token) {\n throw new Error(`Unknown token ${paymentRequirements.asset} on ${network}`);\n }\n\n // Build extra with EIP-712 domain and upto-specific fields\n const extra: Record<string, unknown> = {\n // EIP-712 domain (required for permit signing)\n name: token.name,\n version: token.version,\n\n // Router address (optional - if set, permits go to router)\n ...(this.config.routerAddress && { routerAddress: this.config.routerAddress }),\n\n // Billing unit info (optional)\n ...(this.config.defaultUnit && { unit: this.config.defaultUnit }),\n ...(this.config.defaultUnitPrice && { unitPrice: this.config.defaultUnitPrice }),\n\n // Upto-specific fields\n maxAmount: paymentRequirements.amount,\n minAmount: UPTO_DEFAULTS.MIN_AMOUNT,\n\n // Merge any facilitator extra\n ...supportedKind.extra,\n };\n\n return {\n ...paymentRequirements,\n scheme: \"upto\",\n extra,\n };\n }\n\n /**\n * Get the preferred token for a network.\n *\n * @param network - The network identifier\n * @returns Token configuration\n * @throws Error if no token is found for the network\n */\n private getPreferredToken(network: Network): TokenConfig {\n if (this.config.preferredToken) {\n const token = getTokenConfig(network, this.config.preferredToken);\n if (token) return token;\n }\n const defaultToken = getDefaultToken(network);\n if (!defaultToken) {\n throw new Error(`No token configured for network ${network}`);\n }\n return defaultToken;\n }\n\n /**\n * Parse price to decimal value.\n *\n * @param price - Price string or number\n * @returns Decimal amount\n */\n private parseToDecimal(price: string | number): number {\n if (typeof price === \"number\") {\n return price;\n }\n\n // Remove currency symbols and parse\n const cleaned = price.replace(/[$,]/g, \"\").trim();\n const parsed = parseFloat(cleaned);\n\n if (isNaN(parsed)) {\n throw new Error(`Invalid price format: ${price}`);\n }\n\n return parsed;\n }\n}\n\n/**\n * Factory function to create an UptoEvmServerScheme.\n *\n * @param config - Configuration options\n * @returns A new UptoEvmServerScheme instance\n */\nexport function createUptoEvmServerScheme(config?: UptoEvmServerSchemeConfig): UptoEvmServerScheme {\n return new UptoEvmServerScheme(config);\n}\n","import {\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n SettleResponse,\n VerifyResponse,\n} from \"@t402/core/types\";\nimport { getAddress, Hex, encodeFunctionData, parseAbi } from \"viem\";\nimport { permitTypes, UptoEIP2612Payload, isUptoEIP2612Payload } from \"../../types.js\";\nimport { FacilitatorEvmSigner } from \"../../signer.js\";\n\n/**\n * T402UptoRouter contract ABI (only the functions we need)\n */\nconst T402_UPTO_ROUTER_ABI = parseAbi([\n \"function executeUptoTransfer(address token, address from, address to, uint256 maxAmount, uint256 settleAmount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external\",\n \"function isFacilitator(address facilitator) external view returns (bool)\",\n \"function checkPermitValidity(address token, address from, uint256 maxAmount) external view returns (bool valid, uint256 balance)\",\n]);\n\n/**\n * Configuration for UptoEvmFacilitatorScheme\n */\nexport interface UptoEvmFacilitatorSchemeConfig {\n /**\n * Router contract addresses by network (CAIP-2 format)\n *\n * @example { \"eip155:8453\": \"0x...\" }\n */\n routerAddresses?: Record<string, string>;\n}\n\n/**\n * EVM facilitator implementation for the Up-To payment scheme.\n *\n * Handles verification and settlement of upto payments using\n * the T402UptoRouter contract.\n *\n * @example\n * ```typescript\n * import { UptoEvmFacilitatorScheme } from \"@t402/evm/upto/facilitator\";\n *\n * const facilitator = new UptoEvmFacilitatorScheme(signer, {\n * routerAddresses: {\n * \"eip155:8453\": \"0x...\", // Base mainnet router\n * \"eip155:84532\": \"0x...\", // Base Sepolia router\n * },\n * });\n *\n * facilitatorServer.registerScheme(facilitator);\n * ```\n */\nexport class UptoEvmFacilitatorScheme implements SchemeNetworkFacilitator {\n readonly scheme = \"upto\";\n readonly caipFamily = \"eip155:*\";\n private readonly config: UptoEvmFacilitatorSchemeConfig;\n\n /**\n * Creates a new UptoEvmFacilitatorScheme instance.\n *\n * @param signer - The EVM signer for facilitator operations\n * @param config - Optional configuration\n */\n constructor(\n private readonly signer: FacilitatorEvmSigner,\n config?: UptoEvmFacilitatorSchemeConfig,\n ) {\n this.config = config ?? {};\n }\n\n /**\n * Get mechanism-specific extra data for the supported kinds endpoint.\n *\n * @param network - The network identifier\n * @returns Extra data including router address if configured\n */\n getExtra(network: string): Record<string, unknown> | undefined {\n const routerAddress = this.config.routerAddresses?.[network];\n if (routerAddress) {\n return { routerAddress };\n }\n return undefined;\n }\n\n /**\n * Get signer addresses used by this facilitator.\n *\n * @param _ - The network identifier (unused for EVM)\n * @returns Array of facilitator wallet addresses\n */\n getSigners(_: string): string[] {\n return [...this.signer.getAddresses()];\n }\n\n /**\n * Verifies an upto payment payload.\n *\n * @param payload - The payment payload to verify\n * @param requirements - The payment requirements\n * @returns Promise resolving to verification response\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n const uptoPayload = payload.payload as UptoEIP2612Payload | undefined;\n\n // Validate payload structure\n if (!uptoPayload || !isUptoEIP2612Payload(uptoPayload)) {\n return {\n isValid: false,\n invalidReason: \"invalid_payload_structure\",\n payer: undefined,\n };\n }\n\n // Verify scheme matches\n if (payload.accepted.scheme !== \"upto\" || requirements.scheme !== \"upto\") {\n return {\n isValid: false,\n invalidReason: \"unsupported_scheme\",\n payer: uptoPayload.authorization.owner,\n };\n }\n\n // Verify EIP-712 domain parameters exist\n if (!requirements.extra?.name || !requirements.extra?.version) {\n return {\n isValid: false,\n invalidReason: \"missing_eip712_domain\",\n payer: uptoPayload.authorization.owner,\n };\n }\n\n // Get maxAmount from extra\n const maxAmount = requirements.extra?.maxAmount as string | undefined;\n if (!maxAmount) {\n return {\n isValid: false,\n invalidReason: \"missing_maxAmount\",\n payer: uptoPayload.authorization.owner,\n };\n }\n\n // Verify network matches\n if (payload.accepted.network !== requirements.network) {\n return {\n isValid: false,\n invalidReason: \"network_mismatch\",\n payer: uptoPayload.authorization.owner,\n };\n }\n\n // Verify deadline hasn't passed\n const deadline = parseInt(uptoPayload.authorization.deadline);\n const now = Math.floor(Date.now() / 1000);\n if (deadline <= now) {\n return {\n isValid: false,\n invalidReason: \"permit_expired\",\n payer: uptoPayload.authorization.owner,\n };\n }\n\n // Verify maxAmount matches\n if (uptoPayload.authorization.value !== maxAmount) {\n return {\n isValid: false,\n invalidReason: \"amount_mismatch\",\n payer: uptoPayload.authorization.owner,\n };\n }\n\n // Build typed data for signature verification\n const chainId = parseInt(requirements.network.split(\":\")[1]);\n const permitTypedData = {\n types: permitTypes,\n primaryType: \"Permit\" as const,\n domain: {\n name: requirements.extra.name as string,\n version: requirements.extra.version as string,\n chainId,\n verifyingContract: getAddress(requirements.asset),\n },\n message: {\n owner: getAddress(uptoPayload.authorization.owner),\n spender: getAddress(uptoPayload.authorization.spender),\n value: BigInt(uptoPayload.authorization.value),\n nonce: BigInt(uptoPayload.authorization.nonce),\n deadline: BigInt(uptoPayload.authorization.deadline),\n },\n };\n\n // Reconstruct signature\n const signature =\n `0x${uptoPayload.signature.r.slice(2)}${uptoPayload.signature.s.slice(2)}${uptoPayload.signature.v.toString(16).padStart(2, \"0\")}` as Hex;\n\n // Verify signature\n try {\n const isValid = await this.signer.verifyTypedData({\n address: uptoPayload.authorization.owner,\n ...permitTypedData,\n signature,\n });\n\n if (!isValid) {\n return {\n isValid: false,\n invalidReason: \"invalid_signature\",\n payer: uptoPayload.authorization.owner,\n };\n }\n } catch (error) {\n return {\n isValid: false,\n invalidReason: `signature_verification_failed: ${error instanceof Error ? error.message : \"unknown\"}`,\n payer: uptoPayload.authorization.owner,\n };\n }\n\n return {\n isValid: true,\n payer: uptoPayload.authorization.owner,\n };\n }\n\n /**\n * Settles an upto payment by calling the T402UptoRouter contract.\n *\n * @param payload - The verified payment payload\n * @param requirements - The payment requirements\n * @returns Promise resolving to settlement response\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n const uptoPayload = payload.payload as UptoEIP2612Payload;\n\n // Get upto-specific fields from extra\n const maxAmount = requirements.extra?.maxAmount as string;\n const minAmount = requirements.extra?.minAmount as string | undefined;\n const routerAddress = requirements.extra?.routerAddress as string | undefined;\n\n if (!maxAmount) {\n return {\n success: false,\n errorReason: \"maxAmount not found in payment requirements\",\n transaction: \"\",\n network: requirements.network,\n payer: uptoPayload.authorization.owner,\n };\n }\n\n // For upto scheme, settle the maxAmount (actual usage-based settlement\n // would require additional parameters passed via extension)\n const settleAmount = maxAmount;\n\n // Validate minimum amount\n if (minAmount && BigInt(settleAmount) < BigInt(minAmount)) {\n return {\n success: false,\n errorReason: `Settle amount ${settleAmount} below minimum ${minAmount}`,\n transaction: \"\",\n network: requirements.network,\n payer: uptoPayload.authorization.owner,\n };\n }\n\n // Get router address\n if (!routerAddress) {\n return {\n success: false,\n errorReason: \"Router address not configured\",\n transaction: \"\",\n network: requirements.network,\n payer: uptoPayload.authorization.owner,\n };\n }\n\n try {\n // Execute the transfer through the router\n const txHash = await this.signer.sendTransaction({\n to: getAddress(routerAddress),\n data: encodeFunctionData({\n abi: T402_UPTO_ROUTER_ABI,\n functionName: \"executeUptoTransfer\",\n args: [\n getAddress(requirements.asset),\n getAddress(uptoPayload.authorization.owner),\n getAddress(requirements.payTo),\n BigInt(maxAmount),\n BigInt(settleAmount),\n BigInt(uptoPayload.authorization.deadline),\n uptoPayload.signature.v,\n uptoPayload.signature.r as Hex,\n uptoPayload.signature.s as Hex,\n ],\n }),\n });\n\n // Wait for confirmation\n const receipt = await this.signer.waitForTransactionReceipt({ hash: txHash });\n\n if (receipt.status !== \"success\") {\n return {\n success: false,\n errorReason: \"transaction_reverted\",\n transaction: txHash,\n network: requirements.network,\n payer: uptoPayload.authorization.owner,\n };\n }\n\n return {\n success: true,\n transaction: txHash,\n network: requirements.network,\n payer: uptoPayload.authorization.owner,\n };\n } catch (error) {\n return {\n success: false,\n errorReason: `Settlement failed: ${error instanceof Error ? error.message : \"unknown\"}`,\n transaction: \"\",\n network: requirements.network,\n payer: uptoPayload.authorization.owner,\n };\n }\n }\n}\n\n/**\n * Factory function to create an UptoEvmFacilitatorScheme.\n *\n * @param signer - The EVM signer\n * @param config - Configuration options\n * @returns A new UptoEvmFacilitatorScheme instance\n */\nexport function createUptoEvmFacilitatorScheme(\n signer: FacilitatorEvmSigner,\n config?: UptoEvmFacilitatorSchemeConfig,\n): UptoEvmFacilitatorScheme {\n return new UptoEvmFacilitatorScheme(signer, config);\n}\n"],"mappings":"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","names":["token"]}
@@ -0,0 +1,129 @@
1
+ import {
2
+ createNonce
3
+ } from "./chunk-SYVPLXYV.mjs";
4
+ import {
5
+ __publicField
6
+ } from "./chunk-NSSMTXJJ.mjs";
7
+
8
+ // src/upto/client/scheme.ts
9
+ import { getAddress } from "viem";
10
+
11
+ // src/types.ts
12
+ var permitTypes = {
13
+ Permit: [
14
+ { name: "owner", type: "address" },
15
+ { name: "spender", type: "address" },
16
+ { name: "value", type: "uint256" },
17
+ { name: "nonce", type: "uint256" },
18
+ { name: "deadline", type: "uint256" }
19
+ ]
20
+ };
21
+ function isUptoEIP2612Payload(payload) {
22
+ if (typeof payload !== "object" || payload === null) return false;
23
+ const p = payload;
24
+ return "signature" in p && "authorization" in p && "paymentNonce" in p && typeof p.authorization === "object" && p.authorization !== null && "owner" in p.authorization && "spender" in p.authorization && "value" in p.authorization && "deadline" in p.authorization && "nonce" in p.authorization;
25
+ }
26
+
27
+ // src/upto/client/scheme.ts
28
+ var UptoEvmScheme = class {
29
+ /**
30
+ * Creates a new UptoEvmScheme instance.
31
+ *
32
+ * @param signer - The EVM signer for client operations
33
+ */
34
+ constructor(signer) {
35
+ this.signer = signer;
36
+ __publicField(this, "scheme", "upto");
37
+ }
38
+ /**
39
+ * Creates a payment payload for the Up-To scheme.
40
+ *
41
+ * The payload contains an EIP-2612 permit signature authorizing
42
+ * the router contract (or facilitator) to transfer up to the
43
+ * specified maximum amount.
44
+ *
45
+ * @param t402Version - The t402 protocol version
46
+ * @param paymentRequirements - The payment requirements (must include maxAmount)
47
+ * @returns Promise resolving to a payment payload
48
+ */
49
+ async createPaymentPayload(t402Version, paymentRequirements) {
50
+ if (paymentRequirements.scheme !== "upto") {
51
+ throw new Error(`Expected upto scheme, got ${paymentRequirements.scheme}`);
52
+ }
53
+ const extra = paymentRequirements.extra;
54
+ if (!extra?.name || !extra?.version) {
55
+ throw new Error("EIP-712 domain parameters (name, version) are required for upto scheme");
56
+ }
57
+ const maxAmount = paymentRequirements.maxAmount;
58
+ if (!maxAmount) {
59
+ throw new Error("maxAmount is required for upto scheme");
60
+ }
61
+ const spender = extra.routerAddress ? getAddress(extra.routerAddress) : getAddress(paymentRequirements.payTo);
62
+ const now = Math.floor(Date.now() / 1e3);
63
+ const deadline = now + paymentRequirements.maxTimeoutSeconds;
64
+ const permitNonce = extra.permitNonce ?? 0;
65
+ const authorization = {
66
+ owner: this.signer.address,
67
+ spender,
68
+ value: maxAmount,
69
+ deadline: deadline.toString(),
70
+ nonce: permitNonce
71
+ };
72
+ const signature = await this.signPermit(authorization, paymentRequirements);
73
+ const paymentNonce = createNonce();
74
+ const payload = {
75
+ signature,
76
+ authorization,
77
+ paymentNonce
78
+ };
79
+ return {
80
+ t402Version,
81
+ payload
82
+ };
83
+ }
84
+ /**
85
+ * Sign the EIP-2612 permit using EIP-712
86
+ *
87
+ * @param authorization - The permit authorization to sign
88
+ * @param requirements - The payment requirements
89
+ * @returns Promise resolving to the signature components
90
+ */
91
+ async signPermit(authorization, requirements) {
92
+ const chainId = parseInt(requirements.network.split(":")[1]);
93
+ const extra = requirements.extra;
94
+ const domain = {
95
+ name: extra.name,
96
+ version: extra.version,
97
+ chainId,
98
+ verifyingContract: getAddress(requirements.asset)
99
+ };
100
+ const message = {
101
+ owner: getAddress(authorization.owner),
102
+ spender: getAddress(authorization.spender),
103
+ value: BigInt(authorization.value),
104
+ nonce: BigInt(authorization.nonce),
105
+ deadline: BigInt(authorization.deadline)
106
+ };
107
+ const signature = await this.signer.signTypedData({
108
+ domain,
109
+ types: permitTypes,
110
+ primaryType: "Permit",
111
+ message
112
+ });
113
+ const r = `0x${signature.slice(2, 66)}`;
114
+ const s = `0x${signature.slice(66, 130)}`;
115
+ const v = parseInt(signature.slice(130, 132), 16);
116
+ return { v, r, s };
117
+ }
118
+ };
119
+ function createUptoEvmScheme(signer) {
120
+ return new UptoEvmScheme(signer);
121
+ }
122
+
123
+ export {
124
+ permitTypes,
125
+ isUptoEIP2612Payload,
126
+ UptoEvmScheme,
127
+ createUptoEvmScheme
128
+ };
129
+ //# sourceMappingURL=chunk-SURTCHSX.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/upto/client/scheme.ts","../../src/types.ts"],"sourcesContent":["import { PaymentPayload, PaymentRequirements, SchemeNetworkClient } from \"@t402/core/types\";\nimport { getAddress } from \"viem\";\nimport { permitTypes, UptoEIP2612Payload, UptoEvmExtra } from \"../../types\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { createNonce } from \"../../utils\";\n\n/**\n * EVM client implementation for the Up-To payment scheme.\n *\n * Uses EIP-2612 Permit to authorize up to a maximum amount,\n * enabling usage-based billing where the actual settlement\n * amount is determined by the server based on usage.\n *\n * @example\n * ```typescript\n * import { UptoEvmScheme } from \"@t402/evm/upto/client\";\n * import { privateKeyToAccount } from \"viem/accounts\";\n *\n * const signer = privateKeyToAccount(privateKey);\n * const scheme = new UptoEvmScheme(signer);\n *\n * // Client will register this with the t402 client\n * client.registerScheme(\"eip155:8453\", scheme);\n * ```\n */\nexport class UptoEvmScheme implements SchemeNetworkClient {\n readonly scheme = \"upto\";\n\n /**\n * Creates a new UptoEvmScheme instance.\n *\n * @param signer - The EVM signer for client operations\n */\n constructor(private readonly signer: ClientEvmSigner) {}\n\n /**\n * Creates a payment payload for the Up-To scheme.\n *\n * The payload contains an EIP-2612 permit signature authorizing\n * the router contract (or facilitator) to transfer up to the\n * specified maximum amount.\n *\n * @param t402Version - The t402 protocol version\n * @param paymentRequirements - The payment requirements (must include maxAmount)\n * @returns Promise resolving to a payment payload\n */\n async createPaymentPayload(\n t402Version: number,\n paymentRequirements: PaymentRequirements,\n ): Promise<Pick<PaymentPayload, \"t402Version\" | \"payload\">> {\n // Validate that this is an upto requirement\n if (paymentRequirements.scheme !== \"upto\") {\n throw new Error(`Expected upto scheme, got ${paymentRequirements.scheme}`);\n }\n\n const extra = paymentRequirements.extra as UptoEvmExtra;\n if (!extra?.name || !extra?.version) {\n throw new Error(\"EIP-712 domain parameters (name, version) are required for upto scheme\");\n }\n\n // Get maxAmount from the requirements\n const maxAmount = (paymentRequirements as unknown as { maxAmount: string }).maxAmount;\n if (!maxAmount) {\n throw new Error(\"maxAmount is required for upto scheme\");\n }\n\n // Determine the spender (router contract or payTo address)\n const spender = extra.routerAddress\n ? getAddress(extra.routerAddress)\n : getAddress(paymentRequirements.payTo);\n\n // Calculate deadline\n const now = Math.floor(Date.now() / 1000);\n const deadline = now + paymentRequirements.maxTimeoutSeconds;\n\n // Get the permit nonce from the token contract\n // Note: In a real implementation, this would query the token contract\n // For now, we'll use 0 and expect the caller to provide it via extra\n const permitNonce = (extra as { permitNonce?: number }).permitNonce ?? 0;\n\n // Create the permit authorization\n const authorization: UptoEIP2612Payload[\"authorization\"] = {\n owner: this.signer.address,\n spender,\n value: maxAmount,\n deadline: deadline.toString(),\n nonce: permitNonce,\n };\n\n // Sign the permit\n const signature = await this.signPermit(authorization, paymentRequirements);\n\n // Create unique payment nonce\n const paymentNonce = createNonce();\n\n const payload: UptoEIP2612Payload = {\n signature,\n authorization,\n paymentNonce,\n };\n\n return {\n t402Version,\n payload,\n };\n }\n\n /**\n * Sign the EIP-2612 permit using EIP-712\n *\n * @param authorization - The permit authorization to sign\n * @param requirements - The payment requirements\n * @returns Promise resolving to the signature components\n */\n private async signPermit(\n authorization: UptoEIP2612Payload[\"authorization\"],\n requirements: PaymentRequirements,\n ): Promise<UptoEIP2612Payload[\"signature\"]> {\n const chainId = parseInt(requirements.network.split(\":\")[1]);\n const extra = requirements.extra as UptoEvmExtra;\n\n const domain = {\n name: extra.name,\n version: extra.version,\n chainId,\n verifyingContract: getAddress(requirements.asset),\n };\n\n const message = {\n owner: getAddress(authorization.owner),\n spender: getAddress(authorization.spender),\n value: BigInt(authorization.value),\n nonce: BigInt(authorization.nonce),\n deadline: BigInt(authorization.deadline),\n };\n\n // Sign with EIP-712\n const signature = await this.signer.signTypedData({\n domain,\n types: permitTypes,\n primaryType: \"Permit\",\n message,\n });\n\n // Parse signature into v, r, s components\n const r = `0x${signature.slice(2, 66)}` as `0x${string}`;\n const s = `0x${signature.slice(66, 130)}` as `0x${string}`;\n const v = parseInt(signature.slice(130, 132), 16);\n\n return { v, r, s };\n }\n}\n\n/**\n * Factory function to create an UptoEvmScheme.\n *\n * @param signer - The EVM signer\n * @returns A new UptoEvmScheme instance\n */\nexport function createUptoEvmScheme(signer: ClientEvmSigner): UptoEvmScheme {\n return new UptoEvmScheme(signer);\n}\n","export type ExactEIP3009Payload = {\n signature?: `0x${string}`;\n authorization: {\n from: `0x${string}`;\n to: `0x${string}`;\n value: string;\n validAfter: string;\n validBefore: string;\n nonce: `0x${string}`;\n };\n};\n\nexport type ExactEvmPayloadV1 = ExactEIP3009Payload;\n\nexport type ExactEvmPayloadV2 = ExactEIP3009Payload;\n\n/**\n * Payload for exact-legacy scheme (approve + transferFrom pattern)\n * Used for legacy USDT and other tokens without EIP-3009 support\n */\nexport type ExactLegacyPayload = {\n signature?: `0x${string}`;\n authorization: {\n /** Payer address */\n from: `0x${string}`;\n /** Recipient address */\n to: `0x${string}`;\n /** Payment amount in token units */\n value: string;\n /** Unix timestamp after which the authorization is valid */\n validAfter: string;\n /** Unix timestamp before which the authorization is valid */\n validBefore: string;\n /** Unique nonce to prevent replay attacks */\n nonce: `0x${string}`;\n /** Facilitator address that will call transferFrom */\n spender: `0x${string}`;\n };\n};\n\n// ============================================================================\n// Up-To Scheme Types (EIP-2612 Permit)\n// ============================================================================\n\n/**\n * EIP-2612 Permit signature components\n */\nexport type PermitSignature = {\n v: number;\n r: `0x${string}`;\n s: `0x${string}`;\n};\n\n/**\n * EIP-2612 Permit authorization parameters\n */\nexport type PermitAuthorization = {\n /** Token owner address */\n owner: `0x${string}`;\n /** Spender address (router contract or facilitator) */\n spender: `0x${string}`;\n /** Maximum authorized value */\n value: string;\n /** Permit deadline (unix timestamp) */\n deadline: string;\n /** Permit nonce from token contract */\n nonce: number;\n};\n\n/**\n * Payload for upto scheme using EIP-2612 Permit\n */\nexport type UptoEIP2612Payload = {\n /** EIP-2612 permit signature */\n signature: PermitSignature;\n /** Permit authorization parameters */\n authorization: PermitAuthorization;\n /** Unique payment nonce (separate from permit nonce) */\n paymentNonce: `0x${string}`;\n};\n\n/**\n * Compact payload with combined signature bytes\n */\nexport type UptoEIP2612PayloadCompact = {\n /** Combined permit signature (65 bytes) */\n signature: `0x${string}`;\n /** Permit authorization parameters */\n authorization: PermitAuthorization;\n /** Unique payment nonce */\n paymentNonce: `0x${string}`;\n};\n\nexport type UptoEvmPayloadV2 = UptoEIP2612Payload | UptoEIP2612PayloadCompact;\n\n/**\n * Extra fields for upto scheme requirements on EVM\n */\nexport type UptoEvmExtra = {\n /** EIP-712 domain name (from token contract) */\n name: string;\n /** EIP-712 domain version */\n version: string;\n /** Router contract address for settlement */\n routerAddress?: `0x${string}`;\n /** Billing unit */\n unit?: string;\n /** Price per unit */\n unitPrice?: string;\n};\n\n/**\n * Settlement data for upto scheme\n */\nexport type UptoEvmSettlement = {\n /** Actual amount to settle (must be <= maxAmount) */\n settleAmount: string;\n /** Usage details for auditing */\n usageDetails?: {\n unitsConsumed?: number;\n unitPrice?: string;\n unitType?: string;\n startTime?: number;\n endTime?: number;\n };\n};\n\n/**\n * EIP-712 typed data for EIP-2612 Permit\n */\nexport const permitTypes = {\n Permit: [\n { name: \"owner\", type: \"address\" },\n { name: \"spender\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"deadline\", type: \"uint256\" },\n ],\n} as const;\n\n/**\n * Type guard for UptoEIP2612Payload\n *\n * @param payload - The payload to check\n * @returns True if the payload is a valid UptoEIP2612Payload\n */\nexport function isUptoEIP2612Payload(payload: unknown): payload is UptoEIP2612Payload {\n if (typeof payload !== \"object\" || payload === null) return false;\n const p = payload as Record<string, unknown>;\n return (\n \"signature\" in p &&\n \"authorization\" in p &&\n \"paymentNonce\" in p &&\n typeof p.authorization === \"object\" &&\n p.authorization !== null &&\n \"owner\" in (p.authorization as Record<string, unknown>) &&\n \"spender\" in (p.authorization as Record<string, unknown>) &&\n \"value\" in (p.authorization as Record<string, unknown>) &&\n \"deadline\" in (p.authorization as Record<string, unknown>) &&\n \"nonce\" in (p.authorization as Record<string, unknown>)\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,26 @@
1
+ // src/utils.ts
2
+ import { toHex } from "viem";
3
+ function getEvmChainId(network) {
4
+ const networkMap = {
5
+ base: 8453,
6
+ "base-sepolia": 84532,
7
+ ethereum: 1,
8
+ sepolia: 11155111,
9
+ polygon: 137,
10
+ "polygon-amoy": 80002
11
+ };
12
+ return networkMap[network] || 1;
13
+ }
14
+ function createNonce() {
15
+ const cryptoObj = typeof globalThis.crypto !== "undefined" ? globalThis.crypto : globalThis.crypto;
16
+ if (!cryptoObj) {
17
+ throw new Error("Crypto API not available");
18
+ }
19
+ return toHex(cryptoObj.getRandomValues(new Uint8Array(32)));
20
+ }
21
+
22
+ export {
23
+ getEvmChainId,
24
+ createNonce
25
+ };
26
+ //# sourceMappingURL=chunk-SYVPLXYV.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils.ts"],"sourcesContent":["import { toHex } from \"viem\";\nimport { Network } from \"@t402/core/types\";\n\n/**\n * Extract chain ID from network string (e.g., \"base-sepolia\" -> 84532)\n * Used by v1 implementations\n *\n * @param network - The network identifier\n * @returns The numeric chain ID\n */\nexport function getEvmChainId(network: Network): number {\n const networkMap: Record<string, number> = {\n base: 8453,\n \"base-sepolia\": 84532,\n ethereum: 1,\n sepolia: 11155111,\n polygon: 137,\n \"polygon-amoy\": 80002,\n };\n return networkMap[network] || 1;\n}\n\n/**\n * Create a random 32-byte nonce for authorization\n *\n * @returns A hex-encoded 32-byte nonce\n */\nexport function createNonce(): `0x${string}` {\n // Use dynamic import to avoid require() in ESM context\n const cryptoObj =\n typeof globalThis.crypto !== \"undefined\"\n ? globalThis.crypto\n : (globalThis as { crypto?: Crypto }).crypto;\n\n if (!cryptoObj) {\n throw new Error(\"Crypto API not available\");\n }\n\n return toHex(cryptoObj.getRandomValues(new Uint8Array(32)));\n}\n"],"mappings":";AAAA,SAAS,aAAa;AAUf,SAAS,cAAc,SAA0B;AACtD,QAAM,aAAqC;AAAA,IACzC,MAAM;AAAA,IACN,gBAAgB;AAAA,IAChB,UAAU;AAAA,IACV,SAAS;AAAA,IACT,SAAS;AAAA,IACT,gBAAgB;AAAA,EAClB;AACA,SAAO,WAAW,OAAO,KAAK;AAChC;AAOO,SAAS,cAA6B;AAE3C,QAAM,YACJ,OAAO,WAAW,WAAW,cACzB,WAAW,SACV,WAAmC;AAE1C,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,MAAM,0BAA0B;AAAA,EAC5C;AAEA,SAAO,MAAM,UAAU,gBAAgB,IAAI,WAAW,EAAE,CAAC,CAAC;AAC5D;","names":[]}