@bankofai/x402-evm 1.0.0-beta.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/README.md +172 -0
- package/dist/cjs/auth-capture/client/index.d.ts +44 -0
- package/dist/cjs/auth-capture/client/index.js +298 -0
- package/dist/cjs/auth-capture/client/index.js.map +1 -0
- package/dist/cjs/batch-settlement/client/file-storage.d.ts +47 -0
- package/dist/cjs/batch-settlement/client/file-storage.js +116 -0
- package/dist/cjs/batch-settlement/client/file-storage.js.map +1 -0
- package/dist/cjs/batch-settlement/client/index.d.ts +111 -0
- package/dist/cjs/batch-settlement/client/index.js +1565 -0
- package/dist/cjs/batch-settlement/client/index.js.map +1 -0
- package/dist/cjs/batch-settlement/facilitator/index.d.ts +72 -0
- package/dist/cjs/batch-settlement/facilitator/index.js +2102 -0
- package/dist/cjs/batch-settlement/facilitator/index.js.map +1 -0
- package/dist/cjs/batch-settlement/server/file-storage.d.ts +53 -0
- package/dist/cjs/batch-settlement/server/file-storage.js +181 -0
- package/dist/cjs/batch-settlement/server/file-storage.js.map +1 -0
- package/dist/cjs/batch-settlement/server/index.d.ts +491 -0
- package/dist/cjs/batch-settlement/server/index.js +1978 -0
- package/dist/cjs/batch-settlement/server/index.js.map +1 -0
- package/dist/cjs/batch-settlement/server/redis-storage.d.ts +87 -0
- package/dist/cjs/batch-settlement/server/redis-storage.js +181 -0
- package/dist/cjs/batch-settlement/server/redis-storage.js.map +1 -0
- package/dist/cjs/client/agent-wallet.d.ts +69 -0
- package/dist/cjs/client/agent-wallet.js +84 -0
- package/dist/cjs/client/agent-wallet.js.map +1 -0
- package/dist/cjs/exact/client/index.d.ts +63 -0
- package/dist/cjs/exact/client/index.js +739 -0
- package/dist/cjs/exact/client/index.js.map +1 -0
- package/dist/cjs/exact/facilitator/index.d.ts +141 -0
- package/dist/cjs/exact/facilitator/index.js +1989 -0
- package/dist/cjs/exact/facilitator/index.js.map +1 -0
- package/dist/cjs/exact/server/index.d.ts +118 -0
- package/dist/cjs/exact/server/index.js +326 -0
- package/dist/cjs/exact/server/index.js.map +1 -0
- package/dist/cjs/exact/v1/client/index.d.ts +38 -0
- package/dist/cjs/exact/v1/client/index.js +193 -0
- package/dist/cjs/exact/v1/client/index.js.map +1 -0
- package/dist/cjs/exact/v1/facilitator/index.d.ts +84 -0
- package/dist/cjs/exact/v1/facilitator/index.js +739 -0
- package/dist/cjs/exact/v1/facilitator/index.js.map +1 -0
- package/dist/cjs/facilitator/agent-wallet.d.ts +109 -0
- package/dist/cjs/facilitator/agent-wallet.js +105 -0
- package/dist/cjs/facilitator/agent-wallet.js.map +1 -0
- package/dist/cjs/index.d.ts +338 -0
- package/dist/cjs/index.js +2860 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/permit2-DK5A8alk.d.ts +729 -0
- package/dist/cjs/permit2-DhJRUcgY.d.ts +729 -0
- package/dist/cjs/rpc-DULZzRne.d.ts +13 -0
- package/dist/cjs/scheme-7ehldYoO.d.ts +307 -0
- package/dist/cjs/scheme-BjBJzHF7.d.ts +307 -0
- package/dist/cjs/scheme-DWgpkDgz.d.ts +47 -0
- package/dist/cjs/signer-BFelv8DL.d.ts +170 -0
- package/dist/cjs/storage-6W5MO46W.d.ts +50 -0
- package/dist/cjs/storage-CHNote8s.d.ts +81 -0
- package/dist/cjs/storage-DjCv5IPh.d.ts +81 -0
- package/dist/cjs/types-CKd3Xoi1.d.ts +180 -0
- package/dist/cjs/types-DIt9uAUy.d.ts +180 -0
- package/dist/cjs/upto/client/index.d.ts +34 -0
- package/dist/cjs/upto/client/index.js +509 -0
- package/dist/cjs/upto/client/index.js.map +1 -0
- package/dist/cjs/upto/facilitator/index.d.ts +54 -0
- package/dist/cjs/upto/facilitator/index.js +1313 -0
- package/dist/cjs/upto/facilitator/index.js.map +1 -0
- package/dist/cjs/upto/server/index.d.ts +69 -0
- package/dist/cjs/upto/server/index.js +296 -0
- package/dist/cjs/upto/server/index.js.map +1 -0
- package/dist/cjs/v1/index.d.ts +40 -0
- package/dist/cjs/v1/index.js +199 -0
- package/dist/cjs/v1/index.js.map +1 -0
- package/dist/esm/auth-capture/client/index.d.mts +44 -0
- package/dist/esm/auth-capture/client/index.mjs +8 -0
- package/dist/esm/auth-capture/client/index.mjs.map +1 -0
- package/dist/esm/batch-settlement/client/file-storage.d.mts +47 -0
- package/dist/esm/batch-settlement/client/file-storage.mjs +63 -0
- package/dist/esm/batch-settlement/client/file-storage.mjs.map +1 -0
- package/dist/esm/batch-settlement/client/index.d.mts +111 -0
- package/dist/esm/batch-settlement/client/index.mjs +58 -0
- package/dist/esm/batch-settlement/client/index.mjs.map +1 -0
- package/dist/esm/batch-settlement/facilitator/index.d.mts +72 -0
- package/dist/esm/batch-settlement/facilitator/index.mjs +1252 -0
- package/dist/esm/batch-settlement/facilitator/index.mjs.map +1 -0
- package/dist/esm/batch-settlement/server/file-storage.d.mts +53 -0
- package/dist/esm/batch-settlement/server/file-storage.mjs +128 -0
- package/dist/esm/batch-settlement/server/file-storage.mjs.map +1 -0
- package/dist/esm/batch-settlement/server/index.d.mts +491 -0
- package/dist/esm/batch-settlement/server/index.mjs +1640 -0
- package/dist/esm/batch-settlement/server/index.mjs.map +1 -0
- package/dist/esm/batch-settlement/server/redis-storage.d.mts +87 -0
- package/dist/esm/batch-settlement/server/redis-storage.mjs +156 -0
- package/dist/esm/batch-settlement/server/redis-storage.mjs.map +1 -0
- package/dist/esm/chunk-2EUQTNJO.mjs +38 -0
- package/dist/esm/chunk-2EUQTNJO.mjs.map +1 -0
- package/dist/esm/chunk-3WZF6722.mjs +36 -0
- package/dist/esm/chunk-3WZF6722.mjs.map +1 -0
- package/dist/esm/chunk-E4Z7PNXC.mjs +275 -0
- package/dist/esm/chunk-E4Z7PNXC.mjs.map +1 -0
- package/dist/esm/chunk-GQVMVP4N.mjs +911 -0
- package/dist/esm/chunk-GQVMVP4N.mjs.map +1 -0
- package/dist/esm/chunk-H2EYJIZL.mjs +489 -0
- package/dist/esm/chunk-H2EYJIZL.mjs.map +1 -0
- package/dist/esm/chunk-H3KPLYGI.mjs +152 -0
- package/dist/esm/chunk-H3KPLYGI.mjs.map +1 -0
- package/dist/esm/chunk-HYABYUBD.mjs +432 -0
- package/dist/esm/chunk-HYABYUBD.mjs.map +1 -0
- package/dist/esm/chunk-I2DVUHM5.mjs +123 -0
- package/dist/esm/chunk-I2DVUHM5.mjs.map +1 -0
- package/dist/esm/chunk-JK7SLLF7.mjs +34 -0
- package/dist/esm/chunk-JK7SLLF7.mjs.map +1 -0
- package/dist/esm/chunk-JNT7C46S.mjs +352 -0
- package/dist/esm/chunk-JNT7C46S.mjs.map +1 -0
- package/dist/esm/chunk-MACPBXCT.mjs +415 -0
- package/dist/esm/chunk-MACPBXCT.mjs.map +1 -0
- package/dist/esm/chunk-P3QOX3QZ.mjs +113 -0
- package/dist/esm/chunk-P3QOX3QZ.mjs.map +1 -0
- package/dist/esm/chunk-QVATVA3J.mjs +47 -0
- package/dist/esm/chunk-QVATVA3J.mjs.map +1 -0
- package/dist/esm/chunk-SHJFA25H.mjs +159 -0
- package/dist/esm/chunk-SHJFA25H.mjs.map +1 -0
- package/dist/esm/chunk-TW7Z65AO.mjs +34 -0
- package/dist/esm/chunk-TW7Z65AO.mjs.map +1 -0
- package/dist/esm/chunk-U4HCGTLU.mjs +35 -0
- package/dist/esm/chunk-U4HCGTLU.mjs.map +1 -0
- package/dist/esm/chunk-VS3RYAYE.mjs +80 -0
- package/dist/esm/chunk-VS3RYAYE.mjs.map +1 -0
- package/dist/esm/chunk-W6ON4LG2.mjs +39 -0
- package/dist/esm/chunk-W6ON4LG2.mjs.map +1 -0
- package/dist/esm/chunk-XG2JLZVJ.mjs +627 -0
- package/dist/esm/chunk-XG2JLZVJ.mjs.map +1 -0
- package/dist/esm/chunk-ZCJRY5LQ.mjs +162 -0
- package/dist/esm/chunk-ZCJRY5LQ.mjs.map +1 -0
- package/dist/esm/client/agent-wallet.d.mts +69 -0
- package/dist/esm/client/agent-wallet.mjs +36 -0
- package/dist/esm/client/agent-wallet.mjs.map +1 -0
- package/dist/esm/exact/client/index.d.mts +63 -0
- package/dist/esm/exact/client/index.mjs +25 -0
- package/dist/esm/exact/client/index.mjs.map +1 -0
- package/dist/esm/exact/facilitator/index.d.mts +141 -0
- package/dist/esm/exact/facilitator/index.mjs +694 -0
- package/dist/esm/exact/facilitator/index.mjs.map +1 -0
- package/dist/esm/exact/server/index.d.mts +118 -0
- package/dist/esm/exact/server/index.mjs +153 -0
- package/dist/esm/exact/server/index.mjs.map +1 -0
- package/dist/esm/exact/v1/client/index.d.mts +38 -0
- package/dist/esm/exact/v1/client/index.mjs +12 -0
- package/dist/esm/exact/v1/client/index.mjs.map +1 -0
- package/dist/esm/exact/v1/facilitator/index.d.mts +84 -0
- package/dist/esm/exact/v1/facilitator/index.mjs +12 -0
- package/dist/esm/exact/v1/facilitator/index.mjs.map +1 -0
- package/dist/esm/facilitator/agent-wallet.d.mts +109 -0
- package/dist/esm/facilitator/agent-wallet.mjs +74 -0
- package/dist/esm/facilitator/agent-wallet.mjs.map +1 -0
- package/dist/esm/index.d.mts +338 -0
- package/dist/esm/index.mjs +144 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/permit2-DhJRUcgY.d.mts +729 -0
- package/dist/esm/rpc-DULZzRne.d.mts +13 -0
- package/dist/esm/scheme-CkNhpXrG.d.mts +307 -0
- package/dist/esm/scheme-D8ZbykGV.d.mts +47 -0
- package/dist/esm/signer-BFelv8DL.d.mts +170 -0
- package/dist/esm/storage-6W5MO46W.d.mts +50 -0
- package/dist/esm/storage-BEzTEiUr.d.mts +81 -0
- package/dist/esm/types-DIt9uAUy.d.mts +180 -0
- package/dist/esm/upto/client/index.d.mts +34 -0
- package/dist/esm/upto/client/index.mjs +22 -0
- package/dist/esm/upto/client/index.mjs.map +1 -0
- package/dist/esm/upto/facilitator/index.d.mts +54 -0
- package/dist/esm/upto/facilitator/index.mjs +507 -0
- package/dist/esm/upto/facilitator/index.mjs.map +1 -0
- package/dist/esm/upto/server/index.d.mts +69 -0
- package/dist/esm/upto/server/index.mjs +124 -0
- package/dist/esm/upto/server/index.mjs.map +1 -0
- package/dist/esm/v1/index.d.mts +40 -0
- package/dist/esm/v1/index.mjs +18 -0
- package/dist/esm/v1/index.mjs.map +1 -0
- package/package.json +250 -0
|
@@ -0,0 +1,1989 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/exact/facilitator/index.ts
|
|
21
|
+
var facilitator_exports = {};
|
|
22
|
+
__export(facilitator_exports, {
|
|
23
|
+
ExactEvmScheme: () => ExactEvmScheme,
|
|
24
|
+
registerExactEvmScheme: () => registerExactEvmScheme
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(facilitator_exports);
|
|
27
|
+
|
|
28
|
+
// src/types.ts
|
|
29
|
+
function isPermit2Payload(payload) {
|
|
30
|
+
return "permit2Authorization" in payload;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// src/exact/facilitator/eip3009.ts
|
|
34
|
+
var import_viem8 = require("viem");
|
|
35
|
+
|
|
36
|
+
// src/constants.ts
|
|
37
|
+
var authorizationTypes = {
|
|
38
|
+
TransferWithAuthorization: [
|
|
39
|
+
{ name: "from", type: "address" },
|
|
40
|
+
{ name: "to", type: "address" },
|
|
41
|
+
{ name: "value", type: "uint256" },
|
|
42
|
+
{ name: "validAfter", type: "uint256" },
|
|
43
|
+
{ name: "validBefore", type: "uint256" },
|
|
44
|
+
{ name: "nonce", type: "bytes32" }
|
|
45
|
+
]
|
|
46
|
+
};
|
|
47
|
+
var permit2WitnessTypes = {
|
|
48
|
+
PermitWitnessTransferFrom: [
|
|
49
|
+
{ name: "permitted", type: "TokenPermissions" },
|
|
50
|
+
{ name: "spender", type: "address" },
|
|
51
|
+
{ name: "nonce", type: "uint256" },
|
|
52
|
+
{ name: "deadline", type: "uint256" },
|
|
53
|
+
{ name: "witness", type: "Witness" }
|
|
54
|
+
],
|
|
55
|
+
TokenPermissions: [
|
|
56
|
+
{ name: "token", type: "address" },
|
|
57
|
+
{ name: "amount", type: "uint256" }
|
|
58
|
+
],
|
|
59
|
+
Witness: [
|
|
60
|
+
{ name: "to", type: "address" },
|
|
61
|
+
{ name: "validAfter", type: "uint256" }
|
|
62
|
+
]
|
|
63
|
+
};
|
|
64
|
+
var eip3009ABI = [
|
|
65
|
+
{
|
|
66
|
+
inputs: [
|
|
67
|
+
{ name: "from", type: "address" },
|
|
68
|
+
{ name: "to", type: "address" },
|
|
69
|
+
{ name: "value", type: "uint256" },
|
|
70
|
+
{ name: "validAfter", type: "uint256" },
|
|
71
|
+
{ name: "validBefore", type: "uint256" },
|
|
72
|
+
{ name: "nonce", type: "bytes32" },
|
|
73
|
+
{ name: "v", type: "uint8" },
|
|
74
|
+
{ name: "r", type: "bytes32" },
|
|
75
|
+
{ name: "s", type: "bytes32" }
|
|
76
|
+
],
|
|
77
|
+
name: "transferWithAuthorization",
|
|
78
|
+
outputs: [],
|
|
79
|
+
stateMutability: "nonpayable",
|
|
80
|
+
type: "function"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
inputs: [
|
|
84
|
+
{ name: "from", type: "address" },
|
|
85
|
+
{ name: "to", type: "address" },
|
|
86
|
+
{ name: "value", type: "uint256" },
|
|
87
|
+
{ name: "validAfter", type: "uint256" },
|
|
88
|
+
{ name: "validBefore", type: "uint256" },
|
|
89
|
+
{ name: "nonce", type: "bytes32" },
|
|
90
|
+
{ name: "signature", type: "bytes" }
|
|
91
|
+
],
|
|
92
|
+
name: "transferWithAuthorization",
|
|
93
|
+
outputs: [],
|
|
94
|
+
stateMutability: "nonpayable",
|
|
95
|
+
type: "function"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
inputs: [{ name: "account", type: "address" }],
|
|
99
|
+
name: "balanceOf",
|
|
100
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
101
|
+
stateMutability: "view",
|
|
102
|
+
type: "function"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
inputs: [],
|
|
106
|
+
name: "version",
|
|
107
|
+
outputs: [{ name: "", type: "string" }],
|
|
108
|
+
stateMutability: "view",
|
|
109
|
+
type: "function"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
inputs: [],
|
|
113
|
+
name: "name",
|
|
114
|
+
outputs: [{ name: "", type: "string" }],
|
|
115
|
+
stateMutability: "view",
|
|
116
|
+
type: "function"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
inputs: [
|
|
120
|
+
{ name: "authorizer", type: "address" },
|
|
121
|
+
{ name: "nonce", type: "bytes32" }
|
|
122
|
+
],
|
|
123
|
+
name: "authorizationState",
|
|
124
|
+
outputs: [{ name: "", type: "bool" }],
|
|
125
|
+
stateMutability: "view",
|
|
126
|
+
type: "function"
|
|
127
|
+
}
|
|
128
|
+
];
|
|
129
|
+
var erc20ApproveAbi = [
|
|
130
|
+
{
|
|
131
|
+
type: "function",
|
|
132
|
+
name: "approve",
|
|
133
|
+
inputs: [
|
|
134
|
+
{ name: "spender", type: "address" },
|
|
135
|
+
{ name: "amount", type: "uint256" }
|
|
136
|
+
],
|
|
137
|
+
outputs: [{ type: "bool" }],
|
|
138
|
+
stateMutability: "nonpayable"
|
|
139
|
+
}
|
|
140
|
+
];
|
|
141
|
+
var erc20AllowanceAbi = [
|
|
142
|
+
{
|
|
143
|
+
type: "function",
|
|
144
|
+
name: "allowance",
|
|
145
|
+
inputs: [
|
|
146
|
+
{ name: "owner", type: "address" },
|
|
147
|
+
{ name: "spender", type: "address" }
|
|
148
|
+
],
|
|
149
|
+
outputs: [{ type: "uint256" }],
|
|
150
|
+
stateMutability: "view"
|
|
151
|
+
}
|
|
152
|
+
];
|
|
153
|
+
var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
154
|
+
var x402ExactPermit2ProxyAddress = "0x402085c248EeA27D92E8b30b2C58ed07f9E20001";
|
|
155
|
+
var permit2WitnessABIComponents = [
|
|
156
|
+
{ name: "to", type: "address", internalType: "address" },
|
|
157
|
+
{ name: "validAfter", type: "uint256", internalType: "uint256" }
|
|
158
|
+
];
|
|
159
|
+
var x402ExactPermit2ProxyABI = [
|
|
160
|
+
{
|
|
161
|
+
type: "function",
|
|
162
|
+
name: "PERMIT2",
|
|
163
|
+
inputs: [],
|
|
164
|
+
outputs: [{ name: "", type: "address", internalType: "contract ISignatureTransfer" }],
|
|
165
|
+
stateMutability: "view"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
type: "function",
|
|
169
|
+
name: "WITNESS_TYPEHASH",
|
|
170
|
+
inputs: [],
|
|
171
|
+
outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
|
|
172
|
+
stateMutability: "view"
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
type: "function",
|
|
176
|
+
name: "WITNESS_TYPE_STRING",
|
|
177
|
+
inputs: [],
|
|
178
|
+
outputs: [{ name: "", type: "string", internalType: "string" }],
|
|
179
|
+
stateMutability: "view"
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
type: "function",
|
|
183
|
+
name: "settle",
|
|
184
|
+
inputs: [
|
|
185
|
+
{
|
|
186
|
+
name: "permit",
|
|
187
|
+
type: "tuple",
|
|
188
|
+
internalType: "struct ISignatureTransfer.PermitTransferFrom",
|
|
189
|
+
components: [
|
|
190
|
+
{
|
|
191
|
+
name: "permitted",
|
|
192
|
+
type: "tuple",
|
|
193
|
+
internalType: "struct ISignatureTransfer.TokenPermissions",
|
|
194
|
+
components: [
|
|
195
|
+
{ name: "token", type: "address", internalType: "address" },
|
|
196
|
+
{ name: "amount", type: "uint256", internalType: "uint256" }
|
|
197
|
+
]
|
|
198
|
+
},
|
|
199
|
+
{ name: "nonce", type: "uint256", internalType: "uint256" },
|
|
200
|
+
{ name: "deadline", type: "uint256", internalType: "uint256" }
|
|
201
|
+
]
|
|
202
|
+
},
|
|
203
|
+
{ name: "owner", type: "address", internalType: "address" },
|
|
204
|
+
{
|
|
205
|
+
name: "witness",
|
|
206
|
+
type: "tuple",
|
|
207
|
+
internalType: "struct x402ExactPermit2Proxy.Witness",
|
|
208
|
+
components: permit2WitnessABIComponents
|
|
209
|
+
},
|
|
210
|
+
{ name: "signature", type: "bytes", internalType: "bytes" }
|
|
211
|
+
],
|
|
212
|
+
outputs: [],
|
|
213
|
+
stateMutability: "nonpayable"
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
type: "function",
|
|
217
|
+
name: "settleWithPermit",
|
|
218
|
+
inputs: [
|
|
219
|
+
{
|
|
220
|
+
name: "permit2612",
|
|
221
|
+
type: "tuple",
|
|
222
|
+
internalType: "struct x402ExactPermit2Proxy.EIP2612Permit",
|
|
223
|
+
components: [
|
|
224
|
+
{ name: "value", type: "uint256", internalType: "uint256" },
|
|
225
|
+
{ name: "deadline", type: "uint256", internalType: "uint256" },
|
|
226
|
+
{ name: "r", type: "bytes32", internalType: "bytes32" },
|
|
227
|
+
{ name: "s", type: "bytes32", internalType: "bytes32" },
|
|
228
|
+
{ name: "v", type: "uint8", internalType: "uint8" }
|
|
229
|
+
]
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
name: "permit",
|
|
233
|
+
type: "tuple",
|
|
234
|
+
internalType: "struct ISignatureTransfer.PermitTransferFrom",
|
|
235
|
+
components: [
|
|
236
|
+
{
|
|
237
|
+
name: "permitted",
|
|
238
|
+
type: "tuple",
|
|
239
|
+
internalType: "struct ISignatureTransfer.TokenPermissions",
|
|
240
|
+
components: [
|
|
241
|
+
{ name: "token", type: "address", internalType: "address" },
|
|
242
|
+
{ name: "amount", type: "uint256", internalType: "uint256" }
|
|
243
|
+
]
|
|
244
|
+
},
|
|
245
|
+
{ name: "nonce", type: "uint256", internalType: "uint256" },
|
|
246
|
+
{ name: "deadline", type: "uint256", internalType: "uint256" }
|
|
247
|
+
]
|
|
248
|
+
},
|
|
249
|
+
{ name: "owner", type: "address", internalType: "address" },
|
|
250
|
+
{
|
|
251
|
+
name: "witness",
|
|
252
|
+
type: "tuple",
|
|
253
|
+
internalType: "struct x402ExactPermit2Proxy.Witness",
|
|
254
|
+
components: permit2WitnessABIComponents
|
|
255
|
+
},
|
|
256
|
+
{ name: "signature", type: "bytes", internalType: "bytes" }
|
|
257
|
+
],
|
|
258
|
+
outputs: [],
|
|
259
|
+
stateMutability: "nonpayable"
|
|
260
|
+
},
|
|
261
|
+
{ type: "event", name: "Settled", inputs: [], anonymous: false },
|
|
262
|
+
{ type: "event", name: "SettledWithPermit", inputs: [], anonymous: false },
|
|
263
|
+
{ type: "error", name: "InvalidAmount", inputs: [] },
|
|
264
|
+
{ type: "error", name: "InvalidDestination", inputs: [] },
|
|
265
|
+
{ type: "error", name: "InvalidOwner", inputs: [] },
|
|
266
|
+
{ type: "error", name: "InvalidPermit2Address", inputs: [] },
|
|
267
|
+
{ type: "error", name: "PaymentTooEarly", inputs: [] },
|
|
268
|
+
{ type: "error", name: "Permit2612AmountMismatch", inputs: [] },
|
|
269
|
+
{ type: "error", name: "ReentrancyGuardReentrantCall", inputs: [] }
|
|
270
|
+
];
|
|
271
|
+
|
|
272
|
+
// src/utils.ts
|
|
273
|
+
var import_viem = require("viem");
|
|
274
|
+
function getEvmChainId(network) {
|
|
275
|
+
if (network.startsWith("eip155:")) {
|
|
276
|
+
const idStr = network.split(":")[1];
|
|
277
|
+
const chainId = parseInt(idStr, 10);
|
|
278
|
+
if (isNaN(chainId)) {
|
|
279
|
+
throw new Error(`Invalid CAIP-2 chain ID: ${network}`);
|
|
280
|
+
}
|
|
281
|
+
return chainId;
|
|
282
|
+
}
|
|
283
|
+
throw new Error(`Unsupported network format: ${network} (expected eip155:CHAIN_ID)`);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// src/exact/facilitator/errors.ts
|
|
287
|
+
var ErrAssetNotDeployedContract = "asset_not_deployed_contract";
|
|
288
|
+
var ErrInvalidScheme = "invalid_exact_evm_scheme";
|
|
289
|
+
var ErrNetworkMismatch = "invalid_exact_evm_network_mismatch";
|
|
290
|
+
var ErrMissingEip712Domain = "invalid_exact_evm_missing_eip712_domain";
|
|
291
|
+
var ErrRecipientMismatch = "invalid_exact_evm_recipient_mismatch";
|
|
292
|
+
var ErrInvalidSignature = "invalid_exact_evm_signature";
|
|
293
|
+
var ErrValidBeforeExpired = "invalid_exact_evm_payload_authorization_valid_before";
|
|
294
|
+
var ErrValidAfterInFuture = "invalid_exact_evm_payload_authorization_valid_after";
|
|
295
|
+
var ErrInvalidAuthorizationValue = "invalid_exact_evm_authorization_value";
|
|
296
|
+
var ErrUndeployedSmartWallet = "invalid_exact_evm_payload_undeployed_smart_wallet";
|
|
297
|
+
var ErrTransactionFailed = "invalid_exact_evm_transaction_failed";
|
|
298
|
+
var ErrEip3009TokenNameMismatch = "invalid_exact_evm_token_name_mismatch";
|
|
299
|
+
var ErrEip3009TokenVersionMismatch = "invalid_exact_evm_token_version_mismatch";
|
|
300
|
+
var ErrEip3009NotSupported = "invalid_exact_evm_eip3009_not_supported";
|
|
301
|
+
var ErrEip3009NonceAlreadyUsed = "invalid_exact_evm_nonce_already_used";
|
|
302
|
+
var ErrEip3009InsufficientBalance = "invalid_exact_evm_insufficient_balance";
|
|
303
|
+
var ErrEip3009SimulationFailed = "invalid_exact_evm_transaction_simulation_failed";
|
|
304
|
+
var ErrPermit2InvalidSpender = "invalid_permit2_spender";
|
|
305
|
+
var ErrPermit2RecipientMismatch = "invalid_permit2_recipient_mismatch";
|
|
306
|
+
var ErrPermit2DeadlineExpired = "permit2_deadline_expired";
|
|
307
|
+
var ErrPermit2NotYetValid = "permit2_not_yet_valid";
|
|
308
|
+
var ErrPermit2AmountMismatch = "permit2_amount_mismatch";
|
|
309
|
+
var ErrPermit2TokenMismatch = "permit2_token_mismatch";
|
|
310
|
+
var ErrPermit2InvalidSignature = "invalid_permit2_signature";
|
|
311
|
+
var ErrPermit2AllowanceRequired = "permit2_allowance_required";
|
|
312
|
+
var ErrPermit2SimulationFailed = "permit2_simulation_failed";
|
|
313
|
+
var ErrPermit2InsufficientBalance = "permit2_insufficient_balance";
|
|
314
|
+
var ErrPermit2ProxyNotDeployed = "permit2_proxy_not_deployed";
|
|
315
|
+
var ErrPermit2InvalidAmount = "permit2_invalid_amount";
|
|
316
|
+
var ErrPermit2InvalidDestination = "permit2_invalid_destination";
|
|
317
|
+
var ErrPermit2InvalidOwner = "permit2_invalid_owner";
|
|
318
|
+
var ErrPermit2PaymentTooEarly = "permit2_payment_too_early";
|
|
319
|
+
var ErrPermit2InvalidNonce = "permit2_invalid_nonce";
|
|
320
|
+
var ErrPermit2612AmountMismatch = "permit2_2612_amount_mismatch";
|
|
321
|
+
var ErrErc20ApprovalInvalidFormat = "invalid_erc20_approval_extension_format";
|
|
322
|
+
var ErrErc20ApprovalFromMismatch = "erc20_approval_from_mismatch";
|
|
323
|
+
var ErrErc20ApprovalAssetMismatch = "erc20_approval_asset_mismatch";
|
|
324
|
+
var ErrErc20ApprovalSpenderNotPermit2 = "erc20_approval_spender_not_permit2";
|
|
325
|
+
var ErrErc20ApprovalTxWrongTarget = "erc20_approval_tx_wrong_target";
|
|
326
|
+
var ErrErc20ApprovalTxWrongSelector = "erc20_approval_tx_wrong_selector";
|
|
327
|
+
var ErrErc20ApprovalTxWrongSpender = "erc20_approval_tx_wrong_spender";
|
|
328
|
+
var ErrErc20ApprovalTxInvalidCalldata = "erc20_approval_tx_invalid_calldata";
|
|
329
|
+
var ErrErc20ApprovalTxSignerMismatch = "erc20_approval_tx_signer_mismatch";
|
|
330
|
+
var ErrErc20ApprovalTxInvalidSignature = "erc20_approval_tx_invalid_signature";
|
|
331
|
+
var ErrErc20ApprovalTxParseFailed = "erc20_approval_tx_parse_failed";
|
|
332
|
+
var ErrErc20ApprovalTxFailed = "erc20_approval_tx_failed";
|
|
333
|
+
var ErrInvalidEip2612ExtensionFormat = "invalid_eip2612_extension_format";
|
|
334
|
+
var ErrEip2612FromMismatch = "eip2612_from_mismatch";
|
|
335
|
+
var ErrEip2612AssetMismatch = "eip2612_asset_mismatch";
|
|
336
|
+
var ErrEip2612SpenderNotPermit2 = "eip2612_spender_not_permit2";
|
|
337
|
+
var ErrEip2612DeadlineExpired = "eip2612_deadline_expired";
|
|
338
|
+
var ErrUnsupportedPayloadType = "unsupported_payload_type";
|
|
339
|
+
var ErrInvalidTransactionState = "invalid_transaction_state";
|
|
340
|
+
var ErrFactoryNotAllowed = "eip6492_factory_not_allowed";
|
|
341
|
+
|
|
342
|
+
// src/exact/extensions.ts
|
|
343
|
+
var EIP2612_GAS_SPONSORING_KEY = "eip2612GasSponsoring";
|
|
344
|
+
var ERC20_APPROVAL_GAS_SPONSORING_KEY = "erc20ApprovalGasSponsoring";
|
|
345
|
+
function _extractInfo(payload, extensionKey) {
|
|
346
|
+
const extensions = payload.extensions;
|
|
347
|
+
if (!extensions) return null;
|
|
348
|
+
const extension = extensions[extensionKey];
|
|
349
|
+
if (!extension?.info) return null;
|
|
350
|
+
return extension.info;
|
|
351
|
+
}
|
|
352
|
+
function extractEip2612GasSponsoringInfo(payload) {
|
|
353
|
+
const info = _extractInfo(payload, EIP2612_GAS_SPONSORING_KEY);
|
|
354
|
+
if (!info) return null;
|
|
355
|
+
if (!info.from || !info.asset || !info.spender || !info.amount || !info.nonce || !info.deadline || !info.signature || !info.version) {
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
return info;
|
|
359
|
+
}
|
|
360
|
+
function validateEip2612GasSponsoringInfo(info) {
|
|
361
|
+
const addressPattern = /^0x[a-fA-F0-9]{40}$/;
|
|
362
|
+
const numericPattern = /^[0-9]+$/;
|
|
363
|
+
const hexPattern = /^0x[a-fA-F0-9]+$/;
|
|
364
|
+
const versionPattern = /^[0-9]+(\.[0-9]+)*$/;
|
|
365
|
+
return addressPattern.test(info.from) && addressPattern.test(info.asset) && addressPattern.test(info.spender) && numericPattern.test(info.amount) && numericPattern.test(info.nonce) && numericPattern.test(info.deadline) && hexPattern.test(info.signature) && versionPattern.test(info.version);
|
|
366
|
+
}
|
|
367
|
+
function extractErc20ApprovalGasSponsoringInfo(payload) {
|
|
368
|
+
const info = _extractInfo(payload, ERC20_APPROVAL_GAS_SPONSORING_KEY);
|
|
369
|
+
if (!info) return null;
|
|
370
|
+
if (!info.from || !info.asset || !info.spender || !info.amount || !info.signedTransaction || !info.version) {
|
|
371
|
+
return null;
|
|
372
|
+
}
|
|
373
|
+
return info;
|
|
374
|
+
}
|
|
375
|
+
function validateErc20ApprovalGasSponsoringInfo(info) {
|
|
376
|
+
const addressPattern = /^0x[a-fA-F0-9]{40}$/;
|
|
377
|
+
const numericPattern = /^[0-9]+$/;
|
|
378
|
+
const hexPattern = /^0x[a-fA-F0-9]+$/;
|
|
379
|
+
const versionPattern = /^[0-9]+(\.[0-9]+)*$/;
|
|
380
|
+
return addressPattern.test(info.from) && addressPattern.test(info.asset) && addressPattern.test(info.spender) && numericPattern.test(info.amount) && hexPattern.test(info.signedTransaction) && versionPattern.test(info.version);
|
|
381
|
+
}
|
|
382
|
+
function resolveErc20ApprovalExtensionSigner(extension, network) {
|
|
383
|
+
if (!extension) return void 0;
|
|
384
|
+
return extension.signerForNetwork?.(network) ?? extension.signer;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// src/shared/extensions/gasSponsoring.ts
|
|
388
|
+
var import_viem5 = require("viem");
|
|
389
|
+
|
|
390
|
+
// src/exact/client/eip2612.ts
|
|
391
|
+
var import_viem2 = require("viem");
|
|
392
|
+
|
|
393
|
+
// src/exact/client/erc20approval.ts
|
|
394
|
+
var import_viem3 = require("viem");
|
|
395
|
+
|
|
396
|
+
// src/shared/rpc.ts
|
|
397
|
+
var import_viem4 = require("viem");
|
|
398
|
+
|
|
399
|
+
// src/shared/extensions/builderCode.ts
|
|
400
|
+
var BUILDER_CODE_KEY = "builder-code";
|
|
401
|
+
var BUILDER_CODE_RESOLVER = async (context, ctx) => {
|
|
402
|
+
const ext = context.getExtension(BUILDER_CODE_KEY);
|
|
403
|
+
if (!ext?.buildDataSuffix) {
|
|
404
|
+
return void 0;
|
|
405
|
+
}
|
|
406
|
+
return ext.buildDataSuffix(ctx);
|
|
407
|
+
};
|
|
408
|
+
var DATA_SUFFIX_RESOLVERS = [BUILDER_CODE_RESOLVER];
|
|
409
|
+
async function resolveDataSuffix(context, ctx) {
|
|
410
|
+
if (!context) {
|
|
411
|
+
return void 0;
|
|
412
|
+
}
|
|
413
|
+
const parts = [];
|
|
414
|
+
for (const resolver of DATA_SUFFIX_RESOLVERS) {
|
|
415
|
+
const suffix = await resolver(context, ctx);
|
|
416
|
+
if (suffix && suffix !== "0x" && suffix.length > 2) {
|
|
417
|
+
parts.push(suffix);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
if (parts.length === 0) {
|
|
421
|
+
return void 0;
|
|
422
|
+
}
|
|
423
|
+
if (parts.length === 1) {
|
|
424
|
+
return parts[0];
|
|
425
|
+
}
|
|
426
|
+
return parts.reduce((acc, part, index) => {
|
|
427
|
+
if (index === 0) {
|
|
428
|
+
return part;
|
|
429
|
+
}
|
|
430
|
+
const stripped = part.startsWith("0x") ? part.slice(2) : part;
|
|
431
|
+
return `${acc}${stripped}`;
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
function appendDataSuffix(calldata, suffix) {
|
|
435
|
+
if (!suffix || suffix === "0x" || suffix.length <= 2) {
|
|
436
|
+
return calldata;
|
|
437
|
+
}
|
|
438
|
+
const suffixHex = suffix.startsWith("0x") ? suffix.slice(2) : suffix;
|
|
439
|
+
return `${calldata}${suffixHex}`;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// src/exact/facilitator/eip3009-utils.ts
|
|
443
|
+
var import_viem7 = require("viem");
|
|
444
|
+
|
|
445
|
+
// src/multicall.ts
|
|
446
|
+
var import_viem6 = require("viem");
|
|
447
|
+
var MULTICALL3_ADDRESS = "0xcA11bde05977b3631167028862bE2a173976CA11";
|
|
448
|
+
var multicall3ABI = [
|
|
449
|
+
{
|
|
450
|
+
inputs: [
|
|
451
|
+
{ name: "requireSuccess", type: "bool" },
|
|
452
|
+
{
|
|
453
|
+
name: "calls",
|
|
454
|
+
type: "tuple[]",
|
|
455
|
+
components: [
|
|
456
|
+
{ name: "target", type: "address" },
|
|
457
|
+
{ name: "callData", type: "bytes" }
|
|
458
|
+
]
|
|
459
|
+
}
|
|
460
|
+
],
|
|
461
|
+
name: "tryAggregate",
|
|
462
|
+
outputs: [
|
|
463
|
+
{
|
|
464
|
+
name: "returnData",
|
|
465
|
+
type: "tuple[]",
|
|
466
|
+
components: [
|
|
467
|
+
{ name: "success", type: "bool" },
|
|
468
|
+
{ name: "returnData", type: "bytes" }
|
|
469
|
+
]
|
|
470
|
+
}
|
|
471
|
+
],
|
|
472
|
+
stateMutability: "payable",
|
|
473
|
+
type: "function"
|
|
474
|
+
}
|
|
475
|
+
];
|
|
476
|
+
async function multicall(readContract, calls) {
|
|
477
|
+
const aggregateCalls = calls.map((call) => {
|
|
478
|
+
if ("callData" in call) {
|
|
479
|
+
return { target: call.address, callData: call.callData };
|
|
480
|
+
}
|
|
481
|
+
const callData = (0, import_viem6.encodeFunctionData)({
|
|
482
|
+
abi: call.abi,
|
|
483
|
+
functionName: call.functionName,
|
|
484
|
+
args: call.args
|
|
485
|
+
});
|
|
486
|
+
return { target: call.address, callData };
|
|
487
|
+
});
|
|
488
|
+
const rawResults = await readContract({
|
|
489
|
+
address: MULTICALL3_ADDRESS,
|
|
490
|
+
abi: multicall3ABI,
|
|
491
|
+
functionName: "tryAggregate",
|
|
492
|
+
args: [false, aggregateCalls]
|
|
493
|
+
});
|
|
494
|
+
return rawResults.map((raw, i) => {
|
|
495
|
+
if (!raw.success) {
|
|
496
|
+
return {
|
|
497
|
+
status: "failure",
|
|
498
|
+
error: new Error(`multicall: call reverted (returnData: ${raw.returnData})`)
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
const call = calls[i];
|
|
502
|
+
if ("callData" in call) {
|
|
503
|
+
return { status: "success", result: void 0 };
|
|
504
|
+
}
|
|
505
|
+
try {
|
|
506
|
+
const decoded = (0, import_viem6.decodeFunctionResult)({
|
|
507
|
+
abi: call.abi,
|
|
508
|
+
functionName: call.functionName,
|
|
509
|
+
data: raw.returnData
|
|
510
|
+
});
|
|
511
|
+
return { status: "success", result: decoded };
|
|
512
|
+
} catch (err) {
|
|
513
|
+
return {
|
|
514
|
+
status: "failure",
|
|
515
|
+
error: err instanceof Error ? err : new Error(String(err))
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// src/exact/facilitator/eip3009-utils.ts
|
|
522
|
+
async function simulateEip3009Transfer(signer, erc20Address, payload, eip6492Deployment) {
|
|
523
|
+
const auth = payload.authorization;
|
|
524
|
+
const transferArgs = [
|
|
525
|
+
(0, import_viem7.getAddress)(auth.from),
|
|
526
|
+
(0, import_viem7.getAddress)(auth.to),
|
|
527
|
+
BigInt(auth.value),
|
|
528
|
+
BigInt(auth.validAfter),
|
|
529
|
+
BigInt(auth.validBefore),
|
|
530
|
+
auth.nonce
|
|
531
|
+
];
|
|
532
|
+
if (eip6492Deployment) {
|
|
533
|
+
const { signature: innerSignature } = (0, import_viem7.parseErc6492Signature)(payload.signature);
|
|
534
|
+
const transferCalldata = (0, import_viem7.encodeFunctionData)({
|
|
535
|
+
abi: eip3009ABI,
|
|
536
|
+
functionName: "transferWithAuthorization",
|
|
537
|
+
args: [...transferArgs, innerSignature]
|
|
538
|
+
});
|
|
539
|
+
try {
|
|
540
|
+
const results = await multicall(signer.readContract.bind(signer), [
|
|
541
|
+
{
|
|
542
|
+
address: (0, import_viem7.getAddress)(eip6492Deployment.factoryAddress),
|
|
543
|
+
callData: eip6492Deployment.factoryCalldata
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
address: erc20Address,
|
|
547
|
+
callData: transferCalldata
|
|
548
|
+
}
|
|
549
|
+
]);
|
|
550
|
+
return results[1]?.status === "success";
|
|
551
|
+
} catch {
|
|
552
|
+
return false;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
const sig = payload.signature;
|
|
556
|
+
const sigLength = sig.startsWith("0x") ? sig.length - 2 : sig.length;
|
|
557
|
+
const isECDSA = sigLength === 130;
|
|
558
|
+
try {
|
|
559
|
+
if (isECDSA) {
|
|
560
|
+
const parsedSig = (0, import_viem7.parseSignature)(sig);
|
|
561
|
+
await signer.readContract({
|
|
562
|
+
address: erc20Address,
|
|
563
|
+
abi: eip3009ABI,
|
|
564
|
+
functionName: "transferWithAuthorization",
|
|
565
|
+
args: [
|
|
566
|
+
...transferArgs,
|
|
567
|
+
parsedSig.v ?? parsedSig.yParity,
|
|
568
|
+
parsedSig.r,
|
|
569
|
+
parsedSig.s
|
|
570
|
+
]
|
|
571
|
+
});
|
|
572
|
+
} else {
|
|
573
|
+
await signer.readContract({
|
|
574
|
+
address: erc20Address,
|
|
575
|
+
abi: eip3009ABI,
|
|
576
|
+
functionName: "transferWithAuthorization",
|
|
577
|
+
args: [...transferArgs, sig]
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
return true;
|
|
581
|
+
} catch {
|
|
582
|
+
return false;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
async function diagnoseEip3009SimulationFailure(signer, erc20Address, payload, requirements, amountRequired) {
|
|
586
|
+
const payer = payload.authorization.from;
|
|
587
|
+
const diagnosticCalls = [
|
|
588
|
+
{
|
|
589
|
+
address: erc20Address,
|
|
590
|
+
abi: eip3009ABI,
|
|
591
|
+
functionName: "balanceOf",
|
|
592
|
+
args: [payload.authorization.from]
|
|
593
|
+
},
|
|
594
|
+
{
|
|
595
|
+
address: erc20Address,
|
|
596
|
+
abi: eip3009ABI,
|
|
597
|
+
functionName: "name"
|
|
598
|
+
},
|
|
599
|
+
{
|
|
600
|
+
address: erc20Address,
|
|
601
|
+
abi: eip3009ABI,
|
|
602
|
+
functionName: "version"
|
|
603
|
+
},
|
|
604
|
+
{
|
|
605
|
+
address: erc20Address,
|
|
606
|
+
abi: eip3009ABI,
|
|
607
|
+
functionName: "authorizationState",
|
|
608
|
+
args: [payload.authorization.from, payload.authorization.nonce]
|
|
609
|
+
}
|
|
610
|
+
];
|
|
611
|
+
try {
|
|
612
|
+
const results = await multicall(signer.readContract.bind(signer), diagnosticCalls);
|
|
613
|
+
const [balanceResult, nameResult, versionResult, authStateResult] = results;
|
|
614
|
+
if (authStateResult.status === "failure") {
|
|
615
|
+
return { isValid: false, invalidReason: ErrEip3009NotSupported, payer };
|
|
616
|
+
}
|
|
617
|
+
if (authStateResult.status === "success" && authStateResult.result === true) {
|
|
618
|
+
return { isValid: false, invalidReason: ErrEip3009NonceAlreadyUsed, payer };
|
|
619
|
+
}
|
|
620
|
+
if (nameResult.status === "success" && requirements.extra?.name && nameResult.result !== requirements.extra.name) {
|
|
621
|
+
return { isValid: false, invalidReason: ErrEip3009TokenNameMismatch, payer };
|
|
622
|
+
}
|
|
623
|
+
if (versionResult.status === "success" && requirements.extra?.version && versionResult.result !== requirements.extra.version) {
|
|
624
|
+
return { isValid: false, invalidReason: ErrEip3009TokenVersionMismatch, payer };
|
|
625
|
+
}
|
|
626
|
+
if (balanceResult.status === "success") {
|
|
627
|
+
const balance = balanceResult.result;
|
|
628
|
+
if (balance < BigInt(amountRequired)) {
|
|
629
|
+
return {
|
|
630
|
+
isValid: false,
|
|
631
|
+
invalidReason: ErrEip3009InsufficientBalance,
|
|
632
|
+
payer
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
} catch {
|
|
637
|
+
}
|
|
638
|
+
return { isValid: false, invalidReason: ErrEip3009SimulationFailed, payer };
|
|
639
|
+
}
|
|
640
|
+
function parseEip3009TransferError(error) {
|
|
641
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
642
|
+
if (/authorization.*(expired|valid before)/i.test(msg) || /AuthorizationExpired/i.test(msg)) {
|
|
643
|
+
return ErrValidBeforeExpired;
|
|
644
|
+
}
|
|
645
|
+
if (/authorization.*not.*valid|AuthorizationNotYetValid/i.test(msg)) {
|
|
646
|
+
return ErrValidAfterInFuture;
|
|
647
|
+
}
|
|
648
|
+
if (/authorization.*used|AuthorizationAlreadyUsed|AuthorizationUsedOrCanceled/i.test(msg)) {
|
|
649
|
+
return ErrEip3009NonceAlreadyUsed;
|
|
650
|
+
}
|
|
651
|
+
if (/transfer.*exceeds.*balance|insufficient.*balance|ERC20InsufficientBalance/i.test(msg)) {
|
|
652
|
+
return ErrEip3009InsufficientBalance;
|
|
653
|
+
}
|
|
654
|
+
if (/invalid.*signature|SignerMismatch|InvalidSignatureV|InvalidSignatureS/i.test(msg)) {
|
|
655
|
+
return ErrInvalidSignature;
|
|
656
|
+
}
|
|
657
|
+
return ErrTransactionFailed;
|
|
658
|
+
}
|
|
659
|
+
async function executeTransferWithAuthorization(signer, erc20Address, payload, dataSuffix) {
|
|
660
|
+
const { signature } = (0, import_viem7.parseErc6492Signature)(payload.signature);
|
|
661
|
+
const signatureLength = signature.startsWith("0x") ? signature.length - 2 : signature.length;
|
|
662
|
+
const isECDSA = signatureLength === 130;
|
|
663
|
+
const auth = payload.authorization;
|
|
664
|
+
const baseArgs = [
|
|
665
|
+
(0, import_viem7.getAddress)(auth.from),
|
|
666
|
+
(0, import_viem7.getAddress)(auth.to),
|
|
667
|
+
BigInt(auth.value),
|
|
668
|
+
BigInt(auth.validAfter),
|
|
669
|
+
BigInt(auth.validBefore),
|
|
670
|
+
auth.nonce
|
|
671
|
+
];
|
|
672
|
+
let signatureArgs;
|
|
673
|
+
if (isECDSA) {
|
|
674
|
+
const parsedSig = (0, import_viem7.parseSignature)(signature);
|
|
675
|
+
signatureArgs = [
|
|
676
|
+
parsedSig.v || parsedSig.yParity,
|
|
677
|
+
parsedSig.r,
|
|
678
|
+
parsedSig.s
|
|
679
|
+
];
|
|
680
|
+
} else {
|
|
681
|
+
signatureArgs = [signature];
|
|
682
|
+
}
|
|
683
|
+
return signer.writeContract({
|
|
684
|
+
address: erc20Address,
|
|
685
|
+
abi: eip3009ABI,
|
|
686
|
+
functionName: "transferWithAuthorization",
|
|
687
|
+
args: [...baseArgs, ...signatureArgs],
|
|
688
|
+
dataSuffix
|
|
689
|
+
});
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
// src/exact/facilitator/eip3009.ts
|
|
693
|
+
async function verifyEIP3009(signer, payload, requirements, eip3009Payload, options) {
|
|
694
|
+
const payer = eip3009Payload.authorization.from;
|
|
695
|
+
let eip6492Deployment;
|
|
696
|
+
if (payload.accepted.scheme !== "exact" || requirements.scheme !== "exact") {
|
|
697
|
+
return {
|
|
698
|
+
isValid: false,
|
|
699
|
+
invalidReason: ErrInvalidScheme,
|
|
700
|
+
payer
|
|
701
|
+
};
|
|
702
|
+
}
|
|
703
|
+
if (!requirements.extra?.name || !requirements.extra?.version) {
|
|
704
|
+
return {
|
|
705
|
+
isValid: false,
|
|
706
|
+
invalidReason: ErrMissingEip712Domain,
|
|
707
|
+
payer
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
const { name, version } = requirements.extra;
|
|
711
|
+
const erc20Address = (0, import_viem8.getAddress)(requirements.asset);
|
|
712
|
+
if (payload.accepted.network !== requirements.network) {
|
|
713
|
+
return {
|
|
714
|
+
isValid: false,
|
|
715
|
+
invalidReason: ErrNetworkMismatch,
|
|
716
|
+
payer
|
|
717
|
+
};
|
|
718
|
+
}
|
|
719
|
+
const permitTypedData = {
|
|
720
|
+
types: authorizationTypes,
|
|
721
|
+
primaryType: "TransferWithAuthorization",
|
|
722
|
+
domain: {
|
|
723
|
+
name,
|
|
724
|
+
version,
|
|
725
|
+
chainId: getEvmChainId(requirements.network),
|
|
726
|
+
verifyingContract: erc20Address
|
|
727
|
+
},
|
|
728
|
+
message: {
|
|
729
|
+
from: eip3009Payload.authorization.from,
|
|
730
|
+
to: eip3009Payload.authorization.to,
|
|
731
|
+
value: BigInt(eip3009Payload.authorization.value),
|
|
732
|
+
validAfter: BigInt(eip3009Payload.authorization.validAfter),
|
|
733
|
+
validBefore: BigInt(eip3009Payload.authorization.validBefore),
|
|
734
|
+
nonce: eip3009Payload.authorization.nonce
|
|
735
|
+
}
|
|
736
|
+
};
|
|
737
|
+
let isValid = false;
|
|
738
|
+
try {
|
|
739
|
+
isValid = await signer.verifyTypedData({
|
|
740
|
+
address: eip3009Payload.authorization.from,
|
|
741
|
+
...permitTypedData,
|
|
742
|
+
signature: eip3009Payload.signature
|
|
743
|
+
});
|
|
744
|
+
} catch {
|
|
745
|
+
isValid = false;
|
|
746
|
+
}
|
|
747
|
+
const signature = eip3009Payload.signature;
|
|
748
|
+
const sigLen = signature.startsWith("0x") ? signature.length - 2 : signature.length;
|
|
749
|
+
const erc6492Data = (0, import_viem8.parseErc6492Signature)(signature);
|
|
750
|
+
const hasDeploymentInfo = erc6492Data.address && erc6492Data.data && !(0, import_viem8.isAddressEqual)(erc6492Data.address, "0x0000000000000000000000000000000000000000");
|
|
751
|
+
if (hasDeploymentInfo) {
|
|
752
|
+
eip6492Deployment = {
|
|
753
|
+
factoryAddress: erc6492Data.address,
|
|
754
|
+
factoryCalldata: erc6492Data.data
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
if (!isValid) {
|
|
758
|
+
const isSmartWallet = sigLen > 130;
|
|
759
|
+
if (!isSmartWallet) {
|
|
760
|
+
return {
|
|
761
|
+
isValid: false,
|
|
762
|
+
invalidReason: ErrInvalidSignature,
|
|
763
|
+
payer
|
|
764
|
+
};
|
|
765
|
+
}
|
|
766
|
+
const bytecode = await signer.getCode({ address: payer });
|
|
767
|
+
const isDeployed = bytecode && bytecode !== "0x";
|
|
768
|
+
if (!isDeployed && !hasDeploymentInfo) {
|
|
769
|
+
return {
|
|
770
|
+
isValid: false,
|
|
771
|
+
invalidReason: ErrUndeployedSmartWallet,
|
|
772
|
+
payer
|
|
773
|
+
};
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
if ((0, import_viem8.getAddress)(eip3009Payload.authorization.to) !== (0, import_viem8.getAddress)(requirements.payTo)) {
|
|
777
|
+
return {
|
|
778
|
+
isValid: false,
|
|
779
|
+
invalidReason: ErrRecipientMismatch,
|
|
780
|
+
payer
|
|
781
|
+
};
|
|
782
|
+
}
|
|
783
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
784
|
+
if (BigInt(eip3009Payload.authorization.validBefore) < BigInt(now + 6)) {
|
|
785
|
+
return {
|
|
786
|
+
isValid: false,
|
|
787
|
+
invalidReason: ErrValidBeforeExpired,
|
|
788
|
+
payer
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
if (BigInt(eip3009Payload.authorization.validAfter) > BigInt(now)) {
|
|
792
|
+
return {
|
|
793
|
+
isValid: false,
|
|
794
|
+
invalidReason: ErrValidAfterInFuture,
|
|
795
|
+
payer
|
|
796
|
+
};
|
|
797
|
+
}
|
|
798
|
+
if (BigInt(eip3009Payload.authorization.value) !== BigInt(requirements.amount)) {
|
|
799
|
+
return {
|
|
800
|
+
isValid: false,
|
|
801
|
+
invalidReason: ErrInvalidAuthorizationValue,
|
|
802
|
+
payer
|
|
803
|
+
};
|
|
804
|
+
}
|
|
805
|
+
const assetBytecode = await signer.getCode({ address: erc20Address });
|
|
806
|
+
if (!assetBytecode || assetBytecode === "0x") {
|
|
807
|
+
return { isValid: false, invalidReason: ErrAssetNotDeployedContract, payer };
|
|
808
|
+
}
|
|
809
|
+
if (options?.simulate !== false) {
|
|
810
|
+
const simulationSucceeded = await simulateEip3009Transfer(
|
|
811
|
+
signer,
|
|
812
|
+
erc20Address,
|
|
813
|
+
eip3009Payload,
|
|
814
|
+
eip6492Deployment
|
|
815
|
+
);
|
|
816
|
+
if (!simulationSucceeded) {
|
|
817
|
+
return diagnoseEip3009SimulationFailure(
|
|
818
|
+
signer,
|
|
819
|
+
erc20Address,
|
|
820
|
+
eip3009Payload,
|
|
821
|
+
requirements,
|
|
822
|
+
requirements.amount
|
|
823
|
+
);
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
return {
|
|
827
|
+
isValid: true,
|
|
828
|
+
invalidReason: void 0,
|
|
829
|
+
payer
|
|
830
|
+
};
|
|
831
|
+
}
|
|
832
|
+
async function settleEIP3009(signer, payload, requirements, eip3009Payload, config, context) {
|
|
833
|
+
const payer = eip3009Payload.authorization.from;
|
|
834
|
+
const valid = await verifyEIP3009(signer, payload, requirements, eip3009Payload, {
|
|
835
|
+
simulate: config.simulateInSettle ?? false
|
|
836
|
+
});
|
|
837
|
+
if (!valid.isValid) {
|
|
838
|
+
return {
|
|
839
|
+
success: false,
|
|
840
|
+
network: payload.accepted.network,
|
|
841
|
+
transaction: "",
|
|
842
|
+
errorReason: valid.invalidReason ?? ErrInvalidScheme,
|
|
843
|
+
payer
|
|
844
|
+
};
|
|
845
|
+
}
|
|
846
|
+
try {
|
|
847
|
+
const { address: factoryAddress, data: factoryCalldata } = (0, import_viem8.parseErc6492Signature)(
|
|
848
|
+
eip3009Payload.signature
|
|
849
|
+
);
|
|
850
|
+
if (factoryAddress && factoryCalldata && !(0, import_viem8.isAddressEqual)(factoryAddress, "0x0000000000000000000000000000000000000000")) {
|
|
851
|
+
const bytecode = await signer.getCode({ address: payer });
|
|
852
|
+
if (!bytecode || bytecode === "0x") {
|
|
853
|
+
const normalizedFactory = factoryAddress.toLowerCase();
|
|
854
|
+
const isAllowed = (config.eip6492AllowedFactories ?? []).some(
|
|
855
|
+
(allowed) => allowed.toLowerCase() === normalizedFactory
|
|
856
|
+
);
|
|
857
|
+
if (!isAllowed) {
|
|
858
|
+
return {
|
|
859
|
+
success: false,
|
|
860
|
+
errorReason: ErrFactoryNotAllowed,
|
|
861
|
+
transaction: "",
|
|
862
|
+
network: payload.accepted.network,
|
|
863
|
+
payer
|
|
864
|
+
};
|
|
865
|
+
}
|
|
866
|
+
const deployTx = await signer.sendTransaction({
|
|
867
|
+
to: factoryAddress,
|
|
868
|
+
data: factoryCalldata
|
|
869
|
+
});
|
|
870
|
+
await signer.waitForTransactionReceipt({ hash: deployTx });
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
const dataSuffix = await resolveDataSuffix(context, {
|
|
874
|
+
paymentPayload: payload,
|
|
875
|
+
paymentRequirements: requirements
|
|
876
|
+
});
|
|
877
|
+
const tx = await executeTransferWithAuthorization(
|
|
878
|
+
signer,
|
|
879
|
+
(0, import_viem8.getAddress)(requirements.asset),
|
|
880
|
+
eip3009Payload,
|
|
881
|
+
dataSuffix
|
|
882
|
+
);
|
|
883
|
+
const receipt = await signer.waitForTransactionReceipt({ hash: tx });
|
|
884
|
+
if (receipt.status !== "success") {
|
|
885
|
+
return {
|
|
886
|
+
success: false,
|
|
887
|
+
errorReason: ErrTransactionFailed,
|
|
888
|
+
transaction: tx,
|
|
889
|
+
network: payload.accepted.network,
|
|
890
|
+
payer
|
|
891
|
+
};
|
|
892
|
+
}
|
|
893
|
+
return {
|
|
894
|
+
success: true,
|
|
895
|
+
transaction: tx,
|
|
896
|
+
network: payload.accepted.network,
|
|
897
|
+
payer
|
|
898
|
+
};
|
|
899
|
+
} catch (error) {
|
|
900
|
+
return {
|
|
901
|
+
success: false,
|
|
902
|
+
errorReason: parseEip3009TransferError(error),
|
|
903
|
+
transaction: "",
|
|
904
|
+
network: payload.accepted.network,
|
|
905
|
+
payer
|
|
906
|
+
};
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
// src/exact/facilitator/permit2.ts
|
|
911
|
+
var import_viem11 = require("viem");
|
|
912
|
+
|
|
913
|
+
// src/shared/erc20approval.ts
|
|
914
|
+
var import_viem9 = require("viem");
|
|
915
|
+
var APPROVE_SELECTOR = "0x095ea7b3";
|
|
916
|
+
async function validateErc20ApprovalForPayment(info, payer, tokenAddress) {
|
|
917
|
+
if (!validateErc20ApprovalGasSponsoringInfo(info)) {
|
|
918
|
+
return {
|
|
919
|
+
isValid: false,
|
|
920
|
+
invalidReason: ErrErc20ApprovalInvalidFormat,
|
|
921
|
+
invalidMessage: "ERC-20 approval extension info failed schema validation"
|
|
922
|
+
};
|
|
923
|
+
}
|
|
924
|
+
if ((0, import_viem9.getAddress)(info.from) !== (0, import_viem9.getAddress)(payer)) {
|
|
925
|
+
return {
|
|
926
|
+
isValid: false,
|
|
927
|
+
invalidReason: ErrErc20ApprovalFromMismatch,
|
|
928
|
+
invalidMessage: `Expected from=${payer}, got ${info.from}`
|
|
929
|
+
};
|
|
930
|
+
}
|
|
931
|
+
if ((0, import_viem9.getAddress)(info.asset) !== tokenAddress) {
|
|
932
|
+
return {
|
|
933
|
+
isValid: false,
|
|
934
|
+
invalidReason: ErrErc20ApprovalAssetMismatch,
|
|
935
|
+
invalidMessage: `Expected asset=${tokenAddress}, got ${info.asset}`
|
|
936
|
+
};
|
|
937
|
+
}
|
|
938
|
+
if ((0, import_viem9.getAddress)(info.spender) !== (0, import_viem9.getAddress)(PERMIT2_ADDRESS)) {
|
|
939
|
+
return {
|
|
940
|
+
isValid: false,
|
|
941
|
+
invalidReason: ErrErc20ApprovalSpenderNotPermit2,
|
|
942
|
+
invalidMessage: `Expected spender=${PERMIT2_ADDRESS}, got ${info.spender}`
|
|
943
|
+
};
|
|
944
|
+
}
|
|
945
|
+
try {
|
|
946
|
+
const serializedTx = info.signedTransaction;
|
|
947
|
+
const tx = (0, import_viem9.parseTransaction)(serializedTx);
|
|
948
|
+
if (!tx.to || (0, import_viem9.getAddress)(tx.to) !== tokenAddress) {
|
|
949
|
+
return {
|
|
950
|
+
isValid: false,
|
|
951
|
+
invalidReason: ErrErc20ApprovalTxWrongTarget,
|
|
952
|
+
invalidMessage: `Transaction targets ${tx.to ?? "null"}, expected ${tokenAddress}`
|
|
953
|
+
};
|
|
954
|
+
}
|
|
955
|
+
const data = tx.data ?? "0x";
|
|
956
|
+
if (!data.startsWith(APPROVE_SELECTOR)) {
|
|
957
|
+
return {
|
|
958
|
+
isValid: false,
|
|
959
|
+
invalidReason: ErrErc20ApprovalTxWrongSelector,
|
|
960
|
+
invalidMessage: `Transaction calldata does not start with approve() selector ${APPROVE_SELECTOR}`
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
try {
|
|
964
|
+
const decoded = (0, import_viem9.decodeFunctionData)({
|
|
965
|
+
abi: erc20ApproveAbi,
|
|
966
|
+
data
|
|
967
|
+
});
|
|
968
|
+
const calldataSpender = (0, import_viem9.getAddress)(decoded.args[0]);
|
|
969
|
+
if (calldataSpender !== (0, import_viem9.getAddress)(PERMIT2_ADDRESS)) {
|
|
970
|
+
return {
|
|
971
|
+
isValid: false,
|
|
972
|
+
invalidReason: ErrErc20ApprovalTxWrongSpender,
|
|
973
|
+
invalidMessage: `approve() spender is ${calldataSpender}, expected Permit2 ${PERMIT2_ADDRESS}`
|
|
974
|
+
};
|
|
975
|
+
}
|
|
976
|
+
} catch {
|
|
977
|
+
return {
|
|
978
|
+
isValid: false,
|
|
979
|
+
invalidReason: ErrErc20ApprovalTxInvalidCalldata,
|
|
980
|
+
invalidMessage: "Failed to decode approve() calldata from the signed transaction"
|
|
981
|
+
};
|
|
982
|
+
}
|
|
983
|
+
try {
|
|
984
|
+
const recoveredAddress = await (0, import_viem9.recoverTransactionAddress)({
|
|
985
|
+
serializedTransaction: serializedTx
|
|
986
|
+
});
|
|
987
|
+
if ((0, import_viem9.getAddress)(recoveredAddress) !== (0, import_viem9.getAddress)(payer)) {
|
|
988
|
+
return {
|
|
989
|
+
isValid: false,
|
|
990
|
+
invalidReason: ErrErc20ApprovalTxSignerMismatch,
|
|
991
|
+
invalidMessage: `Transaction signed by ${recoveredAddress}, expected payer ${payer}`
|
|
992
|
+
};
|
|
993
|
+
}
|
|
994
|
+
} catch {
|
|
995
|
+
return {
|
|
996
|
+
isValid: false,
|
|
997
|
+
invalidReason: ErrErc20ApprovalTxInvalidSignature,
|
|
998
|
+
invalidMessage: "Failed to recover signer from the signed transaction"
|
|
999
|
+
};
|
|
1000
|
+
}
|
|
1001
|
+
} catch {
|
|
1002
|
+
return {
|
|
1003
|
+
isValid: false,
|
|
1004
|
+
invalidReason: ErrErc20ApprovalTxParseFailed,
|
|
1005
|
+
invalidMessage: "Failed to parse the signed transaction"
|
|
1006
|
+
};
|
|
1007
|
+
}
|
|
1008
|
+
return { isValid: true };
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
// src/shared/permit2.ts
|
|
1012
|
+
var import_viem10 = require("viem");
|
|
1013
|
+
|
|
1014
|
+
// src/upto/facilitator/errors.ts
|
|
1015
|
+
var ErrUptoAmountExceedsPermitted = "upto_amount_exceeds_permitted";
|
|
1016
|
+
var ErrUptoUnauthorizedFacilitator = "upto_unauthorized_facilitator";
|
|
1017
|
+
|
|
1018
|
+
// src/shared/permit2.ts
|
|
1019
|
+
async function waitAndReturnSettleResponse(signer, tx, payload, payer) {
|
|
1020
|
+
const receipt = await signer.waitForTransactionReceipt({ hash: tx });
|
|
1021
|
+
if (receipt.status !== "success") {
|
|
1022
|
+
return {
|
|
1023
|
+
success: false,
|
|
1024
|
+
errorReason: ErrInvalidTransactionState,
|
|
1025
|
+
transaction: tx,
|
|
1026
|
+
network: payload.accepted.network,
|
|
1027
|
+
payer
|
|
1028
|
+
};
|
|
1029
|
+
}
|
|
1030
|
+
return {
|
|
1031
|
+
success: true,
|
|
1032
|
+
transaction: tx,
|
|
1033
|
+
network: payload.accepted.network,
|
|
1034
|
+
payer
|
|
1035
|
+
};
|
|
1036
|
+
}
|
|
1037
|
+
function mapSettleError(error, payload, payer) {
|
|
1038
|
+
let errorReason = ErrTransactionFailed;
|
|
1039
|
+
if (error instanceof Error) {
|
|
1040
|
+
const message = error.message;
|
|
1041
|
+
if (message.includes("Permit2612AmountMismatch")) {
|
|
1042
|
+
errorReason = ErrPermit2612AmountMismatch;
|
|
1043
|
+
} else if (message.includes("InvalidAmount")) {
|
|
1044
|
+
errorReason = ErrPermit2InvalidAmount;
|
|
1045
|
+
} else if (message.includes("InvalidDestination")) {
|
|
1046
|
+
errorReason = ErrPermit2InvalidDestination;
|
|
1047
|
+
} else if (message.includes("InvalidOwner")) {
|
|
1048
|
+
errorReason = ErrPermit2InvalidOwner;
|
|
1049
|
+
} else if (message.includes("PaymentTooEarly")) {
|
|
1050
|
+
errorReason = ErrPermit2PaymentTooEarly;
|
|
1051
|
+
} else if (message.includes("InvalidSignature") || message.includes("SignatureExpired")) {
|
|
1052
|
+
errorReason = ErrPermit2InvalidSignature;
|
|
1053
|
+
} else if (message.includes("InvalidNonce")) {
|
|
1054
|
+
errorReason = ErrPermit2InvalidNonce;
|
|
1055
|
+
} else if (message.includes("erc20_approval_tx_failed")) {
|
|
1056
|
+
errorReason = ErrErc20ApprovalTxFailed;
|
|
1057
|
+
} else if (message.includes("AmountExceedsPermitted")) {
|
|
1058
|
+
errorReason = ErrUptoAmountExceedsPermitted;
|
|
1059
|
+
} else if (message.includes("UnauthorizedFacilitator")) {
|
|
1060
|
+
errorReason = ErrUptoUnauthorizedFacilitator;
|
|
1061
|
+
} else {
|
|
1062
|
+
errorReason = `${ErrTransactionFailed}: ${message.slice(0, 500)}`;
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
return {
|
|
1066
|
+
success: false,
|
|
1067
|
+
errorReason,
|
|
1068
|
+
transaction: "",
|
|
1069
|
+
network: payload.accepted.network,
|
|
1070
|
+
payer
|
|
1071
|
+
};
|
|
1072
|
+
}
|
|
1073
|
+
function validateEip2612PermitForPayment(info, payer, tokenAddress) {
|
|
1074
|
+
if (!validateEip2612GasSponsoringInfo(info)) {
|
|
1075
|
+
return { isValid: false, invalidReason: ErrInvalidEip2612ExtensionFormat };
|
|
1076
|
+
}
|
|
1077
|
+
if ((0, import_viem10.getAddress)(info.from) !== (0, import_viem10.getAddress)(payer)) {
|
|
1078
|
+
return { isValid: false, invalidReason: ErrEip2612FromMismatch };
|
|
1079
|
+
}
|
|
1080
|
+
if ((0, import_viem10.getAddress)(info.asset) !== tokenAddress) {
|
|
1081
|
+
return { isValid: false, invalidReason: ErrEip2612AssetMismatch };
|
|
1082
|
+
}
|
|
1083
|
+
if ((0, import_viem10.getAddress)(info.spender) !== (0, import_viem10.getAddress)(PERMIT2_ADDRESS)) {
|
|
1084
|
+
return { isValid: false, invalidReason: ErrEip2612SpenderNotPermit2 };
|
|
1085
|
+
}
|
|
1086
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1087
|
+
if (BigInt(info.deadline) < BigInt(now + 6)) {
|
|
1088
|
+
return { isValid: false, invalidReason: ErrEip2612DeadlineExpired };
|
|
1089
|
+
}
|
|
1090
|
+
return { isValid: true };
|
|
1091
|
+
}
|
|
1092
|
+
async function simulatePermit2Settle(config, signer, settleArgs) {
|
|
1093
|
+
try {
|
|
1094
|
+
await signer.readContract({
|
|
1095
|
+
address: config.proxyAddress,
|
|
1096
|
+
abi: config.proxyABI,
|
|
1097
|
+
functionName: "settle",
|
|
1098
|
+
args: settleArgs
|
|
1099
|
+
});
|
|
1100
|
+
return true;
|
|
1101
|
+
} catch {
|
|
1102
|
+
return false;
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
async function simulatePermit2SettleWithPermit(config, signer, settleArgs, eip2612Info) {
|
|
1106
|
+
try {
|
|
1107
|
+
const { v, r, s } = splitEip2612Signature(eip2612Info.signature);
|
|
1108
|
+
await signer.readContract({
|
|
1109
|
+
address: config.proxyAddress,
|
|
1110
|
+
abi: config.proxyABI,
|
|
1111
|
+
functionName: "settleWithPermit",
|
|
1112
|
+
args: [
|
|
1113
|
+
{
|
|
1114
|
+
value: BigInt(eip2612Info.amount),
|
|
1115
|
+
deadline: BigInt(eip2612Info.deadline),
|
|
1116
|
+
r,
|
|
1117
|
+
s,
|
|
1118
|
+
v
|
|
1119
|
+
},
|
|
1120
|
+
...settleArgs
|
|
1121
|
+
]
|
|
1122
|
+
});
|
|
1123
|
+
return true;
|
|
1124
|
+
} catch {
|
|
1125
|
+
return false;
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
async function simulatePermit2SettleWithErc20Approval(config, extensionSigner, settleArgs, erc20Info) {
|
|
1129
|
+
if (!extensionSigner.simulateTransactions) {
|
|
1130
|
+
return false;
|
|
1131
|
+
}
|
|
1132
|
+
try {
|
|
1133
|
+
const settleData = (0, import_viem10.encodeFunctionData)({
|
|
1134
|
+
abi: config.proxyABI,
|
|
1135
|
+
functionName: "settle",
|
|
1136
|
+
args: settleArgs
|
|
1137
|
+
});
|
|
1138
|
+
return await extensionSigner.simulateTransactions([
|
|
1139
|
+
erc20Info.signedTransaction,
|
|
1140
|
+
{ to: config.proxyAddress, data: settleData, gas: BigInt(3e5) }
|
|
1141
|
+
]);
|
|
1142
|
+
} catch {
|
|
1143
|
+
return false;
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
async function diagnosePermit2SimulationFailure(config, signer, tokenAddress, permit2Payload, amountRequired) {
|
|
1147
|
+
const payer = permit2Payload.permit2Authorization.from;
|
|
1148
|
+
const diagnosticCalls = [
|
|
1149
|
+
{
|
|
1150
|
+
address: config.proxyAddress,
|
|
1151
|
+
abi: config.proxyABI,
|
|
1152
|
+
functionName: "PERMIT2"
|
|
1153
|
+
},
|
|
1154
|
+
{
|
|
1155
|
+
address: tokenAddress,
|
|
1156
|
+
abi: eip3009ABI,
|
|
1157
|
+
functionName: "balanceOf",
|
|
1158
|
+
args: [payer]
|
|
1159
|
+
},
|
|
1160
|
+
{
|
|
1161
|
+
address: tokenAddress,
|
|
1162
|
+
abi: erc20AllowanceAbi,
|
|
1163
|
+
functionName: "allowance",
|
|
1164
|
+
args: [payer, PERMIT2_ADDRESS]
|
|
1165
|
+
}
|
|
1166
|
+
];
|
|
1167
|
+
try {
|
|
1168
|
+
const results = await multicall(signer.readContract.bind(signer), diagnosticCalls);
|
|
1169
|
+
const [proxyResult, balanceResult, allowanceResult] = results;
|
|
1170
|
+
if (proxyResult.status === "failure") {
|
|
1171
|
+
return { isValid: false, invalidReason: ErrPermit2ProxyNotDeployed, payer };
|
|
1172
|
+
}
|
|
1173
|
+
if (balanceResult.status === "success") {
|
|
1174
|
+
const balance = balanceResult.result;
|
|
1175
|
+
if (balance < BigInt(amountRequired)) {
|
|
1176
|
+
return { isValid: false, invalidReason: ErrPermit2InsufficientBalance, payer };
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
if (allowanceResult.status === "success") {
|
|
1180
|
+
const allowance = allowanceResult.result;
|
|
1181
|
+
if (allowance < BigInt(amountRequired)) {
|
|
1182
|
+
return { isValid: false, invalidReason: ErrPermit2AllowanceRequired, payer };
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
} catch {
|
|
1186
|
+
}
|
|
1187
|
+
return { isValid: false, invalidReason: ErrPermit2SimulationFailed, payer };
|
|
1188
|
+
}
|
|
1189
|
+
async function checkPermit2Prerequisites(config, signer, tokenAddress, payer, amountRequired) {
|
|
1190
|
+
const diagnosticCalls = [
|
|
1191
|
+
{
|
|
1192
|
+
address: config.proxyAddress,
|
|
1193
|
+
abi: config.proxyABI,
|
|
1194
|
+
functionName: "PERMIT2"
|
|
1195
|
+
},
|
|
1196
|
+
{
|
|
1197
|
+
address: tokenAddress,
|
|
1198
|
+
abi: eip3009ABI,
|
|
1199
|
+
functionName: "balanceOf",
|
|
1200
|
+
args: [payer]
|
|
1201
|
+
}
|
|
1202
|
+
];
|
|
1203
|
+
try {
|
|
1204
|
+
const results = await multicall(signer.readContract.bind(signer), diagnosticCalls);
|
|
1205
|
+
const [proxyResult, balanceResult] = results;
|
|
1206
|
+
if (proxyResult.status === "failure") {
|
|
1207
|
+
return { isValid: false, invalidReason: ErrPermit2ProxyNotDeployed, payer };
|
|
1208
|
+
}
|
|
1209
|
+
if (balanceResult.status === "success") {
|
|
1210
|
+
const balance = balanceResult.result;
|
|
1211
|
+
if (balance < BigInt(amountRequired)) {
|
|
1212
|
+
return { isValid: false, invalidReason: ErrPermit2InsufficientBalance, payer };
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
} catch {
|
|
1216
|
+
}
|
|
1217
|
+
return { isValid: true, invalidReason: void 0, payer };
|
|
1218
|
+
}
|
|
1219
|
+
function buildExactPermit2SettleArgs(permit2Payload) {
|
|
1220
|
+
const { signature } = (0, import_viem10.parseErc6492Signature)(permit2Payload.signature);
|
|
1221
|
+
return [
|
|
1222
|
+
{
|
|
1223
|
+
permitted: {
|
|
1224
|
+
token: (0, import_viem10.getAddress)(permit2Payload.permit2Authorization.permitted.token),
|
|
1225
|
+
amount: BigInt(permit2Payload.permit2Authorization.permitted.amount)
|
|
1226
|
+
},
|
|
1227
|
+
nonce: BigInt(permit2Payload.permit2Authorization.nonce),
|
|
1228
|
+
deadline: BigInt(permit2Payload.permit2Authorization.deadline)
|
|
1229
|
+
},
|
|
1230
|
+
(0, import_viem10.getAddress)(permit2Payload.permit2Authorization.from),
|
|
1231
|
+
{
|
|
1232
|
+
to: (0, import_viem10.getAddress)(permit2Payload.permit2Authorization.witness.to),
|
|
1233
|
+
validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter)
|
|
1234
|
+
},
|
|
1235
|
+
signature
|
|
1236
|
+
];
|
|
1237
|
+
}
|
|
1238
|
+
function splitEip2612Signature(signature) {
|
|
1239
|
+
const sig = signature.startsWith("0x") ? signature.slice(2) : signature;
|
|
1240
|
+
if (sig.length !== 130) {
|
|
1241
|
+
throw new Error(
|
|
1242
|
+
`invalid EIP-2612 signature length: expected 65 bytes (130 hex chars), got ${sig.length / 2} bytes`
|
|
1243
|
+
);
|
|
1244
|
+
}
|
|
1245
|
+
const r = `0x${sig.slice(0, 64)}`;
|
|
1246
|
+
const s = `0x${sig.slice(64, 128)}`;
|
|
1247
|
+
const v = parseInt(sig.slice(128, 130), 16);
|
|
1248
|
+
return { v, r, s };
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
// src/exact/facilitator/permit2.ts
|
|
1252
|
+
var exactProxyConfig = {
|
|
1253
|
+
proxyAddress: x402ExactPermit2ProxyAddress,
|
|
1254
|
+
proxyABI: x402ExactPermit2ProxyABI
|
|
1255
|
+
};
|
|
1256
|
+
async function verifyPermit2(signer, payload, requirements, permit2Payload, context, options) {
|
|
1257
|
+
const payer = permit2Payload.permit2Authorization.from;
|
|
1258
|
+
if (payload.accepted.scheme !== "exact" || requirements.scheme !== "exact") {
|
|
1259
|
+
return {
|
|
1260
|
+
isValid: false,
|
|
1261
|
+
invalidReason: ErrUnsupportedPayloadType,
|
|
1262
|
+
payer
|
|
1263
|
+
};
|
|
1264
|
+
}
|
|
1265
|
+
if (payload.accepted.network !== requirements.network) {
|
|
1266
|
+
return {
|
|
1267
|
+
isValid: false,
|
|
1268
|
+
invalidReason: ErrNetworkMismatch,
|
|
1269
|
+
payer
|
|
1270
|
+
};
|
|
1271
|
+
}
|
|
1272
|
+
const chainId = getEvmChainId(requirements.network);
|
|
1273
|
+
const tokenAddress = (0, import_viem11.getAddress)(requirements.asset);
|
|
1274
|
+
const assetBytecode = await signer.getCode({ address: tokenAddress });
|
|
1275
|
+
if (!assetBytecode || assetBytecode === "0x") {
|
|
1276
|
+
return { isValid: false, invalidReason: ErrAssetNotDeployedContract, payer };
|
|
1277
|
+
}
|
|
1278
|
+
if ((0, import_viem11.getAddress)(permit2Payload.permit2Authorization.spender) !== (0, import_viem11.getAddress)(x402ExactPermit2ProxyAddress)) {
|
|
1279
|
+
return {
|
|
1280
|
+
isValid: false,
|
|
1281
|
+
invalidReason: ErrPermit2InvalidSpender,
|
|
1282
|
+
payer
|
|
1283
|
+
};
|
|
1284
|
+
}
|
|
1285
|
+
if ((0, import_viem11.getAddress)(permit2Payload.permit2Authorization.witness.to) !== (0, import_viem11.getAddress)(requirements.payTo)) {
|
|
1286
|
+
return {
|
|
1287
|
+
isValid: false,
|
|
1288
|
+
invalidReason: ErrPermit2RecipientMismatch,
|
|
1289
|
+
payer
|
|
1290
|
+
};
|
|
1291
|
+
}
|
|
1292
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1293
|
+
if (BigInt(permit2Payload.permit2Authorization.deadline) < BigInt(now + 6)) {
|
|
1294
|
+
return {
|
|
1295
|
+
isValid: false,
|
|
1296
|
+
invalidReason: ErrPermit2DeadlineExpired,
|
|
1297
|
+
payer
|
|
1298
|
+
};
|
|
1299
|
+
}
|
|
1300
|
+
if (BigInt(permit2Payload.permit2Authorization.witness.validAfter) > BigInt(now)) {
|
|
1301
|
+
return {
|
|
1302
|
+
isValid: false,
|
|
1303
|
+
invalidReason: ErrPermit2NotYetValid,
|
|
1304
|
+
payer
|
|
1305
|
+
};
|
|
1306
|
+
}
|
|
1307
|
+
if (BigInt(permit2Payload.permit2Authorization.permitted.amount) !== BigInt(requirements.amount)) {
|
|
1308
|
+
return {
|
|
1309
|
+
isValid: false,
|
|
1310
|
+
invalidReason: ErrPermit2AmountMismatch,
|
|
1311
|
+
payer
|
|
1312
|
+
};
|
|
1313
|
+
}
|
|
1314
|
+
if ((0, import_viem11.getAddress)(permit2Payload.permit2Authorization.permitted.token) !== tokenAddress) {
|
|
1315
|
+
return {
|
|
1316
|
+
isValid: false,
|
|
1317
|
+
invalidReason: ErrPermit2TokenMismatch,
|
|
1318
|
+
payer
|
|
1319
|
+
};
|
|
1320
|
+
}
|
|
1321
|
+
const permit2TypedData = {
|
|
1322
|
+
types: permit2WitnessTypes,
|
|
1323
|
+
primaryType: "PermitWitnessTransferFrom",
|
|
1324
|
+
domain: {
|
|
1325
|
+
name: "Permit2",
|
|
1326
|
+
chainId,
|
|
1327
|
+
verifyingContract: PERMIT2_ADDRESS
|
|
1328
|
+
},
|
|
1329
|
+
message: {
|
|
1330
|
+
permitted: {
|
|
1331
|
+
token: (0, import_viem11.getAddress)(permit2Payload.permit2Authorization.permitted.token),
|
|
1332
|
+
amount: BigInt(permit2Payload.permit2Authorization.permitted.amount)
|
|
1333
|
+
},
|
|
1334
|
+
spender: (0, import_viem11.getAddress)(permit2Payload.permit2Authorization.spender),
|
|
1335
|
+
nonce: BigInt(permit2Payload.permit2Authorization.nonce),
|
|
1336
|
+
deadline: BigInt(permit2Payload.permit2Authorization.deadline),
|
|
1337
|
+
witness: {
|
|
1338
|
+
to: (0, import_viem11.getAddress)(permit2Payload.permit2Authorization.witness.to),
|
|
1339
|
+
validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter)
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
};
|
|
1343
|
+
let signatureValid = false;
|
|
1344
|
+
try {
|
|
1345
|
+
signatureValid = await signer.verifyTypedData({
|
|
1346
|
+
address: payer,
|
|
1347
|
+
...permit2TypedData,
|
|
1348
|
+
signature: permit2Payload.signature
|
|
1349
|
+
});
|
|
1350
|
+
} catch {
|
|
1351
|
+
signatureValid = false;
|
|
1352
|
+
}
|
|
1353
|
+
if (!signatureValid) {
|
|
1354
|
+
const bytecode = await signer.getCode({ address: payer });
|
|
1355
|
+
const isDeployedContract = bytecode && bytecode !== "0x";
|
|
1356
|
+
if (!isDeployedContract) {
|
|
1357
|
+
return {
|
|
1358
|
+
isValid: false,
|
|
1359
|
+
invalidReason: ErrPermit2InvalidSignature,
|
|
1360
|
+
payer
|
|
1361
|
+
};
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
if (options?.simulate === false) {
|
|
1365
|
+
return { isValid: true, invalidReason: void 0, payer };
|
|
1366
|
+
}
|
|
1367
|
+
const eip2612Info = extractEip2612GasSponsoringInfo(payload);
|
|
1368
|
+
if (eip2612Info) {
|
|
1369
|
+
const fieldResult = validateEip2612PermitForPayment(eip2612Info, payer, tokenAddress);
|
|
1370
|
+
if (!fieldResult.isValid) {
|
|
1371
|
+
return { isValid: false, invalidReason: fieldResult.invalidReason, payer };
|
|
1372
|
+
}
|
|
1373
|
+
const exactSettleArgs = buildExactPermit2SettleArgs(permit2Payload);
|
|
1374
|
+
const simOk2 = await simulatePermit2SettleWithPermit(
|
|
1375
|
+
exactProxyConfig,
|
|
1376
|
+
signer,
|
|
1377
|
+
exactSettleArgs,
|
|
1378
|
+
eip2612Info
|
|
1379
|
+
);
|
|
1380
|
+
if (!simOk2) {
|
|
1381
|
+
return diagnosePermit2SimulationFailure(
|
|
1382
|
+
exactProxyConfig,
|
|
1383
|
+
signer,
|
|
1384
|
+
tokenAddress,
|
|
1385
|
+
permit2Payload,
|
|
1386
|
+
requirements.amount
|
|
1387
|
+
);
|
|
1388
|
+
}
|
|
1389
|
+
return { isValid: true, invalidReason: void 0, payer };
|
|
1390
|
+
}
|
|
1391
|
+
const erc20GasSponsorshipExtension = context?.getExtension(
|
|
1392
|
+
ERC20_APPROVAL_GAS_SPONSORING_KEY
|
|
1393
|
+
);
|
|
1394
|
+
if (erc20GasSponsorshipExtension) {
|
|
1395
|
+
const erc20Info = extractErc20ApprovalGasSponsoringInfo(payload);
|
|
1396
|
+
if (erc20Info) {
|
|
1397
|
+
const fieldResult = await validateErc20ApprovalForPayment(erc20Info, payer, tokenAddress);
|
|
1398
|
+
if (!fieldResult.isValid) {
|
|
1399
|
+
return { isValid: false, invalidReason: fieldResult.invalidReason, payer };
|
|
1400
|
+
}
|
|
1401
|
+
const extensionSigner = resolveErc20ApprovalExtensionSigner(
|
|
1402
|
+
erc20GasSponsorshipExtension,
|
|
1403
|
+
requirements.network
|
|
1404
|
+
);
|
|
1405
|
+
if (extensionSigner?.simulateTransactions) {
|
|
1406
|
+
const simOk2 = await simulatePermit2SettleWithErc20Approval(
|
|
1407
|
+
exactProxyConfig,
|
|
1408
|
+
extensionSigner,
|
|
1409
|
+
buildExactPermit2SettleArgs(permit2Payload),
|
|
1410
|
+
erc20Info
|
|
1411
|
+
);
|
|
1412
|
+
if (!simOk2) {
|
|
1413
|
+
return diagnosePermit2SimulationFailure(
|
|
1414
|
+
exactProxyConfig,
|
|
1415
|
+
signer,
|
|
1416
|
+
tokenAddress,
|
|
1417
|
+
permit2Payload,
|
|
1418
|
+
requirements.amount
|
|
1419
|
+
);
|
|
1420
|
+
}
|
|
1421
|
+
return { isValid: true, invalidReason: void 0, payer };
|
|
1422
|
+
}
|
|
1423
|
+
return checkPermit2Prerequisites(
|
|
1424
|
+
exactProxyConfig,
|
|
1425
|
+
signer,
|
|
1426
|
+
tokenAddress,
|
|
1427
|
+
payer,
|
|
1428
|
+
requirements.amount
|
|
1429
|
+
);
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
const simOk = await simulatePermit2Settle(
|
|
1433
|
+
exactProxyConfig,
|
|
1434
|
+
signer,
|
|
1435
|
+
buildExactPermit2SettleArgs(permit2Payload)
|
|
1436
|
+
);
|
|
1437
|
+
if (!simOk) {
|
|
1438
|
+
return diagnosePermit2SimulationFailure(
|
|
1439
|
+
exactProxyConfig,
|
|
1440
|
+
signer,
|
|
1441
|
+
tokenAddress,
|
|
1442
|
+
permit2Payload,
|
|
1443
|
+
requirements.amount
|
|
1444
|
+
);
|
|
1445
|
+
}
|
|
1446
|
+
return { isValid: true, invalidReason: void 0, payer };
|
|
1447
|
+
}
|
|
1448
|
+
async function settlePermit2(signer, payload, requirements, permit2Payload, context, config) {
|
|
1449
|
+
const payer = permit2Payload.permit2Authorization.from;
|
|
1450
|
+
const valid = await verifyPermit2(signer, payload, requirements, permit2Payload, context, {
|
|
1451
|
+
simulate: config?.simulateInSettle ?? false
|
|
1452
|
+
});
|
|
1453
|
+
if (!valid.isValid) {
|
|
1454
|
+
return {
|
|
1455
|
+
success: false,
|
|
1456
|
+
network: payload.accepted.network,
|
|
1457
|
+
transaction: "",
|
|
1458
|
+
errorReason: valid.invalidReason ?? ErrInvalidScheme,
|
|
1459
|
+
payer
|
|
1460
|
+
};
|
|
1461
|
+
}
|
|
1462
|
+
const dataSuffix = await resolveDataSuffix(context, {
|
|
1463
|
+
paymentPayload: payload,
|
|
1464
|
+
paymentRequirements: requirements
|
|
1465
|
+
});
|
|
1466
|
+
const eip2612Info = extractEip2612GasSponsoringInfo(payload);
|
|
1467
|
+
if (eip2612Info) {
|
|
1468
|
+
return settlePermit2WithEIP2612(
|
|
1469
|
+
exactProxyConfig,
|
|
1470
|
+
signer,
|
|
1471
|
+
payload,
|
|
1472
|
+
permit2Payload,
|
|
1473
|
+
eip2612Info,
|
|
1474
|
+
dataSuffix
|
|
1475
|
+
);
|
|
1476
|
+
}
|
|
1477
|
+
const erc20Info = extractErc20ApprovalGasSponsoringInfo(payload);
|
|
1478
|
+
if (erc20Info) {
|
|
1479
|
+
const erc20GasSponsorshipExtension = context?.getExtension(
|
|
1480
|
+
ERC20_APPROVAL_GAS_SPONSORING_KEY
|
|
1481
|
+
);
|
|
1482
|
+
const extensionSigner = resolveErc20ApprovalExtensionSigner(
|
|
1483
|
+
erc20GasSponsorshipExtension,
|
|
1484
|
+
payload.accepted.network
|
|
1485
|
+
);
|
|
1486
|
+
if (extensionSigner) {
|
|
1487
|
+
return settlePermit2WithERC20Approval(
|
|
1488
|
+
exactProxyConfig,
|
|
1489
|
+
extensionSigner,
|
|
1490
|
+
payload,
|
|
1491
|
+
permit2Payload,
|
|
1492
|
+
erc20Info,
|
|
1493
|
+
dataSuffix
|
|
1494
|
+
);
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
return settlePermit2Direct(exactProxyConfig, signer, payload, permit2Payload, dataSuffix);
|
|
1498
|
+
}
|
|
1499
|
+
async function settlePermit2WithEIP2612(config, signer, payload, permit2Payload, eip2612Info, dataSuffix) {
|
|
1500
|
+
const payer = permit2Payload.permit2Authorization.from;
|
|
1501
|
+
try {
|
|
1502
|
+
const { v, r, s } = splitEip2612Signature(eip2612Info.signature);
|
|
1503
|
+
const tx = await signer.writeContract({
|
|
1504
|
+
address: config.proxyAddress,
|
|
1505
|
+
abi: config.proxyABI,
|
|
1506
|
+
functionName: "settleWithPermit",
|
|
1507
|
+
args: [
|
|
1508
|
+
{
|
|
1509
|
+
value: BigInt(eip2612Info.amount),
|
|
1510
|
+
deadline: BigInt(eip2612Info.deadline),
|
|
1511
|
+
r,
|
|
1512
|
+
s,
|
|
1513
|
+
v
|
|
1514
|
+
},
|
|
1515
|
+
...buildExactPermit2SettleArgs(permit2Payload)
|
|
1516
|
+
],
|
|
1517
|
+
dataSuffix
|
|
1518
|
+
});
|
|
1519
|
+
return waitAndReturnSettleResponse(signer, tx, payload, payer);
|
|
1520
|
+
} catch (error) {
|
|
1521
|
+
return mapSettleError(error, payload, payer);
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
async function settlePermit2WithERC20Approval(config, extensionSigner, payload, permit2Payload, erc20Info, dataSuffix) {
|
|
1525
|
+
const payer = permit2Payload.permit2Authorization.from;
|
|
1526
|
+
try {
|
|
1527
|
+
const settleData = appendDataSuffix(
|
|
1528
|
+
(0, import_viem11.encodeFunctionData)({
|
|
1529
|
+
abi: config.proxyABI,
|
|
1530
|
+
functionName: "settle",
|
|
1531
|
+
args: buildExactPermit2SettleArgs(permit2Payload)
|
|
1532
|
+
}),
|
|
1533
|
+
dataSuffix
|
|
1534
|
+
);
|
|
1535
|
+
const txHashes = await extensionSigner.sendTransactions([
|
|
1536
|
+
erc20Info.signedTransaction,
|
|
1537
|
+
{ to: config.proxyAddress, data: settleData, gas: BigInt(3e5) }
|
|
1538
|
+
]);
|
|
1539
|
+
const settleTxHash = txHashes[txHashes.length - 1];
|
|
1540
|
+
return waitAndReturnSettleResponse(extensionSigner, settleTxHash, payload, payer);
|
|
1541
|
+
} catch (error) {
|
|
1542
|
+
return mapSettleError(error, payload, payer);
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
async function settlePermit2Direct(config, signer, payload, permit2Payload, dataSuffix) {
|
|
1546
|
+
const payer = permit2Payload.permit2Authorization.from;
|
|
1547
|
+
try {
|
|
1548
|
+
const tx = await signer.writeContract({
|
|
1549
|
+
address: config.proxyAddress,
|
|
1550
|
+
abi: config.proxyABI,
|
|
1551
|
+
functionName: "settle",
|
|
1552
|
+
args: buildExactPermit2SettleArgs(permit2Payload),
|
|
1553
|
+
dataSuffix
|
|
1554
|
+
});
|
|
1555
|
+
return waitAndReturnSettleResponse(signer, tx, payload, payer);
|
|
1556
|
+
} catch (error) {
|
|
1557
|
+
return mapSettleError(error, payload, payer);
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
// src/exact/facilitator/scheme.ts
|
|
1562
|
+
var ExactEvmScheme = class {
|
|
1563
|
+
/**
|
|
1564
|
+
* Creates a new ExactEvmScheme facilitator instance.
|
|
1565
|
+
*
|
|
1566
|
+
* @param signer - The EVM signer for facilitator operations
|
|
1567
|
+
* @param config - Optional configuration
|
|
1568
|
+
*/
|
|
1569
|
+
constructor(signer, config) {
|
|
1570
|
+
this.signer = signer;
|
|
1571
|
+
this.scheme = "exact";
|
|
1572
|
+
this.caipFamily = "eip155:*";
|
|
1573
|
+
this.config = {
|
|
1574
|
+
eip6492AllowedFactories: config?.eip6492AllowedFactories ?? [],
|
|
1575
|
+
simulateInSettle: config?.simulateInSettle ?? false
|
|
1576
|
+
};
|
|
1577
|
+
}
|
|
1578
|
+
/**
|
|
1579
|
+
* Returns undefined — EVM has no mechanism-specific extra data.
|
|
1580
|
+
*
|
|
1581
|
+
* @param _ - The network identifier (unused)
|
|
1582
|
+
* @returns undefined
|
|
1583
|
+
*/
|
|
1584
|
+
getExtra(_) {
|
|
1585
|
+
return void 0;
|
|
1586
|
+
}
|
|
1587
|
+
/**
|
|
1588
|
+
* Returns facilitator wallet addresses for the supported response.
|
|
1589
|
+
*
|
|
1590
|
+
* @param _ - The network identifier (unused, addresses are network-agnostic)
|
|
1591
|
+
* @returns Array of facilitator wallet addresses
|
|
1592
|
+
*/
|
|
1593
|
+
getSigners(_) {
|
|
1594
|
+
return [...this.signer.getAddresses()];
|
|
1595
|
+
}
|
|
1596
|
+
/**
|
|
1597
|
+
* Verifies a payment payload. Routes to Permit2 or EIP-3009 based on payload type.
|
|
1598
|
+
*
|
|
1599
|
+
* @param payload - The payment payload to verify
|
|
1600
|
+
* @param requirements - The payment requirements
|
|
1601
|
+
* @param context - Optional facilitator context for extension capabilities
|
|
1602
|
+
* @param _ - Payment required extensions (unused; reserved for interface parity)
|
|
1603
|
+
* @returns Promise resolving to verification response
|
|
1604
|
+
*/
|
|
1605
|
+
async verify(payload, requirements, context, _) {
|
|
1606
|
+
const rawPayload = payload.payload;
|
|
1607
|
+
const isPermit2 = isPermit2Payload(rawPayload);
|
|
1608
|
+
if (isPermit2) {
|
|
1609
|
+
return verifyPermit2(this.signer, payload, requirements, rawPayload, context);
|
|
1610
|
+
}
|
|
1611
|
+
const eip3009Payload = rawPayload;
|
|
1612
|
+
return verifyEIP3009(this.signer, payload, requirements, eip3009Payload);
|
|
1613
|
+
}
|
|
1614
|
+
/**
|
|
1615
|
+
* Settles a payment. Routes to Permit2 or EIP-3009 based on payload type.
|
|
1616
|
+
*
|
|
1617
|
+
* @param payload - The payment payload to settle
|
|
1618
|
+
* @param requirements - The payment requirements
|
|
1619
|
+
* @param context - Optional facilitator context for extension capabilities
|
|
1620
|
+
* @returns Promise resolving to settlement response
|
|
1621
|
+
*/
|
|
1622
|
+
async settle(payload, requirements, context) {
|
|
1623
|
+
const rawPayload = payload.payload;
|
|
1624
|
+
const isPermit2 = isPermit2Payload(rawPayload);
|
|
1625
|
+
if (isPermit2) {
|
|
1626
|
+
return settlePermit2(this.signer, payload, requirements, rawPayload, context, {
|
|
1627
|
+
simulateInSettle: this.config.simulateInSettle
|
|
1628
|
+
});
|
|
1629
|
+
}
|
|
1630
|
+
const eip3009Payload = rawPayload;
|
|
1631
|
+
return settleEIP3009(this.signer, payload, requirements, eip3009Payload, this.config, context);
|
|
1632
|
+
}
|
|
1633
|
+
};
|
|
1634
|
+
|
|
1635
|
+
// src/exact/v1/facilitator/scheme.ts
|
|
1636
|
+
var import_viem13 = require("viem");
|
|
1637
|
+
|
|
1638
|
+
// src/exact/v1/client/scheme.ts
|
|
1639
|
+
var import_viem12 = require("viem");
|
|
1640
|
+
|
|
1641
|
+
// src/v1/index.ts
|
|
1642
|
+
var EVM_NETWORK_CHAIN_ID_MAP = {
|
|
1643
|
+
ethereum: 1,
|
|
1644
|
+
sepolia: 11155111,
|
|
1645
|
+
abstract: 2741,
|
|
1646
|
+
"abstract-testnet": 11124,
|
|
1647
|
+
"base-sepolia": 84532,
|
|
1648
|
+
base: 8453,
|
|
1649
|
+
"avalanche-fuji": 43113,
|
|
1650
|
+
avalanche: 43114,
|
|
1651
|
+
iotex: 4689,
|
|
1652
|
+
sei: 1329,
|
|
1653
|
+
"sei-testnet": 1328,
|
|
1654
|
+
polygon: 137,
|
|
1655
|
+
"polygon-amoy": 80002,
|
|
1656
|
+
peaq: 3338,
|
|
1657
|
+
story: 1514,
|
|
1658
|
+
educhain: 41923,
|
|
1659
|
+
"skale-base-sepolia": 324705682,
|
|
1660
|
+
megaeth: 4326,
|
|
1661
|
+
monad: 143,
|
|
1662
|
+
stable: 988,
|
|
1663
|
+
"stable-testnet": 2201
|
|
1664
|
+
};
|
|
1665
|
+
var NETWORKS = Object.keys(EVM_NETWORK_CHAIN_ID_MAP);
|
|
1666
|
+
function getEvmChainIdV1(network) {
|
|
1667
|
+
const chainId = EVM_NETWORK_CHAIN_ID_MAP[network];
|
|
1668
|
+
if (!chainId) {
|
|
1669
|
+
throw new Error(`Unsupported v1 network: ${network}`);
|
|
1670
|
+
}
|
|
1671
|
+
return chainId;
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
// src/exact/v1/facilitator/scheme.ts
|
|
1675
|
+
var ExactEvmSchemeV12 = class {
|
|
1676
|
+
/**
|
|
1677
|
+
* Creates a new ExactEvmFacilitatorV1 instance.
|
|
1678
|
+
*
|
|
1679
|
+
* @param signer - The EVM signer for facilitator operations
|
|
1680
|
+
* @param config - Optional configuration for the facilitator
|
|
1681
|
+
*/
|
|
1682
|
+
constructor(signer, config) {
|
|
1683
|
+
this.signer = signer;
|
|
1684
|
+
this.scheme = "exact";
|
|
1685
|
+
this.caipFamily = "eip155:*";
|
|
1686
|
+
this.config = {
|
|
1687
|
+
eip6492AllowedFactories: config?.eip6492AllowedFactories ?? [],
|
|
1688
|
+
simulateInSettle: config?.simulateInSettle ?? false
|
|
1689
|
+
};
|
|
1690
|
+
}
|
|
1691
|
+
/**
|
|
1692
|
+
* Get mechanism-specific extra data for the supported kinds endpoint.
|
|
1693
|
+
* For EVM, no extra data is needed.
|
|
1694
|
+
*
|
|
1695
|
+
* @param _ - The network identifier (unused for EVM)
|
|
1696
|
+
* @returns undefined (EVM has no extra data)
|
|
1697
|
+
*/
|
|
1698
|
+
getExtra(_) {
|
|
1699
|
+
return void 0;
|
|
1700
|
+
}
|
|
1701
|
+
/**
|
|
1702
|
+
* Get signer addresses used by this facilitator.
|
|
1703
|
+
* Returns all addresses this facilitator can use for signing/settling transactions.
|
|
1704
|
+
*
|
|
1705
|
+
* @param _ - The network identifier (unused for EVM, addresses are network-agnostic)
|
|
1706
|
+
* @returns Array of facilitator wallet addresses
|
|
1707
|
+
*/
|
|
1708
|
+
getSigners(_) {
|
|
1709
|
+
return [...this.signer.getAddresses()];
|
|
1710
|
+
}
|
|
1711
|
+
/**
|
|
1712
|
+
* Verifies a payment payload (V1).
|
|
1713
|
+
*
|
|
1714
|
+
* @param payload - The payment payload to verify
|
|
1715
|
+
* @param requirements - The payment requirements
|
|
1716
|
+
* @returns Promise resolving to verification response
|
|
1717
|
+
*/
|
|
1718
|
+
async verify(payload, requirements) {
|
|
1719
|
+
return this._verify(payload, requirements);
|
|
1720
|
+
}
|
|
1721
|
+
/**
|
|
1722
|
+
* Settles a payment by executing the transfer (V1).
|
|
1723
|
+
*
|
|
1724
|
+
* @param payload - The payment payload to settle
|
|
1725
|
+
* @param requirements - The payment requirements
|
|
1726
|
+
* @param context - Optional facilitator context for extension capabilities
|
|
1727
|
+
* @returns Promise resolving to settlement response
|
|
1728
|
+
*/
|
|
1729
|
+
async settle(payload, requirements, context) {
|
|
1730
|
+
const payloadV1 = payload;
|
|
1731
|
+
const exactEvmPayload = payload.payload;
|
|
1732
|
+
const valid = await this._verify(payload, requirements, {
|
|
1733
|
+
simulate: this.config.simulateInSettle ?? false
|
|
1734
|
+
});
|
|
1735
|
+
if (!valid.isValid) {
|
|
1736
|
+
return {
|
|
1737
|
+
success: false,
|
|
1738
|
+
network: payloadV1.network,
|
|
1739
|
+
transaction: "",
|
|
1740
|
+
errorReason: valid.invalidReason ?? ErrInvalidScheme,
|
|
1741
|
+
payer: exactEvmPayload.authorization.from
|
|
1742
|
+
};
|
|
1743
|
+
}
|
|
1744
|
+
try {
|
|
1745
|
+
const { address: factoryAddress, data: factoryCalldata } = (0, import_viem13.parseErc6492Signature)(
|
|
1746
|
+
exactEvmPayload.signature
|
|
1747
|
+
);
|
|
1748
|
+
if (factoryAddress && factoryCalldata && !(0, import_viem13.isAddressEqual)(factoryAddress, "0x0000000000000000000000000000000000000000")) {
|
|
1749
|
+
const payerAddress = exactEvmPayload.authorization.from;
|
|
1750
|
+
const bytecode = await this.signer.getCode({ address: payerAddress });
|
|
1751
|
+
if (!bytecode || bytecode === "0x") {
|
|
1752
|
+
const normalizedFactory = factoryAddress.toLowerCase();
|
|
1753
|
+
const isAllowed = (this.config.eip6492AllowedFactories ?? []).some(
|
|
1754
|
+
(allowed) => allowed.toLowerCase() === normalizedFactory
|
|
1755
|
+
);
|
|
1756
|
+
if (!isAllowed) {
|
|
1757
|
+
return {
|
|
1758
|
+
success: false,
|
|
1759
|
+
errorReason: ErrFactoryNotAllowed,
|
|
1760
|
+
transaction: "",
|
|
1761
|
+
network: payloadV1.network,
|
|
1762
|
+
payer: exactEvmPayload.authorization.from
|
|
1763
|
+
};
|
|
1764
|
+
}
|
|
1765
|
+
const deployTx = await this.signer.sendTransaction({
|
|
1766
|
+
to: factoryAddress,
|
|
1767
|
+
data: factoryCalldata
|
|
1768
|
+
});
|
|
1769
|
+
await this.signer.waitForTransactionReceipt({ hash: deployTx });
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
const dataSuffix = await resolveDataSuffix(context, {
|
|
1773
|
+
paymentPayload: payload,
|
|
1774
|
+
paymentRequirements: requirements
|
|
1775
|
+
});
|
|
1776
|
+
const tx = await executeTransferWithAuthorization(
|
|
1777
|
+
this.signer,
|
|
1778
|
+
(0, import_viem13.getAddress)(requirements.asset),
|
|
1779
|
+
exactEvmPayload,
|
|
1780
|
+
dataSuffix
|
|
1781
|
+
);
|
|
1782
|
+
const receipt = await this.signer.waitForTransactionReceipt({ hash: tx });
|
|
1783
|
+
if (receipt.status !== "success") {
|
|
1784
|
+
return {
|
|
1785
|
+
success: false,
|
|
1786
|
+
errorReason: ErrTransactionFailed,
|
|
1787
|
+
transaction: tx,
|
|
1788
|
+
network: payloadV1.network,
|
|
1789
|
+
payer: exactEvmPayload.authorization.from
|
|
1790
|
+
};
|
|
1791
|
+
}
|
|
1792
|
+
return {
|
|
1793
|
+
success: true,
|
|
1794
|
+
transaction: tx,
|
|
1795
|
+
network: payloadV1.network,
|
|
1796
|
+
payer: exactEvmPayload.authorization.from
|
|
1797
|
+
};
|
|
1798
|
+
} catch (error) {
|
|
1799
|
+
return {
|
|
1800
|
+
success: false,
|
|
1801
|
+
errorReason: error instanceof Error ? error.message : ErrTransactionFailed,
|
|
1802
|
+
transaction: "",
|
|
1803
|
+
network: payloadV1.network,
|
|
1804
|
+
payer: exactEvmPayload.authorization.from
|
|
1805
|
+
};
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
/**
|
|
1809
|
+
* Internal verify with optional simulation control.
|
|
1810
|
+
*
|
|
1811
|
+
* @param payload - The payment payload to verify
|
|
1812
|
+
* @param requirements - The payment requirements
|
|
1813
|
+
* @param options - Verification options (e.g. simulate)
|
|
1814
|
+
* @returns Promise resolving to verification response
|
|
1815
|
+
*/
|
|
1816
|
+
async _verify(payload, requirements, options) {
|
|
1817
|
+
const requirementsV1 = requirements;
|
|
1818
|
+
const payloadV1 = payload;
|
|
1819
|
+
const exactEvmPayload = payload.payload;
|
|
1820
|
+
const payer = exactEvmPayload.authorization.from;
|
|
1821
|
+
let eip6492Deployment;
|
|
1822
|
+
if (payloadV1.scheme !== "exact" || requirements.scheme !== "exact") {
|
|
1823
|
+
return {
|
|
1824
|
+
isValid: false,
|
|
1825
|
+
invalidReason: ErrInvalidScheme,
|
|
1826
|
+
payer
|
|
1827
|
+
};
|
|
1828
|
+
}
|
|
1829
|
+
let chainId;
|
|
1830
|
+
try {
|
|
1831
|
+
chainId = getEvmChainIdV1(payloadV1.network);
|
|
1832
|
+
} catch {
|
|
1833
|
+
return {
|
|
1834
|
+
isValid: false,
|
|
1835
|
+
invalidReason: ErrNetworkMismatch,
|
|
1836
|
+
payer
|
|
1837
|
+
};
|
|
1838
|
+
}
|
|
1839
|
+
if (!requirements.extra?.name || !requirements.extra?.version) {
|
|
1840
|
+
return {
|
|
1841
|
+
isValid: false,
|
|
1842
|
+
invalidReason: ErrMissingEip712Domain,
|
|
1843
|
+
payer
|
|
1844
|
+
};
|
|
1845
|
+
}
|
|
1846
|
+
const { name, version } = requirements.extra;
|
|
1847
|
+
const erc20Address = (0, import_viem13.getAddress)(requirements.asset);
|
|
1848
|
+
if (payloadV1.network !== requirements.network) {
|
|
1849
|
+
return {
|
|
1850
|
+
isValid: false,
|
|
1851
|
+
invalidReason: ErrNetworkMismatch,
|
|
1852
|
+
payer
|
|
1853
|
+
};
|
|
1854
|
+
}
|
|
1855
|
+
const permitTypedData = {
|
|
1856
|
+
types: authorizationTypes,
|
|
1857
|
+
primaryType: "TransferWithAuthorization",
|
|
1858
|
+
domain: {
|
|
1859
|
+
name,
|
|
1860
|
+
version,
|
|
1861
|
+
chainId,
|
|
1862
|
+
verifyingContract: erc20Address
|
|
1863
|
+
},
|
|
1864
|
+
message: {
|
|
1865
|
+
from: exactEvmPayload.authorization.from,
|
|
1866
|
+
to: exactEvmPayload.authorization.to,
|
|
1867
|
+
value: BigInt(exactEvmPayload.authorization.value),
|
|
1868
|
+
validAfter: BigInt(exactEvmPayload.authorization.validAfter),
|
|
1869
|
+
validBefore: BigInt(exactEvmPayload.authorization.validBefore),
|
|
1870
|
+
nonce: exactEvmPayload.authorization.nonce
|
|
1871
|
+
}
|
|
1872
|
+
};
|
|
1873
|
+
let isValid = false;
|
|
1874
|
+
try {
|
|
1875
|
+
isValid = await this.signer.verifyTypedData({
|
|
1876
|
+
address: payer,
|
|
1877
|
+
...permitTypedData,
|
|
1878
|
+
signature: exactEvmPayload.signature
|
|
1879
|
+
});
|
|
1880
|
+
} catch {
|
|
1881
|
+
isValid = false;
|
|
1882
|
+
}
|
|
1883
|
+
const signature = exactEvmPayload.signature;
|
|
1884
|
+
const sigLen = signature.startsWith("0x") ? signature.length - 2 : signature.length;
|
|
1885
|
+
const erc6492Data = (0, import_viem13.parseErc6492Signature)(signature);
|
|
1886
|
+
const hasDeploymentInfo = erc6492Data.address && erc6492Data.data && !(0, import_viem13.isAddressEqual)(erc6492Data.address, "0x0000000000000000000000000000000000000000");
|
|
1887
|
+
if (hasDeploymentInfo) {
|
|
1888
|
+
eip6492Deployment = {
|
|
1889
|
+
factoryAddress: erc6492Data.address,
|
|
1890
|
+
factoryCalldata: erc6492Data.data
|
|
1891
|
+
};
|
|
1892
|
+
}
|
|
1893
|
+
if (!isValid) {
|
|
1894
|
+
const isSmartWallet = sigLen > 130;
|
|
1895
|
+
if (!isSmartWallet) {
|
|
1896
|
+
return {
|
|
1897
|
+
isValid: false,
|
|
1898
|
+
invalidReason: ErrInvalidSignature,
|
|
1899
|
+
payer
|
|
1900
|
+
};
|
|
1901
|
+
}
|
|
1902
|
+
const bytecode = await this.signer.getCode({ address: payer });
|
|
1903
|
+
const isDeployed = bytecode && bytecode !== "0x";
|
|
1904
|
+
if (!isDeployed && !hasDeploymentInfo) {
|
|
1905
|
+
return {
|
|
1906
|
+
isValid: false,
|
|
1907
|
+
invalidReason: ErrUndeployedSmartWallet,
|
|
1908
|
+
payer
|
|
1909
|
+
};
|
|
1910
|
+
}
|
|
1911
|
+
}
|
|
1912
|
+
if ((0, import_viem13.getAddress)(exactEvmPayload.authorization.to) !== (0, import_viem13.getAddress)(requirements.payTo)) {
|
|
1913
|
+
return {
|
|
1914
|
+
isValid: false,
|
|
1915
|
+
invalidReason: ErrRecipientMismatch,
|
|
1916
|
+
payer
|
|
1917
|
+
};
|
|
1918
|
+
}
|
|
1919
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1920
|
+
if (BigInt(exactEvmPayload.authorization.validBefore) < BigInt(now + 6)) {
|
|
1921
|
+
return {
|
|
1922
|
+
isValid: false,
|
|
1923
|
+
invalidReason: ErrValidBeforeExpired,
|
|
1924
|
+
payer
|
|
1925
|
+
};
|
|
1926
|
+
}
|
|
1927
|
+
if (BigInt(exactEvmPayload.authorization.validAfter) > BigInt(now)) {
|
|
1928
|
+
return {
|
|
1929
|
+
isValid: false,
|
|
1930
|
+
invalidReason: ErrValidAfterInFuture,
|
|
1931
|
+
payer
|
|
1932
|
+
};
|
|
1933
|
+
}
|
|
1934
|
+
if (BigInt(exactEvmPayload.authorization.value) !== BigInt(requirementsV1.maxAmountRequired)) {
|
|
1935
|
+
return {
|
|
1936
|
+
isValid: false,
|
|
1937
|
+
invalidReason: ErrInvalidAuthorizationValue,
|
|
1938
|
+
payer
|
|
1939
|
+
};
|
|
1940
|
+
}
|
|
1941
|
+
if (options?.simulate !== false) {
|
|
1942
|
+
const simulationSucceeded = await simulateEip3009Transfer(
|
|
1943
|
+
this.signer,
|
|
1944
|
+
erc20Address,
|
|
1945
|
+
exactEvmPayload,
|
|
1946
|
+
eip6492Deployment
|
|
1947
|
+
);
|
|
1948
|
+
if (!simulationSucceeded) {
|
|
1949
|
+
return diagnoseEip3009SimulationFailure(
|
|
1950
|
+
this.signer,
|
|
1951
|
+
erc20Address,
|
|
1952
|
+
exactEvmPayload,
|
|
1953
|
+
requirements,
|
|
1954
|
+
requirementsV1.maxAmountRequired
|
|
1955
|
+
);
|
|
1956
|
+
}
|
|
1957
|
+
}
|
|
1958
|
+
return {
|
|
1959
|
+
isValid: true,
|
|
1960
|
+
invalidReason: void 0,
|
|
1961
|
+
payer
|
|
1962
|
+
};
|
|
1963
|
+
}
|
|
1964
|
+
};
|
|
1965
|
+
|
|
1966
|
+
// src/exact/facilitator/register.ts
|
|
1967
|
+
function registerExactEvmScheme(facilitator, config) {
|
|
1968
|
+
facilitator.register(
|
|
1969
|
+
config.networks,
|
|
1970
|
+
new ExactEvmScheme(config.signer, {
|
|
1971
|
+
eip6492AllowedFactories: config.eip6492AllowedFactories,
|
|
1972
|
+
simulateInSettle: config.simulateInSettle
|
|
1973
|
+
})
|
|
1974
|
+
);
|
|
1975
|
+
facilitator.registerV1(
|
|
1976
|
+
NETWORKS,
|
|
1977
|
+
new ExactEvmSchemeV12(config.signer, {
|
|
1978
|
+
eip6492AllowedFactories: config.eip6492AllowedFactories,
|
|
1979
|
+
simulateInSettle: config.simulateInSettle
|
|
1980
|
+
})
|
|
1981
|
+
);
|
|
1982
|
+
return facilitator;
|
|
1983
|
+
}
|
|
1984
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1985
|
+
0 && (module.exports = {
|
|
1986
|
+
ExactEvmScheme,
|
|
1987
|
+
registerExactEvmScheme
|
|
1988
|
+
});
|
|
1989
|
+
//# sourceMappingURL=index.js.map
|