@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.
- package/dist/cjs/exact/client/index.d.ts +2 -2
- package/dist/cjs/exact/client/index.js +4 -2
- package/dist/cjs/exact/client/index.js.map +1 -1
- package/dist/cjs/exact/facilitator/index.d.ts +1 -1
- package/dist/cjs/exact/facilitator/index.js +40 -4
- package/dist/cjs/exact/facilitator/index.js.map +1 -1
- package/dist/cjs/exact/server/index.d.ts +1 -1
- package/dist/cjs/exact/server/index.js +301 -33
- package/dist/cjs/exact/server/index.js.map +1 -1
- package/dist/cjs/exact/v1/client/index.d.ts +1 -1
- package/dist/cjs/exact/v1/client/index.js +3 -1
- package/dist/cjs/exact/v1/client/index.js.map +1 -1
- package/dist/cjs/exact/v1/facilitator/index.d.ts +1 -1
- package/dist/cjs/exact/v1/facilitator/index.js +21 -2
- package/dist/cjs/exact/v1/facilitator/index.js.map +1 -1
- package/dist/cjs/index.d.ts +606 -352
- package/dist/cjs/index.js +1436 -268
- package/dist/cjs/index.js.map +1 -1
- package/dist/{esm/scheme-yqGaK9rK.d.mts → cjs/scheme-B4rXSKCN.d.ts} +18 -16
- package/dist/cjs/scheme-CIar5W2B.d.ts +200 -0
- package/dist/cjs/{scheme-OojTBKAz.d.ts → scheme-CjijeY7y.d.ts} +1 -1
- package/dist/{esm/signer-BkcAzwYi.d.mts → cjs/signer-DcavxxZt.d.ts} +1 -18
- package/dist/cjs/upto/client/index.d.ts +61 -0
- package/dist/cjs/upto/client/index.js +154 -0
- package/dist/cjs/upto/client/index.js.map +1 -0
- package/dist/cjs/upto/index.d.ts +111 -0
- package/dist/cjs/upto/index.js +1030 -0
- package/dist/cjs/upto/index.js.map +1 -0
- package/dist/cjs/v1/index.d.ts +1 -1
- package/dist/cjs/v1/index.js +3 -1
- package/dist/cjs/v1/index.js.map +1 -1
- package/dist/esm/{chunk-ACDQ5QNT.mjs → chunk-4FBTQTNM.mjs} +27 -5
- package/dist/esm/chunk-4FBTQTNM.mjs.map +1 -0
- package/dist/esm/chunk-IWSDEZKI.mjs +477 -0
- package/dist/esm/chunk-IWSDEZKI.mjs.map +1 -0
- package/dist/esm/{chunk-LGSG73NJ.mjs → chunk-LM5RZBVP.mjs} +9 -4
- package/dist/esm/{chunk-LGSG73NJ.mjs.map → chunk-LM5RZBVP.mjs.map} +1 -1
- package/dist/esm/chunk-NSSMTXJJ.mjs +8 -0
- package/dist/esm/chunk-NSSMTXJJ.mjs.map +1 -0
- package/dist/esm/chunk-SJ52GTJJ.mjs +411 -0
- package/dist/esm/chunk-SJ52GTJJ.mjs.map +1 -0
- package/dist/esm/chunk-SURTCHSX.mjs +129 -0
- package/dist/esm/chunk-SURTCHSX.mjs.map +1 -0
- package/dist/esm/chunk-SYVPLXYV.mjs +26 -0
- package/dist/esm/chunk-SYVPLXYV.mjs.map +1 -0
- package/dist/esm/{chunk-XYKAO6KJ.mjs → chunk-Y4U7Q543.mjs} +2 -25
- package/dist/esm/chunk-Y4U7Q543.mjs.map +1 -0
- package/dist/esm/{chunk-JBWWBRYY.mjs → chunk-ZWEYARER.mjs} +9 -4
- package/dist/esm/{chunk-JBWWBRYY.mjs.map → chunk-ZWEYARER.mjs.map} +1 -1
- package/dist/esm/exact/client/index.d.mts +2 -2
- package/dist/esm/exact/client/index.mjs +6 -4
- package/dist/esm/exact/client/index.mjs.map +1 -1
- package/dist/esm/exact/facilitator/index.d.mts +1 -1
- package/dist/esm/exact/facilitator/index.mjs +26 -5
- package/dist/esm/exact/facilitator/index.mjs.map +1 -1
- package/dist/esm/exact/server/index.d.mts +1 -1
- package/dist/esm/exact/server/index.mjs +29 -30
- package/dist/esm/exact/server/index.mjs.map +1 -1
- package/dist/esm/exact/v1/client/index.d.mts +1 -1
- package/dist/esm/exact/v1/client/index.mjs +4 -2
- package/dist/esm/exact/v1/facilitator/index.d.mts +1 -1
- package/dist/esm/exact/v1/facilitator/index.mjs +4 -2
- package/dist/esm/index.d.mts +606 -352
- package/dist/esm/index.mjs +626 -138
- package/dist/esm/index.mjs.map +1 -1
- package/dist/{cjs/scheme-yqGaK9rK.d.ts → esm/scheme-B4rXSKCN.d.mts} +18 -16
- package/dist/esm/scheme-DATfd6oM.d.mts +200 -0
- package/dist/esm/{scheme-D4mOqq9l.d.mts → scheme-Ddb0dG_F.d.mts} +1 -1
- package/dist/{cjs/signer-BkcAzwYi.d.ts → esm/signer-DcavxxZt.d.mts} +1 -18
- package/dist/esm/upto/client/index.d.mts +61 -0
- package/dist/esm/upto/client/index.mjs +11 -0
- package/dist/esm/upto/client/index.mjs.map +1 -0
- package/dist/esm/upto/index.d.mts +111 -0
- package/dist/esm/upto/index.mjs +26 -0
- package/dist/esm/upto/index.mjs.map +1 -0
- package/dist/esm/v1/index.d.mts +1 -1
- package/dist/esm/v1/index.mjs +5 -3
- package/package.json +30 -6
- package/dist/cjs/scheme-C6uD7PdY.d.ts +0 -130
- package/dist/esm/chunk-ACDQ5QNT.mjs.map +0 -1
- package/dist/esm/chunk-OEXW2OK2.mjs +0 -251
- package/dist/esm/chunk-OEXW2OK2.mjs.map +0 -1
- package/dist/esm/chunk-XYKAO6KJ.mjs.map +0 -1
package/dist/cjs/index.js
CHANGED
|
@@ -3,6 +3,7 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6
7
|
var __export = (target, all) => {
|
|
7
8
|
for (var name in all)
|
|
8
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -15,7 +16,9 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
16
|
}
|
|
16
17
|
return to;
|
|
17
18
|
};
|
|
19
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
18
20
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
21
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
19
22
|
|
|
20
23
|
// src/index.ts
|
|
21
24
|
var src_exports = {};
|
|
@@ -24,6 +27,7 @@ __export(src_exports, {
|
|
|
24
27
|
BUNDLER_METHODS: () => BUNDLER_METHODS,
|
|
25
28
|
BundlerClient: () => BundlerClient,
|
|
26
29
|
BundlerError: () => BundlerError,
|
|
30
|
+
CrossChainPaymentRouter: () => CrossChainPaymentRouter,
|
|
27
31
|
DEFAULT_GAS_LIMITS: () => DEFAULT_GAS_LIMITS,
|
|
28
32
|
ENTRYPOINT_V06_ADDRESS: () => ENTRYPOINT_V06_ADDRESS,
|
|
29
33
|
ENTRYPOINT_V07_ABI: () => ENTRYPOINT_V07_ABI,
|
|
@@ -35,49 +39,41 @@ __export(src_exports, {
|
|
|
35
39
|
GaslessT402Client: () => GaslessT402Client,
|
|
36
40
|
LAYERZERO_ENDPOINT_IDS: () => LAYERZERO_ENDPOINT_IDS,
|
|
37
41
|
LAYERZERO_ENDPOINT_V2: () => LAYERZERO_ENDPOINT_V2,
|
|
42
|
+
LAYERZERO_SCAN_BASE_URL: () => LAYERZERO_SCAN_BASE_URL,
|
|
43
|
+
LayerZeroScanClient: () => LayerZeroScanClient,
|
|
38
44
|
PaymasterClient: () => PaymasterClient,
|
|
39
45
|
PaymasterType: () => PaymasterType,
|
|
40
|
-
TOKEN_PRIORITY: () => TOKEN_PRIORITY,
|
|
41
|
-
TOKEN_REGISTRY: () => TOKEN_REGISTRY,
|
|
42
|
-
USDC_ADDRESSES: () => USDC_ADDRESSES,
|
|
43
|
-
USDT0_ADDRESSES: () => USDT0_ADDRESSES,
|
|
44
46
|
USDT0_OFT_ADDRESSES: () => USDT0_OFT_ADDRESSES,
|
|
45
|
-
|
|
47
|
+
UptoEvmFacilitatorScheme: () => UptoEvmFacilitatorScheme,
|
|
48
|
+
UptoEvmScheme: () => UptoEvmScheme,
|
|
49
|
+
UptoEvmServerScheme: () => UptoEvmServerScheme,
|
|
46
50
|
Usdt0Bridge: () => Usdt0Bridge,
|
|
47
51
|
UserOpBuilder: () => UserOpBuilder,
|
|
48
52
|
addressToBytes32: () => addressToBytes32,
|
|
49
|
-
authorizationTypes: () => authorizationTypes,
|
|
50
53
|
bytes32ToAddress: () => bytes32ToAddress,
|
|
51
54
|
createBundlerClient: () => createBundlerClient,
|
|
55
|
+
createCrossChainPaymentRouter: () => createCrossChainPaymentRouter,
|
|
52
56
|
createGaslessT402Client: () => createGaslessT402Client,
|
|
57
|
+
createLayerZeroScanClient: () => createLayerZeroScanClient,
|
|
53
58
|
createPaymasterClient: () => createPaymasterClient,
|
|
59
|
+
createUptoEvmFacilitatorScheme: () => createUptoEvmFacilitatorScheme,
|
|
60
|
+
createUptoEvmScheme: () => createUptoEvmScheme,
|
|
61
|
+
createUptoEvmServerScheme: () => createUptoEvmServerScheme,
|
|
54
62
|
createUsdt0Bridge: () => createUsdt0Bridge,
|
|
55
63
|
createUserOpBuilder: () => createUserOpBuilder,
|
|
56
64
|
decodePaymasterAndData: () => decodePaymasterAndData,
|
|
57
|
-
eip3009ABI: () => eip3009ABI,
|
|
58
65
|
encodePaymasterAndData: () => encodePaymasterAndData,
|
|
59
|
-
erc20LegacyABI: () => erc20LegacyABI,
|
|
60
66
|
getBridgeableChains: () => getBridgeableChains,
|
|
61
|
-
getDefaultToken: () => getDefaultToken,
|
|
62
|
-
getEIP712Domain: () => getEIP712Domain,
|
|
63
67
|
getEndpointId: () => getEndpointId,
|
|
64
|
-
getNetworkTokens: () => getNetworkTokens,
|
|
65
|
-
getNetworksForToken: () => getNetworksForToken,
|
|
66
|
-
getTokenByAddress: () => getTokenByAddress,
|
|
67
|
-
getTokenConfig: () => getTokenConfig,
|
|
68
|
-
getUsdt0Networks: () => getUsdt0Networks,
|
|
69
68
|
getUsdt0OftAddress: () => getUsdt0OftAddress,
|
|
70
|
-
legacyAuthorizationTypes: () => legacyAuthorizationTypes,
|
|
71
69
|
packAccountGasLimits: () => packAccountGasLimits,
|
|
72
70
|
packGasFees: () => packGasFees,
|
|
73
71
|
supportsBridging: () => supportsBridging,
|
|
74
|
-
supportsEIP3009: () => supportsEIP3009,
|
|
75
|
-
toClientEvmSigner: () => toClientEvmSigner,
|
|
76
|
-
toFacilitatorEvmSigner: () => toFacilitatorEvmSigner,
|
|
77
72
|
unpackAccountGasLimits: () => unpackAccountGasLimits,
|
|
78
73
|
unpackGasFees: () => unpackGasFees
|
|
79
74
|
});
|
|
80
75
|
module.exports = __toCommonJS(src_exports);
|
|
76
|
+
__reExport(src_exports, require("@t402/evm-core"), module.exports);
|
|
81
77
|
|
|
82
78
|
// src/exact/client/scheme.ts
|
|
83
79
|
var import_viem2 = require("viem");
|
|
@@ -104,54 +100,6 @@ var legacyAuthorizationTypes = {
|
|
|
104
100
|
{ name: "spender", type: "address" }
|
|
105
101
|
]
|
|
106
102
|
};
|
|
107
|
-
var eip3009ABI = [
|
|
108
|
-
{
|
|
109
|
-
inputs: [
|
|
110
|
-
{ name: "from", type: "address" },
|
|
111
|
-
{ name: "to", type: "address" },
|
|
112
|
-
{ name: "value", type: "uint256" },
|
|
113
|
-
{ name: "validAfter", type: "uint256" },
|
|
114
|
-
{ name: "validBefore", type: "uint256" },
|
|
115
|
-
{ name: "nonce", type: "bytes32" },
|
|
116
|
-
{ name: "v", type: "uint8" },
|
|
117
|
-
{ name: "r", type: "bytes32" },
|
|
118
|
-
{ name: "s", type: "bytes32" }
|
|
119
|
-
],
|
|
120
|
-
name: "transferWithAuthorization",
|
|
121
|
-
outputs: [],
|
|
122
|
-
stateMutability: "nonpayable",
|
|
123
|
-
type: "function"
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
inputs: [
|
|
127
|
-
{ name: "from", type: "address" },
|
|
128
|
-
{ name: "to", type: "address" },
|
|
129
|
-
{ name: "value", type: "uint256" },
|
|
130
|
-
{ name: "validAfter", type: "uint256" },
|
|
131
|
-
{ name: "validBefore", type: "uint256" },
|
|
132
|
-
{ name: "nonce", type: "bytes32" },
|
|
133
|
-
{ name: "signature", type: "bytes" }
|
|
134
|
-
],
|
|
135
|
-
name: "transferWithAuthorization",
|
|
136
|
-
outputs: [],
|
|
137
|
-
stateMutability: "nonpayable",
|
|
138
|
-
type: "function"
|
|
139
|
-
},
|
|
140
|
-
{
|
|
141
|
-
inputs: [{ name: "account", type: "address" }],
|
|
142
|
-
name: "balanceOf",
|
|
143
|
-
outputs: [{ name: "", type: "uint256" }],
|
|
144
|
-
stateMutability: "view",
|
|
145
|
-
type: "function"
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
inputs: [],
|
|
149
|
-
name: "version",
|
|
150
|
-
outputs: [{ name: "", type: "string" }],
|
|
151
|
-
stateMutability: "view",
|
|
152
|
-
type: "function"
|
|
153
|
-
}
|
|
154
|
-
];
|
|
155
103
|
var erc20LegacyABI = [
|
|
156
104
|
{
|
|
157
105
|
inputs: [{ name: "account", type: "address" }],
|
|
@@ -212,7 +160,7 @@ var ExactEvmScheme = class {
|
|
|
212
160
|
*/
|
|
213
161
|
constructor(signer) {
|
|
214
162
|
this.signer = signer;
|
|
215
|
-
this
|
|
163
|
+
__publicField(this, "scheme", "exact");
|
|
216
164
|
}
|
|
217
165
|
/**
|
|
218
166
|
* Creates a payment payload for the Exact scheme.
|
|
@@ -291,7 +239,7 @@ var ExactLegacyEvmScheme = class {
|
|
|
291
239
|
*/
|
|
292
240
|
constructor(signer) {
|
|
293
241
|
this.signer = signer;
|
|
294
|
-
this
|
|
242
|
+
__publicField(this, "scheme", "exact-legacy");
|
|
295
243
|
}
|
|
296
244
|
/**
|
|
297
245
|
* Creates a payment payload for the exact-legacy scheme.
|
|
@@ -366,6 +314,7 @@ var ExactLegacyEvmScheme = class {
|
|
|
366
314
|
|
|
367
315
|
// src/tokens.ts
|
|
368
316
|
var USDT0_ADDRESSES = {
|
|
317
|
+
// === Existing Networks ===
|
|
369
318
|
// Ethereum Mainnet - OFT Adapter (bridge endpoint)
|
|
370
319
|
"eip155:1": "0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee",
|
|
371
320
|
// Arbitrum One - Native USDT0
|
|
@@ -374,8 +323,38 @@ var USDT0_ADDRESSES = {
|
|
|
374
323
|
"eip155:57073": "0x0200C29006150606B650577BBE7B6248F58470c1",
|
|
375
324
|
// Berachain Mainnet
|
|
376
325
|
"eip155:80094": "0x779Ded0c9e1022225f8E0630b35a9b54bE713736",
|
|
377
|
-
// Unichain Mainnet
|
|
378
|
-
"eip155:130": "
|
|
326
|
+
// Unichain Mainnet (updated address)
|
|
327
|
+
"eip155:130": "0x9151434b16b9763660705744891fA906F660EcC5",
|
|
328
|
+
// === Phase 1: High Priority Networks ===
|
|
329
|
+
// Polygon PoS
|
|
330
|
+
"eip155:137": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F",
|
|
331
|
+
// Mantle
|
|
332
|
+
"eip155:5000": "0x779Ded0c9e1022225f8E0630b35a9b54bE713736",
|
|
333
|
+
// Optimism
|
|
334
|
+
"eip155:10": "0x01bFF41798a0BcF287b996046Ca68b395DbC1071",
|
|
335
|
+
// Plasma
|
|
336
|
+
"eip155:9745": "0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb",
|
|
337
|
+
// Sei
|
|
338
|
+
"eip155:1329": "0x9151434b16b9763660705744891fA906F660EcC5",
|
|
339
|
+
// Conflux eSpace
|
|
340
|
+
"eip155:1030": "0xaf37E8B6C9ED7f6318979f56Fc287d76c30847ff",
|
|
341
|
+
// Monad
|
|
342
|
+
"eip155:143": "0xe7cd86e13AC4309349F30B3435a9d337750fC82D",
|
|
343
|
+
// === Phase 2: Medium Priority Networks ===
|
|
344
|
+
// Rootstock (Bitcoin sidechain)
|
|
345
|
+
"eip155:30": "0x779dED0C9e1022225F8e0630b35A9B54Be713736",
|
|
346
|
+
// XLayer (OKX L2)
|
|
347
|
+
"eip155:196": "0x779Ded0c9e1022225f8E0630b35a9b54bE713736",
|
|
348
|
+
// Flare
|
|
349
|
+
"eip155:14": "0xe7cd86e13AC4309349F30B3435a9d337750fC82D",
|
|
350
|
+
// Corn
|
|
351
|
+
"eip155:21000000": "0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb",
|
|
352
|
+
// HyperEVM
|
|
353
|
+
"eip155:999": "0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb",
|
|
354
|
+
// MegaETH
|
|
355
|
+
"eip155:4326": "0xb8ce59fc3717ada4c02eadf9682a9e934f625ebb",
|
|
356
|
+
// Stable
|
|
357
|
+
"eip155:988": "0x779Ded0c9e1022225f8E0630b35a9b54bE713736"
|
|
379
358
|
};
|
|
380
359
|
var USDC_ADDRESSES = {
|
|
381
360
|
// Ethereum Mainnet
|
|
@@ -394,8 +373,18 @@ var USDC_ADDRESSES = {
|
|
|
394
373
|
var USDT_LEGACY_ADDRESSES = {
|
|
395
374
|
// Ethereum Mainnet
|
|
396
375
|
"eip155:1": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
|
397
|
-
// Polygon Mainnet
|
|
398
|
-
"eip155:137": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F"
|
|
376
|
+
// Polygon Mainnet (native USDT, not USDT0)
|
|
377
|
+
"eip155:137": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F",
|
|
378
|
+
// BNB Chain (BSC) - BEP-20 USDT
|
|
379
|
+
"eip155:56": "0x55d398326f99059fF775485246999027B3197955",
|
|
380
|
+
// Avalanche C-Chain
|
|
381
|
+
"eip155:43114": "0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7",
|
|
382
|
+
// Fantom
|
|
383
|
+
"eip155:250": "0x049d68029688eabf473097a2fc38ef61633a3c7a",
|
|
384
|
+
// Celo
|
|
385
|
+
"eip155:42220": "0x48065fbBE25f71C9282ddf5e1cD6D6A887483D5e",
|
|
386
|
+
// Kaia (formerly Klaytn)
|
|
387
|
+
"eip155:8217": "0xcee8faf64bb97a73bb51e115aa89c17ffa8dd167"
|
|
399
388
|
};
|
|
400
389
|
var TOKEN_REGISTRY = {
|
|
401
390
|
// Ethereum Mainnet
|
|
@@ -524,6 +513,15 @@ var TOKEN_REGISTRY = {
|
|
|
524
513
|
},
|
|
525
514
|
// Polygon Mainnet
|
|
526
515
|
"eip155:137": {
|
|
516
|
+
USDT0: {
|
|
517
|
+
address: USDT0_ADDRESSES["eip155:137"],
|
|
518
|
+
symbol: "USDT0",
|
|
519
|
+
name: "TetherToken",
|
|
520
|
+
version: "1",
|
|
521
|
+
decimals: 6,
|
|
522
|
+
tokenType: "eip3009",
|
|
523
|
+
priority: 1
|
|
524
|
+
},
|
|
527
525
|
USDC: {
|
|
528
526
|
address: USDC_ADDRESSES["eip155:137"],
|
|
529
527
|
symbol: "USDC",
|
|
@@ -542,18 +540,228 @@ var TOKEN_REGISTRY = {
|
|
|
542
540
|
tokenType: "legacy",
|
|
543
541
|
priority: 10
|
|
544
542
|
}
|
|
543
|
+
},
|
|
544
|
+
// === Phase 1: High Priority USDT0 Networks ===
|
|
545
|
+
// Optimism Mainnet
|
|
546
|
+
"eip155:10": {
|
|
547
|
+
USDT0: {
|
|
548
|
+
address: USDT0_ADDRESSES["eip155:10"],
|
|
549
|
+
symbol: "USDT0",
|
|
550
|
+
name: "TetherToken",
|
|
551
|
+
version: "1",
|
|
552
|
+
decimals: 6,
|
|
553
|
+
tokenType: "eip3009",
|
|
554
|
+
priority: 1
|
|
555
|
+
}
|
|
556
|
+
},
|
|
557
|
+
// Mantle Mainnet
|
|
558
|
+
"eip155:5000": {
|
|
559
|
+
USDT0: {
|
|
560
|
+
address: USDT0_ADDRESSES["eip155:5000"],
|
|
561
|
+
symbol: "USDT0",
|
|
562
|
+
name: "TetherToken",
|
|
563
|
+
version: "1",
|
|
564
|
+
decimals: 6,
|
|
565
|
+
tokenType: "eip3009",
|
|
566
|
+
priority: 1
|
|
567
|
+
}
|
|
568
|
+
},
|
|
569
|
+
// Plasma Mainnet
|
|
570
|
+
"eip155:9745": {
|
|
571
|
+
USDT0: {
|
|
572
|
+
address: USDT0_ADDRESSES["eip155:9745"],
|
|
573
|
+
symbol: "USDT0",
|
|
574
|
+
name: "TetherToken",
|
|
575
|
+
version: "1",
|
|
576
|
+
decimals: 6,
|
|
577
|
+
tokenType: "eip3009",
|
|
578
|
+
priority: 1
|
|
579
|
+
}
|
|
580
|
+
},
|
|
581
|
+
// Sei Mainnet
|
|
582
|
+
"eip155:1329": {
|
|
583
|
+
USDT0: {
|
|
584
|
+
address: USDT0_ADDRESSES["eip155:1329"],
|
|
585
|
+
symbol: "USDT0",
|
|
586
|
+
name: "TetherToken",
|
|
587
|
+
version: "1",
|
|
588
|
+
decimals: 6,
|
|
589
|
+
tokenType: "eip3009",
|
|
590
|
+
priority: 1
|
|
591
|
+
}
|
|
592
|
+
},
|
|
593
|
+
// Conflux eSpace Mainnet
|
|
594
|
+
"eip155:1030": {
|
|
595
|
+
USDT0: {
|
|
596
|
+
address: USDT0_ADDRESSES["eip155:1030"],
|
|
597
|
+
symbol: "USDT0",
|
|
598
|
+
name: "TetherToken",
|
|
599
|
+
version: "1",
|
|
600
|
+
decimals: 6,
|
|
601
|
+
tokenType: "eip3009",
|
|
602
|
+
priority: 1
|
|
603
|
+
}
|
|
604
|
+
},
|
|
605
|
+
// Monad Mainnet
|
|
606
|
+
"eip155:143": {
|
|
607
|
+
USDT0: {
|
|
608
|
+
address: USDT0_ADDRESSES["eip155:143"],
|
|
609
|
+
symbol: "USDT0",
|
|
610
|
+
name: "TetherToken",
|
|
611
|
+
version: "1",
|
|
612
|
+
decimals: 6,
|
|
613
|
+
tokenType: "eip3009",
|
|
614
|
+
priority: 1
|
|
615
|
+
}
|
|
616
|
+
},
|
|
617
|
+
// === Phase 2: Medium Priority USDT0 Networks ===
|
|
618
|
+
// Flare Mainnet
|
|
619
|
+
"eip155:14": {
|
|
620
|
+
USDT0: {
|
|
621
|
+
address: USDT0_ADDRESSES["eip155:14"],
|
|
622
|
+
symbol: "USDT0",
|
|
623
|
+
name: "TetherToken",
|
|
624
|
+
version: "1",
|
|
625
|
+
decimals: 6,
|
|
626
|
+
tokenType: "eip3009",
|
|
627
|
+
priority: 1
|
|
628
|
+
}
|
|
629
|
+
},
|
|
630
|
+
// Rootstock Mainnet (Bitcoin sidechain)
|
|
631
|
+
"eip155:30": {
|
|
632
|
+
USDT0: {
|
|
633
|
+
address: USDT0_ADDRESSES["eip155:30"],
|
|
634
|
+
symbol: "USDT0",
|
|
635
|
+
name: "TetherToken",
|
|
636
|
+
version: "1",
|
|
637
|
+
decimals: 6,
|
|
638
|
+
tokenType: "eip3009",
|
|
639
|
+
priority: 1
|
|
640
|
+
}
|
|
641
|
+
},
|
|
642
|
+
// XLayer Mainnet (OKX L2)
|
|
643
|
+
"eip155:196": {
|
|
644
|
+
USDT0: {
|
|
645
|
+
address: USDT0_ADDRESSES["eip155:196"],
|
|
646
|
+
symbol: "USDT0",
|
|
647
|
+
name: "TetherToken",
|
|
648
|
+
version: "1",
|
|
649
|
+
decimals: 6,
|
|
650
|
+
tokenType: "eip3009",
|
|
651
|
+
priority: 1
|
|
652
|
+
}
|
|
653
|
+
},
|
|
654
|
+
// Stable Mainnet
|
|
655
|
+
"eip155:988": {
|
|
656
|
+
USDT0: {
|
|
657
|
+
address: USDT0_ADDRESSES["eip155:988"],
|
|
658
|
+
symbol: "USDT0",
|
|
659
|
+
name: "TetherToken",
|
|
660
|
+
version: "1",
|
|
661
|
+
decimals: 6,
|
|
662
|
+
tokenType: "eip3009",
|
|
663
|
+
priority: 1
|
|
664
|
+
}
|
|
665
|
+
},
|
|
666
|
+
// HyperEVM Mainnet
|
|
667
|
+
"eip155:999": {
|
|
668
|
+
USDT0: {
|
|
669
|
+
address: USDT0_ADDRESSES["eip155:999"],
|
|
670
|
+
symbol: "USDT0",
|
|
671
|
+
name: "TetherToken",
|
|
672
|
+
version: "1",
|
|
673
|
+
decimals: 6,
|
|
674
|
+
tokenType: "eip3009",
|
|
675
|
+
priority: 1
|
|
676
|
+
}
|
|
677
|
+
},
|
|
678
|
+
// MegaETH Mainnet
|
|
679
|
+
"eip155:4326": {
|
|
680
|
+
USDT0: {
|
|
681
|
+
address: USDT0_ADDRESSES["eip155:4326"],
|
|
682
|
+
symbol: "USDT0",
|
|
683
|
+
name: "TetherToken",
|
|
684
|
+
version: "1",
|
|
685
|
+
decimals: 6,
|
|
686
|
+
tokenType: "eip3009",
|
|
687
|
+
priority: 1
|
|
688
|
+
}
|
|
689
|
+
},
|
|
690
|
+
// Corn Mainnet
|
|
691
|
+
"eip155:21000000": {
|
|
692
|
+
USDT0: {
|
|
693
|
+
address: USDT0_ADDRESSES["eip155:21000000"],
|
|
694
|
+
symbol: "USDT0",
|
|
695
|
+
name: "TetherToken",
|
|
696
|
+
version: "1",
|
|
697
|
+
decimals: 6,
|
|
698
|
+
tokenType: "eip3009",
|
|
699
|
+
priority: 1
|
|
700
|
+
}
|
|
701
|
+
},
|
|
702
|
+
// === Legacy USDT Networks (no EIP-3009 support) ===
|
|
703
|
+
// BNB Chain (BSC) - BEP-20 USDT
|
|
704
|
+
"eip155:56": {
|
|
705
|
+
USDT: {
|
|
706
|
+
address: USDT_LEGACY_ADDRESSES["eip155:56"],
|
|
707
|
+
symbol: "USDT",
|
|
708
|
+
name: "Tether USD",
|
|
709
|
+
version: "1",
|
|
710
|
+
decimals: 18,
|
|
711
|
+
// BSC USDT uses 18 decimals
|
|
712
|
+
tokenType: "legacy",
|
|
713
|
+
priority: 10
|
|
714
|
+
}
|
|
715
|
+
},
|
|
716
|
+
// Avalanche C-Chain
|
|
717
|
+
"eip155:43114": {
|
|
718
|
+
USDT: {
|
|
719
|
+
address: USDT_LEGACY_ADDRESSES["eip155:43114"],
|
|
720
|
+
symbol: "USDT",
|
|
721
|
+
name: "TetherToken",
|
|
722
|
+
version: "1",
|
|
723
|
+
decimals: 6,
|
|
724
|
+
tokenType: "legacy",
|
|
725
|
+
priority: 10
|
|
726
|
+
}
|
|
727
|
+
},
|
|
728
|
+
// Fantom
|
|
729
|
+
"eip155:250": {
|
|
730
|
+
USDT: {
|
|
731
|
+
address: USDT_LEGACY_ADDRESSES["eip155:250"],
|
|
732
|
+
symbol: "USDT",
|
|
733
|
+
name: "Frapped USDT",
|
|
734
|
+
version: "1",
|
|
735
|
+
decimals: 6,
|
|
736
|
+
tokenType: "legacy",
|
|
737
|
+
priority: 10
|
|
738
|
+
}
|
|
739
|
+
},
|
|
740
|
+
// Celo
|
|
741
|
+
"eip155:42220": {
|
|
742
|
+
USDT: {
|
|
743
|
+
address: USDT_LEGACY_ADDRESSES["eip155:42220"],
|
|
744
|
+
symbol: "USDT",
|
|
745
|
+
name: "Tether USD",
|
|
746
|
+
version: "1",
|
|
747
|
+
decimals: 18,
|
|
748
|
+
tokenType: "legacy",
|
|
749
|
+
priority: 10
|
|
750
|
+
}
|
|
751
|
+
},
|
|
752
|
+
// Kaia (formerly Klaytn)
|
|
753
|
+
"eip155:8217": {
|
|
754
|
+
USDT: {
|
|
755
|
+
address: USDT_LEGACY_ADDRESSES["eip155:8217"],
|
|
756
|
+
symbol: "USDT",
|
|
757
|
+
name: "Tether USD",
|
|
758
|
+
version: "1",
|
|
759
|
+
decimals: 6,
|
|
760
|
+
tokenType: "legacy",
|
|
761
|
+
priority: 10
|
|
762
|
+
}
|
|
545
763
|
}
|
|
546
764
|
};
|
|
547
|
-
var TOKEN_PRIORITY = {
|
|
548
|
-
USDT0: 1,
|
|
549
|
-
// Highest priority - gasless, cross-chain
|
|
550
|
-
USDC: 2,
|
|
551
|
-
// Second - wide support, EIP-3009
|
|
552
|
-
USDT: 10,
|
|
553
|
-
// Lower - requires approval transaction
|
|
554
|
-
DAI: 5
|
|
555
|
-
// Medium - good support
|
|
556
|
-
};
|
|
557
765
|
function getTokenConfig(network, symbol) {
|
|
558
766
|
return TOKEN_REGISTRY[network]?.[symbol.toUpperCase()];
|
|
559
767
|
}
|
|
@@ -572,42 +780,42 @@ function getTokenByAddress(network, address) {
|
|
|
572
780
|
const lowerAddress = address.toLowerCase();
|
|
573
781
|
return Object.values(tokens).find((t) => t.address.toLowerCase() === lowerAddress);
|
|
574
782
|
}
|
|
575
|
-
function supportsEIP3009(network, symbol) {
|
|
576
|
-
const config = getTokenConfig(network, symbol);
|
|
577
|
-
return config?.tokenType === "eip3009";
|
|
578
|
-
}
|
|
579
|
-
function getNetworksForToken(symbol) {
|
|
580
|
-
const networks = [];
|
|
581
|
-
for (const [network, tokens] of Object.entries(TOKEN_REGISTRY)) {
|
|
582
|
-
if (tokens[symbol.toUpperCase()]) {
|
|
583
|
-
networks.push(network);
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
return networks;
|
|
587
|
-
}
|
|
588
|
-
function getUsdt0Networks() {
|
|
589
|
-
return getNetworksForToken("USDT0");
|
|
590
|
-
}
|
|
591
|
-
function getEIP712Domain(network, tokenAddress, chainId) {
|
|
592
|
-
const token = getTokenByAddress(network, tokenAddress);
|
|
593
|
-
if (!token) return void 0;
|
|
594
|
-
return {
|
|
595
|
-
name: token.name,
|
|
596
|
-
version: token.version,
|
|
597
|
-
chainId,
|
|
598
|
-
verifyingContract: token.address
|
|
599
|
-
};
|
|
600
|
-
}
|
|
601
783
|
|
|
602
784
|
// src/exact-legacy/server/scheme.ts
|
|
603
785
|
var ExactLegacyEvmScheme2 = class {
|
|
786
|
+
/**
|
|
787
|
+
* Creates a new ExactLegacyEvmScheme instance.
|
|
788
|
+
*
|
|
789
|
+
* @param config - Optional configuration options for the scheme
|
|
790
|
+
*/
|
|
604
791
|
constructor(config = {}) {
|
|
605
|
-
this
|
|
606
|
-
this
|
|
792
|
+
__publicField(this, "scheme", "exact-legacy");
|
|
793
|
+
__publicField(this, "moneyParsers", []);
|
|
794
|
+
__publicField(this, "config");
|
|
607
795
|
this.config = config;
|
|
608
796
|
}
|
|
797
|
+
/**
|
|
798
|
+
* Get all supported networks that have legacy tokens
|
|
799
|
+
*
|
|
800
|
+
* @returns Array of network identifiers with legacy token support
|
|
801
|
+
*/
|
|
802
|
+
static getSupportedNetworks() {
|
|
803
|
+
return Object.keys(USDT_LEGACY_ADDRESSES);
|
|
804
|
+
}
|
|
805
|
+
/**
|
|
806
|
+
* Check if a network has legacy token support
|
|
807
|
+
*
|
|
808
|
+
* @param network - The network identifier to check
|
|
809
|
+
* @returns True if the network has legacy token support
|
|
810
|
+
*/
|
|
811
|
+
static isNetworkSupported(network) {
|
|
812
|
+
return network in USDT_LEGACY_ADDRESSES;
|
|
813
|
+
}
|
|
609
814
|
/**
|
|
610
815
|
* Register a custom money parser in the parser chain.
|
|
816
|
+
*
|
|
817
|
+
* @param parser - Custom function to convert amount to AssetAmount
|
|
818
|
+
* @returns The scheme instance for method chaining
|
|
611
819
|
*/
|
|
612
820
|
registerMoneyParser(parser) {
|
|
613
821
|
this.moneyParsers.push(parser);
|
|
@@ -615,6 +823,10 @@ var ExactLegacyEvmScheme2 = class {
|
|
|
615
823
|
}
|
|
616
824
|
/**
|
|
617
825
|
* Parses a price into an asset amount for legacy tokens.
|
|
826
|
+
*
|
|
827
|
+
* @param price - The price to parse (Money or AssetAmount)
|
|
828
|
+
* @param network - The network identifier in CAIP-2 format
|
|
829
|
+
* @returns Promise resolving to the parsed asset amount
|
|
618
830
|
*/
|
|
619
831
|
async parsePrice(price, network) {
|
|
620
832
|
if (typeof price === "object" && price !== null && "amount" in price) {
|
|
@@ -642,6 +854,15 @@ var ExactLegacyEvmScheme2 = class {
|
|
|
642
854
|
/**
|
|
643
855
|
* Build payment requirements for this scheme/network combination.
|
|
644
856
|
* Adds the spender (facilitator) address to the extra field.
|
|
857
|
+
*
|
|
858
|
+
* @param paymentRequirements - The base payment requirements to enhance
|
|
859
|
+
* @param supportedKind - The supported kind from facilitator
|
|
860
|
+
* @param supportedKind.t402Version - The t402 protocol version
|
|
861
|
+
* @param supportedKind.scheme - The logical payment scheme identifier
|
|
862
|
+
* @param supportedKind.network - The network identifier in CAIP-2 format
|
|
863
|
+
* @param supportedKind.extra - Optional extra metadata with spender address
|
|
864
|
+
* @param extensionKeys - Extension keys supported by the facilitator (unused)
|
|
865
|
+
* @returns Promise resolving to enhanced payment requirements
|
|
645
866
|
*/
|
|
646
867
|
enhancePaymentRequirements(paymentRequirements, supportedKind, extensionKeys) {
|
|
647
868
|
void extensionKeys;
|
|
@@ -657,6 +878,9 @@ var ExactLegacyEvmScheme2 = class {
|
|
|
657
878
|
}
|
|
658
879
|
/**
|
|
659
880
|
* Parse Money (string | number) to a decimal number.
|
|
881
|
+
*
|
|
882
|
+
* @param money - The money value to parse (e.g., "$1.50" or 1.50)
|
|
883
|
+
* @returns The decimal number representation
|
|
660
884
|
*/
|
|
661
885
|
parseMoneyToDecimal(money) {
|
|
662
886
|
if (typeof money === "number") {
|
|
@@ -671,6 +895,10 @@ var ExactLegacyEvmScheme2 = class {
|
|
|
671
895
|
}
|
|
672
896
|
/**
|
|
673
897
|
* Default money conversion implementation for legacy tokens.
|
|
898
|
+
*
|
|
899
|
+
* @param amount - The decimal amount to convert (e.g., 1.50)
|
|
900
|
+
* @param network - The network identifier in CAIP-2 format
|
|
901
|
+
* @returns The asset amount in token units
|
|
674
902
|
*/
|
|
675
903
|
defaultMoneyConversion(amount, network) {
|
|
676
904
|
const token = this.getDefaultAsset(network);
|
|
@@ -688,6 +916,10 @@ var ExactLegacyEvmScheme2 = class {
|
|
|
688
916
|
}
|
|
689
917
|
/**
|
|
690
918
|
* Convert decimal amount to token units
|
|
919
|
+
*
|
|
920
|
+
* @param decimalAmount - The decimal amount as a string (e.g., "1.50")
|
|
921
|
+
* @param decimals - The number of decimal places for the token
|
|
922
|
+
* @returns The token amount as a string in smallest units
|
|
691
923
|
*/
|
|
692
924
|
convertToTokenAmount(decimalAmount, decimals) {
|
|
693
925
|
const amount = parseFloat(decimalAmount);
|
|
@@ -699,6 +931,9 @@ var ExactLegacyEvmScheme2 = class {
|
|
|
699
931
|
}
|
|
700
932
|
/**
|
|
701
933
|
* Get the default legacy token for a network.
|
|
934
|
+
*
|
|
935
|
+
* @param network - The network identifier in CAIP-2 format
|
|
936
|
+
* @returns The token configuration for the default legacy token
|
|
702
937
|
*/
|
|
703
938
|
getDefaultAsset(network) {
|
|
704
939
|
if (this.config.preferredToken) {
|
|
@@ -718,18 +953,6 @@ var ExactLegacyEvmScheme2 = class {
|
|
|
718
953
|
}
|
|
719
954
|
throw new Error(`No legacy tokens configured for network ${network}`);
|
|
720
955
|
}
|
|
721
|
-
/**
|
|
722
|
-
* Get all supported networks that have legacy tokens
|
|
723
|
-
*/
|
|
724
|
-
static getSupportedNetworks() {
|
|
725
|
-
return Object.keys(USDT_LEGACY_ADDRESSES);
|
|
726
|
-
}
|
|
727
|
-
/**
|
|
728
|
-
* Check if a network has legacy token support
|
|
729
|
-
*/
|
|
730
|
-
static isNetworkSupported(network) {
|
|
731
|
-
return network in USDT_LEGACY_ADDRESSES;
|
|
732
|
-
}
|
|
733
956
|
};
|
|
734
957
|
|
|
735
958
|
// src/exact-legacy/facilitator/scheme.ts
|
|
@@ -743,8 +966,9 @@ var ExactLegacyEvmScheme3 = class {
|
|
|
743
966
|
*/
|
|
744
967
|
constructor(signer, config) {
|
|
745
968
|
this.signer = signer;
|
|
746
|
-
this
|
|
747
|
-
this
|
|
969
|
+
__publicField(this, "scheme", "exact-legacy");
|
|
970
|
+
__publicField(this, "caipFamily", "eip155:*");
|
|
971
|
+
__publicField(this, "config");
|
|
748
972
|
this.config = {
|
|
749
973
|
minAllowanceRatio: config?.minAllowanceRatio ?? 1
|
|
750
974
|
};
|
|
@@ -769,6 +993,9 @@ var ExactLegacyEvmScheme3 = class {
|
|
|
769
993
|
}
|
|
770
994
|
/**
|
|
771
995
|
* Get signer addresses used by this facilitator.
|
|
996
|
+
*
|
|
997
|
+
* @param network - The network identifier (unused, returns same addresses for all networks)
|
|
998
|
+
* @returns Array of signer addresses
|
|
772
999
|
*/
|
|
773
1000
|
getSigners(network) {
|
|
774
1001
|
void network;
|
|
@@ -776,6 +1003,10 @@ var ExactLegacyEvmScheme3 = class {
|
|
|
776
1003
|
}
|
|
777
1004
|
/**
|
|
778
1005
|
* Verifies a payment payload.
|
|
1006
|
+
*
|
|
1007
|
+
* @param payload - The payment payload to verify
|
|
1008
|
+
* @param requirements - The payment requirements to verify against
|
|
1009
|
+
* @returns Promise resolving to verification response with validity status
|
|
779
1010
|
*/
|
|
780
1011
|
async verify(payload, requirements) {
|
|
781
1012
|
const legacyPayload = payload.payload;
|
|
@@ -910,84 +1141,580 @@ var ExactLegacyEvmScheme3 = class {
|
|
|
910
1141
|
if (BigInt(legacyPayload.authorization.value) < BigInt(requirements.amount)) {
|
|
911
1142
|
return {
|
|
912
1143
|
isValid: false,
|
|
913
|
-
invalidReason: "insufficient_amount",
|
|
914
|
-
payer: legacyPayload.authorization.from
|
|
1144
|
+
invalidReason: "insufficient_amount",
|
|
1145
|
+
payer: legacyPayload.authorization.from
|
|
1146
|
+
};
|
|
1147
|
+
}
|
|
1148
|
+
return {
|
|
1149
|
+
isValid: true,
|
|
1150
|
+
invalidReason: void 0,
|
|
1151
|
+
payer: legacyPayload.authorization.from
|
|
1152
|
+
};
|
|
1153
|
+
}
|
|
1154
|
+
/**
|
|
1155
|
+
* Settles a payment by executing transferFrom.
|
|
1156
|
+
*
|
|
1157
|
+
* @param payload - The payment payload containing transfer authorization
|
|
1158
|
+
* @param requirements - The payment requirements specifying amount and recipient
|
|
1159
|
+
* @returns Promise resolving to settlement response with transaction hash
|
|
1160
|
+
*/
|
|
1161
|
+
async settle(payload, requirements) {
|
|
1162
|
+
const legacyPayload = payload.payload;
|
|
1163
|
+
const valid = await this.verify(payload, requirements);
|
|
1164
|
+
if (!valid.isValid) {
|
|
1165
|
+
return {
|
|
1166
|
+
success: false,
|
|
1167
|
+
network: payload.accepted.network,
|
|
1168
|
+
transaction: "",
|
|
1169
|
+
errorReason: valid.invalidReason ?? "invalid_payment",
|
|
1170
|
+
payer: legacyPayload.authorization.from
|
|
1171
|
+
};
|
|
1172
|
+
}
|
|
1173
|
+
try {
|
|
1174
|
+
const tx = await this.signer.writeContract({
|
|
1175
|
+
address: (0, import_viem4.getAddress)(requirements.asset),
|
|
1176
|
+
abi: erc20LegacyABI,
|
|
1177
|
+
functionName: "transferFrom",
|
|
1178
|
+
args: [
|
|
1179
|
+
(0, import_viem4.getAddress)(legacyPayload.authorization.from),
|
|
1180
|
+
(0, import_viem4.getAddress)(legacyPayload.authorization.to),
|
|
1181
|
+
BigInt(legacyPayload.authorization.value)
|
|
1182
|
+
]
|
|
1183
|
+
});
|
|
1184
|
+
const receipt = await this.signer.waitForTransactionReceipt({ hash: tx });
|
|
1185
|
+
if (receipt.status !== "success") {
|
|
1186
|
+
return {
|
|
1187
|
+
success: false,
|
|
1188
|
+
errorReason: "transaction_failed",
|
|
1189
|
+
transaction: tx,
|
|
1190
|
+
network: payload.accepted.network,
|
|
1191
|
+
payer: legacyPayload.authorization.from
|
|
1192
|
+
};
|
|
1193
|
+
}
|
|
1194
|
+
return {
|
|
1195
|
+
success: true,
|
|
1196
|
+
transaction: tx,
|
|
1197
|
+
network: payload.accepted.network,
|
|
1198
|
+
payer: legacyPayload.authorization.from
|
|
1199
|
+
};
|
|
1200
|
+
} catch (error) {
|
|
1201
|
+
console.error("Failed to settle legacy transaction:", error);
|
|
1202
|
+
return {
|
|
1203
|
+
success: false,
|
|
1204
|
+
errorReason: "settlement_failed",
|
|
1205
|
+
transaction: "",
|
|
1206
|
+
network: payload.accepted.network,
|
|
1207
|
+
payer: legacyPayload.authorization.from
|
|
1208
|
+
};
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
};
|
|
1212
|
+
|
|
1213
|
+
// src/upto/client/scheme.ts
|
|
1214
|
+
var import_viem5 = require("viem");
|
|
1215
|
+
|
|
1216
|
+
// src/types.ts
|
|
1217
|
+
var permitTypes = {
|
|
1218
|
+
Permit: [
|
|
1219
|
+
{ name: "owner", type: "address" },
|
|
1220
|
+
{ name: "spender", type: "address" },
|
|
1221
|
+
{ name: "value", type: "uint256" },
|
|
1222
|
+
{ name: "nonce", type: "uint256" },
|
|
1223
|
+
{ name: "deadline", type: "uint256" }
|
|
1224
|
+
]
|
|
1225
|
+
};
|
|
1226
|
+
function isUptoEIP2612Payload(payload) {
|
|
1227
|
+
if (typeof payload !== "object" || payload === null) return false;
|
|
1228
|
+
const p = payload;
|
|
1229
|
+
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;
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
// src/upto/client/scheme.ts
|
|
1233
|
+
var UptoEvmScheme = class {
|
|
1234
|
+
/**
|
|
1235
|
+
* Creates a new UptoEvmScheme instance.
|
|
1236
|
+
*
|
|
1237
|
+
* @param signer - The EVM signer for client operations
|
|
1238
|
+
*/
|
|
1239
|
+
constructor(signer) {
|
|
1240
|
+
this.signer = signer;
|
|
1241
|
+
__publicField(this, "scheme", "upto");
|
|
1242
|
+
}
|
|
1243
|
+
/**
|
|
1244
|
+
* Creates a payment payload for the Up-To scheme.
|
|
1245
|
+
*
|
|
1246
|
+
* The payload contains an EIP-2612 permit signature authorizing
|
|
1247
|
+
* the router contract (or facilitator) to transfer up to the
|
|
1248
|
+
* specified maximum amount.
|
|
1249
|
+
*
|
|
1250
|
+
* @param t402Version - The t402 protocol version
|
|
1251
|
+
* @param paymentRequirements - The payment requirements (must include maxAmount)
|
|
1252
|
+
* @returns Promise resolving to a payment payload
|
|
1253
|
+
*/
|
|
1254
|
+
async createPaymentPayload(t402Version, paymentRequirements) {
|
|
1255
|
+
if (paymentRequirements.scheme !== "upto") {
|
|
1256
|
+
throw new Error(`Expected upto scheme, got ${paymentRequirements.scheme}`);
|
|
1257
|
+
}
|
|
1258
|
+
const extra = paymentRequirements.extra;
|
|
1259
|
+
if (!extra?.name || !extra?.version) {
|
|
1260
|
+
throw new Error("EIP-712 domain parameters (name, version) are required for upto scheme");
|
|
1261
|
+
}
|
|
1262
|
+
const maxAmount = paymentRequirements.maxAmount;
|
|
1263
|
+
if (!maxAmount) {
|
|
1264
|
+
throw new Error("maxAmount is required for upto scheme");
|
|
1265
|
+
}
|
|
1266
|
+
const spender = extra.routerAddress ? (0, import_viem5.getAddress)(extra.routerAddress) : (0, import_viem5.getAddress)(paymentRequirements.payTo);
|
|
1267
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1268
|
+
const deadline = now + paymentRequirements.maxTimeoutSeconds;
|
|
1269
|
+
const permitNonce = extra.permitNonce ?? 0;
|
|
1270
|
+
const authorization = {
|
|
1271
|
+
owner: this.signer.address,
|
|
1272
|
+
spender,
|
|
1273
|
+
value: maxAmount,
|
|
1274
|
+
deadline: deadline.toString(),
|
|
1275
|
+
nonce: permitNonce
|
|
1276
|
+
};
|
|
1277
|
+
const signature = await this.signPermit(authorization, paymentRequirements);
|
|
1278
|
+
const paymentNonce = createNonce();
|
|
1279
|
+
const payload = {
|
|
1280
|
+
signature,
|
|
1281
|
+
authorization,
|
|
1282
|
+
paymentNonce
|
|
1283
|
+
};
|
|
1284
|
+
return {
|
|
1285
|
+
t402Version,
|
|
1286
|
+
payload
|
|
1287
|
+
};
|
|
1288
|
+
}
|
|
1289
|
+
/**
|
|
1290
|
+
* Sign the EIP-2612 permit using EIP-712
|
|
1291
|
+
*
|
|
1292
|
+
* @param authorization - The permit authorization to sign
|
|
1293
|
+
* @param requirements - The payment requirements
|
|
1294
|
+
* @returns Promise resolving to the signature components
|
|
1295
|
+
*/
|
|
1296
|
+
async signPermit(authorization, requirements) {
|
|
1297
|
+
const chainId = parseInt(requirements.network.split(":")[1]);
|
|
1298
|
+
const extra = requirements.extra;
|
|
1299
|
+
const domain = {
|
|
1300
|
+
name: extra.name,
|
|
1301
|
+
version: extra.version,
|
|
1302
|
+
chainId,
|
|
1303
|
+
verifyingContract: (0, import_viem5.getAddress)(requirements.asset)
|
|
1304
|
+
};
|
|
1305
|
+
const message = {
|
|
1306
|
+
owner: (0, import_viem5.getAddress)(authorization.owner),
|
|
1307
|
+
spender: (0, import_viem5.getAddress)(authorization.spender),
|
|
1308
|
+
value: BigInt(authorization.value),
|
|
1309
|
+
nonce: BigInt(authorization.nonce),
|
|
1310
|
+
deadline: BigInt(authorization.deadline)
|
|
1311
|
+
};
|
|
1312
|
+
const signature = await this.signer.signTypedData({
|
|
1313
|
+
domain,
|
|
1314
|
+
types: permitTypes,
|
|
1315
|
+
primaryType: "Permit",
|
|
1316
|
+
message
|
|
1317
|
+
});
|
|
1318
|
+
const r = `0x${signature.slice(2, 66)}`;
|
|
1319
|
+
const s = `0x${signature.slice(66, 130)}`;
|
|
1320
|
+
const v = parseInt(signature.slice(130, 132), 16);
|
|
1321
|
+
return { v, r, s };
|
|
1322
|
+
}
|
|
1323
|
+
};
|
|
1324
|
+
function createUptoEvmScheme(signer) {
|
|
1325
|
+
return new UptoEvmScheme(signer);
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
// src/upto/server/scheme.ts
|
|
1329
|
+
var import_types2 = require("@t402/core/types");
|
|
1330
|
+
var UptoEvmServerScheme = class {
|
|
1331
|
+
/**
|
|
1332
|
+
* Creates a new UptoEvmServerScheme instance.
|
|
1333
|
+
*
|
|
1334
|
+
* @param config - Optional configuration options for the scheme
|
|
1335
|
+
*/
|
|
1336
|
+
constructor(config = {}) {
|
|
1337
|
+
__publicField(this, "scheme", "upto");
|
|
1338
|
+
__publicField(this, "moneyParsers", []);
|
|
1339
|
+
__publicField(this, "config");
|
|
1340
|
+
this.config = config;
|
|
1341
|
+
}
|
|
1342
|
+
/**
|
|
1343
|
+
* Get all supported networks
|
|
1344
|
+
*
|
|
1345
|
+
* @returns Array of network identifiers in CAIP-2 format
|
|
1346
|
+
*/
|
|
1347
|
+
static getSupportedNetworks() {
|
|
1348
|
+
return Object.keys(TOKEN_REGISTRY);
|
|
1349
|
+
}
|
|
1350
|
+
/**
|
|
1351
|
+
* Check if a network is supported
|
|
1352
|
+
*
|
|
1353
|
+
* @param network - The network identifier to check
|
|
1354
|
+
* @returns True if the network is supported
|
|
1355
|
+
*/
|
|
1356
|
+
static isNetworkSupported(network) {
|
|
1357
|
+
return network in TOKEN_REGISTRY;
|
|
1358
|
+
}
|
|
1359
|
+
/**
|
|
1360
|
+
* Register a custom money parser in the parser chain.
|
|
1361
|
+
*
|
|
1362
|
+
* @param parser - Custom function to convert amount to AssetAmount
|
|
1363
|
+
* @returns The server instance for chaining
|
|
1364
|
+
*/
|
|
1365
|
+
registerMoneyParser(parser) {
|
|
1366
|
+
this.moneyParsers.push(parser);
|
|
1367
|
+
return this;
|
|
1368
|
+
}
|
|
1369
|
+
/**
|
|
1370
|
+
* Parses a price into an asset amount for maxAmount.
|
|
1371
|
+
*
|
|
1372
|
+
* @param price - The price to parse (represents maxAmount)
|
|
1373
|
+
* @param network - The network to use
|
|
1374
|
+
* @returns Promise resolving to the parsed asset amount
|
|
1375
|
+
*/
|
|
1376
|
+
async parsePrice(price, network) {
|
|
1377
|
+
if (typeof price === "object" && price !== null && "amount" in price) {
|
|
1378
|
+
if (!price.asset) {
|
|
1379
|
+
const token2 = this.getPreferredToken(network);
|
|
1380
|
+
return { amount: price.amount, asset: token2.address };
|
|
1381
|
+
}
|
|
1382
|
+
return price;
|
|
1383
|
+
}
|
|
1384
|
+
const decimalAmount = this.parseToDecimal(price);
|
|
1385
|
+
for (const parser of this.moneyParsers) {
|
|
1386
|
+
const result = await parser(decimalAmount, network);
|
|
1387
|
+
if (result !== null) {
|
|
1388
|
+
return result;
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
const token = this.getPreferredToken(network);
|
|
1392
|
+
const amount = Math.floor(decimalAmount * 10 ** token.decimals).toString();
|
|
1393
|
+
return {
|
|
1394
|
+
amount,
|
|
1395
|
+
asset: token.address
|
|
1396
|
+
};
|
|
1397
|
+
}
|
|
1398
|
+
/**
|
|
1399
|
+
* Enhance payment requirements for the upto scheme.
|
|
1400
|
+
*
|
|
1401
|
+
* @param paymentRequirements - Base payment requirements
|
|
1402
|
+
* @param supportedKind - The supported kind from facilitator
|
|
1403
|
+
* @param supportedKind.t402Version - T402 protocol version
|
|
1404
|
+
* @param supportedKind.scheme - Payment scheme
|
|
1405
|
+
* @param supportedKind.network - Network identifier
|
|
1406
|
+
* @param supportedKind.extra - Extra configuration
|
|
1407
|
+
* @param facilitatorExtensions - Extensions supported by the facilitator
|
|
1408
|
+
* @returns Enhanced payment requirements for upto scheme
|
|
1409
|
+
*/
|
|
1410
|
+
async enhancePaymentRequirements(paymentRequirements, supportedKind, facilitatorExtensions) {
|
|
1411
|
+
void facilitatorExtensions;
|
|
1412
|
+
const network = supportedKind.network;
|
|
1413
|
+
const token = getTokenByAddress(network, paymentRequirements.asset);
|
|
1414
|
+
if (!token) {
|
|
1415
|
+
throw new Error(`Unknown token ${paymentRequirements.asset} on ${network}`);
|
|
1416
|
+
}
|
|
1417
|
+
const extra = {
|
|
1418
|
+
// EIP-712 domain (required for permit signing)
|
|
1419
|
+
name: token.name,
|
|
1420
|
+
version: token.version,
|
|
1421
|
+
// Router address (optional - if set, permits go to router)
|
|
1422
|
+
...this.config.routerAddress && { routerAddress: this.config.routerAddress },
|
|
1423
|
+
// Billing unit info (optional)
|
|
1424
|
+
...this.config.defaultUnit && { unit: this.config.defaultUnit },
|
|
1425
|
+
...this.config.defaultUnitPrice && { unitPrice: this.config.defaultUnitPrice },
|
|
1426
|
+
// Upto-specific fields
|
|
1427
|
+
maxAmount: paymentRequirements.amount,
|
|
1428
|
+
minAmount: import_types2.UPTO_DEFAULTS.MIN_AMOUNT,
|
|
1429
|
+
// Merge any facilitator extra
|
|
1430
|
+
...supportedKind.extra
|
|
1431
|
+
};
|
|
1432
|
+
return {
|
|
1433
|
+
...paymentRequirements,
|
|
1434
|
+
scheme: "upto",
|
|
1435
|
+
extra
|
|
1436
|
+
};
|
|
1437
|
+
}
|
|
1438
|
+
/**
|
|
1439
|
+
* Get the preferred token for a network.
|
|
1440
|
+
*
|
|
1441
|
+
* @param network - The network identifier
|
|
1442
|
+
* @returns Token configuration
|
|
1443
|
+
* @throws Error if no token is found for the network
|
|
1444
|
+
*/
|
|
1445
|
+
getPreferredToken(network) {
|
|
1446
|
+
if (this.config.preferredToken) {
|
|
1447
|
+
const token = getTokenConfig(network, this.config.preferredToken);
|
|
1448
|
+
if (token) return token;
|
|
1449
|
+
}
|
|
1450
|
+
const defaultToken = getDefaultToken(network);
|
|
1451
|
+
if (!defaultToken) {
|
|
1452
|
+
throw new Error(`No token configured for network ${network}`);
|
|
1453
|
+
}
|
|
1454
|
+
return defaultToken;
|
|
1455
|
+
}
|
|
1456
|
+
/**
|
|
1457
|
+
* Parse price to decimal value.
|
|
1458
|
+
*
|
|
1459
|
+
* @param price - Price string or number
|
|
1460
|
+
* @returns Decimal amount
|
|
1461
|
+
*/
|
|
1462
|
+
parseToDecimal(price) {
|
|
1463
|
+
if (typeof price === "number") {
|
|
1464
|
+
return price;
|
|
1465
|
+
}
|
|
1466
|
+
const cleaned = price.replace(/[$,]/g, "").trim();
|
|
1467
|
+
const parsed = parseFloat(cleaned);
|
|
1468
|
+
if (isNaN(parsed)) {
|
|
1469
|
+
throw new Error(`Invalid price format: ${price}`);
|
|
1470
|
+
}
|
|
1471
|
+
return parsed;
|
|
1472
|
+
}
|
|
1473
|
+
};
|
|
1474
|
+
function createUptoEvmServerScheme(config) {
|
|
1475
|
+
return new UptoEvmServerScheme(config);
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
// src/upto/facilitator/scheme.ts
|
|
1479
|
+
var import_viem6 = require("viem");
|
|
1480
|
+
var T402_UPTO_ROUTER_ABI = (0, import_viem6.parseAbi)([
|
|
1481
|
+
"function executeUptoTransfer(address token, address from, address to, uint256 maxAmount, uint256 settleAmount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external",
|
|
1482
|
+
"function isFacilitator(address facilitator) external view returns (bool)",
|
|
1483
|
+
"function checkPermitValidity(address token, address from, uint256 maxAmount) external view returns (bool valid, uint256 balance)"
|
|
1484
|
+
]);
|
|
1485
|
+
var UptoEvmFacilitatorScheme = class {
|
|
1486
|
+
/**
|
|
1487
|
+
* Creates a new UptoEvmFacilitatorScheme instance.
|
|
1488
|
+
*
|
|
1489
|
+
* @param signer - The EVM signer for facilitator operations
|
|
1490
|
+
* @param config - Optional configuration
|
|
1491
|
+
*/
|
|
1492
|
+
constructor(signer, config) {
|
|
1493
|
+
this.signer = signer;
|
|
1494
|
+
__publicField(this, "scheme", "upto");
|
|
1495
|
+
__publicField(this, "caipFamily", "eip155:*");
|
|
1496
|
+
__publicField(this, "config");
|
|
1497
|
+
this.config = config ?? {};
|
|
1498
|
+
}
|
|
1499
|
+
/**
|
|
1500
|
+
* Get mechanism-specific extra data for the supported kinds endpoint.
|
|
1501
|
+
*
|
|
1502
|
+
* @param network - The network identifier
|
|
1503
|
+
* @returns Extra data including router address if configured
|
|
1504
|
+
*/
|
|
1505
|
+
getExtra(network) {
|
|
1506
|
+
const routerAddress = this.config.routerAddresses?.[network];
|
|
1507
|
+
if (routerAddress) {
|
|
1508
|
+
return { routerAddress };
|
|
1509
|
+
}
|
|
1510
|
+
return void 0;
|
|
1511
|
+
}
|
|
1512
|
+
/**
|
|
1513
|
+
* Get signer addresses used by this facilitator.
|
|
1514
|
+
*
|
|
1515
|
+
* @param _ - The network identifier (unused for EVM)
|
|
1516
|
+
* @returns Array of facilitator wallet addresses
|
|
1517
|
+
*/
|
|
1518
|
+
getSigners(_) {
|
|
1519
|
+
return [...this.signer.getAddresses()];
|
|
1520
|
+
}
|
|
1521
|
+
/**
|
|
1522
|
+
* Verifies an upto payment payload.
|
|
1523
|
+
*
|
|
1524
|
+
* @param payload - The payment payload to verify
|
|
1525
|
+
* @param requirements - The payment requirements
|
|
1526
|
+
* @returns Promise resolving to verification response
|
|
1527
|
+
*/
|
|
1528
|
+
async verify(payload, requirements) {
|
|
1529
|
+
const uptoPayload = payload.payload;
|
|
1530
|
+
if (!uptoPayload || !isUptoEIP2612Payload(uptoPayload)) {
|
|
1531
|
+
return {
|
|
1532
|
+
isValid: false,
|
|
1533
|
+
invalidReason: "invalid_payload_structure",
|
|
1534
|
+
payer: void 0
|
|
1535
|
+
};
|
|
1536
|
+
}
|
|
1537
|
+
if (payload.accepted.scheme !== "upto" || requirements.scheme !== "upto") {
|
|
1538
|
+
return {
|
|
1539
|
+
isValid: false,
|
|
1540
|
+
invalidReason: "unsupported_scheme",
|
|
1541
|
+
payer: uptoPayload.authorization.owner
|
|
1542
|
+
};
|
|
1543
|
+
}
|
|
1544
|
+
if (!requirements.extra?.name || !requirements.extra?.version) {
|
|
1545
|
+
return {
|
|
1546
|
+
isValid: false,
|
|
1547
|
+
invalidReason: "missing_eip712_domain",
|
|
1548
|
+
payer: uptoPayload.authorization.owner
|
|
1549
|
+
};
|
|
1550
|
+
}
|
|
1551
|
+
const maxAmount = requirements.extra?.maxAmount;
|
|
1552
|
+
if (!maxAmount) {
|
|
1553
|
+
return {
|
|
1554
|
+
isValid: false,
|
|
1555
|
+
invalidReason: "missing_maxAmount",
|
|
1556
|
+
payer: uptoPayload.authorization.owner
|
|
1557
|
+
};
|
|
1558
|
+
}
|
|
1559
|
+
if (payload.accepted.network !== requirements.network) {
|
|
1560
|
+
return {
|
|
1561
|
+
isValid: false,
|
|
1562
|
+
invalidReason: "network_mismatch",
|
|
1563
|
+
payer: uptoPayload.authorization.owner
|
|
1564
|
+
};
|
|
1565
|
+
}
|
|
1566
|
+
const deadline = parseInt(uptoPayload.authorization.deadline);
|
|
1567
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1568
|
+
if (deadline <= now) {
|
|
1569
|
+
return {
|
|
1570
|
+
isValid: false,
|
|
1571
|
+
invalidReason: "permit_expired",
|
|
1572
|
+
payer: uptoPayload.authorization.owner
|
|
1573
|
+
};
|
|
1574
|
+
}
|
|
1575
|
+
if (uptoPayload.authorization.value !== maxAmount) {
|
|
1576
|
+
return {
|
|
1577
|
+
isValid: false,
|
|
1578
|
+
invalidReason: "amount_mismatch",
|
|
1579
|
+
payer: uptoPayload.authorization.owner
|
|
1580
|
+
};
|
|
1581
|
+
}
|
|
1582
|
+
const chainId = parseInt(requirements.network.split(":")[1]);
|
|
1583
|
+
const permitTypedData = {
|
|
1584
|
+
types: permitTypes,
|
|
1585
|
+
primaryType: "Permit",
|
|
1586
|
+
domain: {
|
|
1587
|
+
name: requirements.extra.name,
|
|
1588
|
+
version: requirements.extra.version,
|
|
1589
|
+
chainId,
|
|
1590
|
+
verifyingContract: (0, import_viem6.getAddress)(requirements.asset)
|
|
1591
|
+
},
|
|
1592
|
+
message: {
|
|
1593
|
+
owner: (0, import_viem6.getAddress)(uptoPayload.authorization.owner),
|
|
1594
|
+
spender: (0, import_viem6.getAddress)(uptoPayload.authorization.spender),
|
|
1595
|
+
value: BigInt(uptoPayload.authorization.value),
|
|
1596
|
+
nonce: BigInt(uptoPayload.authorization.nonce),
|
|
1597
|
+
deadline: BigInt(uptoPayload.authorization.deadline)
|
|
1598
|
+
}
|
|
1599
|
+
};
|
|
1600
|
+
const signature = `0x${uptoPayload.signature.r.slice(2)}${uptoPayload.signature.s.slice(2)}${uptoPayload.signature.v.toString(16).padStart(2, "0")}`;
|
|
1601
|
+
try {
|
|
1602
|
+
const isValid = await this.signer.verifyTypedData({
|
|
1603
|
+
address: uptoPayload.authorization.owner,
|
|
1604
|
+
...permitTypedData,
|
|
1605
|
+
signature
|
|
1606
|
+
});
|
|
1607
|
+
if (!isValid) {
|
|
1608
|
+
return {
|
|
1609
|
+
isValid: false,
|
|
1610
|
+
invalidReason: "invalid_signature",
|
|
1611
|
+
payer: uptoPayload.authorization.owner
|
|
1612
|
+
};
|
|
1613
|
+
}
|
|
1614
|
+
} catch (error) {
|
|
1615
|
+
return {
|
|
1616
|
+
isValid: false,
|
|
1617
|
+
invalidReason: `signature_verification_failed: ${error instanceof Error ? error.message : "unknown"}`,
|
|
1618
|
+
payer: uptoPayload.authorization.owner
|
|
915
1619
|
};
|
|
916
1620
|
}
|
|
917
1621
|
return {
|
|
918
1622
|
isValid: true,
|
|
919
|
-
|
|
920
|
-
payer: legacyPayload.authorization.from
|
|
1623
|
+
payer: uptoPayload.authorization.owner
|
|
921
1624
|
};
|
|
922
1625
|
}
|
|
923
1626
|
/**
|
|
924
|
-
* Settles
|
|
1627
|
+
* Settles an upto payment by calling the T402UptoRouter contract.
|
|
1628
|
+
*
|
|
1629
|
+
* @param payload - The verified payment payload
|
|
1630
|
+
* @param requirements - The payment requirements
|
|
1631
|
+
* @returns Promise resolving to settlement response
|
|
925
1632
|
*/
|
|
926
1633
|
async settle(payload, requirements) {
|
|
927
|
-
const
|
|
928
|
-
const
|
|
929
|
-
|
|
1634
|
+
const uptoPayload = payload.payload;
|
|
1635
|
+
const maxAmount = requirements.extra?.maxAmount;
|
|
1636
|
+
const minAmount = requirements.extra?.minAmount;
|
|
1637
|
+
const routerAddress = requirements.extra?.routerAddress;
|
|
1638
|
+
if (!maxAmount) {
|
|
930
1639
|
return {
|
|
931
1640
|
success: false,
|
|
932
|
-
|
|
1641
|
+
errorReason: "maxAmount not found in payment requirements",
|
|
933
1642
|
transaction: "",
|
|
934
|
-
|
|
935
|
-
payer:
|
|
1643
|
+
network: requirements.network,
|
|
1644
|
+
payer: uptoPayload.authorization.owner
|
|
1645
|
+
};
|
|
1646
|
+
}
|
|
1647
|
+
const settleAmount = maxAmount;
|
|
1648
|
+
if (minAmount && BigInt(settleAmount) < BigInt(minAmount)) {
|
|
1649
|
+
return {
|
|
1650
|
+
success: false,
|
|
1651
|
+
errorReason: `Settle amount ${settleAmount} below minimum ${minAmount}`,
|
|
1652
|
+
transaction: "",
|
|
1653
|
+
network: requirements.network,
|
|
1654
|
+
payer: uptoPayload.authorization.owner
|
|
1655
|
+
};
|
|
1656
|
+
}
|
|
1657
|
+
if (!routerAddress) {
|
|
1658
|
+
return {
|
|
1659
|
+
success: false,
|
|
1660
|
+
errorReason: "Router address not configured",
|
|
1661
|
+
transaction: "",
|
|
1662
|
+
network: requirements.network,
|
|
1663
|
+
payer: uptoPayload.authorization.owner
|
|
936
1664
|
};
|
|
937
1665
|
}
|
|
938
1666
|
try {
|
|
939
|
-
const
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
1667
|
+
const txHash = await this.signer.sendTransaction({
|
|
1668
|
+
to: (0, import_viem6.getAddress)(routerAddress),
|
|
1669
|
+
data: (0, import_viem6.encodeFunctionData)({
|
|
1670
|
+
abi: T402_UPTO_ROUTER_ABI,
|
|
1671
|
+
functionName: "executeUptoTransfer",
|
|
1672
|
+
args: [
|
|
1673
|
+
(0, import_viem6.getAddress)(requirements.asset),
|
|
1674
|
+
(0, import_viem6.getAddress)(uptoPayload.authorization.owner),
|
|
1675
|
+
(0, import_viem6.getAddress)(requirements.payTo),
|
|
1676
|
+
BigInt(maxAmount),
|
|
1677
|
+
BigInt(settleAmount),
|
|
1678
|
+
BigInt(uptoPayload.authorization.deadline),
|
|
1679
|
+
uptoPayload.signature.v,
|
|
1680
|
+
uptoPayload.signature.r,
|
|
1681
|
+
uptoPayload.signature.s
|
|
1682
|
+
]
|
|
1683
|
+
})
|
|
948
1684
|
});
|
|
949
|
-
const receipt = await this.signer.waitForTransactionReceipt({ hash:
|
|
1685
|
+
const receipt = await this.signer.waitForTransactionReceipt({ hash: txHash });
|
|
950
1686
|
if (receipt.status !== "success") {
|
|
951
1687
|
return {
|
|
952
1688
|
success: false,
|
|
953
|
-
errorReason: "
|
|
954
|
-
transaction:
|
|
955
|
-
network:
|
|
956
|
-
payer:
|
|
1689
|
+
errorReason: "transaction_reverted",
|
|
1690
|
+
transaction: txHash,
|
|
1691
|
+
network: requirements.network,
|
|
1692
|
+
payer: uptoPayload.authorization.owner
|
|
957
1693
|
};
|
|
958
1694
|
}
|
|
959
1695
|
return {
|
|
960
1696
|
success: true,
|
|
961
|
-
transaction:
|
|
962
|
-
network:
|
|
963
|
-
payer:
|
|
1697
|
+
transaction: txHash,
|
|
1698
|
+
network: requirements.network,
|
|
1699
|
+
payer: uptoPayload.authorization.owner
|
|
964
1700
|
};
|
|
965
1701
|
} catch (error) {
|
|
966
|
-
console.error("Failed to settle legacy transaction:", error);
|
|
967
1702
|
return {
|
|
968
1703
|
success: false,
|
|
969
|
-
errorReason: "
|
|
1704
|
+
errorReason: `Settlement failed: ${error instanceof Error ? error.message : "unknown"}`,
|
|
970
1705
|
transaction: "",
|
|
971
|
-
network:
|
|
972
|
-
payer:
|
|
1706
|
+
network: requirements.network,
|
|
1707
|
+
payer: uptoPayload.authorization.owner
|
|
973
1708
|
};
|
|
974
1709
|
}
|
|
975
1710
|
}
|
|
976
1711
|
};
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
function toClientEvmSigner(signer) {
|
|
980
|
-
return signer;
|
|
981
|
-
}
|
|
982
|
-
function toFacilitatorEvmSigner(client) {
|
|
983
|
-
return {
|
|
984
|
-
...client,
|
|
985
|
-
getAddresses: () => [client.address]
|
|
986
|
-
};
|
|
1712
|
+
function createUptoEvmFacilitatorScheme(signer, config) {
|
|
1713
|
+
return new UptoEvmFacilitatorScheme(signer, config);
|
|
987
1714
|
}
|
|
988
1715
|
|
|
989
1716
|
// src/bridge/client.ts
|
|
990
|
-
var
|
|
1717
|
+
var import_viem7 = require("viem");
|
|
991
1718
|
|
|
992
1719
|
// src/bridge/constants.ts
|
|
993
1720
|
var LAYERZERO_ENDPOINT_IDS = {
|
|
@@ -1161,9 +1888,7 @@ function supportsBridging(chain) {
|
|
|
1161
1888
|
return chain in USDT0_OFT_ADDRESSES && chain in LAYERZERO_ENDPOINT_IDS;
|
|
1162
1889
|
}
|
|
1163
1890
|
function getBridgeableChains() {
|
|
1164
|
-
return Object.keys(USDT0_OFT_ADDRESSES).filter(
|
|
1165
|
-
(chain) => chain in LAYERZERO_ENDPOINT_IDS
|
|
1166
|
-
);
|
|
1891
|
+
return Object.keys(USDT0_OFT_ADDRESSES).filter((chain) => chain in LAYERZERO_ENDPOINT_IDS);
|
|
1167
1892
|
}
|
|
1168
1893
|
function addressToBytes32(address) {
|
|
1169
1894
|
const cleanAddress = address.slice(2).toLowerCase();
|
|
@@ -1174,9 +1899,7 @@ function bytes32ToAddress(bytes32) {
|
|
|
1174
1899
|
}
|
|
1175
1900
|
|
|
1176
1901
|
// src/bridge/client.ts
|
|
1177
|
-
var OFT_SENT_EVENT_TOPIC = (0,
|
|
1178
|
-
(0, import_viem5.toBytes)("OFTSent(bytes32,uint32,address,uint256,uint256)")
|
|
1179
|
-
);
|
|
1902
|
+
var OFT_SENT_EVENT_TOPIC = (0, import_viem7.keccak256)((0, import_viem7.toBytes)("OFTSent(bytes32,uint32,address,uint256,uint256)"));
|
|
1180
1903
|
var DEFAULT_SLIPPAGE = 0.5;
|
|
1181
1904
|
var ESTIMATED_BRIDGE_TIME = 300;
|
|
1182
1905
|
var Usdt0Bridge = class {
|
|
@@ -1187,6 +1910,8 @@ var Usdt0Bridge = class {
|
|
|
1187
1910
|
* @param chain - Source chain name (e.g., "arbitrum", "ethereum")
|
|
1188
1911
|
*/
|
|
1189
1912
|
constructor(signer, chain) {
|
|
1913
|
+
__publicField(this, "signer");
|
|
1914
|
+
__publicField(this, "chain");
|
|
1190
1915
|
if (!supportsBridging(chain)) {
|
|
1191
1916
|
throw new Error(
|
|
1192
1917
|
`Chain "${chain}" does not support USDT0 bridging. Supported chains: ${getBridgeableChains().join(", ")}`
|
|
@@ -1260,6 +1985,23 @@ var Usdt0Bridge = class {
|
|
|
1260
1985
|
estimatedTime: ESTIMATED_BRIDGE_TIME
|
|
1261
1986
|
};
|
|
1262
1987
|
}
|
|
1988
|
+
/**
|
|
1989
|
+
* Get all supported destination chains from current chain
|
|
1990
|
+
*
|
|
1991
|
+
* @returns Array of supported destination chain names
|
|
1992
|
+
*/
|
|
1993
|
+
getSupportedDestinations() {
|
|
1994
|
+
return getBridgeableChains().filter((chain) => chain !== this.chain);
|
|
1995
|
+
}
|
|
1996
|
+
/**
|
|
1997
|
+
* Check if a destination chain is supported
|
|
1998
|
+
*
|
|
1999
|
+
* @param toChain - The destination chain to check
|
|
2000
|
+
* @returns True if the destination chain is supported
|
|
2001
|
+
*/
|
|
2002
|
+
supportsDestination(toChain) {
|
|
2003
|
+
return toChain !== this.chain && supportsBridging(toChain);
|
|
2004
|
+
}
|
|
1263
2005
|
/**
|
|
1264
2006
|
* Extract LayerZero message GUID from OFTSent event logs
|
|
1265
2007
|
*
|
|
@@ -1278,6 +2020,9 @@ var Usdt0Bridge = class {
|
|
|
1278
2020
|
}
|
|
1279
2021
|
/**
|
|
1280
2022
|
* Ensure sufficient token allowance for the OFT contract
|
|
2023
|
+
*
|
|
2024
|
+
* @param oftAddress - The OFT contract address
|
|
2025
|
+
* @param amount - The amount to approve
|
|
1281
2026
|
*/
|
|
1282
2027
|
async ensureAllowance(oftAddress, amount) {
|
|
1283
2028
|
const allowance = await this.signer.readContract({
|
|
@@ -1298,6 +2043,9 @@ var Usdt0Bridge = class {
|
|
|
1298
2043
|
}
|
|
1299
2044
|
/**
|
|
1300
2045
|
* Build SendParam struct for LayerZero
|
|
2046
|
+
*
|
|
2047
|
+
* @param params - Bridge parameters
|
|
2048
|
+
* @returns SendParam struct for the OFT contract
|
|
1301
2049
|
*/
|
|
1302
2050
|
buildSendParam(params) {
|
|
1303
2051
|
const dstEid = getEndpointId(params.toChain);
|
|
@@ -1318,6 +2066,8 @@ var Usdt0Bridge = class {
|
|
|
1318
2066
|
}
|
|
1319
2067
|
/**
|
|
1320
2068
|
* Validate bridge parameters
|
|
2069
|
+
*
|
|
2070
|
+
* @param params - Bridge parameters to validate
|
|
1321
2071
|
*/
|
|
1322
2072
|
validateBridgeParams(params) {
|
|
1323
2073
|
if (params.fromChain !== this.chain) {
|
|
@@ -1338,21 +2088,301 @@ var Usdt0Bridge = class {
|
|
|
1338
2088
|
throw new Error("Amount must be greater than 0");
|
|
1339
2089
|
}
|
|
1340
2090
|
}
|
|
2091
|
+
};
|
|
2092
|
+
function createUsdt0Bridge(signer, chain) {
|
|
2093
|
+
return new Usdt0Bridge(signer, chain);
|
|
2094
|
+
}
|
|
2095
|
+
|
|
2096
|
+
// src/bridge/scan.ts
|
|
2097
|
+
var LAYERZERO_SCAN_BASE_URL = "https://scan.layerzero-api.com/v1";
|
|
2098
|
+
var DEFAULT_TIMEOUT = 6e5;
|
|
2099
|
+
var DEFAULT_POLL_INTERVAL = 1e4;
|
|
2100
|
+
var LayerZeroScanClient = class {
|
|
1341
2101
|
/**
|
|
1342
|
-
*
|
|
2102
|
+
* Create a new LayerZero Scan client
|
|
2103
|
+
*
|
|
2104
|
+
* @param baseUrl - API base URL (default: production endpoint)
|
|
2105
|
+
*/
|
|
2106
|
+
constructor(baseUrl = LAYERZERO_SCAN_BASE_URL) {
|
|
2107
|
+
__publicField(this, "baseUrl");
|
|
2108
|
+
this.baseUrl = baseUrl;
|
|
2109
|
+
}
|
|
2110
|
+
/**
|
|
2111
|
+
* Get message by GUID
|
|
2112
|
+
*
|
|
2113
|
+
* @param guid - LayerZero message GUID
|
|
2114
|
+
* @returns Message details including status
|
|
2115
|
+
* @throws Error if message not found or API error
|
|
2116
|
+
*/
|
|
2117
|
+
async getMessage(guid) {
|
|
2118
|
+
const url = `${this.baseUrl}/messages/guid/${guid}`;
|
|
2119
|
+
const response = await fetch(url, {
|
|
2120
|
+
method: "GET",
|
|
2121
|
+
headers: {
|
|
2122
|
+
Accept: "application/json"
|
|
2123
|
+
}
|
|
2124
|
+
});
|
|
2125
|
+
if (!response.ok) {
|
|
2126
|
+
if (response.status === 404) {
|
|
2127
|
+
throw new Error(`Message not found: ${guid}`);
|
|
2128
|
+
}
|
|
2129
|
+
throw new Error(`LayerZero Scan API error: ${response.status} ${response.statusText}`);
|
|
2130
|
+
}
|
|
2131
|
+
const data = await response.json();
|
|
2132
|
+
return this.mapApiResponse(data);
|
|
2133
|
+
}
|
|
2134
|
+
/**
|
|
2135
|
+
* Get messages by wallet address
|
|
2136
|
+
*
|
|
2137
|
+
* @param address - Wallet address that initiated messages
|
|
2138
|
+
* @param limit - Maximum number of messages to return (default: 20)
|
|
2139
|
+
* @returns Array of messages
|
|
2140
|
+
*/
|
|
2141
|
+
async getMessagesByWallet(address, limit = 20) {
|
|
2142
|
+
const url = `${this.baseUrl}/messages/wallet/${address}?limit=${limit}`;
|
|
2143
|
+
const response = await fetch(url, {
|
|
2144
|
+
method: "GET",
|
|
2145
|
+
headers: {
|
|
2146
|
+
Accept: "application/json"
|
|
2147
|
+
}
|
|
2148
|
+
});
|
|
2149
|
+
if (!response.ok) {
|
|
2150
|
+
throw new Error(`LayerZero Scan API error: ${response.status} ${response.statusText}`);
|
|
2151
|
+
}
|
|
2152
|
+
const data = await response.json();
|
|
2153
|
+
const messages = data.messages ?? data.data ?? [];
|
|
2154
|
+
return messages.map((msg) => this.mapApiResponse(msg));
|
|
2155
|
+
}
|
|
2156
|
+
/**
|
|
2157
|
+
* Poll message status until delivered or failed
|
|
2158
|
+
*
|
|
2159
|
+
* @param guid - LayerZero message GUID
|
|
2160
|
+
* @param options - Wait configuration options
|
|
2161
|
+
* @returns Final message state (DELIVERED)
|
|
2162
|
+
* @throws Error if message fails, is blocked, or times out
|
|
2163
|
+
*/
|
|
2164
|
+
async waitForDelivery(guid, options = {}) {
|
|
2165
|
+
const {
|
|
2166
|
+
timeout = DEFAULT_TIMEOUT,
|
|
2167
|
+
pollInterval = DEFAULT_POLL_INTERVAL,
|
|
2168
|
+
onStatusChange
|
|
2169
|
+
} = options;
|
|
2170
|
+
const startTime = Date.now();
|
|
2171
|
+
let lastStatus = null;
|
|
2172
|
+
while (Date.now() - startTime < timeout) {
|
|
2173
|
+
try {
|
|
2174
|
+
const message = await this.getMessage(guid);
|
|
2175
|
+
if (lastStatus !== message.status) {
|
|
2176
|
+
lastStatus = message.status;
|
|
2177
|
+
onStatusChange?.(message.status);
|
|
2178
|
+
}
|
|
2179
|
+
if (message.status === "DELIVERED") {
|
|
2180
|
+
return message;
|
|
2181
|
+
}
|
|
2182
|
+
if (message.status === "FAILED") {
|
|
2183
|
+
throw new Error(`Bridge message failed: ${guid}`);
|
|
2184
|
+
}
|
|
2185
|
+
if (message.status === "BLOCKED") {
|
|
2186
|
+
throw new Error(`Bridge message blocked by DVN: ${guid}`);
|
|
2187
|
+
}
|
|
2188
|
+
await this.sleep(pollInterval);
|
|
2189
|
+
} catch (error) {
|
|
2190
|
+
if (error.message.includes("not found")) {
|
|
2191
|
+
await this.sleep(pollInterval);
|
|
2192
|
+
continue;
|
|
2193
|
+
}
|
|
2194
|
+
throw error;
|
|
2195
|
+
}
|
|
2196
|
+
}
|
|
2197
|
+
throw new Error(`Timeout waiting for message delivery: ${guid}`);
|
|
2198
|
+
}
|
|
2199
|
+
/**
|
|
2200
|
+
* Check if a message has been delivered
|
|
2201
|
+
*
|
|
2202
|
+
* @param guid - LayerZero message GUID
|
|
2203
|
+
* @returns True if delivered, false otherwise
|
|
2204
|
+
*/
|
|
2205
|
+
async isDelivered(guid) {
|
|
2206
|
+
try {
|
|
2207
|
+
const message = await this.getMessage(guid);
|
|
2208
|
+
return message.status === "DELIVERED";
|
|
2209
|
+
} catch {
|
|
2210
|
+
return false;
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
/**
|
|
2214
|
+
* Map API response to our interface
|
|
2215
|
+
*
|
|
2216
|
+
* @param data - The raw API response data
|
|
2217
|
+
* @returns The mapped LayerZeroMessage object
|
|
2218
|
+
*/
|
|
2219
|
+
mapApiResponse(data) {
|
|
2220
|
+
const msg = data;
|
|
2221
|
+
return {
|
|
2222
|
+
guid: msg.guid ?? msg.messageGuid ?? "",
|
|
2223
|
+
srcEid: msg.srcEid ?? msg.srcChainId ?? 0,
|
|
2224
|
+
dstEid: msg.dstEid ?? msg.dstChainId ?? 0,
|
|
2225
|
+
srcUaAddress: msg.srcUaAddress ?? msg.srcAddress ?? "",
|
|
2226
|
+
dstUaAddress: msg.dstUaAddress ?? msg.dstAddress ?? "",
|
|
2227
|
+
srcTxHash: msg.srcTxHash ?? "",
|
|
2228
|
+
dstTxHash: msg.dstTxHash ?? void 0,
|
|
2229
|
+
status: msg.status ?? "INFLIGHT",
|
|
2230
|
+
srcBlockNumber: msg.srcBlockNumber ?? 0,
|
|
2231
|
+
dstBlockNumber: msg.dstBlockNumber ?? void 0,
|
|
2232
|
+
created: msg.created ?? msg.createdAt ?? "",
|
|
2233
|
+
updated: msg.updated ?? msg.updatedAt ?? ""
|
|
2234
|
+
};
|
|
2235
|
+
}
|
|
2236
|
+
/**
|
|
2237
|
+
* Sleep helper
|
|
2238
|
+
*
|
|
2239
|
+
* @param ms - The number of milliseconds to sleep
|
|
2240
|
+
* @returns A promise that resolves after the specified delay
|
|
2241
|
+
*/
|
|
2242
|
+
sleep(ms) {
|
|
2243
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
2244
|
+
}
|
|
2245
|
+
};
|
|
2246
|
+
function createLayerZeroScanClient(baseUrl) {
|
|
2247
|
+
return new LayerZeroScanClient(baseUrl);
|
|
2248
|
+
}
|
|
2249
|
+
|
|
2250
|
+
// src/bridge/router.ts
|
|
2251
|
+
var CrossChainPaymentRouter = class {
|
|
2252
|
+
/**
|
|
2253
|
+
* Create a cross-chain payment router
|
|
2254
|
+
*
|
|
2255
|
+
* @param signer - Wallet signer for bridge operations
|
|
2256
|
+
* @param sourceChain - Chain where user's funds are located
|
|
2257
|
+
*/
|
|
2258
|
+
constructor(signer, sourceChain) {
|
|
2259
|
+
__publicField(this, "bridge");
|
|
2260
|
+
__publicField(this, "scanClient");
|
|
2261
|
+
__publicField(this, "sourceChain");
|
|
2262
|
+
this.bridge = new Usdt0Bridge(signer, sourceChain);
|
|
2263
|
+
this.scanClient = new LayerZeroScanClient();
|
|
2264
|
+
this.sourceChain = sourceChain;
|
|
2265
|
+
}
|
|
2266
|
+
/**
|
|
2267
|
+
* Get all bridgeable chains
|
|
2268
|
+
*
|
|
2269
|
+
* @returns Array of all chain names that support USDT0 bridging
|
|
2270
|
+
*/
|
|
2271
|
+
static getBridgeableChains() {
|
|
2272
|
+
return getBridgeableChains();
|
|
2273
|
+
}
|
|
2274
|
+
/**
|
|
2275
|
+
* Route payment across chains
|
|
2276
|
+
*
|
|
2277
|
+
* This method:
|
|
2278
|
+
* 1. Bridges USDT0 from source chain to destination chain
|
|
2279
|
+
* 2. Sends funds to the payer's address on destination chain
|
|
2280
|
+
* 3. Returns tracking info for monitoring delivery
|
|
2281
|
+
*
|
|
2282
|
+
* After delivery, the payer can use the bridged funds to pay on the destination chain.
|
|
2283
|
+
*
|
|
2284
|
+
* @param params - Payment routing parameters
|
|
2285
|
+
* @returns Result with transaction hash and tracking info
|
|
2286
|
+
*/
|
|
2287
|
+
async routePayment(params) {
|
|
2288
|
+
this.validateParams(params);
|
|
2289
|
+
const result = await this.bridge.send({
|
|
2290
|
+
fromChain: params.sourceChain,
|
|
2291
|
+
toChain: params.destinationChain,
|
|
2292
|
+
amount: params.amount,
|
|
2293
|
+
recipient: params.payer,
|
|
2294
|
+
slippageTolerance: params.slippageTolerance
|
|
2295
|
+
});
|
|
2296
|
+
return {
|
|
2297
|
+
bridgeTxHash: result.txHash,
|
|
2298
|
+
messageGuid: result.messageGuid,
|
|
2299
|
+
amountBridged: result.amountSent,
|
|
2300
|
+
estimatedReceiveAmount: result.amountToReceive,
|
|
2301
|
+
sourceChain: params.sourceChain,
|
|
2302
|
+
destinationChain: params.destinationChain,
|
|
2303
|
+
estimatedDeliveryTime: result.estimatedTime
|
|
2304
|
+
};
|
|
2305
|
+
}
|
|
2306
|
+
/**
|
|
2307
|
+
* Get estimated fees for routing a payment
|
|
2308
|
+
*
|
|
2309
|
+
* @param params - Payment parameters
|
|
2310
|
+
* @returns Quote with native fee and estimated receive amount
|
|
2311
|
+
*/
|
|
2312
|
+
async estimateFees(params) {
|
|
2313
|
+
const quote = await this.bridge.quote({
|
|
2314
|
+
fromChain: params.sourceChain,
|
|
2315
|
+
toChain: params.destinationChain,
|
|
2316
|
+
amount: params.amount,
|
|
2317
|
+
recipient: params.payer
|
|
2318
|
+
});
|
|
2319
|
+
return {
|
|
2320
|
+
nativeFee: quote.nativeFee,
|
|
2321
|
+
estimatedReceiveAmount: quote.minAmountToReceive,
|
|
2322
|
+
estimatedTime: quote.estimatedTime
|
|
2323
|
+
};
|
|
2324
|
+
}
|
|
2325
|
+
/**
|
|
2326
|
+
* Track message delivery status
|
|
2327
|
+
*
|
|
2328
|
+
* @param messageGuid - LayerZero message GUID from routePayment result
|
|
2329
|
+
* @returns Current message status
|
|
2330
|
+
*/
|
|
2331
|
+
async trackMessage(messageGuid) {
|
|
2332
|
+
return this.scanClient.getMessage(messageGuid);
|
|
2333
|
+
}
|
|
2334
|
+
/**
|
|
2335
|
+
* Wait for payment to be delivered on destination chain
|
|
2336
|
+
*
|
|
2337
|
+
* @param messageGuid - LayerZero message GUID from routePayment result
|
|
2338
|
+
* @param options - Wait options (timeout, poll interval, callbacks)
|
|
2339
|
+
* @returns Final message state when delivered
|
|
2340
|
+
*/
|
|
2341
|
+
async waitForDelivery(messageGuid, options) {
|
|
2342
|
+
return this.scanClient.waitForDelivery(messageGuid, options);
|
|
2343
|
+
}
|
|
2344
|
+
/**
|
|
2345
|
+
* Check if routing between two chains is supported
|
|
2346
|
+
*
|
|
2347
|
+
* @param sourceChain - Source chain name
|
|
2348
|
+
* @param destinationChain - Destination chain name
|
|
2349
|
+
* @returns True if routing is supported
|
|
2350
|
+
*/
|
|
2351
|
+
canRoute(sourceChain, destinationChain) {
|
|
2352
|
+
return sourceChain !== destinationChain && supportsBridging(sourceChain) && supportsBridging(destinationChain);
|
|
2353
|
+
}
|
|
2354
|
+
/**
|
|
2355
|
+
* Get all supported destination chains from source chain
|
|
2356
|
+
*
|
|
2357
|
+
* @returns Array of chain names that can receive bridged funds
|
|
1343
2358
|
*/
|
|
1344
2359
|
getSupportedDestinations() {
|
|
1345
|
-
return
|
|
2360
|
+
return this.bridge.getSupportedDestinations();
|
|
1346
2361
|
}
|
|
1347
2362
|
/**
|
|
1348
|
-
*
|
|
2363
|
+
* Validate routing parameters
|
|
2364
|
+
*
|
|
2365
|
+
* @param params - The cross-chain payment parameters to validate
|
|
2366
|
+
* @throws Error if parameters are invalid or routing is not supported
|
|
1349
2367
|
*/
|
|
1350
|
-
|
|
1351
|
-
|
|
2368
|
+
validateParams(params) {
|
|
2369
|
+
if (params.sourceChain !== this.sourceChain) {
|
|
2370
|
+
throw new Error(
|
|
2371
|
+
`Source chain mismatch: router initialized for "${this.sourceChain}" but got "${params.sourceChain}"`
|
|
2372
|
+
);
|
|
2373
|
+
}
|
|
2374
|
+
if (!this.canRoute(params.sourceChain, params.destinationChain)) {
|
|
2375
|
+
throw new Error(
|
|
2376
|
+
`Cannot route payment from "${params.sourceChain}" to "${params.destinationChain}". Supported chains: ${getBridgeableChains().join(", ")}`
|
|
2377
|
+
);
|
|
2378
|
+
}
|
|
2379
|
+
if (params.amount <= 0n) {
|
|
2380
|
+
throw new Error("Amount must be greater than 0");
|
|
2381
|
+
}
|
|
1352
2382
|
}
|
|
1353
2383
|
};
|
|
1354
|
-
function
|
|
1355
|
-
return new
|
|
2384
|
+
function createCrossChainPaymentRouter(signer, sourceChain) {
|
|
2385
|
+
return new CrossChainPaymentRouter(signer, sourceChain);
|
|
1356
2386
|
}
|
|
1357
2387
|
|
|
1358
2388
|
// src/erc4337/constants.ts
|
|
@@ -1530,25 +2560,35 @@ function unpackGasFees(packed) {
|
|
|
1530
2560
|
}
|
|
1531
2561
|
|
|
1532
2562
|
// src/erc4337/builder.ts
|
|
1533
|
-
var
|
|
2563
|
+
var import_viem8 = require("viem");
|
|
1534
2564
|
var UserOpBuilder = class {
|
|
2565
|
+
/**
|
|
2566
|
+
* Create a new UserOpBuilder instance
|
|
2567
|
+
*
|
|
2568
|
+
* @param options - Optional configuration for the builder
|
|
2569
|
+
*/
|
|
1535
2570
|
constructor(options = {}) {
|
|
2571
|
+
__publicField(this, "entryPoint");
|
|
2572
|
+
__publicField(this, "gasMultiplier");
|
|
1536
2573
|
this.entryPoint = options.entryPoint ?? ENTRYPOINT_V07_ADDRESS;
|
|
1537
2574
|
this.gasMultiplier = options.gasMultiplier ?? 1.2;
|
|
1538
2575
|
}
|
|
1539
2576
|
/**
|
|
1540
2577
|
* Build a UserOperation from a transaction intent
|
|
2578
|
+
*
|
|
2579
|
+
* @param signer - The smart account signer
|
|
2580
|
+
* @param intent - The transaction intent to execute
|
|
2581
|
+
* @param client - The public client for chain interaction
|
|
2582
|
+
* @param gasEstimate - Optional gas estimates (uses defaults if not provided)
|
|
2583
|
+
* @param paymaster - Optional paymaster data for sponsored transactions
|
|
2584
|
+
* @returns A UserOperation ready for signing
|
|
1541
2585
|
*/
|
|
1542
2586
|
async buildUserOp(signer, intent, client, gasEstimate, paymaster) {
|
|
1543
2587
|
const sender = await signer.getAddress();
|
|
1544
2588
|
const nonce = await this.getNonce(client, sender);
|
|
1545
2589
|
const isDeployed = await signer.isDeployed();
|
|
1546
2590
|
const initCode = isDeployed ? "0x" : await signer.getInitCode();
|
|
1547
|
-
const callData = signer.encodeExecute(
|
|
1548
|
-
intent.to,
|
|
1549
|
-
intent.value ?? 0n,
|
|
1550
|
-
intent.data ?? "0x"
|
|
1551
|
-
);
|
|
2591
|
+
const callData = signer.encodeExecute(intent.to, intent.value ?? 0n, intent.data ?? "0x");
|
|
1552
2592
|
const { maxFeePerGas, maxPriorityFeePerGas } = await this.getGasPrices(client);
|
|
1553
2593
|
const gas = gasEstimate ?? DEFAULT_GAS_LIMITS;
|
|
1554
2594
|
const verificationGasLimit = this.applyMultiplier(gas.verificationGasLimit);
|
|
@@ -1572,6 +2612,13 @@ var UserOpBuilder = class {
|
|
|
1572
2612
|
}
|
|
1573
2613
|
/**
|
|
1574
2614
|
* Build a batch UserOperation from multiple transaction intents
|
|
2615
|
+
*
|
|
2616
|
+
* @param signer - The smart account signer
|
|
2617
|
+
* @param intents - Array of transaction intents to execute
|
|
2618
|
+
* @param client - The public client for chain interaction
|
|
2619
|
+
* @param gasEstimate - Optional gas estimates (uses defaults if not provided)
|
|
2620
|
+
* @param paymaster - Optional paymaster data for sponsored transactions
|
|
2621
|
+
* @returns A UserOperation ready for signing
|
|
1575
2622
|
*/
|
|
1576
2623
|
async buildBatchUserOp(signer, intents, client, gasEstimate, paymaster) {
|
|
1577
2624
|
const sender = await signer.getAddress();
|
|
@@ -1608,6 +2655,9 @@ var UserOpBuilder = class {
|
|
|
1608
2655
|
}
|
|
1609
2656
|
/**
|
|
1610
2657
|
* Pack a UserOperation for on-chain submission (v0.7 format)
|
|
2658
|
+
*
|
|
2659
|
+
* @param userOp - The UserOperation to pack
|
|
2660
|
+
* @returns The packed UserOperation for on-chain submission
|
|
1611
2661
|
*/
|
|
1612
2662
|
packUserOp(userOp) {
|
|
1613
2663
|
return {
|
|
@@ -1615,10 +2665,7 @@ var UserOpBuilder = class {
|
|
|
1615
2665
|
nonce: userOp.nonce,
|
|
1616
2666
|
initCode: userOp.initCode,
|
|
1617
2667
|
callData: userOp.callData,
|
|
1618
|
-
accountGasLimits: packAccountGasLimits(
|
|
1619
|
-
userOp.verificationGasLimit,
|
|
1620
|
-
userOp.callGasLimit
|
|
1621
|
-
),
|
|
2668
|
+
accountGasLimits: packAccountGasLimits(userOp.verificationGasLimit, userOp.callGasLimit),
|
|
1622
2669
|
preVerificationGas: userOp.preVerificationGas,
|
|
1623
2670
|
gasFees: packGasFees(userOp.maxPriorityFeePerGas, userOp.maxFeePerGas),
|
|
1624
2671
|
paymasterAndData: userOp.paymasterAndData,
|
|
@@ -1627,8 +2674,13 @@ var UserOpBuilder = class {
|
|
|
1627
2674
|
}
|
|
1628
2675
|
/**
|
|
1629
2676
|
* Compute the UserOperation hash for signing
|
|
2677
|
+
*
|
|
2678
|
+
* @param userOp - The UserOperation to hash
|
|
2679
|
+
* @param client - The public client for chain interaction
|
|
2680
|
+
* @param _ - The chain ID (reserved for future use)
|
|
2681
|
+
* @returns The UserOperation hash
|
|
1630
2682
|
*/
|
|
1631
|
-
async getUserOpHash(userOp, client,
|
|
2683
|
+
async getUserOpHash(userOp, client, _) {
|
|
1632
2684
|
const packed = this.packUserOp(userOp);
|
|
1633
2685
|
const userOpTuple = {
|
|
1634
2686
|
sender: packed.sender,
|
|
@@ -1651,6 +2703,12 @@ var UserOpBuilder = class {
|
|
|
1651
2703
|
}
|
|
1652
2704
|
/**
|
|
1653
2705
|
* Sign a UserOperation
|
|
2706
|
+
*
|
|
2707
|
+
* @param userOp - The UserOperation to sign
|
|
2708
|
+
* @param signer - The smart account signer
|
|
2709
|
+
* @param client - The public client for chain interaction
|
|
2710
|
+
* @param chainId - The chain ID for the signature
|
|
2711
|
+
* @returns The UserOperation with signature attached
|
|
1654
2712
|
*/
|
|
1655
2713
|
async signUserOp(userOp, signer, client, chainId) {
|
|
1656
2714
|
const userOpHash = await this.getUserOpHash(userOp, client, chainId);
|
|
@@ -1662,6 +2720,10 @@ var UserOpBuilder = class {
|
|
|
1662
2720
|
}
|
|
1663
2721
|
/**
|
|
1664
2722
|
* Get the nonce for an account from EntryPoint
|
|
2723
|
+
*
|
|
2724
|
+
* @param client - The public client for chain interaction
|
|
2725
|
+
* @param sender - The smart account address
|
|
2726
|
+
* @returns The current nonce for the account
|
|
1665
2727
|
*/
|
|
1666
2728
|
async getNonce(client, sender) {
|
|
1667
2729
|
try {
|
|
@@ -1679,6 +2741,9 @@ var UserOpBuilder = class {
|
|
|
1679
2741
|
}
|
|
1680
2742
|
/**
|
|
1681
2743
|
* Get current gas prices from the chain
|
|
2744
|
+
*
|
|
2745
|
+
* @param client - The public client for chain interaction
|
|
2746
|
+
* @returns The current gas prices for EIP-1559 transactions
|
|
1682
2747
|
*/
|
|
1683
2748
|
async getGasPrices(client) {
|
|
1684
2749
|
const block = await client.getBlock({ blockTag: "latest" });
|
|
@@ -1689,25 +2754,26 @@ var UserOpBuilder = class {
|
|
|
1689
2754
|
}
|
|
1690
2755
|
/**
|
|
1691
2756
|
* Apply gas multiplier for safety margin
|
|
2757
|
+
*
|
|
2758
|
+
* @param gas - The gas amount to multiply
|
|
2759
|
+
* @returns The gas amount with safety margin applied
|
|
1692
2760
|
*/
|
|
1693
2761
|
applyMultiplier(gas) {
|
|
1694
2762
|
return BigInt(Math.ceil(Number(gas) * this.gasMultiplier));
|
|
1695
2763
|
}
|
|
1696
2764
|
/**
|
|
1697
2765
|
* Encode paymaster data for the UserOperation
|
|
2766
|
+
*
|
|
2767
|
+
* @param paymaster - The paymaster configuration
|
|
2768
|
+
* @returns The encoded paymaster data
|
|
1698
2769
|
*/
|
|
1699
2770
|
encodePaymasterData(paymaster) {
|
|
1700
2771
|
const paymasterAddress = paymaster.paymaster;
|
|
1701
|
-
const verificationGas = (0,
|
|
2772
|
+
const verificationGas = (0, import_viem8.pad)((0, import_viem8.toHex)(paymaster.paymasterVerificationGasLimit), {
|
|
1702
2773
|
size: 16
|
|
1703
2774
|
});
|
|
1704
|
-
const postOpGas = (0,
|
|
1705
|
-
return (0,
|
|
1706
|
-
paymasterAddress,
|
|
1707
|
-
verificationGas,
|
|
1708
|
-
postOpGas,
|
|
1709
|
-
paymaster.paymasterData
|
|
1710
|
-
]);
|
|
2775
|
+
const postOpGas = (0, import_viem8.pad)((0, import_viem8.toHex)(paymaster.paymasterPostOpGasLimit), { size: 16 });
|
|
2776
|
+
return (0, import_viem8.concat)([paymasterAddress, verificationGas, postOpGas, paymaster.paymasterData]);
|
|
1711
2777
|
}
|
|
1712
2778
|
};
|
|
1713
2779
|
function createUserOpBuilder(options) {
|
|
@@ -1716,6 +2782,13 @@ function createUserOpBuilder(options) {
|
|
|
1716
2782
|
|
|
1717
2783
|
// src/erc4337/bundler.ts
|
|
1718
2784
|
var BundlerError = class extends Error {
|
|
2785
|
+
/**
|
|
2786
|
+
* Create a new BundlerError
|
|
2787
|
+
*
|
|
2788
|
+
* @param message - The error message
|
|
2789
|
+
* @param code - Optional JSON-RPC error code
|
|
2790
|
+
* @param data - Optional additional error data
|
|
2791
|
+
*/
|
|
1719
2792
|
constructor(message, code, data) {
|
|
1720
2793
|
super(message);
|
|
1721
2794
|
this.code = code;
|
|
@@ -1724,21 +2797,31 @@ var BundlerError = class extends Error {
|
|
|
1724
2797
|
}
|
|
1725
2798
|
};
|
|
1726
2799
|
var BundlerClient = class {
|
|
2800
|
+
/**
|
|
2801
|
+
* Create a new BundlerClient instance
|
|
2802
|
+
*
|
|
2803
|
+
* @param config - Configuration for the bundler client
|
|
2804
|
+
*/
|
|
1727
2805
|
constructor(config) {
|
|
1728
|
-
this
|
|
2806
|
+
__publicField(this, "bundlerUrl");
|
|
2807
|
+
__publicField(this, "entryPoint");
|
|
2808
|
+
__publicField(this, "requestId", 0);
|
|
1729
2809
|
this.bundlerUrl = config.bundlerUrl;
|
|
1730
2810
|
this.entryPoint = config.entryPoint ?? ENTRYPOINT_V07_ADDRESS;
|
|
1731
|
-
|
|
2811
|
+
void config.chainId;
|
|
1732
2812
|
}
|
|
1733
2813
|
/**
|
|
1734
2814
|
* Send a UserOperation to the bundler
|
|
2815
|
+
*
|
|
2816
|
+
* @param userOp - The UserOperation to send
|
|
2817
|
+
* @returns The result containing the userOpHash and a wait function
|
|
1735
2818
|
*/
|
|
1736
2819
|
async sendUserOperation(userOp) {
|
|
1737
2820
|
const packed = this.packForRpc(userOp);
|
|
1738
|
-
const userOpHash = await this.rpcCall(
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
);
|
|
2821
|
+
const userOpHash = await this.rpcCall(BUNDLER_METHODS.sendUserOperation, [
|
|
2822
|
+
packed,
|
|
2823
|
+
this.entryPoint
|
|
2824
|
+
]);
|
|
1742
2825
|
return {
|
|
1743
2826
|
userOpHash,
|
|
1744
2827
|
wait: () => this.waitForReceipt(userOpHash)
|
|
@@ -1746,6 +2829,9 @@ var BundlerClient = class {
|
|
|
1746
2829
|
}
|
|
1747
2830
|
/**
|
|
1748
2831
|
* Estimate gas for a UserOperation
|
|
2832
|
+
*
|
|
2833
|
+
* @param userOp - Partial UserOperation with required sender and callData
|
|
2834
|
+
* @returns Gas estimates for the UserOperation
|
|
1749
2835
|
*/
|
|
1750
2836
|
async estimateUserOperationGas(userOp) {
|
|
1751
2837
|
const estimationOp = {
|
|
@@ -1774,6 +2860,9 @@ var BundlerClient = class {
|
|
|
1774
2860
|
}
|
|
1775
2861
|
/**
|
|
1776
2862
|
* Get UserOperation by hash
|
|
2863
|
+
*
|
|
2864
|
+
* @param userOpHash - The hash of the UserOperation to retrieve
|
|
2865
|
+
* @returns The UserOperation and EntryPoint, or null if not found
|
|
1777
2866
|
*/
|
|
1778
2867
|
async getUserOperationByHash(userOpHash) {
|
|
1779
2868
|
const result = await this.rpcCall(BUNDLER_METHODS.getUserOperationByHash, [userOpHash]);
|
|
@@ -1781,6 +2870,9 @@ var BundlerClient = class {
|
|
|
1781
2870
|
}
|
|
1782
2871
|
/**
|
|
1783
2872
|
* Get UserOperation receipt
|
|
2873
|
+
*
|
|
2874
|
+
* @param userOpHash - The hash of the UserOperation
|
|
2875
|
+
* @returns The receipt, or null if not yet included
|
|
1784
2876
|
*/
|
|
1785
2877
|
async getUserOperationReceipt(userOpHash) {
|
|
1786
2878
|
const result = await this.rpcCall(BUNDLER_METHODS.getUserOperationReceipt, [userOpHash]);
|
|
@@ -1803,12 +2895,16 @@ var BundlerClient = class {
|
|
|
1803
2895
|
}
|
|
1804
2896
|
/**
|
|
1805
2897
|
* Get supported EntryPoints
|
|
2898
|
+
*
|
|
2899
|
+
* @returns Array of supported EntryPoint addresses
|
|
1806
2900
|
*/
|
|
1807
2901
|
async getSupportedEntryPoints() {
|
|
1808
2902
|
return this.rpcCall(BUNDLER_METHODS.supportedEntryPoints, []);
|
|
1809
2903
|
}
|
|
1810
2904
|
/**
|
|
1811
2905
|
* Get chain ID from bundler
|
|
2906
|
+
*
|
|
2907
|
+
* @returns The chain ID
|
|
1812
2908
|
*/
|
|
1813
2909
|
async getChainId() {
|
|
1814
2910
|
const result = await this.rpcCall(BUNDLER_METHODS.chainId, []);
|
|
@@ -1816,6 +2912,12 @@ var BundlerClient = class {
|
|
|
1816
2912
|
}
|
|
1817
2913
|
/**
|
|
1818
2914
|
* Wait for UserOperation receipt with polling
|
|
2915
|
+
*
|
|
2916
|
+
* @param userOpHash - The hash of the UserOperation to wait for
|
|
2917
|
+
* @param options - Polling options
|
|
2918
|
+
* @param options.timeout - Maximum time to wait in milliseconds (default: 60000)
|
|
2919
|
+
* @param options.pollingInterval - Interval between polls in milliseconds (default: 2000)
|
|
2920
|
+
* @returns The UserOperation receipt
|
|
1819
2921
|
*/
|
|
1820
2922
|
async waitForReceipt(userOpHash, options = {}) {
|
|
1821
2923
|
const timeout = options.timeout ?? 6e4;
|
|
@@ -1828,12 +2930,13 @@ var BundlerClient = class {
|
|
|
1828
2930
|
}
|
|
1829
2931
|
await new Promise((resolve) => setTimeout(resolve, pollingInterval));
|
|
1830
2932
|
}
|
|
1831
|
-
throw new BundlerError(
|
|
1832
|
-
`Timeout waiting for UserOperation receipt: ${userOpHash}`
|
|
1833
|
-
);
|
|
2933
|
+
throw new BundlerError(`Timeout waiting for UserOperation receipt: ${userOpHash}`);
|
|
1834
2934
|
}
|
|
1835
2935
|
/**
|
|
1836
2936
|
* Pack UserOperation for RPC (convert bigints to hex strings)
|
|
2937
|
+
*
|
|
2938
|
+
* @param userOp - The UserOperation to pack
|
|
2939
|
+
* @returns The packed UserOperation for RPC transmission
|
|
1837
2940
|
*/
|
|
1838
2941
|
packForRpc(userOp) {
|
|
1839
2942
|
return {
|
|
@@ -1841,10 +2944,7 @@ var BundlerClient = class {
|
|
|
1841
2944
|
nonce: this.toHex(userOp.nonce),
|
|
1842
2945
|
initCode: userOp.initCode,
|
|
1843
2946
|
callData: userOp.callData,
|
|
1844
|
-
accountGasLimits: packAccountGasLimits(
|
|
1845
|
-
userOp.verificationGasLimit,
|
|
1846
|
-
userOp.callGasLimit
|
|
1847
|
-
),
|
|
2947
|
+
accountGasLimits: packAccountGasLimits(userOp.verificationGasLimit, userOp.callGasLimit),
|
|
1848
2948
|
preVerificationGas: this.toHex(userOp.preVerificationGas),
|
|
1849
2949
|
gasFees: packGasFees(userOp.maxPriorityFeePerGas, userOp.maxFeePerGas),
|
|
1850
2950
|
paymasterAndData: userOp.paymasterAndData,
|
|
@@ -1853,12 +2953,19 @@ var BundlerClient = class {
|
|
|
1853
2953
|
}
|
|
1854
2954
|
/**
|
|
1855
2955
|
* Convert bigint to hex string
|
|
2956
|
+
*
|
|
2957
|
+
* @param value - The bigint value to convert
|
|
2958
|
+
* @returns The hex string representation
|
|
1856
2959
|
*/
|
|
1857
2960
|
toHex(value) {
|
|
1858
2961
|
return `0x${value.toString(16)}`;
|
|
1859
2962
|
}
|
|
1860
2963
|
/**
|
|
1861
2964
|
* Make a JSON-RPC call to the bundler
|
|
2965
|
+
*
|
|
2966
|
+
* @param method - The JSON-RPC method name
|
|
2967
|
+
* @param params - The method parameters
|
|
2968
|
+
* @returns The result from the bundler
|
|
1862
2969
|
*/
|
|
1863
2970
|
async rpcCall(method, params) {
|
|
1864
2971
|
const request = {
|
|
@@ -1875,9 +2982,7 @@ var BundlerClient = class {
|
|
|
1875
2982
|
body: JSON.stringify(request)
|
|
1876
2983
|
});
|
|
1877
2984
|
if (!response.ok) {
|
|
1878
|
-
throw new BundlerError(
|
|
1879
|
-
`HTTP error: ${response.status} ${response.statusText}`
|
|
1880
|
-
);
|
|
2985
|
+
throw new BundlerError(`HTTP error: ${response.status} ${response.statusText}`);
|
|
1881
2986
|
}
|
|
1882
2987
|
const json = await response.json();
|
|
1883
2988
|
if (json.error) {
|
|
@@ -1891,25 +2996,32 @@ function createBundlerClient(config) {
|
|
|
1891
2996
|
}
|
|
1892
2997
|
|
|
1893
2998
|
// src/erc4337/paymaster.ts
|
|
1894
|
-
var
|
|
2999
|
+
var import_viem9 = require("viem");
|
|
1895
3000
|
var PaymasterClient = class {
|
|
3001
|
+
/**
|
|
3002
|
+
* Creates a new PaymasterClient instance
|
|
3003
|
+
*
|
|
3004
|
+
* @param config - Paymaster configuration including type, address, and optional URL
|
|
3005
|
+
*/
|
|
1896
3006
|
constructor(config) {
|
|
3007
|
+
__publicField(this, "config");
|
|
1897
3008
|
this.config = config;
|
|
1898
3009
|
}
|
|
1899
3010
|
/**
|
|
1900
3011
|
* Get paymaster data for a UserOperation
|
|
3012
|
+
*
|
|
3013
|
+
* @param userOp - Partial UserOperation to get paymaster data for
|
|
3014
|
+
* @param chainId - The chain ID for the operation
|
|
3015
|
+
* @param entryPoint - The EntryPoint contract address
|
|
3016
|
+
* @param context - Optional context data for the paymaster
|
|
3017
|
+
* @returns Paymaster data including address and gas limits
|
|
1901
3018
|
*/
|
|
1902
3019
|
async getPaymasterData(userOp, chainId, entryPoint, context) {
|
|
1903
3020
|
switch (this.config.type) {
|
|
1904
3021
|
case "verifying":
|
|
1905
3022
|
return this.getVerifyingPaymasterData(userOp, chainId, entryPoint);
|
|
1906
3023
|
case "sponsoring":
|
|
1907
|
-
return this.getSponsoringPaymasterData(
|
|
1908
|
-
userOp,
|
|
1909
|
-
chainId,
|
|
1910
|
-
entryPoint,
|
|
1911
|
-
context
|
|
1912
|
-
);
|
|
3024
|
+
return this.getSponsoringPaymasterData(userOp, chainId, entryPoint, context);
|
|
1913
3025
|
case "token":
|
|
1914
3026
|
return this.getTokenPaymasterData(userOp, chainId, entryPoint);
|
|
1915
3027
|
default:
|
|
@@ -1918,8 +3030,12 @@ var PaymasterClient = class {
|
|
|
1918
3030
|
}
|
|
1919
3031
|
/**
|
|
1920
3032
|
* Get gas estimates including paymaster gas
|
|
3033
|
+
*
|
|
3034
|
+
* @param _userOp - Partial UserOperation to estimate gas for (reserved for future use)
|
|
3035
|
+
* @param _chainId - The chain ID for the operation (reserved for future use)
|
|
3036
|
+
* @returns Gas estimates including paymaster verification and postOp gas
|
|
1921
3037
|
*/
|
|
1922
|
-
async estimatePaymasterGas(
|
|
3038
|
+
async estimatePaymasterGas(_userOp, _chainId) {
|
|
1923
3039
|
return {
|
|
1924
3040
|
verificationGasLimit: DEFAULT_GAS_LIMITS.verificationGasLimit,
|
|
1925
3041
|
callGasLimit: DEFAULT_GAS_LIMITS.callGasLimit,
|
|
@@ -1930,6 +3046,12 @@ var PaymasterClient = class {
|
|
|
1930
3046
|
}
|
|
1931
3047
|
/**
|
|
1932
3048
|
* Check if the paymaster will sponsor this operation
|
|
3049
|
+
*
|
|
3050
|
+
* @param userOp - Partial UserOperation to check sponsorship for
|
|
3051
|
+
* @param chainId - The chain ID for the operation
|
|
3052
|
+
* @param entryPoint - The EntryPoint contract address
|
|
3053
|
+
* @param context - Optional context data for policy validation
|
|
3054
|
+
* @returns True if the paymaster will sponsor the operation
|
|
1933
3055
|
*/
|
|
1934
3056
|
async willSponsor(userOp, chainId, entryPoint, context) {
|
|
1935
3057
|
if (!this.config.url) {
|
|
@@ -1955,6 +3077,11 @@ var PaymasterClient = class {
|
|
|
1955
3077
|
}
|
|
1956
3078
|
/**
|
|
1957
3079
|
* Get verifying paymaster data (off-chain signature)
|
|
3080
|
+
*
|
|
3081
|
+
* @param userOp - Partial UserOperation to get paymaster data for
|
|
3082
|
+
* @param chainId - The chain ID for the operation
|
|
3083
|
+
* @param entryPoint - The EntryPoint contract address
|
|
3084
|
+
* @returns Paymaster data with verification signature
|
|
1958
3085
|
*/
|
|
1959
3086
|
async getVerifyingPaymasterData(userOp, chainId, entryPoint) {
|
|
1960
3087
|
if (this.config.url) {
|
|
@@ -1969,6 +3096,12 @@ var PaymasterClient = class {
|
|
|
1969
3096
|
}
|
|
1970
3097
|
/**
|
|
1971
3098
|
* Get sponsoring paymaster data (third-party pays)
|
|
3099
|
+
*
|
|
3100
|
+
* @param userOp - Partial UserOperation to get sponsorship for
|
|
3101
|
+
* @param chainId - The chain ID for the operation
|
|
3102
|
+
* @param entryPoint - The EntryPoint contract address
|
|
3103
|
+
* @param context - Optional context data for sponsorship validation
|
|
3104
|
+
* @returns Paymaster data for sponsored operation
|
|
1972
3105
|
*/
|
|
1973
3106
|
async getSponsoringPaymasterData(userOp, chainId, entryPoint, context) {
|
|
1974
3107
|
if (!this.config.url) {
|
|
@@ -1998,6 +3131,11 @@ var PaymasterClient = class {
|
|
|
1998
3131
|
}
|
|
1999
3132
|
/**
|
|
2000
3133
|
* Get token paymaster data (pay gas with ERC20)
|
|
3134
|
+
*
|
|
3135
|
+
* @param userOp - Partial UserOperation to get token paymaster data for
|
|
3136
|
+
* @param chainId - The chain ID for the operation
|
|
3137
|
+
* @param entryPoint - The EntryPoint contract address
|
|
3138
|
+
* @returns Paymaster data for ERC20 token payment
|
|
2001
3139
|
*/
|
|
2002
3140
|
async getTokenPaymasterData(userOp, chainId, entryPoint) {
|
|
2003
3141
|
const tokenAddress = this.config.options?.tokenAddress;
|
|
@@ -2019,6 +3157,12 @@ var PaymasterClient = class {
|
|
|
2019
3157
|
}
|
|
2020
3158
|
/**
|
|
2021
3159
|
* Call paymaster service API
|
|
3160
|
+
*
|
|
3161
|
+
* @param userOp - Partial UserOperation to send to the service
|
|
3162
|
+
* @param chainId - The chain ID for the operation
|
|
3163
|
+
* @param entryPoint - The EntryPoint contract address
|
|
3164
|
+
* @param context - Optional context data for the service
|
|
3165
|
+
* @returns Paymaster data from the service response
|
|
2022
3166
|
*/
|
|
2023
3167
|
async callPaymasterService(userOp, chainId, entryPoint, context) {
|
|
2024
3168
|
if (!this.config.url) {
|
|
@@ -2048,12 +3192,14 @@ var PaymasterClient = class {
|
|
|
2048
3192
|
}
|
|
2049
3193
|
/**
|
|
2050
3194
|
* Serialize UserOperation for API calls
|
|
3195
|
+
*
|
|
3196
|
+
* @param userOp - Partial UserOperation to serialize
|
|
3197
|
+
* @returns Serialized UserOperation with hex-encoded values
|
|
2051
3198
|
*/
|
|
2052
3199
|
serializeUserOp(userOp) {
|
|
2053
3200
|
const result = {};
|
|
2054
3201
|
if (userOp.sender) result.sender = userOp.sender;
|
|
2055
|
-
if (userOp.nonce !== void 0)
|
|
2056
|
-
result.nonce = `0x${userOp.nonce.toString(16)}`;
|
|
3202
|
+
if (userOp.nonce !== void 0) result.nonce = `0x${userOp.nonce.toString(16)}`;
|
|
2057
3203
|
if (userOp.initCode) result.initCode = userOp.initCode;
|
|
2058
3204
|
if (userOp.callData) result.callData = userOp.callData;
|
|
2059
3205
|
if (userOp.verificationGasLimit !== void 0)
|
|
@@ -2075,10 +3221,10 @@ function createPaymasterClient(config) {
|
|
|
2075
3221
|
return new PaymasterClient(config);
|
|
2076
3222
|
}
|
|
2077
3223
|
function encodePaymasterAndData(data) {
|
|
2078
|
-
return (0,
|
|
3224
|
+
return (0, import_viem9.concat)([
|
|
2079
3225
|
data.paymaster,
|
|
2080
|
-
(0,
|
|
2081
|
-
(0,
|
|
3226
|
+
(0, import_viem9.pad)((0, import_viem9.toHex)(data.paymasterVerificationGasLimit), { size: 16 }),
|
|
3227
|
+
(0, import_viem9.pad)((0, import_viem9.toHex)(data.paymasterPostOpGasLimit), { size: 16 }),
|
|
2082
3228
|
data.paymasterData
|
|
2083
3229
|
]);
|
|
2084
3230
|
}
|
|
@@ -2087,9 +3233,7 @@ function decodePaymasterAndData(paymasterAndData) {
|
|
|
2087
3233
|
return null;
|
|
2088
3234
|
}
|
|
2089
3235
|
const paymaster = `0x${paymasterAndData.slice(2, 42)}`;
|
|
2090
|
-
const paymasterVerificationGasLimit = BigInt(
|
|
2091
|
-
`0x${paymasterAndData.slice(42, 74)}`
|
|
2092
|
-
);
|
|
3236
|
+
const paymasterVerificationGasLimit = BigInt(`0x${paymasterAndData.slice(42, 74)}`);
|
|
2093
3237
|
const paymasterPostOpGasLimit = BigInt(`0x${paymasterAndData.slice(74, 106)}`);
|
|
2094
3238
|
const paymasterData = `0x${paymasterAndData.slice(106)}`;
|
|
2095
3239
|
return {
|
|
@@ -2101,13 +3245,13 @@ function decodePaymasterAndData(paymasterAndData) {
|
|
|
2101
3245
|
}
|
|
2102
3246
|
|
|
2103
3247
|
// src/erc4337/paymasters/pimlico.ts
|
|
2104
|
-
var
|
|
3248
|
+
var import_viem10 = require("viem");
|
|
2105
3249
|
|
|
2106
3250
|
// src/erc4337/accounts/safe.ts
|
|
2107
|
-
var
|
|
3251
|
+
var import_viem11 = require("viem");
|
|
2108
3252
|
|
|
2109
3253
|
// src/erc4337/t402.ts
|
|
2110
|
-
var
|
|
3254
|
+
var import_viem12 = require("viem");
|
|
2111
3255
|
var ERC20_TRANSFER_ABI = [
|
|
2112
3256
|
{
|
|
2113
3257
|
inputs: [
|
|
@@ -2140,7 +3284,18 @@ var EIP3009_TRANSFER_ABI = [
|
|
|
2140
3284
|
}
|
|
2141
3285
|
];
|
|
2142
3286
|
var GaslessT402Client = class {
|
|
3287
|
+
/**
|
|
3288
|
+
* Creates a new GaslessT402Client instance
|
|
3289
|
+
*
|
|
3290
|
+
* @param config - Configuration including signer, bundler, paymaster, and chain settings
|
|
3291
|
+
*/
|
|
2143
3292
|
constructor(config) {
|
|
3293
|
+
__publicField(this, "signer");
|
|
3294
|
+
__publicField(this, "builder");
|
|
3295
|
+
__publicField(this, "bundler");
|
|
3296
|
+
__publicField(this, "paymaster");
|
|
3297
|
+
__publicField(this, "chainId");
|
|
3298
|
+
__publicField(this, "publicClient");
|
|
2144
3299
|
this.signer = config.signer;
|
|
2145
3300
|
this.builder = new UserOpBuilder();
|
|
2146
3301
|
this.bundler = new BundlerClient(config.bundler);
|
|
@@ -2154,6 +3309,9 @@ var GaslessT402Client = class {
|
|
|
2154
3309
|
* This submits the payment as a UserOperation which can be:
|
|
2155
3310
|
* - Sponsored by a paymaster (truly gasless)
|
|
2156
3311
|
* - Paid from the smart account's balance
|
|
3312
|
+
*
|
|
3313
|
+
* @param params - Payment parameters including token, recipient, and amount
|
|
3314
|
+
* @returns Result containing the user operation hash and wait function
|
|
2157
3315
|
*/
|
|
2158
3316
|
async executePayment(params) {
|
|
2159
3317
|
const callData = params.authorization ? this.buildAuthorizedTransferCallData(params) : this.buildTransferCallData(params);
|
|
@@ -2181,6 +3339,9 @@ var GaslessT402Client = class {
|
|
|
2181
3339
|
}
|
|
2182
3340
|
/**
|
|
2183
3341
|
* Execute multiple T402 payments in a single UserOperation
|
|
3342
|
+
*
|
|
3343
|
+
* @param payments - Array of payment parameters to batch together
|
|
3344
|
+
* @returns Result containing the user operation hash and wait function
|
|
2184
3345
|
*/
|
|
2185
3346
|
async executeBatchPayments(payments) {
|
|
2186
3347
|
const intents = payments.map((params) => ({
|
|
@@ -2207,6 +3368,9 @@ var GaslessT402Client = class {
|
|
|
2207
3368
|
}
|
|
2208
3369
|
/**
|
|
2209
3370
|
* Check if a payment can be sponsored (gasless)
|
|
3371
|
+
*
|
|
3372
|
+
* @param params - Payment parameters to check for sponsorship eligibility
|
|
3373
|
+
* @returns True if the payment can be sponsored by the paymaster
|
|
2210
3374
|
*/
|
|
2211
3375
|
async canSponsor(params) {
|
|
2212
3376
|
if (!this.paymaster) return false;
|
|
@@ -2224,21 +3388,28 @@ var GaslessT402Client = class {
|
|
|
2224
3388
|
}
|
|
2225
3389
|
/**
|
|
2226
3390
|
* Get the smart account address
|
|
3391
|
+
*
|
|
3392
|
+
* @returns The address of the smart account
|
|
2227
3393
|
*/
|
|
2228
3394
|
async getAccountAddress() {
|
|
2229
3395
|
return this.signer.getAddress();
|
|
2230
3396
|
}
|
|
2231
3397
|
/**
|
|
2232
3398
|
* Check if the smart account is deployed
|
|
3399
|
+
*
|
|
3400
|
+
* @returns True if the smart account contract is deployed on-chain
|
|
2233
3401
|
*/
|
|
2234
3402
|
async isAccountDeployed() {
|
|
2235
3403
|
return this.signer.isDeployed();
|
|
2236
3404
|
}
|
|
2237
3405
|
/**
|
|
2238
3406
|
* Build call data for a simple ERC20 transfer
|
|
3407
|
+
*
|
|
3408
|
+
* @param params - Payment parameters including recipient and amount
|
|
3409
|
+
* @returns Encoded call data for ERC20 transfer function
|
|
2239
3410
|
*/
|
|
2240
3411
|
buildTransferCallData(params) {
|
|
2241
|
-
return (0,
|
|
3412
|
+
return (0, import_viem12.encodeFunctionData)({
|
|
2242
3413
|
abi: ERC20_TRANSFER_ABI,
|
|
2243
3414
|
functionName: "transfer",
|
|
2244
3415
|
args: [params.to, params.amount]
|
|
@@ -2246,6 +3417,9 @@ var GaslessT402Client = class {
|
|
|
2246
3417
|
}
|
|
2247
3418
|
/**
|
|
2248
3419
|
* Build call data for an authorized transfer (EIP-3009)
|
|
3420
|
+
*
|
|
3421
|
+
* @param params - Payment parameters including authorization signature
|
|
3422
|
+
* @returns Encoded call data for transferWithAuthorization function
|
|
2249
3423
|
*/
|
|
2250
3424
|
buildAuthorizedTransferCallData(params) {
|
|
2251
3425
|
if (!params.authorization) {
|
|
@@ -2255,7 +3429,7 @@ var GaslessT402Client = class {
|
|
|
2255
3429
|
const r = `0x${sig.slice(2, 66)}`;
|
|
2256
3430
|
const s = `0x${sig.slice(66, 130)}`;
|
|
2257
3431
|
const v = parseInt(sig.slice(130, 132), 16);
|
|
2258
|
-
return (0,
|
|
3432
|
+
return (0, import_viem12.encodeFunctionData)({
|
|
2259
3433
|
abi: EIP3009_TRANSFER_ABI,
|
|
2260
3434
|
functionName: "transferWithAuthorization",
|
|
2261
3435
|
args: [
|
|
@@ -2274,14 +3448,13 @@ var GaslessT402Client = class {
|
|
|
2274
3448
|
}
|
|
2275
3449
|
/**
|
|
2276
3450
|
* Estimate gas for a single transaction
|
|
3451
|
+
*
|
|
3452
|
+
* @param intent - Transaction intent with target, value, and data
|
|
3453
|
+
* @returns Gas estimates for the UserOperation
|
|
2277
3454
|
*/
|
|
2278
3455
|
async estimateGas(intent) {
|
|
2279
3456
|
const sender = await this.signer.getAddress();
|
|
2280
|
-
const callData = this.signer.encodeExecute(
|
|
2281
|
-
intent.to,
|
|
2282
|
-
intent.value ?? 0n,
|
|
2283
|
-
intent.data ?? "0x"
|
|
2284
|
-
);
|
|
3457
|
+
const callData = this.signer.encodeExecute(intent.to, intent.value ?? 0n, intent.data ?? "0x");
|
|
2285
3458
|
try {
|
|
2286
3459
|
return await this.bundler.estimateUserOperationGas({
|
|
2287
3460
|
sender,
|
|
@@ -2297,6 +3470,9 @@ var GaslessT402Client = class {
|
|
|
2297
3470
|
}
|
|
2298
3471
|
/**
|
|
2299
3472
|
* Estimate gas for a batch transaction
|
|
3473
|
+
*
|
|
3474
|
+
* @param intents - Array of transaction intents to batch
|
|
3475
|
+
* @returns Gas estimates for the batched UserOperation
|
|
2300
3476
|
*/
|
|
2301
3477
|
async estimateBatchGas(intents) {
|
|
2302
3478
|
const sender = await this.signer.getAddress();
|
|
@@ -2320,15 +3496,14 @@ var GaslessT402Client = class {
|
|
|
2320
3496
|
}
|
|
2321
3497
|
/**
|
|
2322
3498
|
* Get paymaster data if configured
|
|
3499
|
+
*
|
|
3500
|
+
* @param _ - Gas estimates (unused but kept for potential future use)
|
|
3501
|
+
* @returns Paymaster data or undefined if no paymaster configured
|
|
2323
3502
|
*/
|
|
2324
|
-
async getPaymasterData(
|
|
3503
|
+
async getPaymasterData(_) {
|
|
2325
3504
|
if (!this.paymaster) return void 0;
|
|
2326
3505
|
const sender = await this.signer.getAddress();
|
|
2327
|
-
return this.paymaster.getPaymasterData(
|
|
2328
|
-
{ sender },
|
|
2329
|
-
this.chainId,
|
|
2330
|
-
ENTRYPOINT_V07_ADDRESS
|
|
2331
|
-
);
|
|
3506
|
+
return this.paymaster.getPaymasterData({ sender }, this.chainId, ENTRYPOINT_V07_ADDRESS);
|
|
2332
3507
|
}
|
|
2333
3508
|
};
|
|
2334
3509
|
function createGaslessT402Client(config) {
|
|
@@ -2340,6 +3515,7 @@ function createGaslessT402Client(config) {
|
|
|
2340
3515
|
BUNDLER_METHODS,
|
|
2341
3516
|
BundlerClient,
|
|
2342
3517
|
BundlerError,
|
|
3518
|
+
CrossChainPaymentRouter,
|
|
2343
3519
|
DEFAULT_GAS_LIMITS,
|
|
2344
3520
|
ENTRYPOINT_V06_ADDRESS,
|
|
2345
3521
|
ENTRYPOINT_V07_ABI,
|
|
@@ -2351,46 +3527,38 @@ function createGaslessT402Client(config) {
|
|
|
2351
3527
|
GaslessT402Client,
|
|
2352
3528
|
LAYERZERO_ENDPOINT_IDS,
|
|
2353
3529
|
LAYERZERO_ENDPOINT_V2,
|
|
3530
|
+
LAYERZERO_SCAN_BASE_URL,
|
|
3531
|
+
LayerZeroScanClient,
|
|
2354
3532
|
PaymasterClient,
|
|
2355
3533
|
PaymasterType,
|
|
2356
|
-
TOKEN_PRIORITY,
|
|
2357
|
-
TOKEN_REGISTRY,
|
|
2358
|
-
USDC_ADDRESSES,
|
|
2359
|
-
USDT0_ADDRESSES,
|
|
2360
3534
|
USDT0_OFT_ADDRESSES,
|
|
2361
|
-
|
|
3535
|
+
UptoEvmFacilitatorScheme,
|
|
3536
|
+
UptoEvmScheme,
|
|
3537
|
+
UptoEvmServerScheme,
|
|
2362
3538
|
Usdt0Bridge,
|
|
2363
3539
|
UserOpBuilder,
|
|
2364
3540
|
addressToBytes32,
|
|
2365
|
-
authorizationTypes,
|
|
2366
3541
|
bytes32ToAddress,
|
|
2367
3542
|
createBundlerClient,
|
|
3543
|
+
createCrossChainPaymentRouter,
|
|
2368
3544
|
createGaslessT402Client,
|
|
3545
|
+
createLayerZeroScanClient,
|
|
2369
3546
|
createPaymasterClient,
|
|
3547
|
+
createUptoEvmFacilitatorScheme,
|
|
3548
|
+
createUptoEvmScheme,
|
|
3549
|
+
createUptoEvmServerScheme,
|
|
2370
3550
|
createUsdt0Bridge,
|
|
2371
3551
|
createUserOpBuilder,
|
|
2372
3552
|
decodePaymasterAndData,
|
|
2373
|
-
eip3009ABI,
|
|
2374
3553
|
encodePaymasterAndData,
|
|
2375
|
-
erc20LegacyABI,
|
|
2376
3554
|
getBridgeableChains,
|
|
2377
|
-
getDefaultToken,
|
|
2378
|
-
getEIP712Domain,
|
|
2379
3555
|
getEndpointId,
|
|
2380
|
-
getNetworkTokens,
|
|
2381
|
-
getNetworksForToken,
|
|
2382
|
-
getTokenByAddress,
|
|
2383
|
-
getTokenConfig,
|
|
2384
|
-
getUsdt0Networks,
|
|
2385
3556
|
getUsdt0OftAddress,
|
|
2386
|
-
legacyAuthorizationTypes,
|
|
2387
3557
|
packAccountGasLimits,
|
|
2388
3558
|
packGasFees,
|
|
2389
3559
|
supportsBridging,
|
|
2390
|
-
supportsEIP3009,
|
|
2391
|
-
toClientEvmSigner,
|
|
2392
|
-
toFacilitatorEvmSigner,
|
|
2393
3560
|
unpackAccountGasLimits,
|
|
2394
|
-
unpackGasFees
|
|
3561
|
+
unpackGasFees,
|
|
3562
|
+
...require("@t402/evm-core")
|
|
2395
3563
|
});
|
|
2396
3564
|
//# sourceMappingURL=index.js.map
|