@x402/evm 2.8.0 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -39
- package/dist/cjs/exact/client/index.d.ts +3 -2
- package/dist/cjs/exact/client/index.js +173 -194
- package/dist/cjs/exact/client/index.js.map +1 -1
- package/dist/cjs/exact/facilitator/index.js +199 -185
- package/dist/cjs/exact/facilitator/index.js.map +1 -1
- package/dist/cjs/exact/server/index.d.ts +18 -17
- package/dist/cjs/exact/server/index.js +100 -55
- package/dist/cjs/exact/server/index.js.map +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.js +3 -1
- package/dist/cjs/exact/v1/facilitator/index.js.map +1 -1
- package/dist/cjs/index.d.ts +38 -2
- package/dist/cjs/index.js +441 -191
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/{permit2-U9Zolx3O.d.ts → permit2-CyZxwngN.d.ts} +278 -87
- package/dist/cjs/scheme-CXDF0D2A.d.ts +47 -0
- package/dist/cjs/upto/client/index.d.ts +32 -0
- package/dist/cjs/upto/client/index.js +507 -0
- package/dist/cjs/upto/client/index.js.map +1 -0
- package/dist/cjs/upto/facilitator/index.d.ts +52 -0
- package/dist/cjs/upto/facilitator/index.js +1233 -0
- package/dist/cjs/upto/facilitator/index.js.map +1 -0
- package/dist/cjs/upto/server/index.d.ts +77 -0
- package/dist/cjs/upto/server/index.js +246 -0
- package/dist/cjs/upto/server/index.js.map +1 -0
- package/dist/cjs/v1/index.d.ts +2 -0
- package/dist/cjs/v1/index.js +3 -1
- package/dist/cjs/v1/index.js.map +1 -1
- package/dist/esm/chunk-C4ZQMS77.mjs +629 -0
- package/dist/esm/chunk-C4ZQMS77.mjs.map +1 -0
- package/dist/esm/chunk-CRT6YNY5.mjs +529 -0
- package/dist/esm/chunk-CRT6YNY5.mjs.map +1 -0
- package/dist/esm/chunk-GJ57SZGI.mjs +121 -0
- package/dist/esm/chunk-GJ57SZGI.mjs.map +1 -0
- package/dist/esm/chunk-JII456TS.mjs +34 -0
- package/dist/esm/chunk-JII456TS.mjs.map +1 -0
- package/dist/esm/chunk-NSFLAANF.mjs +80 -0
- package/dist/esm/chunk-NSFLAANF.mjs.map +1 -0
- package/dist/esm/chunk-RN3WQM6A.mjs +158 -0
- package/dist/esm/chunk-RN3WQM6A.mjs.map +1 -0
- package/dist/esm/chunk-WKBC5YMI.mjs +291 -0
- package/dist/esm/chunk-WKBC5YMI.mjs.map +1 -0
- package/dist/esm/{chunk-IZEI7JTG.mjs → chunk-YUJQ7TLD.mjs} +29 -501
- package/dist/esm/chunk-YUJQ7TLD.mjs.map +1 -0
- package/dist/esm/exact/client/index.d.mts +3 -2
- package/dist/esm/exact/client/index.mjs +8 -5
- package/dist/esm/exact/facilitator/index.mjs +84 -430
- package/dist/esm/exact/facilitator/index.mjs.map +1 -1
- package/dist/esm/exact/server/index.d.mts +18 -17
- package/dist/esm/exact/server/index.mjs +28 -55
- package/dist/esm/exact/server/index.mjs.map +1 -1
- package/dist/esm/exact/v1/client/index.mjs +2 -1
- package/dist/esm/exact/v1/facilitator/index.mjs +2 -1
- package/dist/esm/index.d.mts +38 -2
- package/dist/esm/index.mjs +21 -8
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/{permit2-Bbh3a8_h.d.mts → permit2-CyZxwngN.d.mts} +278 -87
- package/dist/esm/scheme-DCR7hsa3.d.mts +47 -0
- package/dist/esm/upto/client/index.d.mts +32 -0
- package/dist/esm/upto/client/index.mjs +18 -0
- package/dist/esm/upto/client/index.mjs.map +1 -0
- package/dist/esm/upto/facilitator/index.d.mts +52 -0
- package/dist/esm/upto/facilitator/index.mjs +473 -0
- package/dist/esm/upto/facilitator/index.mjs.map +1 -0
- package/dist/esm/upto/server/index.d.mts +77 -0
- package/dist/esm/upto/server/index.mjs +145 -0
- package/dist/esm/upto/server/index.mjs.map +1 -0
- package/dist/esm/v1/index.d.mts +2 -0
- package/dist/esm/v1/index.mjs +2 -1
- package/package.json +34 -4
- package/dist/esm/chunk-GD4MKCN7.mjs +0 -57
- package/dist/esm/chunk-GD4MKCN7.mjs.map +0 -1
- package/dist/esm/chunk-IZEI7JTG.mjs.map +0 -1
- package/dist/esm/chunk-TKN5V2BV.mjs +0 -13
- package/dist/esm/chunk-TKN5V2BV.mjs.map +0 -1
- package/dist/esm/chunk-WJWNS4G4.mjs +0 -518
- package/dist/esm/chunk-WJWNS4G4.mjs.map +0 -1
|
@@ -0,0 +1,1233 @@
|
|
|
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/upto/facilitator/index.ts
|
|
21
|
+
var facilitator_exports = {};
|
|
22
|
+
__export(facilitator_exports, {
|
|
23
|
+
UptoEvmScheme: () => UptoEvmScheme
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(facilitator_exports);
|
|
26
|
+
|
|
27
|
+
// src/types.ts
|
|
28
|
+
function isUptoPermit2Payload(payload) {
|
|
29
|
+
if (typeof payload.signature !== "string") return false;
|
|
30
|
+
if (!("permit2Authorization" in payload)) return false;
|
|
31
|
+
const auth = payload.permit2Authorization;
|
|
32
|
+
if (typeof auth !== "object" || auth === null) return false;
|
|
33
|
+
const a = auth;
|
|
34
|
+
if (typeof a.from !== "string") return false;
|
|
35
|
+
if (typeof a.spender !== "string") return false;
|
|
36
|
+
if (typeof a.nonce !== "string") return false;
|
|
37
|
+
if (typeof a.deadline !== "string") return false;
|
|
38
|
+
const permitted = a.permitted;
|
|
39
|
+
if (typeof permitted !== "object" || permitted === null) return false;
|
|
40
|
+
const p = permitted;
|
|
41
|
+
if (typeof p.token !== "string") return false;
|
|
42
|
+
if (typeof p.amount !== "string") return false;
|
|
43
|
+
const witness = a.witness;
|
|
44
|
+
if (typeof witness !== "object" || witness === null) return false;
|
|
45
|
+
const w = witness;
|
|
46
|
+
return typeof w.facilitator === "string" && typeof w.to === "string" && typeof w.validAfter === "string";
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/exact/extensions.ts
|
|
50
|
+
var EIP2612_GAS_SPONSORING_KEY = "eip2612GasSponsoring";
|
|
51
|
+
var ERC20_APPROVAL_GAS_SPONSORING_KEY = "erc20ApprovalGasSponsoring";
|
|
52
|
+
function _extractInfo(payload, extensionKey) {
|
|
53
|
+
const extensions = payload.extensions;
|
|
54
|
+
if (!extensions) return null;
|
|
55
|
+
const extension = extensions[extensionKey];
|
|
56
|
+
if (!extension?.info) return null;
|
|
57
|
+
return extension.info;
|
|
58
|
+
}
|
|
59
|
+
function extractEip2612GasSponsoringInfo(payload) {
|
|
60
|
+
const info = _extractInfo(payload, EIP2612_GAS_SPONSORING_KEY);
|
|
61
|
+
if (!info) return null;
|
|
62
|
+
if (!info.from || !info.asset || !info.spender || !info.amount || !info.nonce || !info.deadline || !info.signature || !info.version) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
return info;
|
|
66
|
+
}
|
|
67
|
+
function validateEip2612GasSponsoringInfo(info) {
|
|
68
|
+
const addressPattern = /^0x[a-fA-F0-9]{40}$/;
|
|
69
|
+
const numericPattern = /^[0-9]+$/;
|
|
70
|
+
const hexPattern = /^0x[a-fA-F0-9]+$/;
|
|
71
|
+
const versionPattern = /^[0-9]+(\.[0-9]+)*$/;
|
|
72
|
+
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);
|
|
73
|
+
}
|
|
74
|
+
function extractErc20ApprovalGasSponsoringInfo(payload) {
|
|
75
|
+
const info = _extractInfo(payload, ERC20_APPROVAL_GAS_SPONSORING_KEY);
|
|
76
|
+
if (!info) return null;
|
|
77
|
+
if (!info.from || !info.asset || !info.spender || !info.amount || !info.signedTransaction || !info.version) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
return info;
|
|
81
|
+
}
|
|
82
|
+
function validateErc20ApprovalGasSponsoringInfo(info) {
|
|
83
|
+
const addressPattern = /^0x[a-fA-F0-9]{40}$/;
|
|
84
|
+
const numericPattern = /^[0-9]+$/;
|
|
85
|
+
const hexPattern = /^0x[a-fA-F0-9]+$/;
|
|
86
|
+
const versionPattern = /^[0-9]+(\.[0-9]+)*$/;
|
|
87
|
+
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);
|
|
88
|
+
}
|
|
89
|
+
function resolveErc20ApprovalExtensionSigner(extension, network) {
|
|
90
|
+
if (!extension) return void 0;
|
|
91
|
+
return extension.signerForNetwork?.(network) ?? extension.signer;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// src/upto/facilitator/permit2.ts
|
|
95
|
+
var import_viem5 = require("viem");
|
|
96
|
+
|
|
97
|
+
// src/constants.ts
|
|
98
|
+
var uptoPermit2WitnessTypes = {
|
|
99
|
+
PermitWitnessTransferFrom: [
|
|
100
|
+
{ name: "permitted", type: "TokenPermissions" },
|
|
101
|
+
{ name: "spender", type: "address" },
|
|
102
|
+
{ name: "nonce", type: "uint256" },
|
|
103
|
+
{ name: "deadline", type: "uint256" },
|
|
104
|
+
{ name: "witness", type: "Witness" }
|
|
105
|
+
],
|
|
106
|
+
TokenPermissions: [
|
|
107
|
+
{ name: "token", type: "address" },
|
|
108
|
+
{ name: "amount", type: "uint256" }
|
|
109
|
+
],
|
|
110
|
+
Witness: [
|
|
111
|
+
{ name: "to", type: "address" },
|
|
112
|
+
{ name: "facilitator", type: "address" },
|
|
113
|
+
{ name: "validAfter", type: "uint256" }
|
|
114
|
+
]
|
|
115
|
+
};
|
|
116
|
+
var eip3009ABI = [
|
|
117
|
+
{
|
|
118
|
+
inputs: [
|
|
119
|
+
{ name: "from", type: "address" },
|
|
120
|
+
{ name: "to", type: "address" },
|
|
121
|
+
{ name: "value", type: "uint256" },
|
|
122
|
+
{ name: "validAfter", type: "uint256" },
|
|
123
|
+
{ name: "validBefore", type: "uint256" },
|
|
124
|
+
{ name: "nonce", type: "bytes32" },
|
|
125
|
+
{ name: "v", type: "uint8" },
|
|
126
|
+
{ name: "r", type: "bytes32" },
|
|
127
|
+
{ name: "s", type: "bytes32" }
|
|
128
|
+
],
|
|
129
|
+
name: "transferWithAuthorization",
|
|
130
|
+
outputs: [],
|
|
131
|
+
stateMutability: "nonpayable",
|
|
132
|
+
type: "function"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
inputs: [
|
|
136
|
+
{ name: "from", type: "address" },
|
|
137
|
+
{ name: "to", type: "address" },
|
|
138
|
+
{ name: "value", type: "uint256" },
|
|
139
|
+
{ name: "validAfter", type: "uint256" },
|
|
140
|
+
{ name: "validBefore", type: "uint256" },
|
|
141
|
+
{ name: "nonce", type: "bytes32" },
|
|
142
|
+
{ name: "signature", type: "bytes" }
|
|
143
|
+
],
|
|
144
|
+
name: "transferWithAuthorization",
|
|
145
|
+
outputs: [],
|
|
146
|
+
stateMutability: "nonpayable",
|
|
147
|
+
type: "function"
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
inputs: [{ name: "account", type: "address" }],
|
|
151
|
+
name: "balanceOf",
|
|
152
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
153
|
+
stateMutability: "view",
|
|
154
|
+
type: "function"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
inputs: [],
|
|
158
|
+
name: "version",
|
|
159
|
+
outputs: [{ name: "", type: "string" }],
|
|
160
|
+
stateMutability: "view",
|
|
161
|
+
type: "function"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
inputs: [],
|
|
165
|
+
name: "name",
|
|
166
|
+
outputs: [{ name: "", type: "string" }],
|
|
167
|
+
stateMutability: "view",
|
|
168
|
+
type: "function"
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
inputs: [
|
|
172
|
+
{ name: "authorizer", type: "address" },
|
|
173
|
+
{ name: "nonce", type: "bytes32" }
|
|
174
|
+
],
|
|
175
|
+
name: "authorizationState",
|
|
176
|
+
outputs: [{ name: "", type: "bool" }],
|
|
177
|
+
stateMutability: "view",
|
|
178
|
+
type: "function"
|
|
179
|
+
}
|
|
180
|
+
];
|
|
181
|
+
var erc20ApproveAbi = [
|
|
182
|
+
{
|
|
183
|
+
type: "function",
|
|
184
|
+
name: "approve",
|
|
185
|
+
inputs: [
|
|
186
|
+
{ name: "spender", type: "address" },
|
|
187
|
+
{ name: "amount", type: "uint256" }
|
|
188
|
+
],
|
|
189
|
+
outputs: [{ type: "bool" }],
|
|
190
|
+
stateMutability: "nonpayable"
|
|
191
|
+
}
|
|
192
|
+
];
|
|
193
|
+
var erc20AllowanceAbi = [
|
|
194
|
+
{
|
|
195
|
+
type: "function",
|
|
196
|
+
name: "allowance",
|
|
197
|
+
inputs: [
|
|
198
|
+
{ name: "owner", type: "address" },
|
|
199
|
+
{ name: "spender", type: "address" }
|
|
200
|
+
],
|
|
201
|
+
outputs: [{ type: "uint256" }],
|
|
202
|
+
stateMutability: "view"
|
|
203
|
+
}
|
|
204
|
+
];
|
|
205
|
+
var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
206
|
+
var x402UptoPermit2ProxyAddress = "0x4020A4f3b7b90ccA423B9fabCc0CE57C6C240002";
|
|
207
|
+
var uptoPermit2WitnessABIComponents = [
|
|
208
|
+
{ name: "to", type: "address", internalType: "address" },
|
|
209
|
+
{ name: "facilitator", type: "address", internalType: "address" },
|
|
210
|
+
{ name: "validAfter", type: "uint256", internalType: "uint256" }
|
|
211
|
+
];
|
|
212
|
+
var x402UptoPermit2ProxyABI = [
|
|
213
|
+
{
|
|
214
|
+
type: "function",
|
|
215
|
+
name: "PERMIT2",
|
|
216
|
+
inputs: [],
|
|
217
|
+
outputs: [{ name: "", type: "address", internalType: "contract ISignatureTransfer" }],
|
|
218
|
+
stateMutability: "view"
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
type: "function",
|
|
222
|
+
name: "WITNESS_TYPEHASH",
|
|
223
|
+
inputs: [],
|
|
224
|
+
outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }],
|
|
225
|
+
stateMutability: "view"
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
type: "function",
|
|
229
|
+
name: "WITNESS_TYPE_STRING",
|
|
230
|
+
inputs: [],
|
|
231
|
+
outputs: [{ name: "", type: "string", internalType: "string" }],
|
|
232
|
+
stateMutability: "view"
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
type: "function",
|
|
236
|
+
name: "settle",
|
|
237
|
+
inputs: [
|
|
238
|
+
{
|
|
239
|
+
name: "permit",
|
|
240
|
+
type: "tuple",
|
|
241
|
+
internalType: "struct ISignatureTransfer.PermitTransferFrom",
|
|
242
|
+
components: [
|
|
243
|
+
{
|
|
244
|
+
name: "permitted",
|
|
245
|
+
type: "tuple",
|
|
246
|
+
internalType: "struct ISignatureTransfer.TokenPermissions",
|
|
247
|
+
components: [
|
|
248
|
+
{ name: "token", type: "address", internalType: "address" },
|
|
249
|
+
{ name: "amount", type: "uint256", internalType: "uint256" }
|
|
250
|
+
]
|
|
251
|
+
},
|
|
252
|
+
{ name: "nonce", type: "uint256", internalType: "uint256" },
|
|
253
|
+
{ name: "deadline", type: "uint256", internalType: "uint256" }
|
|
254
|
+
]
|
|
255
|
+
},
|
|
256
|
+
{ name: "amount", type: "uint256", internalType: "uint256" },
|
|
257
|
+
{ name: "owner", type: "address", internalType: "address" },
|
|
258
|
+
{
|
|
259
|
+
name: "witness",
|
|
260
|
+
type: "tuple",
|
|
261
|
+
internalType: "struct x402UptoPermit2Proxy.Witness",
|
|
262
|
+
components: uptoPermit2WitnessABIComponents
|
|
263
|
+
},
|
|
264
|
+
{ name: "signature", type: "bytes", internalType: "bytes" }
|
|
265
|
+
],
|
|
266
|
+
outputs: [],
|
|
267
|
+
stateMutability: "nonpayable"
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
type: "function",
|
|
271
|
+
name: "settleWithPermit",
|
|
272
|
+
inputs: [
|
|
273
|
+
{
|
|
274
|
+
name: "permit2612",
|
|
275
|
+
type: "tuple",
|
|
276
|
+
internalType: "struct x402UptoPermit2Proxy.EIP2612Permit",
|
|
277
|
+
components: [
|
|
278
|
+
{ name: "value", type: "uint256", internalType: "uint256" },
|
|
279
|
+
{ name: "deadline", type: "uint256", internalType: "uint256" },
|
|
280
|
+
{ name: "r", type: "bytes32", internalType: "bytes32" },
|
|
281
|
+
{ name: "s", type: "bytes32", internalType: "bytes32" },
|
|
282
|
+
{ name: "v", type: "uint8", internalType: "uint8" }
|
|
283
|
+
]
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
name: "permit",
|
|
287
|
+
type: "tuple",
|
|
288
|
+
internalType: "struct ISignatureTransfer.PermitTransferFrom",
|
|
289
|
+
components: [
|
|
290
|
+
{
|
|
291
|
+
name: "permitted",
|
|
292
|
+
type: "tuple",
|
|
293
|
+
internalType: "struct ISignatureTransfer.TokenPermissions",
|
|
294
|
+
components: [
|
|
295
|
+
{ name: "token", type: "address", internalType: "address" },
|
|
296
|
+
{ name: "amount", type: "uint256", internalType: "uint256" }
|
|
297
|
+
]
|
|
298
|
+
},
|
|
299
|
+
{ name: "nonce", type: "uint256", internalType: "uint256" },
|
|
300
|
+
{ name: "deadline", type: "uint256", internalType: "uint256" }
|
|
301
|
+
]
|
|
302
|
+
},
|
|
303
|
+
{ name: "amount", type: "uint256", internalType: "uint256" },
|
|
304
|
+
{ name: "owner", type: "address", internalType: "address" },
|
|
305
|
+
{
|
|
306
|
+
name: "witness",
|
|
307
|
+
type: "tuple",
|
|
308
|
+
internalType: "struct x402UptoPermit2Proxy.Witness",
|
|
309
|
+
components: uptoPermit2WitnessABIComponents
|
|
310
|
+
},
|
|
311
|
+
{ name: "signature", type: "bytes", internalType: "bytes" }
|
|
312
|
+
],
|
|
313
|
+
outputs: [],
|
|
314
|
+
stateMutability: "nonpayable"
|
|
315
|
+
},
|
|
316
|
+
{ type: "event", name: "Settled", inputs: [], anonymous: false },
|
|
317
|
+
{ type: "event", name: "SettledWithPermit", inputs: [], anonymous: false },
|
|
318
|
+
{ type: "error", name: "AmountExceedsPermitted", inputs: [] },
|
|
319
|
+
{ type: "error", name: "InvalidDestination", inputs: [] },
|
|
320
|
+
{ type: "error", name: "InvalidOwner", inputs: [] },
|
|
321
|
+
{ type: "error", name: "InvalidPermit2Address", inputs: [] },
|
|
322
|
+
{ type: "error", name: "PaymentTooEarly", inputs: [] },
|
|
323
|
+
{ type: "error", name: "Permit2612AmountMismatch", inputs: [] },
|
|
324
|
+
{ type: "error", name: "ReentrancyGuardReentrantCall", inputs: [] },
|
|
325
|
+
{ type: "error", name: "UnauthorizedFacilitator", inputs: [] }
|
|
326
|
+
];
|
|
327
|
+
|
|
328
|
+
// src/exact/facilitator/errors.ts
|
|
329
|
+
var ErrTransactionFailed = "invalid_exact_evm_transaction_failed";
|
|
330
|
+
var ErrPermit2AmountMismatch = "permit2_amount_mismatch";
|
|
331
|
+
var ErrPermit2InvalidSignature = "invalid_permit2_signature";
|
|
332
|
+
var ErrPermit2AllowanceRequired = "permit2_allowance_required";
|
|
333
|
+
var ErrPermit2SimulationFailed = "permit2_simulation_failed";
|
|
334
|
+
var ErrPermit2InsufficientBalance = "permit2_insufficient_balance";
|
|
335
|
+
var ErrPermit2ProxyNotDeployed = "permit2_proxy_not_deployed";
|
|
336
|
+
var ErrPermit2InvalidAmount = "permit2_invalid_amount";
|
|
337
|
+
var ErrPermit2InvalidDestination = "permit2_invalid_destination";
|
|
338
|
+
var ErrPermit2InvalidOwner = "permit2_invalid_owner";
|
|
339
|
+
var ErrPermit2PaymentTooEarly = "permit2_payment_too_early";
|
|
340
|
+
var ErrPermit2InvalidNonce = "permit2_invalid_nonce";
|
|
341
|
+
var ErrPermit2612AmountMismatch = "permit2_2612_amount_mismatch";
|
|
342
|
+
var ErrErc20ApprovalInvalidFormat = "invalid_erc20_approval_extension_format";
|
|
343
|
+
var ErrErc20ApprovalFromMismatch = "erc20_approval_from_mismatch";
|
|
344
|
+
var ErrErc20ApprovalAssetMismatch = "erc20_approval_asset_mismatch";
|
|
345
|
+
var ErrErc20ApprovalSpenderNotPermit2 = "erc20_approval_spender_not_permit2";
|
|
346
|
+
var ErrErc20ApprovalTxWrongTarget = "erc20_approval_tx_wrong_target";
|
|
347
|
+
var ErrErc20ApprovalTxWrongSelector = "erc20_approval_tx_wrong_selector";
|
|
348
|
+
var ErrErc20ApprovalTxWrongSpender = "erc20_approval_tx_wrong_spender";
|
|
349
|
+
var ErrErc20ApprovalTxInvalidCalldata = "erc20_approval_tx_invalid_calldata";
|
|
350
|
+
var ErrErc20ApprovalTxSignerMismatch = "erc20_approval_tx_signer_mismatch";
|
|
351
|
+
var ErrErc20ApprovalTxInvalidSignature = "erc20_approval_tx_invalid_signature";
|
|
352
|
+
var ErrErc20ApprovalTxParseFailed = "erc20_approval_tx_parse_failed";
|
|
353
|
+
var ErrErc20ApprovalTxFailed = "erc20_approval_tx_failed";
|
|
354
|
+
var ErrInvalidEip2612ExtensionFormat = "invalid_eip2612_extension_format";
|
|
355
|
+
var ErrEip2612FromMismatch = "eip2612_from_mismatch";
|
|
356
|
+
var ErrEip2612AssetMismatch = "eip2612_asset_mismatch";
|
|
357
|
+
var ErrEip2612SpenderNotPermit2 = "eip2612_spender_not_permit2";
|
|
358
|
+
var ErrEip2612DeadlineExpired = "eip2612_deadline_expired";
|
|
359
|
+
var ErrInvalidTransactionState = "invalid_transaction_state";
|
|
360
|
+
|
|
361
|
+
// src/upto/facilitator/errors.ts
|
|
362
|
+
var ErrUptoInvalidScheme = "invalid_upto_evm_scheme";
|
|
363
|
+
var ErrUptoNetworkMismatch = "invalid_upto_evm_network_mismatch";
|
|
364
|
+
var ErrUptoSettlementExceedsAmount = "invalid_upto_evm_payload_settlement_exceeds_amount";
|
|
365
|
+
var ErrUptoAmountExceedsPermitted = "upto_amount_exceeds_permitted";
|
|
366
|
+
var ErrUptoUnauthorizedFacilitator = "upto_unauthorized_facilitator";
|
|
367
|
+
var ErrUptoFacilitatorMismatch = "upto_facilitator_mismatch";
|
|
368
|
+
|
|
369
|
+
// src/utils.ts
|
|
370
|
+
var import_viem = require("viem");
|
|
371
|
+
function getEvmChainId(network) {
|
|
372
|
+
if (network.startsWith("eip155:")) {
|
|
373
|
+
const idStr = network.split(":")[1];
|
|
374
|
+
const chainId = parseInt(idStr, 10);
|
|
375
|
+
if (isNaN(chainId)) {
|
|
376
|
+
throw new Error(`Invalid CAIP-2 chain ID: ${network}`);
|
|
377
|
+
}
|
|
378
|
+
return chainId;
|
|
379
|
+
}
|
|
380
|
+
throw new Error(`Unsupported network format: ${network} (expected eip155:CHAIN_ID)`);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// src/shared/erc20approval.ts
|
|
384
|
+
var import_viem2 = require("viem");
|
|
385
|
+
var APPROVE_SELECTOR = "0x095ea7b3";
|
|
386
|
+
async function validateErc20ApprovalForPayment(info, payer, tokenAddress) {
|
|
387
|
+
if (!validateErc20ApprovalGasSponsoringInfo(info)) {
|
|
388
|
+
return {
|
|
389
|
+
isValid: false,
|
|
390
|
+
invalidReason: ErrErc20ApprovalInvalidFormat,
|
|
391
|
+
invalidMessage: "ERC-20 approval extension info failed schema validation"
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
if ((0, import_viem2.getAddress)(info.from) !== (0, import_viem2.getAddress)(payer)) {
|
|
395
|
+
return {
|
|
396
|
+
isValid: false,
|
|
397
|
+
invalidReason: ErrErc20ApprovalFromMismatch,
|
|
398
|
+
invalidMessage: `Expected from=${payer}, got ${info.from}`
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
if ((0, import_viem2.getAddress)(info.asset) !== tokenAddress) {
|
|
402
|
+
return {
|
|
403
|
+
isValid: false,
|
|
404
|
+
invalidReason: ErrErc20ApprovalAssetMismatch,
|
|
405
|
+
invalidMessage: `Expected asset=${tokenAddress}, got ${info.asset}`
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
if ((0, import_viem2.getAddress)(info.spender) !== (0, import_viem2.getAddress)(PERMIT2_ADDRESS)) {
|
|
409
|
+
return {
|
|
410
|
+
isValid: false,
|
|
411
|
+
invalidReason: ErrErc20ApprovalSpenderNotPermit2,
|
|
412
|
+
invalidMessage: `Expected spender=${PERMIT2_ADDRESS}, got ${info.spender}`
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
try {
|
|
416
|
+
const serializedTx = info.signedTransaction;
|
|
417
|
+
const tx = (0, import_viem2.parseTransaction)(serializedTx);
|
|
418
|
+
if (!tx.to || (0, import_viem2.getAddress)(tx.to) !== tokenAddress) {
|
|
419
|
+
return {
|
|
420
|
+
isValid: false,
|
|
421
|
+
invalidReason: ErrErc20ApprovalTxWrongTarget,
|
|
422
|
+
invalidMessage: `Transaction targets ${tx.to ?? "null"}, expected ${tokenAddress}`
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
const data = tx.data ?? "0x";
|
|
426
|
+
if (!data.startsWith(APPROVE_SELECTOR)) {
|
|
427
|
+
return {
|
|
428
|
+
isValid: false,
|
|
429
|
+
invalidReason: ErrErc20ApprovalTxWrongSelector,
|
|
430
|
+
invalidMessage: `Transaction calldata does not start with approve() selector ${APPROVE_SELECTOR}`
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
try {
|
|
434
|
+
const decoded = (0, import_viem2.decodeFunctionData)({
|
|
435
|
+
abi: erc20ApproveAbi,
|
|
436
|
+
data
|
|
437
|
+
});
|
|
438
|
+
const calldataSpender = (0, import_viem2.getAddress)(decoded.args[0]);
|
|
439
|
+
if (calldataSpender !== (0, import_viem2.getAddress)(PERMIT2_ADDRESS)) {
|
|
440
|
+
return {
|
|
441
|
+
isValid: false,
|
|
442
|
+
invalidReason: ErrErc20ApprovalTxWrongSpender,
|
|
443
|
+
invalidMessage: `approve() spender is ${calldataSpender}, expected Permit2 ${PERMIT2_ADDRESS}`
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
} catch {
|
|
447
|
+
return {
|
|
448
|
+
isValid: false,
|
|
449
|
+
invalidReason: ErrErc20ApprovalTxInvalidCalldata,
|
|
450
|
+
invalidMessage: "Failed to decode approve() calldata from the signed transaction"
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
try {
|
|
454
|
+
const recoveredAddress = await (0, import_viem2.recoverTransactionAddress)({
|
|
455
|
+
serializedTransaction: serializedTx
|
|
456
|
+
});
|
|
457
|
+
if ((0, import_viem2.getAddress)(recoveredAddress) !== (0, import_viem2.getAddress)(payer)) {
|
|
458
|
+
return {
|
|
459
|
+
isValid: false,
|
|
460
|
+
invalidReason: ErrErc20ApprovalTxSignerMismatch,
|
|
461
|
+
invalidMessage: `Transaction signed by ${recoveredAddress}, expected payer ${payer}`
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
} catch {
|
|
465
|
+
return {
|
|
466
|
+
isValid: false,
|
|
467
|
+
invalidReason: ErrErc20ApprovalTxInvalidSignature,
|
|
468
|
+
invalidMessage: "Failed to recover signer from the signed transaction"
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
} catch {
|
|
472
|
+
return {
|
|
473
|
+
isValid: false,
|
|
474
|
+
invalidReason: ErrErc20ApprovalTxParseFailed,
|
|
475
|
+
invalidMessage: "Failed to parse the signed transaction"
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
return { isValid: true };
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// src/shared/permit2.ts
|
|
482
|
+
var import_viem4 = require("viem");
|
|
483
|
+
|
|
484
|
+
// src/multicall.ts
|
|
485
|
+
var import_viem3 = require("viem");
|
|
486
|
+
var MULTICALL3_ADDRESS = "0xcA11bde05977b3631167028862bE2a173976CA11";
|
|
487
|
+
var multicall3ABI = [
|
|
488
|
+
{
|
|
489
|
+
inputs: [
|
|
490
|
+
{ name: "requireSuccess", type: "bool" },
|
|
491
|
+
{
|
|
492
|
+
name: "calls",
|
|
493
|
+
type: "tuple[]",
|
|
494
|
+
components: [
|
|
495
|
+
{ name: "target", type: "address" },
|
|
496
|
+
{ name: "callData", type: "bytes" }
|
|
497
|
+
]
|
|
498
|
+
}
|
|
499
|
+
],
|
|
500
|
+
name: "tryAggregate",
|
|
501
|
+
outputs: [
|
|
502
|
+
{
|
|
503
|
+
name: "returnData",
|
|
504
|
+
type: "tuple[]",
|
|
505
|
+
components: [
|
|
506
|
+
{ name: "success", type: "bool" },
|
|
507
|
+
{ name: "returnData", type: "bytes" }
|
|
508
|
+
]
|
|
509
|
+
}
|
|
510
|
+
],
|
|
511
|
+
stateMutability: "payable",
|
|
512
|
+
type: "function"
|
|
513
|
+
}
|
|
514
|
+
];
|
|
515
|
+
async function multicall(readContract, calls) {
|
|
516
|
+
const aggregateCalls = calls.map((call) => {
|
|
517
|
+
if ("callData" in call) {
|
|
518
|
+
return { target: call.address, callData: call.callData };
|
|
519
|
+
}
|
|
520
|
+
const callData = (0, import_viem3.encodeFunctionData)({
|
|
521
|
+
abi: call.abi,
|
|
522
|
+
functionName: call.functionName,
|
|
523
|
+
args: call.args
|
|
524
|
+
});
|
|
525
|
+
return { target: call.address, callData };
|
|
526
|
+
});
|
|
527
|
+
const rawResults = await readContract({
|
|
528
|
+
address: MULTICALL3_ADDRESS,
|
|
529
|
+
abi: multicall3ABI,
|
|
530
|
+
functionName: "tryAggregate",
|
|
531
|
+
args: [false, aggregateCalls]
|
|
532
|
+
});
|
|
533
|
+
return rawResults.map((raw, i) => {
|
|
534
|
+
if (!raw.success) {
|
|
535
|
+
return {
|
|
536
|
+
status: "failure",
|
|
537
|
+
error: new Error(`multicall: call reverted (returnData: ${raw.returnData})`)
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
const call = calls[i];
|
|
541
|
+
if ("callData" in call) {
|
|
542
|
+
return { status: "success", result: void 0 };
|
|
543
|
+
}
|
|
544
|
+
try {
|
|
545
|
+
const decoded = (0, import_viem3.decodeFunctionResult)({
|
|
546
|
+
abi: call.abi,
|
|
547
|
+
functionName: call.functionName,
|
|
548
|
+
data: raw.returnData
|
|
549
|
+
});
|
|
550
|
+
return { status: "success", result: decoded };
|
|
551
|
+
} catch (err) {
|
|
552
|
+
return {
|
|
553
|
+
status: "failure",
|
|
554
|
+
error: err instanceof Error ? err : new Error(String(err))
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// src/shared/permit2.ts
|
|
561
|
+
async function waitAndReturnSettleResponse(signer, tx, payload, payer) {
|
|
562
|
+
const receipt = await signer.waitForTransactionReceipt({ hash: tx });
|
|
563
|
+
if (receipt.status !== "success") {
|
|
564
|
+
return {
|
|
565
|
+
success: false,
|
|
566
|
+
errorReason: ErrInvalidTransactionState,
|
|
567
|
+
transaction: tx,
|
|
568
|
+
network: payload.accepted.network,
|
|
569
|
+
payer
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
return {
|
|
573
|
+
success: true,
|
|
574
|
+
transaction: tx,
|
|
575
|
+
network: payload.accepted.network,
|
|
576
|
+
payer
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
function mapSettleError(error, payload, payer) {
|
|
580
|
+
let errorReason = ErrTransactionFailed;
|
|
581
|
+
if (error instanceof Error) {
|
|
582
|
+
const message = error.message;
|
|
583
|
+
if (message.includes("Permit2612AmountMismatch")) {
|
|
584
|
+
errorReason = ErrPermit2612AmountMismatch;
|
|
585
|
+
} else if (message.includes("InvalidAmount")) {
|
|
586
|
+
errorReason = ErrPermit2InvalidAmount;
|
|
587
|
+
} else if (message.includes("InvalidDestination")) {
|
|
588
|
+
errorReason = ErrPermit2InvalidDestination;
|
|
589
|
+
} else if (message.includes("InvalidOwner")) {
|
|
590
|
+
errorReason = ErrPermit2InvalidOwner;
|
|
591
|
+
} else if (message.includes("PaymentTooEarly")) {
|
|
592
|
+
errorReason = ErrPermit2PaymentTooEarly;
|
|
593
|
+
} else if (message.includes("InvalidSignature") || message.includes("SignatureExpired")) {
|
|
594
|
+
errorReason = ErrPermit2InvalidSignature;
|
|
595
|
+
} else if (message.includes("InvalidNonce")) {
|
|
596
|
+
errorReason = ErrPermit2InvalidNonce;
|
|
597
|
+
} else if (message.includes("erc20_approval_tx_failed")) {
|
|
598
|
+
errorReason = ErrErc20ApprovalTxFailed;
|
|
599
|
+
} else if (message.includes("AmountExceedsPermitted")) {
|
|
600
|
+
errorReason = ErrUptoAmountExceedsPermitted;
|
|
601
|
+
} else if (message.includes("UnauthorizedFacilitator")) {
|
|
602
|
+
errorReason = ErrUptoUnauthorizedFacilitator;
|
|
603
|
+
} else {
|
|
604
|
+
errorReason = `${ErrTransactionFailed}: ${message.slice(0, 500)}`;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
return {
|
|
608
|
+
success: false,
|
|
609
|
+
errorReason,
|
|
610
|
+
transaction: "",
|
|
611
|
+
network: payload.accepted.network,
|
|
612
|
+
payer
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
function validateEip2612PermitForPayment(info, payer, tokenAddress) {
|
|
616
|
+
if (!validateEip2612GasSponsoringInfo(info)) {
|
|
617
|
+
return { isValid: false, invalidReason: ErrInvalidEip2612ExtensionFormat };
|
|
618
|
+
}
|
|
619
|
+
if ((0, import_viem4.getAddress)(info.from) !== (0, import_viem4.getAddress)(payer)) {
|
|
620
|
+
return { isValid: false, invalidReason: ErrEip2612FromMismatch };
|
|
621
|
+
}
|
|
622
|
+
if ((0, import_viem4.getAddress)(info.asset) !== tokenAddress) {
|
|
623
|
+
return { isValid: false, invalidReason: ErrEip2612AssetMismatch };
|
|
624
|
+
}
|
|
625
|
+
if ((0, import_viem4.getAddress)(info.spender) !== (0, import_viem4.getAddress)(PERMIT2_ADDRESS)) {
|
|
626
|
+
return { isValid: false, invalidReason: ErrEip2612SpenderNotPermit2 };
|
|
627
|
+
}
|
|
628
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
629
|
+
if (BigInt(info.deadline) < BigInt(now + 6)) {
|
|
630
|
+
return { isValid: false, invalidReason: ErrEip2612DeadlineExpired };
|
|
631
|
+
}
|
|
632
|
+
return { isValid: true };
|
|
633
|
+
}
|
|
634
|
+
async function simulatePermit2Settle(config, signer, settleArgs) {
|
|
635
|
+
try {
|
|
636
|
+
await signer.readContract({
|
|
637
|
+
address: config.proxyAddress,
|
|
638
|
+
abi: config.proxyABI,
|
|
639
|
+
functionName: "settle",
|
|
640
|
+
args: settleArgs
|
|
641
|
+
});
|
|
642
|
+
return true;
|
|
643
|
+
} catch {
|
|
644
|
+
return false;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
async function simulatePermit2SettleWithPermit(config, signer, settleArgs, eip2612Info) {
|
|
648
|
+
try {
|
|
649
|
+
const { v, r, s } = splitEip2612Signature(eip2612Info.signature);
|
|
650
|
+
await signer.readContract({
|
|
651
|
+
address: config.proxyAddress,
|
|
652
|
+
abi: config.proxyABI,
|
|
653
|
+
functionName: "settleWithPermit",
|
|
654
|
+
args: [
|
|
655
|
+
{
|
|
656
|
+
value: BigInt(eip2612Info.amount),
|
|
657
|
+
deadline: BigInt(eip2612Info.deadline),
|
|
658
|
+
r,
|
|
659
|
+
s,
|
|
660
|
+
v
|
|
661
|
+
},
|
|
662
|
+
...settleArgs
|
|
663
|
+
]
|
|
664
|
+
});
|
|
665
|
+
return true;
|
|
666
|
+
} catch {
|
|
667
|
+
return false;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
async function simulatePermit2SettleWithErc20Approval(config, extensionSigner, settleArgs, erc20Info) {
|
|
671
|
+
if (!extensionSigner.simulateTransactions) {
|
|
672
|
+
return false;
|
|
673
|
+
}
|
|
674
|
+
try {
|
|
675
|
+
const settleData = (0, import_viem4.encodeFunctionData)({
|
|
676
|
+
abi: config.proxyABI,
|
|
677
|
+
functionName: "settle",
|
|
678
|
+
args: settleArgs
|
|
679
|
+
});
|
|
680
|
+
return await extensionSigner.simulateTransactions([
|
|
681
|
+
erc20Info.signedTransaction,
|
|
682
|
+
{ to: config.proxyAddress, data: settleData, gas: BigInt(3e5) }
|
|
683
|
+
]);
|
|
684
|
+
} catch {
|
|
685
|
+
return false;
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
async function diagnosePermit2SimulationFailure(config, signer, tokenAddress, permit2Payload, amountRequired) {
|
|
689
|
+
const payer = permit2Payload.permit2Authorization.from;
|
|
690
|
+
const diagnosticCalls = [
|
|
691
|
+
{
|
|
692
|
+
address: config.proxyAddress,
|
|
693
|
+
abi: config.proxyABI,
|
|
694
|
+
functionName: "PERMIT2"
|
|
695
|
+
},
|
|
696
|
+
{
|
|
697
|
+
address: tokenAddress,
|
|
698
|
+
abi: eip3009ABI,
|
|
699
|
+
functionName: "balanceOf",
|
|
700
|
+
args: [payer]
|
|
701
|
+
},
|
|
702
|
+
{
|
|
703
|
+
address: tokenAddress,
|
|
704
|
+
abi: erc20AllowanceAbi,
|
|
705
|
+
functionName: "allowance",
|
|
706
|
+
args: [payer, PERMIT2_ADDRESS]
|
|
707
|
+
}
|
|
708
|
+
];
|
|
709
|
+
try {
|
|
710
|
+
const results = await multicall(signer.readContract.bind(signer), diagnosticCalls);
|
|
711
|
+
const [proxyResult, balanceResult, allowanceResult] = results;
|
|
712
|
+
if (proxyResult.status === "failure") {
|
|
713
|
+
return { isValid: false, invalidReason: ErrPermit2ProxyNotDeployed, payer };
|
|
714
|
+
}
|
|
715
|
+
if (balanceResult.status === "success") {
|
|
716
|
+
const balance = balanceResult.result;
|
|
717
|
+
if (balance < BigInt(amountRequired)) {
|
|
718
|
+
return { isValid: false, invalidReason: ErrPermit2InsufficientBalance, payer };
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
if (allowanceResult.status === "success") {
|
|
722
|
+
const allowance = allowanceResult.result;
|
|
723
|
+
if (allowance < BigInt(amountRequired)) {
|
|
724
|
+
return { isValid: false, invalidReason: ErrPermit2AllowanceRequired, payer };
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
} catch {
|
|
728
|
+
}
|
|
729
|
+
return { isValid: false, invalidReason: ErrPermit2SimulationFailed, payer };
|
|
730
|
+
}
|
|
731
|
+
async function checkPermit2Prerequisites(config, signer, tokenAddress, payer, amountRequired) {
|
|
732
|
+
const diagnosticCalls = [
|
|
733
|
+
{
|
|
734
|
+
address: config.proxyAddress,
|
|
735
|
+
abi: config.proxyABI,
|
|
736
|
+
functionName: "PERMIT2"
|
|
737
|
+
},
|
|
738
|
+
{
|
|
739
|
+
address: tokenAddress,
|
|
740
|
+
abi: eip3009ABI,
|
|
741
|
+
functionName: "balanceOf",
|
|
742
|
+
args: [payer]
|
|
743
|
+
}
|
|
744
|
+
];
|
|
745
|
+
try {
|
|
746
|
+
const results = await multicall(signer.readContract.bind(signer), diagnosticCalls);
|
|
747
|
+
const [proxyResult, balanceResult] = results;
|
|
748
|
+
if (proxyResult.status === "failure") {
|
|
749
|
+
return { isValid: false, invalidReason: ErrPermit2ProxyNotDeployed, payer };
|
|
750
|
+
}
|
|
751
|
+
if (balanceResult.status === "success") {
|
|
752
|
+
const balance = balanceResult.result;
|
|
753
|
+
if (balance < BigInt(amountRequired)) {
|
|
754
|
+
return { isValid: false, invalidReason: ErrPermit2InsufficientBalance, payer };
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
} catch {
|
|
758
|
+
}
|
|
759
|
+
return { isValid: true, invalidReason: void 0, payer };
|
|
760
|
+
}
|
|
761
|
+
function buildUptoPermit2SettleArgs(permit2Payload, settlementAmount, facilitatorAddress) {
|
|
762
|
+
return [
|
|
763
|
+
{
|
|
764
|
+
permitted: {
|
|
765
|
+
token: (0, import_viem4.getAddress)(permit2Payload.permit2Authorization.permitted.token),
|
|
766
|
+
amount: BigInt(permit2Payload.permit2Authorization.permitted.amount)
|
|
767
|
+
},
|
|
768
|
+
nonce: BigInt(permit2Payload.permit2Authorization.nonce),
|
|
769
|
+
deadline: BigInt(permit2Payload.permit2Authorization.deadline)
|
|
770
|
+
},
|
|
771
|
+
settlementAmount,
|
|
772
|
+
(0, import_viem4.getAddress)(permit2Payload.permit2Authorization.from),
|
|
773
|
+
{
|
|
774
|
+
to: (0, import_viem4.getAddress)(permit2Payload.permit2Authorization.witness.to),
|
|
775
|
+
facilitator: (0, import_viem4.getAddress)(facilitatorAddress),
|
|
776
|
+
validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter)
|
|
777
|
+
},
|
|
778
|
+
permit2Payload.signature
|
|
779
|
+
];
|
|
780
|
+
}
|
|
781
|
+
function splitEip2612Signature(signature) {
|
|
782
|
+
const sig = signature.startsWith("0x") ? signature.slice(2) : signature;
|
|
783
|
+
if (sig.length !== 130) {
|
|
784
|
+
throw new Error(
|
|
785
|
+
`invalid EIP-2612 signature length: expected 65 bytes (130 hex chars), got ${sig.length / 2} bytes`
|
|
786
|
+
);
|
|
787
|
+
}
|
|
788
|
+
const r = `0x${sig.slice(0, 64)}`;
|
|
789
|
+
const s = `0x${sig.slice(64, 128)}`;
|
|
790
|
+
const v = parseInt(sig.slice(128, 130), 16);
|
|
791
|
+
return { v, r, s };
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
// src/upto/facilitator/permit2.ts
|
|
795
|
+
var uptoProxyConfig = {
|
|
796
|
+
proxyAddress: x402UptoPermit2ProxyAddress,
|
|
797
|
+
proxyABI: x402UptoPermit2ProxyABI
|
|
798
|
+
};
|
|
799
|
+
async function verifyUptoPermit2(signer, payload, requirements, permit2Payload, context, options) {
|
|
800
|
+
const payer = permit2Payload.permit2Authorization.from;
|
|
801
|
+
if (payload.accepted.scheme !== "upto" || requirements.scheme !== "upto") {
|
|
802
|
+
return {
|
|
803
|
+
isValid: false,
|
|
804
|
+
invalidReason: ErrUptoInvalidScheme,
|
|
805
|
+
payer
|
|
806
|
+
};
|
|
807
|
+
}
|
|
808
|
+
if (payload.accepted.network !== requirements.network) {
|
|
809
|
+
return {
|
|
810
|
+
isValid: false,
|
|
811
|
+
invalidReason: ErrUptoNetworkMismatch,
|
|
812
|
+
payer
|
|
813
|
+
};
|
|
814
|
+
}
|
|
815
|
+
const chainId = getEvmChainId(requirements.network);
|
|
816
|
+
const tokenAddress = (0, import_viem5.getAddress)(requirements.asset);
|
|
817
|
+
if ((0, import_viem5.getAddress)(permit2Payload.permit2Authorization.spender) !== (0, import_viem5.getAddress)(x402UptoPermit2ProxyAddress)) {
|
|
818
|
+
return {
|
|
819
|
+
isValid: false,
|
|
820
|
+
invalidReason: "invalid_permit2_spender",
|
|
821
|
+
payer
|
|
822
|
+
};
|
|
823
|
+
}
|
|
824
|
+
if ((0, import_viem5.getAddress)(permit2Payload.permit2Authorization.witness.to) !== (0, import_viem5.getAddress)(requirements.payTo)) {
|
|
825
|
+
return {
|
|
826
|
+
isValid: false,
|
|
827
|
+
invalidReason: "invalid_permit2_recipient_mismatch",
|
|
828
|
+
payer
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
const facilitatorAddresses = signer.getAddresses();
|
|
832
|
+
const witnessFacilitator = (0, import_viem5.getAddress)(permit2Payload.permit2Authorization.witness.facilitator);
|
|
833
|
+
const isFacilitatorMatch = facilitatorAddresses.some(
|
|
834
|
+
(addr) => (0, import_viem5.getAddress)(addr) === witnessFacilitator
|
|
835
|
+
);
|
|
836
|
+
if (!isFacilitatorMatch) {
|
|
837
|
+
return {
|
|
838
|
+
isValid: false,
|
|
839
|
+
invalidReason: ErrUptoFacilitatorMismatch,
|
|
840
|
+
payer
|
|
841
|
+
};
|
|
842
|
+
}
|
|
843
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
844
|
+
if (BigInt(permit2Payload.permit2Authorization.deadline) < BigInt(now + 6)) {
|
|
845
|
+
return {
|
|
846
|
+
isValid: false,
|
|
847
|
+
invalidReason: "permit2_deadline_expired",
|
|
848
|
+
payer
|
|
849
|
+
};
|
|
850
|
+
}
|
|
851
|
+
if (BigInt(permit2Payload.permit2Authorization.witness.validAfter) > BigInt(now)) {
|
|
852
|
+
return {
|
|
853
|
+
isValid: false,
|
|
854
|
+
invalidReason: "permit2_not_yet_valid",
|
|
855
|
+
payer
|
|
856
|
+
};
|
|
857
|
+
}
|
|
858
|
+
if (BigInt(permit2Payload.permit2Authorization.permitted.amount) !== BigInt(requirements.amount)) {
|
|
859
|
+
return {
|
|
860
|
+
isValid: false,
|
|
861
|
+
invalidReason: ErrPermit2AmountMismatch,
|
|
862
|
+
payer
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
if ((0, import_viem5.getAddress)(permit2Payload.permit2Authorization.permitted.token) !== tokenAddress) {
|
|
866
|
+
return {
|
|
867
|
+
isValid: false,
|
|
868
|
+
invalidReason: "permit2_token_mismatch",
|
|
869
|
+
payer
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
const permit2TypedData = {
|
|
873
|
+
types: uptoPermit2WitnessTypes,
|
|
874
|
+
primaryType: "PermitWitnessTransferFrom",
|
|
875
|
+
domain: {
|
|
876
|
+
name: "Permit2",
|
|
877
|
+
chainId,
|
|
878
|
+
verifyingContract: PERMIT2_ADDRESS
|
|
879
|
+
},
|
|
880
|
+
message: {
|
|
881
|
+
permitted: {
|
|
882
|
+
token: (0, import_viem5.getAddress)(permit2Payload.permit2Authorization.permitted.token),
|
|
883
|
+
amount: BigInt(permit2Payload.permit2Authorization.permitted.amount)
|
|
884
|
+
},
|
|
885
|
+
spender: (0, import_viem5.getAddress)(permit2Payload.permit2Authorization.spender),
|
|
886
|
+
nonce: BigInt(permit2Payload.permit2Authorization.nonce),
|
|
887
|
+
deadline: BigInt(permit2Payload.permit2Authorization.deadline),
|
|
888
|
+
witness: {
|
|
889
|
+
to: (0, import_viem5.getAddress)(permit2Payload.permit2Authorization.witness.to),
|
|
890
|
+
facilitator: (0, import_viem5.getAddress)(permit2Payload.permit2Authorization.witness.facilitator),
|
|
891
|
+
validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter)
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
};
|
|
895
|
+
let signatureValid = false;
|
|
896
|
+
try {
|
|
897
|
+
signatureValid = await signer.verifyTypedData({
|
|
898
|
+
address: payer,
|
|
899
|
+
...permit2TypedData,
|
|
900
|
+
signature: permit2Payload.signature
|
|
901
|
+
});
|
|
902
|
+
} catch {
|
|
903
|
+
signatureValid = false;
|
|
904
|
+
}
|
|
905
|
+
if (!signatureValid) {
|
|
906
|
+
const bytecode = await signer.getCode({ address: payer });
|
|
907
|
+
const isDeployedContract = bytecode && bytecode !== "0x";
|
|
908
|
+
if (!isDeployedContract) {
|
|
909
|
+
return {
|
|
910
|
+
isValid: false,
|
|
911
|
+
invalidReason: "invalid_permit2_signature",
|
|
912
|
+
payer
|
|
913
|
+
};
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
if (options?.simulate === false) {
|
|
917
|
+
return { isValid: true, invalidReason: void 0, payer };
|
|
918
|
+
}
|
|
919
|
+
const facilitatorAddress = (0, import_viem5.getAddress)(permit2Payload.permit2Authorization.witness.facilitator);
|
|
920
|
+
const uptoSettleArgs = buildUptoPermit2SettleArgs(
|
|
921
|
+
permit2Payload,
|
|
922
|
+
BigInt(requirements.amount),
|
|
923
|
+
facilitatorAddress
|
|
924
|
+
);
|
|
925
|
+
const eip2612InfoForSim = extractEip2612GasSponsoringInfo(payload);
|
|
926
|
+
if (eip2612InfoForSim) {
|
|
927
|
+
const fieldResult = validateEip2612PermitForPayment(eip2612InfoForSim, payer, tokenAddress);
|
|
928
|
+
if (!fieldResult.isValid) {
|
|
929
|
+
return { isValid: false, invalidReason: fieldResult.invalidReason, payer };
|
|
930
|
+
}
|
|
931
|
+
const simOk2 = await simulatePermit2SettleWithPermit(
|
|
932
|
+
uptoProxyConfig,
|
|
933
|
+
signer,
|
|
934
|
+
uptoSettleArgs,
|
|
935
|
+
eip2612InfoForSim
|
|
936
|
+
);
|
|
937
|
+
if (!simOk2) {
|
|
938
|
+
return diagnosePermit2SimulationFailure(
|
|
939
|
+
uptoProxyConfig,
|
|
940
|
+
signer,
|
|
941
|
+
tokenAddress,
|
|
942
|
+
permit2Payload,
|
|
943
|
+
requirements.amount
|
|
944
|
+
);
|
|
945
|
+
}
|
|
946
|
+
return { isValid: true, invalidReason: void 0, payer };
|
|
947
|
+
}
|
|
948
|
+
const erc20GasSponsorshipExtension = context?.getExtension(
|
|
949
|
+
ERC20_APPROVAL_GAS_SPONSORING_KEY
|
|
950
|
+
);
|
|
951
|
+
if (erc20GasSponsorshipExtension) {
|
|
952
|
+
const erc20Info = extractErc20ApprovalGasSponsoringInfo(payload);
|
|
953
|
+
if (erc20Info) {
|
|
954
|
+
const fieldResult = await validateErc20ApprovalForPayment(erc20Info, payer, tokenAddress);
|
|
955
|
+
if (!fieldResult.isValid) {
|
|
956
|
+
return { isValid: false, invalidReason: fieldResult.invalidReason, payer };
|
|
957
|
+
}
|
|
958
|
+
const extensionSigner = resolveErc20ApprovalExtensionSigner(
|
|
959
|
+
erc20GasSponsorshipExtension,
|
|
960
|
+
requirements.network
|
|
961
|
+
);
|
|
962
|
+
if (extensionSigner?.simulateTransactions) {
|
|
963
|
+
const simOk2 = await simulatePermit2SettleWithErc20Approval(
|
|
964
|
+
uptoProxyConfig,
|
|
965
|
+
extensionSigner,
|
|
966
|
+
uptoSettleArgs,
|
|
967
|
+
erc20Info
|
|
968
|
+
);
|
|
969
|
+
if (!simOk2) {
|
|
970
|
+
return diagnosePermit2SimulationFailure(
|
|
971
|
+
uptoProxyConfig,
|
|
972
|
+
signer,
|
|
973
|
+
tokenAddress,
|
|
974
|
+
permit2Payload,
|
|
975
|
+
requirements.amount
|
|
976
|
+
);
|
|
977
|
+
}
|
|
978
|
+
return { isValid: true, invalidReason: void 0, payer };
|
|
979
|
+
}
|
|
980
|
+
return checkPermit2Prerequisites(
|
|
981
|
+
uptoProxyConfig,
|
|
982
|
+
signer,
|
|
983
|
+
tokenAddress,
|
|
984
|
+
payer,
|
|
985
|
+
requirements.amount
|
|
986
|
+
);
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
const simOk = await simulatePermit2Settle(uptoProxyConfig, signer, uptoSettleArgs);
|
|
990
|
+
if (!simOk) {
|
|
991
|
+
return diagnosePermit2SimulationFailure(
|
|
992
|
+
uptoProxyConfig,
|
|
993
|
+
signer,
|
|
994
|
+
tokenAddress,
|
|
995
|
+
permit2Payload,
|
|
996
|
+
requirements.amount
|
|
997
|
+
);
|
|
998
|
+
}
|
|
999
|
+
return {
|
|
1000
|
+
isValid: true,
|
|
1001
|
+
invalidReason: void 0,
|
|
1002
|
+
payer
|
|
1003
|
+
};
|
|
1004
|
+
}
|
|
1005
|
+
async function settleUptoPermit2(signer, payload, requirements, permit2Payload, context, config) {
|
|
1006
|
+
const payer = permit2Payload.permit2Authorization.from;
|
|
1007
|
+
const settlementAmount = BigInt(requirements.amount);
|
|
1008
|
+
const verifyRequirements = {
|
|
1009
|
+
...requirements,
|
|
1010
|
+
amount: permit2Payload.permit2Authorization.permitted.amount
|
|
1011
|
+
};
|
|
1012
|
+
const valid = await verifyUptoPermit2(
|
|
1013
|
+
signer,
|
|
1014
|
+
payload,
|
|
1015
|
+
verifyRequirements,
|
|
1016
|
+
permit2Payload,
|
|
1017
|
+
context,
|
|
1018
|
+
{ simulate: config?.simulateInSettle ?? true }
|
|
1019
|
+
);
|
|
1020
|
+
if (!valid.isValid) {
|
|
1021
|
+
return {
|
|
1022
|
+
success: false,
|
|
1023
|
+
network: payload.accepted.network,
|
|
1024
|
+
transaction: "",
|
|
1025
|
+
errorReason: valid.invalidReason ?? "invalid_scheme",
|
|
1026
|
+
payer
|
|
1027
|
+
};
|
|
1028
|
+
}
|
|
1029
|
+
if (settlementAmount === 0n) {
|
|
1030
|
+
return {
|
|
1031
|
+
success: true,
|
|
1032
|
+
transaction: "",
|
|
1033
|
+
network: payload.accepted.network,
|
|
1034
|
+
payer,
|
|
1035
|
+
amount: "0"
|
|
1036
|
+
};
|
|
1037
|
+
}
|
|
1038
|
+
if (settlementAmount > BigInt(permit2Payload.permit2Authorization.permitted.amount)) {
|
|
1039
|
+
return {
|
|
1040
|
+
success: false,
|
|
1041
|
+
network: payload.accepted.network,
|
|
1042
|
+
transaction: "",
|
|
1043
|
+
errorReason: ErrUptoSettlementExceedsAmount,
|
|
1044
|
+
payer
|
|
1045
|
+
};
|
|
1046
|
+
}
|
|
1047
|
+
const facilitatorAddress = (0, import_viem5.getAddress)(permit2Payload.permit2Authorization.witness.facilitator);
|
|
1048
|
+
const eip2612Info = extractEip2612GasSponsoringInfo(payload);
|
|
1049
|
+
if (eip2612Info) {
|
|
1050
|
+
return settleUptoWithEIP2612(
|
|
1051
|
+
signer,
|
|
1052
|
+
payload,
|
|
1053
|
+
permit2Payload,
|
|
1054
|
+
eip2612Info,
|
|
1055
|
+
settlementAmount,
|
|
1056
|
+
facilitatorAddress
|
|
1057
|
+
);
|
|
1058
|
+
}
|
|
1059
|
+
const erc20Info = extractErc20ApprovalGasSponsoringInfo(payload);
|
|
1060
|
+
if (erc20Info) {
|
|
1061
|
+
const erc20GasSponsorshipExtension = context?.getExtension(
|
|
1062
|
+
ERC20_APPROVAL_GAS_SPONSORING_KEY
|
|
1063
|
+
);
|
|
1064
|
+
const extensionSigner = resolveErc20ApprovalExtensionSigner(
|
|
1065
|
+
erc20GasSponsorshipExtension,
|
|
1066
|
+
payload.accepted.network
|
|
1067
|
+
);
|
|
1068
|
+
if (extensionSigner) {
|
|
1069
|
+
return settleUptoWithERC20Approval(
|
|
1070
|
+
extensionSigner,
|
|
1071
|
+
payload,
|
|
1072
|
+
permit2Payload,
|
|
1073
|
+
erc20Info,
|
|
1074
|
+
settlementAmount,
|
|
1075
|
+
facilitatorAddress
|
|
1076
|
+
);
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
return settleUptoDirect(signer, payload, permit2Payload, settlementAmount, facilitatorAddress);
|
|
1080
|
+
}
|
|
1081
|
+
async function settleUptoWithEIP2612(signer, payload, permit2Payload, eip2612Info, settlementAmount, facilitatorAddress) {
|
|
1082
|
+
const payer = permit2Payload.permit2Authorization.from;
|
|
1083
|
+
try {
|
|
1084
|
+
const { v, r, s } = splitEip2612Signature(eip2612Info.signature);
|
|
1085
|
+
const tx = await signer.writeContract({
|
|
1086
|
+
address: uptoProxyConfig.proxyAddress,
|
|
1087
|
+
abi: uptoProxyConfig.proxyABI,
|
|
1088
|
+
functionName: "settleWithPermit",
|
|
1089
|
+
args: [
|
|
1090
|
+
{
|
|
1091
|
+
value: BigInt(eip2612Info.amount),
|
|
1092
|
+
deadline: BigInt(eip2612Info.deadline),
|
|
1093
|
+
r,
|
|
1094
|
+
s,
|
|
1095
|
+
v
|
|
1096
|
+
},
|
|
1097
|
+
...buildUptoPermit2SettleArgs(permit2Payload, settlementAmount, facilitatorAddress)
|
|
1098
|
+
]
|
|
1099
|
+
});
|
|
1100
|
+
const response = await waitAndReturnSettleResponse(signer, tx, payload, payer);
|
|
1101
|
+
return { ...response, amount: settlementAmount.toString() };
|
|
1102
|
+
} catch (error) {
|
|
1103
|
+
return mapSettleError(error, payload, payer);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
async function settleUptoWithERC20Approval(extensionSigner, payload, permit2Payload, erc20Info, settlementAmount, facilitatorAddress) {
|
|
1107
|
+
const payer = permit2Payload.permit2Authorization.from;
|
|
1108
|
+
try {
|
|
1109
|
+
const settleData = (0, import_viem5.encodeFunctionData)({
|
|
1110
|
+
abi: uptoProxyConfig.proxyABI,
|
|
1111
|
+
functionName: "settle",
|
|
1112
|
+
args: buildUptoPermit2SettleArgs(permit2Payload, settlementAmount, facilitatorAddress)
|
|
1113
|
+
});
|
|
1114
|
+
const txHashes = await extensionSigner.sendTransactions([
|
|
1115
|
+
erc20Info.signedTransaction,
|
|
1116
|
+
{ to: uptoProxyConfig.proxyAddress, data: settleData, gas: BigInt(3e5) }
|
|
1117
|
+
]);
|
|
1118
|
+
const settleTxHash = txHashes[txHashes.length - 1];
|
|
1119
|
+
const response = await waitAndReturnSettleResponse(
|
|
1120
|
+
extensionSigner,
|
|
1121
|
+
settleTxHash,
|
|
1122
|
+
payload,
|
|
1123
|
+
payer
|
|
1124
|
+
);
|
|
1125
|
+
return { ...response, amount: settlementAmount.toString() };
|
|
1126
|
+
} catch (error) {
|
|
1127
|
+
return mapSettleError(error, payload, payer);
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
async function settleUptoDirect(signer, payload, permit2Payload, settlementAmount, facilitatorAddress) {
|
|
1131
|
+
const payer = permit2Payload.permit2Authorization.from;
|
|
1132
|
+
try {
|
|
1133
|
+
const tx = await signer.writeContract({
|
|
1134
|
+
address: uptoProxyConfig.proxyAddress,
|
|
1135
|
+
abi: uptoProxyConfig.proxyABI,
|
|
1136
|
+
functionName: "settle",
|
|
1137
|
+
args: buildUptoPermit2SettleArgs(permit2Payload, settlementAmount, facilitatorAddress)
|
|
1138
|
+
});
|
|
1139
|
+
const response = await waitAndReturnSettleResponse(signer, tx, payload, payer);
|
|
1140
|
+
return { ...response, amount: settlementAmount.toString() };
|
|
1141
|
+
} catch (error) {
|
|
1142
|
+
return mapSettleError(error, payload, payer);
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
// src/upto/facilitator/scheme.ts
|
|
1147
|
+
var UptoEvmScheme = class {
|
|
1148
|
+
/**
|
|
1149
|
+
* Creates a new UptoEvmScheme facilitator instance.
|
|
1150
|
+
*
|
|
1151
|
+
* @param signer - The EVM signer for facilitator operations
|
|
1152
|
+
*/
|
|
1153
|
+
constructor(signer) {
|
|
1154
|
+
this.signer = signer;
|
|
1155
|
+
this.scheme = "upto";
|
|
1156
|
+
this.caipFamily = "eip155:*";
|
|
1157
|
+
}
|
|
1158
|
+
/**
|
|
1159
|
+
* Returns extra metadata required by the upto scheme, including the facilitator address.
|
|
1160
|
+
*
|
|
1161
|
+
* @param _ - The network identifier (unused)
|
|
1162
|
+
* @returns Object with facilitatorAddress, or undefined if no signer addresses are available
|
|
1163
|
+
*/
|
|
1164
|
+
getExtra(_) {
|
|
1165
|
+
const addresses = this.signer.getAddresses();
|
|
1166
|
+
if (addresses.length === 0) {
|
|
1167
|
+
return void 0;
|
|
1168
|
+
}
|
|
1169
|
+
return { facilitatorAddress: addresses[Math.floor(Math.random() * addresses.length)] };
|
|
1170
|
+
}
|
|
1171
|
+
/**
|
|
1172
|
+
* Returns the list of facilitator signer addresses for the upto scheme.
|
|
1173
|
+
*
|
|
1174
|
+
* @param _ - The network identifier (unused)
|
|
1175
|
+
* @returns Array of facilitator signer addresses
|
|
1176
|
+
*/
|
|
1177
|
+
getSigners(_) {
|
|
1178
|
+
return [...this.signer.getAddresses()];
|
|
1179
|
+
}
|
|
1180
|
+
/**
|
|
1181
|
+
* Verifies an upto Permit2 payment payload against the given requirements.
|
|
1182
|
+
*
|
|
1183
|
+
* @param payload - The payment payload to verify
|
|
1184
|
+
* @param requirements - The payment requirements to verify against
|
|
1185
|
+
* @param context - Optional facilitator context
|
|
1186
|
+
* @returns Promise resolving to a verification response
|
|
1187
|
+
*/
|
|
1188
|
+
async verify(payload, requirements, context) {
|
|
1189
|
+
const rawPayload = payload.payload;
|
|
1190
|
+
if (!isUptoPermit2Payload(rawPayload)) {
|
|
1191
|
+
return { isValid: false, invalidReason: "unsupported_payload_type", payer: "" };
|
|
1192
|
+
}
|
|
1193
|
+
return verifyUptoPermit2(
|
|
1194
|
+
this.signer,
|
|
1195
|
+
payload,
|
|
1196
|
+
requirements,
|
|
1197
|
+
rawPayload,
|
|
1198
|
+
context
|
|
1199
|
+
);
|
|
1200
|
+
}
|
|
1201
|
+
/**
|
|
1202
|
+
* Settles an upto Permit2 payment on-chain.
|
|
1203
|
+
*
|
|
1204
|
+
* @param payload - The payment payload to settle
|
|
1205
|
+
* @param requirements - The payment requirements
|
|
1206
|
+
* @param context - Optional facilitator context
|
|
1207
|
+
* @returns Promise resolving to a settlement response
|
|
1208
|
+
*/
|
|
1209
|
+
async settle(payload, requirements, context) {
|
|
1210
|
+
const rawPayload = payload.payload;
|
|
1211
|
+
if (!isUptoPermit2Payload(rawPayload)) {
|
|
1212
|
+
return {
|
|
1213
|
+
success: false,
|
|
1214
|
+
network: payload.accepted.network,
|
|
1215
|
+
transaction: "",
|
|
1216
|
+
errorReason: "unsupported_payload_type",
|
|
1217
|
+
payer: ""
|
|
1218
|
+
};
|
|
1219
|
+
}
|
|
1220
|
+
return settleUptoPermit2(
|
|
1221
|
+
this.signer,
|
|
1222
|
+
payload,
|
|
1223
|
+
requirements,
|
|
1224
|
+
rawPayload,
|
|
1225
|
+
context
|
|
1226
|
+
);
|
|
1227
|
+
}
|
|
1228
|
+
};
|
|
1229
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1230
|
+
0 && (module.exports = {
|
|
1231
|
+
UptoEvmScheme
|
|
1232
|
+
});
|
|
1233
|
+
//# sourceMappingURL=index.js.map
|