x402z-facilitator 0.0.10 → 0.0.12
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 +23 -3
- package/dist/bootstrap.js +106 -89
- package/dist/chunk-3E55KK5J.mjs +633 -0
- package/dist/chunk-B6WVQBNK.mjs +636 -0
- package/dist/chunk-TDT6WJI7.mjs +711 -0
- package/dist/index.d.mts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +165 -30
- package/dist/index.mjs +1 -1
- package/dist/service/bootstrap.js +165 -30
- package/dist/service/bootstrap.mjs +1 -1
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -5,8 +5,16 @@ import * as http from 'http';
|
|
|
5
5
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
6
6
|
export { startFacilitator } from './service/bootstrap.mjs';
|
|
7
7
|
|
|
8
|
+
type X402zFacilitatorSigner = FacilitatorEvmSigner & {
|
|
9
|
+
simulateContract: (args: {
|
|
10
|
+
address: `0x${string}`;
|
|
11
|
+
abi: readonly unknown[];
|
|
12
|
+
functionName: string;
|
|
13
|
+
args?: readonly unknown[];
|
|
14
|
+
}) => Promise<readonly [boolean[], `0x${string}`[]]>;
|
|
15
|
+
};
|
|
8
16
|
type X402zFacilitatorSchemeOptions = {
|
|
9
|
-
signer:
|
|
17
|
+
signer: X402zFacilitatorSigner;
|
|
10
18
|
batcherAddress: `0x${string}`;
|
|
11
19
|
hashEncryptedAmountInput?: (encryptedAmountInput: `0x${string}`) => `0x${string}`;
|
|
12
20
|
checkUsedNonces?: boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -5,8 +5,16 @@ import * as http from 'http';
|
|
|
5
5
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
6
6
|
export { startFacilitator } from './service/bootstrap.js';
|
|
7
7
|
|
|
8
|
+
type X402zFacilitatorSigner = FacilitatorEvmSigner & {
|
|
9
|
+
simulateContract: (args: {
|
|
10
|
+
address: `0x${string}`;
|
|
11
|
+
abi: readonly unknown[];
|
|
12
|
+
functionName: string;
|
|
13
|
+
args?: readonly unknown[];
|
|
14
|
+
}) => Promise<readonly [boolean[], `0x${string}`[]]>;
|
|
15
|
+
};
|
|
8
16
|
type X402zFacilitatorSchemeOptions = {
|
|
9
|
-
signer:
|
|
17
|
+
signer: X402zFacilitatorSigner;
|
|
10
18
|
batcherAddress: `0x${string}`;
|
|
11
19
|
hashEncryptedAmountInput?: (encryptedAmountInput: `0x${string}`) => `0x${string}`;
|
|
12
20
|
checkUsedNonces?: boolean;
|
package/dist/index.js
CHANGED
|
@@ -210,6 +210,38 @@ var X402zEvmFacilitator = class {
|
|
|
210
210
|
};
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
|
+
try {
|
|
214
|
+
const txRequest = {
|
|
215
|
+
address: this.batcherAddress,
|
|
216
|
+
abi: batcherAbi,
|
|
217
|
+
functionName: "batchConfidentialTransferWithAuthorization",
|
|
218
|
+
args: [
|
|
219
|
+
(0, import_viem.getAddress)(requirements.asset),
|
|
220
|
+
[
|
|
221
|
+
{
|
|
222
|
+
p: confidentialPayload.authorization,
|
|
223
|
+
encryptedAmountInput: confidentialPayload.encryptedAmountInput,
|
|
224
|
+
inputProof: confidentialPayload.inputProof,
|
|
225
|
+
sig: confidentialPayload.signature
|
|
226
|
+
}
|
|
227
|
+
]
|
|
228
|
+
]
|
|
229
|
+
};
|
|
230
|
+
const [successes] = await this.config.signer.simulateContract(txRequest);
|
|
231
|
+
if (!successes[0]) {
|
|
232
|
+
return {
|
|
233
|
+
isValid: false,
|
|
234
|
+
invalidReason: "preflight_failed",
|
|
235
|
+
payer: confidentialPayload.authorization.holder
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
} catch {
|
|
239
|
+
return {
|
|
240
|
+
isValid: false,
|
|
241
|
+
invalidReason: "preflight_failed",
|
|
242
|
+
payer: confidentialPayload.authorization.holder
|
|
243
|
+
};
|
|
244
|
+
}
|
|
213
245
|
return {
|
|
214
246
|
isValid: true,
|
|
215
247
|
payer: confidentialPayload.authorization.holder
|
|
@@ -263,7 +295,7 @@ var X402zEvmFacilitator = class {
|
|
|
263
295
|
}
|
|
264
296
|
}
|
|
265
297
|
async flushBatch(tokenAddress, entries) {
|
|
266
|
-
const
|
|
298
|
+
const buildRequests = (batchEntries2) => batchEntries2.map(({ entry }) => {
|
|
267
299
|
const confidentialPayload = entry.payload.payload;
|
|
268
300
|
return {
|
|
269
301
|
p: confidentialPayload.authorization,
|
|
@@ -272,7 +304,10 @@ var X402zEvmFacilitator = class {
|
|
|
272
304
|
sig: confidentialPayload.signature
|
|
273
305
|
};
|
|
274
306
|
});
|
|
275
|
-
const
|
|
307
|
+
const originalEntries = entries.map((entry, index) => ({ entry, index }));
|
|
308
|
+
let batchEntries = originalEntries;
|
|
309
|
+
let requests = buildRequests(batchEntries);
|
|
310
|
+
let txRequest = {
|
|
276
311
|
address: this.batcherAddress,
|
|
277
312
|
abi: batcherAbi,
|
|
278
313
|
functionName: "batchConfidentialTransferWithAuthorization",
|
|
@@ -287,11 +322,57 @@ var X402zEvmFacilitator = class {
|
|
|
287
322
|
size: requests.length
|
|
288
323
|
});
|
|
289
324
|
}
|
|
325
|
+
try {
|
|
326
|
+
const [successes, transferredHandles] = await this.config.signer.simulateContract(txRequest);
|
|
327
|
+
if (successes.length === batchEntries.length && transferredHandles.length === batchEntries.length) {
|
|
328
|
+
const filtered = [];
|
|
329
|
+
batchEntries.forEach((item, index) => {
|
|
330
|
+
if (successes[index]) {
|
|
331
|
+
filtered.push(item);
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
const confidentialPayload = item.entry.payload.payload;
|
|
335
|
+
item.entry.resolve({
|
|
336
|
+
success: false,
|
|
337
|
+
errorReason: "preflight_failed",
|
|
338
|
+
payer: confidentialPayload.authorization.holder,
|
|
339
|
+
transaction: "",
|
|
340
|
+
network: item.entry.requirements.network,
|
|
341
|
+
batch: { index: item.index, success: false, transferredHandle: transferredHandles[index] }
|
|
342
|
+
});
|
|
343
|
+
});
|
|
344
|
+
if (filtered.length === 0) {
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
batchEntries = filtered;
|
|
348
|
+
requests = buildRequests(batchEntries);
|
|
349
|
+
txRequest = {
|
|
350
|
+
...txRequest,
|
|
351
|
+
args: [tokenAddress, requests]
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
} catch (error) {
|
|
355
|
+
if (process.env.X402Z_DEBUG === "1") {
|
|
356
|
+
console.error("[x402z-facilitator] settle tx error", error);
|
|
357
|
+
}
|
|
358
|
+
for (const entry of entries) {
|
|
359
|
+
const confidentialPayload = entry.payload.payload;
|
|
360
|
+
entry.resolve({
|
|
361
|
+
success: false,
|
|
362
|
+
errorReason: "preflight_failed",
|
|
363
|
+
payer: confidentialPayload.authorization.holder,
|
|
364
|
+
transaction: "",
|
|
365
|
+
network: entry.requirements.network
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
const settleEntries = batchEntries.map((item) => item.entry);
|
|
290
371
|
let txHash;
|
|
291
372
|
try {
|
|
292
373
|
txHash = await this.config.signer.writeContract(txRequest);
|
|
293
374
|
} catch (error) {
|
|
294
|
-
for (const entry of
|
|
375
|
+
for (const entry of settleEntries) {
|
|
295
376
|
const confidentialPayload = entry.payload.payload;
|
|
296
377
|
entry.resolve({
|
|
297
378
|
success: false,
|
|
@@ -313,7 +394,7 @@ var X402zEvmFacilitator = class {
|
|
|
313
394
|
console.debug("[x402z-facilitator] tx receipt", receipt);
|
|
314
395
|
}
|
|
315
396
|
if (receipt.status !== "success") {
|
|
316
|
-
for (const entry of
|
|
397
|
+
for (const entry of settleEntries) {
|
|
317
398
|
const confidentialPayload = entry.payload.payload;
|
|
318
399
|
entry.resolve({
|
|
319
400
|
success: false,
|
|
@@ -327,7 +408,7 @@ var X402zEvmFacilitator = class {
|
|
|
327
408
|
}
|
|
328
409
|
}
|
|
329
410
|
if (!this.waitForReceipt) {
|
|
330
|
-
|
|
411
|
+
settleEntries.forEach((entry) => {
|
|
331
412
|
const confidentialPayload = entry.payload.payload;
|
|
332
413
|
entry.resolve({
|
|
333
414
|
success: true,
|
|
@@ -370,31 +451,27 @@ var X402zEvmFacilitator = class {
|
|
|
370
451
|
}
|
|
371
452
|
}
|
|
372
453
|
}
|
|
373
|
-
|
|
454
|
+
settleEntries.forEach((entry, index) => {
|
|
374
455
|
const confidentialPayload = entry.payload.payload;
|
|
375
456
|
const batchResult = batchResults.get(index);
|
|
376
457
|
if (!batchResult || !batchResult.success) {
|
|
377
|
-
entry.resolve(
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
errorReason: "settlement_failed",
|
|
381
|
-
payer: confidentialPayload.authorization.holder,
|
|
382
|
-
transaction: txHash,
|
|
383
|
-
network: entry.requirements.network,
|
|
384
|
-
...batchResult ? { batch: { index, ...batchResult } } : {}
|
|
385
|
-
}
|
|
386
|
-
);
|
|
387
|
-
return;
|
|
388
|
-
}
|
|
389
|
-
entry.resolve(
|
|
390
|
-
{
|
|
391
|
-
success: true,
|
|
458
|
+
entry.resolve({
|
|
459
|
+
success: false,
|
|
460
|
+
errorReason: "settlement_failed",
|
|
392
461
|
payer: confidentialPayload.authorization.holder,
|
|
393
462
|
transaction: txHash,
|
|
394
463
|
network: entry.requirements.network,
|
|
395
|
-
batch: { index, ...batchResult }
|
|
396
|
-
}
|
|
397
|
-
|
|
464
|
+
...batchResult ? { batch: { index, ...batchResult } } : {}
|
|
465
|
+
});
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
entry.resolve({
|
|
469
|
+
success: true,
|
|
470
|
+
payer: confidentialPayload.authorization.holder,
|
|
471
|
+
transaction: txHash,
|
|
472
|
+
network: entry.requirements.network,
|
|
473
|
+
batch: { index, ...batchResult }
|
|
474
|
+
});
|
|
398
475
|
});
|
|
399
476
|
}
|
|
400
477
|
};
|
|
@@ -493,6 +570,7 @@ function createFacilitatorFromEnv() {
|
|
|
493
570
|
const receiptConfirmations = process.env.FACILITATOR_RECEIPT_CONFIRMATIONS ? Number(process.env.FACILITATOR_RECEIPT_CONFIRMATIONS) : void 0;
|
|
494
571
|
const receiptPollingIntervalMs = process.env.FACILITATOR_RECEIPT_POLLING_INTERVAL_MS ? Number(process.env.FACILITATOR_RECEIPT_POLLING_INTERVAL_MS) : void 0;
|
|
495
572
|
const gasMultiplier = process.env.FACILITATOR_GAS_MULTIPLIER ? Number(process.env.FACILITATOR_GAS_MULTIPLIER) : void 0;
|
|
573
|
+
const feeMultiplier = process.env.FACILITATOR_FEE_MULTIPLIER ? Number(process.env.FACILITATOR_FEE_MULTIPLIER) : void 0;
|
|
496
574
|
const debugEnabled = process.env.X402Z_DEBUG === "1";
|
|
497
575
|
const account = (0, import_accounts.privateKeyToAccount)(privateKey);
|
|
498
576
|
if (debugEnabled) {
|
|
@@ -503,6 +581,7 @@ function createFacilitatorFromEnv() {
|
|
|
503
581
|
waitForReceipt,
|
|
504
582
|
batcherAddress,
|
|
505
583
|
gasMultiplier,
|
|
584
|
+
feeMultiplier,
|
|
506
585
|
batchIntervalMs,
|
|
507
586
|
receipt: {
|
|
508
587
|
confirmations: receiptConfirmations,
|
|
@@ -522,7 +601,7 @@ function createFacilitatorFromEnv() {
|
|
|
522
601
|
},
|
|
523
602
|
transport: (0, import_viem2.http)(rpcUrl)
|
|
524
603
|
}).extend(import_viem2.publicActions);
|
|
525
|
-
const
|
|
604
|
+
const baseSigner = (0, import_evm.toFacilitatorEvmSigner)({
|
|
526
605
|
address: account.address,
|
|
527
606
|
readContract: (args) => client.readContract({
|
|
528
607
|
...args,
|
|
@@ -532,6 +611,8 @@ function createFacilitatorFromEnv() {
|
|
|
532
611
|
verifyTypedData: (args) => client.verifyTypedData(args),
|
|
533
612
|
writeContract: async (args) => {
|
|
534
613
|
let gas;
|
|
614
|
+
let maxFeePerGas;
|
|
615
|
+
let maxPriorityFeePerGas;
|
|
535
616
|
if (gasMultiplier && gasMultiplier > 0) {
|
|
536
617
|
try {
|
|
537
618
|
const estimated = await client.estimateContractGas({
|
|
@@ -549,20 +630,74 @@ function createFacilitatorFromEnv() {
|
|
|
549
630
|
}
|
|
550
631
|
}
|
|
551
632
|
}
|
|
633
|
+
if (feeMultiplier && feeMultiplier > 0) {
|
|
634
|
+
try {
|
|
635
|
+
const fees = await client.estimateFeesPerGas();
|
|
636
|
+
if (fees.maxFeePerGas) {
|
|
637
|
+
const scale = BigInt(Math.round(feeMultiplier * 1e3));
|
|
638
|
+
maxFeePerGas = fees.maxFeePerGas * scale / 1000n;
|
|
639
|
+
}
|
|
640
|
+
if (fees.maxPriorityFeePerGas) {
|
|
641
|
+
const scale = BigInt(Math.round(feeMultiplier * 1e3));
|
|
642
|
+
maxPriorityFeePerGas = fees.maxPriorityFeePerGas * scale / 1000n;
|
|
643
|
+
}
|
|
644
|
+
} catch (error) {
|
|
645
|
+
if (debugEnabled) {
|
|
646
|
+
console.debug("[x402z-facilitator] fee estimate failed", error);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
}
|
|
552
650
|
return client.writeContract({
|
|
553
651
|
...args,
|
|
554
652
|
args: args.args || [],
|
|
555
|
-
...gas ? { gas } : {}
|
|
653
|
+
...gas ? { gas } : {},
|
|
654
|
+
...maxFeePerGas ? { maxFeePerGas } : {},
|
|
655
|
+
...maxPriorityFeePerGas ? { maxPriorityFeePerGas } : {}
|
|
556
656
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
557
657
|
});
|
|
558
658
|
},
|
|
559
|
-
sendTransaction: (args) =>
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
659
|
+
sendTransaction: async (args) => {
|
|
660
|
+
let maxFeePerGas;
|
|
661
|
+
let maxPriorityFeePerGas;
|
|
662
|
+
if (feeMultiplier && feeMultiplier > 0) {
|
|
663
|
+
try {
|
|
664
|
+
const fees = await client.estimateFeesPerGas();
|
|
665
|
+
if (fees.maxFeePerGas) {
|
|
666
|
+
const scale = BigInt(Math.round(feeMultiplier * 1e3));
|
|
667
|
+
maxFeePerGas = fees.maxFeePerGas * scale / 1000n;
|
|
668
|
+
}
|
|
669
|
+
if (fees.maxPriorityFeePerGas) {
|
|
670
|
+
const scale = BigInt(Math.round(feeMultiplier * 1e3));
|
|
671
|
+
maxPriorityFeePerGas = fees.maxPriorityFeePerGas * scale / 1000n;
|
|
672
|
+
}
|
|
673
|
+
} catch (error) {
|
|
674
|
+
if (debugEnabled) {
|
|
675
|
+
console.debug("[x402z-facilitator] fee estimate failed", error);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
return client.sendTransaction({
|
|
680
|
+
to: args.to,
|
|
681
|
+
data: args.data,
|
|
682
|
+
...maxFeePerGas ? { maxFeePerGas } : {},
|
|
683
|
+
...maxPriorityFeePerGas ? { maxPriorityFeePerGas } : {}
|
|
684
|
+
});
|
|
685
|
+
},
|
|
563
686
|
waitForTransactionReceipt: (args) => client.waitForTransactionReceipt(args),
|
|
564
687
|
getCode: (args) => client.getCode(args)
|
|
565
688
|
});
|
|
689
|
+
const signer = {
|
|
690
|
+
...baseSigner,
|
|
691
|
+
simulateContract: async (args) => {
|
|
692
|
+
const result = await client.simulateContract({
|
|
693
|
+
...args,
|
|
694
|
+
args: args.args || [],
|
|
695
|
+
account
|
|
696
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
697
|
+
});
|
|
698
|
+
return result.result;
|
|
699
|
+
}
|
|
700
|
+
};
|
|
566
701
|
const facilitator = new import_facilitator.x402Facilitator();
|
|
567
702
|
for (const network of networks) {
|
|
568
703
|
facilitator.register(
|
package/dist/index.mjs
CHANGED
|
@@ -262,6 +262,38 @@ var X402zEvmFacilitator = class {
|
|
|
262
262
|
};
|
|
263
263
|
}
|
|
264
264
|
}
|
|
265
|
+
try {
|
|
266
|
+
const txRequest = {
|
|
267
|
+
address: this.batcherAddress,
|
|
268
|
+
abi: batcherAbi,
|
|
269
|
+
functionName: "batchConfidentialTransferWithAuthorization",
|
|
270
|
+
args: [
|
|
271
|
+
(0, import_viem.getAddress)(requirements.asset),
|
|
272
|
+
[
|
|
273
|
+
{
|
|
274
|
+
p: confidentialPayload.authorization,
|
|
275
|
+
encryptedAmountInput: confidentialPayload.encryptedAmountInput,
|
|
276
|
+
inputProof: confidentialPayload.inputProof,
|
|
277
|
+
sig: confidentialPayload.signature
|
|
278
|
+
}
|
|
279
|
+
]
|
|
280
|
+
]
|
|
281
|
+
};
|
|
282
|
+
const [successes] = await this.config.signer.simulateContract(txRequest);
|
|
283
|
+
if (!successes[0]) {
|
|
284
|
+
return {
|
|
285
|
+
isValid: false,
|
|
286
|
+
invalidReason: "preflight_failed",
|
|
287
|
+
payer: confidentialPayload.authorization.holder
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
} catch {
|
|
291
|
+
return {
|
|
292
|
+
isValid: false,
|
|
293
|
+
invalidReason: "preflight_failed",
|
|
294
|
+
payer: confidentialPayload.authorization.holder
|
|
295
|
+
};
|
|
296
|
+
}
|
|
265
297
|
return {
|
|
266
298
|
isValid: true,
|
|
267
299
|
payer: confidentialPayload.authorization.holder
|
|
@@ -315,7 +347,7 @@ var X402zEvmFacilitator = class {
|
|
|
315
347
|
}
|
|
316
348
|
}
|
|
317
349
|
async flushBatch(tokenAddress, entries) {
|
|
318
|
-
const
|
|
350
|
+
const buildRequests = (batchEntries2) => batchEntries2.map(({ entry }) => {
|
|
319
351
|
const confidentialPayload = entry.payload.payload;
|
|
320
352
|
return {
|
|
321
353
|
p: confidentialPayload.authorization,
|
|
@@ -324,7 +356,10 @@ var X402zEvmFacilitator = class {
|
|
|
324
356
|
sig: confidentialPayload.signature
|
|
325
357
|
};
|
|
326
358
|
});
|
|
327
|
-
const
|
|
359
|
+
const originalEntries = entries.map((entry, index) => ({ entry, index }));
|
|
360
|
+
let batchEntries = originalEntries;
|
|
361
|
+
let requests = buildRequests(batchEntries);
|
|
362
|
+
let txRequest = {
|
|
328
363
|
address: this.batcherAddress,
|
|
329
364
|
abi: batcherAbi,
|
|
330
365
|
functionName: "batchConfidentialTransferWithAuthorization",
|
|
@@ -339,11 +374,57 @@ var X402zEvmFacilitator = class {
|
|
|
339
374
|
size: requests.length
|
|
340
375
|
});
|
|
341
376
|
}
|
|
377
|
+
try {
|
|
378
|
+
const [successes, transferredHandles] = await this.config.signer.simulateContract(txRequest);
|
|
379
|
+
if (successes.length === batchEntries.length && transferredHandles.length === batchEntries.length) {
|
|
380
|
+
const filtered = [];
|
|
381
|
+
batchEntries.forEach((item, index) => {
|
|
382
|
+
if (successes[index]) {
|
|
383
|
+
filtered.push(item);
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
const confidentialPayload = item.entry.payload.payload;
|
|
387
|
+
item.entry.resolve({
|
|
388
|
+
success: false,
|
|
389
|
+
errorReason: "preflight_failed",
|
|
390
|
+
payer: confidentialPayload.authorization.holder,
|
|
391
|
+
transaction: "",
|
|
392
|
+
network: item.entry.requirements.network,
|
|
393
|
+
batch: { index: item.index, success: false, transferredHandle: transferredHandles[index] }
|
|
394
|
+
});
|
|
395
|
+
});
|
|
396
|
+
if (filtered.length === 0) {
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
batchEntries = filtered;
|
|
400
|
+
requests = buildRequests(batchEntries);
|
|
401
|
+
txRequest = {
|
|
402
|
+
...txRequest,
|
|
403
|
+
args: [tokenAddress, requests]
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
} catch (error) {
|
|
407
|
+
if (process.env.X402Z_DEBUG === "1") {
|
|
408
|
+
console.error("[x402z-facilitator] settle tx error", error);
|
|
409
|
+
}
|
|
410
|
+
for (const entry of entries) {
|
|
411
|
+
const confidentialPayload = entry.payload.payload;
|
|
412
|
+
entry.resolve({
|
|
413
|
+
success: false,
|
|
414
|
+
errorReason: "preflight_failed",
|
|
415
|
+
payer: confidentialPayload.authorization.holder,
|
|
416
|
+
transaction: "",
|
|
417
|
+
network: entry.requirements.network
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
const settleEntries = batchEntries.map((item) => item.entry);
|
|
342
423
|
let txHash;
|
|
343
424
|
try {
|
|
344
425
|
txHash = await this.config.signer.writeContract(txRequest);
|
|
345
426
|
} catch (error) {
|
|
346
|
-
for (const entry of
|
|
427
|
+
for (const entry of settleEntries) {
|
|
347
428
|
const confidentialPayload = entry.payload.payload;
|
|
348
429
|
entry.resolve({
|
|
349
430
|
success: false,
|
|
@@ -365,7 +446,7 @@ var X402zEvmFacilitator = class {
|
|
|
365
446
|
console.debug("[x402z-facilitator] tx receipt", receipt);
|
|
366
447
|
}
|
|
367
448
|
if (receipt.status !== "success") {
|
|
368
|
-
for (const entry of
|
|
449
|
+
for (const entry of settleEntries) {
|
|
369
450
|
const confidentialPayload = entry.payload.payload;
|
|
370
451
|
entry.resolve({
|
|
371
452
|
success: false,
|
|
@@ -379,7 +460,7 @@ var X402zEvmFacilitator = class {
|
|
|
379
460
|
}
|
|
380
461
|
}
|
|
381
462
|
if (!this.waitForReceipt) {
|
|
382
|
-
|
|
463
|
+
settleEntries.forEach((entry) => {
|
|
383
464
|
const confidentialPayload = entry.payload.payload;
|
|
384
465
|
entry.resolve({
|
|
385
466
|
success: true,
|
|
@@ -422,31 +503,27 @@ var X402zEvmFacilitator = class {
|
|
|
422
503
|
}
|
|
423
504
|
}
|
|
424
505
|
}
|
|
425
|
-
|
|
506
|
+
settleEntries.forEach((entry, index) => {
|
|
426
507
|
const confidentialPayload = entry.payload.payload;
|
|
427
508
|
const batchResult = batchResults.get(index);
|
|
428
509
|
if (!batchResult || !batchResult.success) {
|
|
429
|
-
entry.resolve(
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
errorReason: "settlement_failed",
|
|
433
|
-
payer: confidentialPayload.authorization.holder,
|
|
434
|
-
transaction: txHash,
|
|
435
|
-
network: entry.requirements.network,
|
|
436
|
-
...batchResult ? { batch: { index, ...batchResult } } : {}
|
|
437
|
-
}
|
|
438
|
-
);
|
|
439
|
-
return;
|
|
440
|
-
}
|
|
441
|
-
entry.resolve(
|
|
442
|
-
{
|
|
443
|
-
success: true,
|
|
510
|
+
entry.resolve({
|
|
511
|
+
success: false,
|
|
512
|
+
errorReason: "settlement_failed",
|
|
444
513
|
payer: confidentialPayload.authorization.holder,
|
|
445
514
|
transaction: txHash,
|
|
446
515
|
network: entry.requirements.network,
|
|
447
|
-
batch: { index, ...batchResult }
|
|
448
|
-
}
|
|
449
|
-
|
|
516
|
+
...batchResult ? { batch: { index, ...batchResult } } : {}
|
|
517
|
+
});
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
entry.resolve({
|
|
521
|
+
success: true,
|
|
522
|
+
payer: confidentialPayload.authorization.holder,
|
|
523
|
+
transaction: txHash,
|
|
524
|
+
network: entry.requirements.network,
|
|
525
|
+
batch: { index, ...batchResult }
|
|
526
|
+
});
|
|
450
527
|
});
|
|
451
528
|
}
|
|
452
529
|
};
|
|
@@ -474,6 +551,7 @@ function createFacilitatorFromEnv() {
|
|
|
474
551
|
const receiptConfirmations = process.env.FACILITATOR_RECEIPT_CONFIRMATIONS ? Number(process.env.FACILITATOR_RECEIPT_CONFIRMATIONS) : void 0;
|
|
475
552
|
const receiptPollingIntervalMs = process.env.FACILITATOR_RECEIPT_POLLING_INTERVAL_MS ? Number(process.env.FACILITATOR_RECEIPT_POLLING_INTERVAL_MS) : void 0;
|
|
476
553
|
const gasMultiplier = process.env.FACILITATOR_GAS_MULTIPLIER ? Number(process.env.FACILITATOR_GAS_MULTIPLIER) : void 0;
|
|
554
|
+
const feeMultiplier = process.env.FACILITATOR_FEE_MULTIPLIER ? Number(process.env.FACILITATOR_FEE_MULTIPLIER) : void 0;
|
|
477
555
|
const debugEnabled = process.env.X402Z_DEBUG === "1";
|
|
478
556
|
const account = (0, import_accounts.privateKeyToAccount)(privateKey);
|
|
479
557
|
if (debugEnabled) {
|
|
@@ -484,6 +562,7 @@ function createFacilitatorFromEnv() {
|
|
|
484
562
|
waitForReceipt,
|
|
485
563
|
batcherAddress,
|
|
486
564
|
gasMultiplier,
|
|
565
|
+
feeMultiplier,
|
|
487
566
|
batchIntervalMs,
|
|
488
567
|
receipt: {
|
|
489
568
|
confirmations: receiptConfirmations,
|
|
@@ -503,7 +582,7 @@ function createFacilitatorFromEnv() {
|
|
|
503
582
|
},
|
|
504
583
|
transport: (0, import_viem2.http)(rpcUrl)
|
|
505
584
|
}).extend(import_viem2.publicActions);
|
|
506
|
-
const
|
|
585
|
+
const baseSigner = (0, import_evm.toFacilitatorEvmSigner)({
|
|
507
586
|
address: account.address,
|
|
508
587
|
readContract: (args) => client.readContract({
|
|
509
588
|
...args,
|
|
@@ -513,6 +592,8 @@ function createFacilitatorFromEnv() {
|
|
|
513
592
|
verifyTypedData: (args) => client.verifyTypedData(args),
|
|
514
593
|
writeContract: async (args) => {
|
|
515
594
|
let gas;
|
|
595
|
+
let maxFeePerGas;
|
|
596
|
+
let maxPriorityFeePerGas;
|
|
516
597
|
if (gasMultiplier && gasMultiplier > 0) {
|
|
517
598
|
try {
|
|
518
599
|
const estimated = await client.estimateContractGas({
|
|
@@ -530,20 +611,74 @@ function createFacilitatorFromEnv() {
|
|
|
530
611
|
}
|
|
531
612
|
}
|
|
532
613
|
}
|
|
614
|
+
if (feeMultiplier && feeMultiplier > 0) {
|
|
615
|
+
try {
|
|
616
|
+
const fees = await client.estimateFeesPerGas();
|
|
617
|
+
if (fees.maxFeePerGas) {
|
|
618
|
+
const scale = BigInt(Math.round(feeMultiplier * 1e3));
|
|
619
|
+
maxFeePerGas = fees.maxFeePerGas * scale / 1000n;
|
|
620
|
+
}
|
|
621
|
+
if (fees.maxPriorityFeePerGas) {
|
|
622
|
+
const scale = BigInt(Math.round(feeMultiplier * 1e3));
|
|
623
|
+
maxPriorityFeePerGas = fees.maxPriorityFeePerGas * scale / 1000n;
|
|
624
|
+
}
|
|
625
|
+
} catch (error) {
|
|
626
|
+
if (debugEnabled) {
|
|
627
|
+
console.debug("[x402z-facilitator] fee estimate failed", error);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
533
631
|
return client.writeContract({
|
|
534
632
|
...args,
|
|
535
633
|
args: args.args || [],
|
|
536
|
-
...gas ? { gas } : {}
|
|
634
|
+
...gas ? { gas } : {},
|
|
635
|
+
...maxFeePerGas ? { maxFeePerGas } : {},
|
|
636
|
+
...maxPriorityFeePerGas ? { maxPriorityFeePerGas } : {}
|
|
537
637
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
538
638
|
});
|
|
539
639
|
},
|
|
540
|
-
sendTransaction: (args) =>
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
640
|
+
sendTransaction: async (args) => {
|
|
641
|
+
let maxFeePerGas;
|
|
642
|
+
let maxPriorityFeePerGas;
|
|
643
|
+
if (feeMultiplier && feeMultiplier > 0) {
|
|
644
|
+
try {
|
|
645
|
+
const fees = await client.estimateFeesPerGas();
|
|
646
|
+
if (fees.maxFeePerGas) {
|
|
647
|
+
const scale = BigInt(Math.round(feeMultiplier * 1e3));
|
|
648
|
+
maxFeePerGas = fees.maxFeePerGas * scale / 1000n;
|
|
649
|
+
}
|
|
650
|
+
if (fees.maxPriorityFeePerGas) {
|
|
651
|
+
const scale = BigInt(Math.round(feeMultiplier * 1e3));
|
|
652
|
+
maxPriorityFeePerGas = fees.maxPriorityFeePerGas * scale / 1000n;
|
|
653
|
+
}
|
|
654
|
+
} catch (error) {
|
|
655
|
+
if (debugEnabled) {
|
|
656
|
+
console.debug("[x402z-facilitator] fee estimate failed", error);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
return client.sendTransaction({
|
|
661
|
+
to: args.to,
|
|
662
|
+
data: args.data,
|
|
663
|
+
...maxFeePerGas ? { maxFeePerGas } : {},
|
|
664
|
+
...maxPriorityFeePerGas ? { maxPriorityFeePerGas } : {}
|
|
665
|
+
});
|
|
666
|
+
},
|
|
544
667
|
waitForTransactionReceipt: (args) => client.waitForTransactionReceipt(args),
|
|
545
668
|
getCode: (args) => client.getCode(args)
|
|
546
669
|
});
|
|
670
|
+
const signer = {
|
|
671
|
+
...baseSigner,
|
|
672
|
+
simulateContract: async (args) => {
|
|
673
|
+
const result = await client.simulateContract({
|
|
674
|
+
...args,
|
|
675
|
+
args: args.args || [],
|
|
676
|
+
account
|
|
677
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
678
|
+
});
|
|
679
|
+
return result.result;
|
|
680
|
+
}
|
|
681
|
+
};
|
|
547
682
|
const facilitator = new import_facilitator.x402Facilitator();
|
|
548
683
|
for (const network of networks) {
|
|
549
684
|
facilitator.register(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "x402z-facilitator",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"module": "./dist/index.mjs",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"@x402/core": "^2.0.0",
|
|
12
12
|
"@x402/evm": "^2.0.0",
|
|
13
13
|
"viem": "^2.39.3",
|
|
14
|
-
"x402z-shared": "0.0.
|
|
14
|
+
"x402z-shared": "0.0.19"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
17
|
"jest": "^29.7.0",
|