@appliedblockchain/silentdatarollup-core 1.0.7 → 1.0.9
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/LICENSE +21 -0
- package/README.md +1 -1
- package/dist/{chunk-5VQIOQAW.mjs → chunk-53A5RGL2.mjs} +242 -95
- package/dist/index.d.mts +96 -9
- package/dist/index.d.ts +96 -9
- package/dist/index.js +243 -90
- package/dist/index.mjs +15 -1
- package/dist/tests.js +15 -9
- package/dist/tests.mjs +1 -1
- package/package.json +8 -9
package/dist/index.js
CHANGED
|
@@ -34,12 +34,17 @@ __export(index_exports, {
|
|
|
34
34
|
DEBUG_NAMESPACE: () => DEBUG_NAMESPACE,
|
|
35
35
|
DEBUG_NAMESPACE_SILENTDATA_INTERCEPTOR: () => DEBUG_NAMESPACE_SILENTDATA_INTERCEPTOR,
|
|
36
36
|
DEFAULT_DELEGATE_EXPIRES: () => DEFAULT_DELEGATE_EXPIRES,
|
|
37
|
+
DEFAULT_USER_OPERATION_RECEIPT_LOOKUP_RANGE: () => DEFAULT_USER_OPERATION_RECEIPT_LOOKUP_RANGE,
|
|
37
38
|
DELEGATE_EXPIRATION_THRESHOLD_BUFFER: () => DELEGATE_EXPIRATION_THRESHOLD_BUFFER,
|
|
39
|
+
ENTRYPOINT_ADDRESS: () => ENTRYPOINT_ADDRESS,
|
|
38
40
|
HEADER_DELEGATE: () => HEADER_DELEGATE,
|
|
39
41
|
HEADER_DELEGATE_SIGNATURE: () => HEADER_DELEGATE_SIGNATURE,
|
|
40
42
|
HEADER_EIP712_DELEGATE_SIGNATURE: () => HEADER_EIP712_DELEGATE_SIGNATURE,
|
|
41
43
|
HEADER_EIP712_SIGNATURE: () => HEADER_EIP712_SIGNATURE,
|
|
44
|
+
HEADER_FROM_BLOCK: () => HEADER_FROM_BLOCK,
|
|
42
45
|
HEADER_SIGNATURE: () => HEADER_SIGNATURE,
|
|
46
|
+
HEADER_SIGNATURE_TYPE: () => HEADER_SIGNATURE_TYPE,
|
|
47
|
+
HEADER_SIGNER_SWC: () => HEADER_SIGNER_SWC,
|
|
43
48
|
HEADER_TIMESTAMP: () => HEADER_TIMESTAMP,
|
|
44
49
|
NetworkName: () => NetworkName,
|
|
45
50
|
PRIVATE_EVENT_SIGNATURE: () => PRIVATE_EVENT_SIGNATURE,
|
|
@@ -48,6 +53,8 @@ __export(index_exports, {
|
|
|
48
53
|
SignatureType: () => SignatureType,
|
|
49
54
|
SilentDataRollupBase: () => SilentDataRollupBase,
|
|
50
55
|
SilentDataRollupContract: () => SilentDataRollupContract,
|
|
56
|
+
USER_OPERATION_EVENT_HASH: () => USER_OPERATION_EVENT_HASH,
|
|
57
|
+
USER_OPERATION_EVENT_SIGNATURE: () => USER_OPERATION_EVENT_SIGNATURE,
|
|
51
58
|
WHITELISTED_METHODS: () => WHITELISTED_METHODS,
|
|
52
59
|
calculateEventTypeHash: () => calculateEventTypeHash,
|
|
53
60
|
defaultGetDelegate: () => defaultGetDelegate,
|
|
@@ -62,13 +69,17 @@ module.exports = __toCommonJS(index_exports);
|
|
|
62
69
|
|
|
63
70
|
// src/Base.ts
|
|
64
71
|
var import_debug2 = __toESM(require("debug"));
|
|
72
|
+
var import_ethers4 = require("ethers");
|
|
65
73
|
|
|
66
74
|
// src/constants.ts
|
|
75
|
+
var import_ethers = require("ethers");
|
|
67
76
|
var SIGN_RPC_METHODS = [
|
|
68
77
|
"eth_estimateGas",
|
|
69
78
|
"eth_getProof",
|
|
70
79
|
"eth_getTransactionByHash",
|
|
71
|
-
"eth_getTransactionReceipt"
|
|
80
|
+
"eth_getTransactionReceipt",
|
|
81
|
+
"eth_getUserOperationReceipt",
|
|
82
|
+
"eth_getUserOperationByHash"
|
|
72
83
|
];
|
|
73
84
|
var eip721Domain = {
|
|
74
85
|
name: "Silent Data [Rollup]",
|
|
@@ -84,10 +95,19 @@ var DEBUG_NAMESPACE = "silentdata:core";
|
|
|
84
95
|
var DEBUG_NAMESPACE_SILENTDATA_INTERCEPTOR = "silentdata:interceptor";
|
|
85
96
|
var HEADER_SIGNATURE = "x-signature";
|
|
86
97
|
var HEADER_TIMESTAMP = "x-timestamp";
|
|
98
|
+
var HEADER_SIGNATURE_TYPE = "x-signature-type";
|
|
87
99
|
var HEADER_EIP712_SIGNATURE = "x-eip712-signature";
|
|
88
100
|
var HEADER_DELEGATE = "x-delegate";
|
|
89
101
|
var HEADER_DELEGATE_SIGNATURE = "x-delegate-signature";
|
|
90
102
|
var HEADER_EIP712_DELEGATE_SIGNATURE = "x-eip712-delegate-signature";
|
|
103
|
+
var HEADER_SIGNER_SWC = "x-signer-swc";
|
|
104
|
+
var HEADER_FROM_BLOCK = "x-from-block";
|
|
105
|
+
var ENTRYPOINT_ADDRESS = "0x34F5Bda45f2Ce00B646BD6B19D0F9817b5D8D398";
|
|
106
|
+
var DEFAULT_USER_OPERATION_RECEIPT_LOOKUP_RANGE = 1024;
|
|
107
|
+
var USER_OPERATION_EVENT_SIGNATURE = "UserOperationEvent(bytes32,address,address,uint256,bool,uint256,uint256)";
|
|
108
|
+
var USER_OPERATION_EVENT_HASH = (0, import_ethers.keccak256)(
|
|
109
|
+
(0, import_ethers.toUtf8Bytes)(USER_OPERATION_EVENT_SIGNATURE)
|
|
110
|
+
);
|
|
91
111
|
var DEFAULT_DELEGATE_EXPIRES = 10 * 60 * 60;
|
|
92
112
|
var DELEGATE_EXPIRATION_THRESHOLD_BUFFER = 5;
|
|
93
113
|
var WHITELISTED_METHODS = [
|
|
@@ -103,19 +123,15 @@ var WHITELISTED_METHODS = [
|
|
|
103
123
|
"eth_getCode",
|
|
104
124
|
"eth_getFilterChanges",
|
|
105
125
|
"eth_getFilterLogs",
|
|
106
|
-
"eth_getHashrate",
|
|
107
126
|
"eth_getHeaderByHash",
|
|
108
127
|
"eth_getLogs",
|
|
109
128
|
"eth_getProof",
|
|
110
129
|
"eth_getTransactionByHash",
|
|
111
130
|
"eth_getTransactionCount",
|
|
112
131
|
"eth_getTransactionReceipt",
|
|
113
|
-
"eth_hashrate",
|
|
114
132
|
"eth_maxPriorityFeePerGas",
|
|
115
|
-
"eth_mining",
|
|
116
133
|
"eth_newBlockFilter",
|
|
117
134
|
"eth_sendRawTransaction",
|
|
118
|
-
"eth_submitTransaction",
|
|
119
135
|
"eth_syncing",
|
|
120
136
|
"eth_newFilter",
|
|
121
137
|
"eth_newPendingTransactionFilter",
|
|
@@ -123,21 +139,19 @@ var WHITELISTED_METHODS = [
|
|
|
123
139
|
"net_version",
|
|
124
140
|
"net_peerCount",
|
|
125
141
|
"web3_clientVersion",
|
|
126
|
-
"web3_sha3"
|
|
127
|
-
"zkevm_batchNumber",
|
|
128
|
-
"zkevm_batchNumberByBlockNumber",
|
|
129
|
-
"zkevm_consolidatedBlockNumber",
|
|
130
|
-
"zkevm_estimateGasPrice",
|
|
131
|
-
"zkevm_getBatchByNumber",
|
|
132
|
-
"zkevm_getFullBlockByHash",
|
|
133
|
-
"zkevm_getFullBlockByNumber",
|
|
134
|
-
"zkevm_getLatestGlobalExitRoot",
|
|
135
|
-
"zkevm_isBlockConsolidated",
|
|
136
|
-
"zkevm_isBlockVirtualized",
|
|
137
|
-
"zkevm_verifiedBatchNumber",
|
|
138
|
-
"zkevm_virtualBatchNumber"
|
|
142
|
+
"web3_sha3"
|
|
139
143
|
];
|
|
140
144
|
|
|
145
|
+
// src/privateEvents.ts
|
|
146
|
+
var import_ethers2 = require("ethers");
|
|
147
|
+
var PRIVATE_EVENT_SIGNATURE = "PrivateEvent(address[],bytes32,bytes)";
|
|
148
|
+
var PRIVATE_EVENT_SIGNATURE_HASH = (0, import_ethers2.keccak256)(
|
|
149
|
+
(0, import_ethers2.toUtf8Bytes)(PRIVATE_EVENT_SIGNATURE)
|
|
150
|
+
);
|
|
151
|
+
function calculateEventTypeHash(eventSignature) {
|
|
152
|
+
return (0, import_ethers2.keccak256)((0, import_ethers2.toUtf8Bytes)(eventSignature));
|
|
153
|
+
}
|
|
154
|
+
|
|
141
155
|
// src/types.ts
|
|
142
156
|
var ChainId = /* @__PURE__ */ ((ChainId2) => {
|
|
143
157
|
ChainId2[ChainId2["MAINNET"] = 380929] = "MAINNET";
|
|
@@ -158,7 +172,7 @@ var SignatureType = /* @__PURE__ */ ((SignatureType2) => {
|
|
|
158
172
|
|
|
159
173
|
// src/utils.ts
|
|
160
174
|
var import_debug = __toESM(require("debug"));
|
|
161
|
-
var
|
|
175
|
+
var import_ethers3 = require("ethers");
|
|
162
176
|
var log = (0, import_debug.default)(DEBUG_NAMESPACE);
|
|
163
177
|
function getAuthEIP721Types(payload) {
|
|
164
178
|
return {
|
|
@@ -280,7 +294,7 @@ function isSignableContractCall(payload, contracts) {
|
|
|
280
294
|
return isSignable;
|
|
281
295
|
}
|
|
282
296
|
var defaultGetDelegate = async (provider) => {
|
|
283
|
-
return
|
|
297
|
+
return import_ethers3.Wallet.createRandom();
|
|
284
298
|
};
|
|
285
299
|
var prepareTypedDataPayload = (p) => ({
|
|
286
300
|
...p,
|
|
@@ -300,7 +314,7 @@ var SilentDataRollupBase = class {
|
|
|
300
314
|
this._cachedNetwork = null;
|
|
301
315
|
this.config = {
|
|
302
316
|
...config,
|
|
303
|
-
authSignatureType: config.authSignatureType ?? "
|
|
317
|
+
authSignatureType: config.authSignatureType ?? "EIP191" /* EIP191 */
|
|
304
318
|
};
|
|
305
319
|
this.delegateConfig = this.resolveDelegateConfig(config);
|
|
306
320
|
log2(
|
|
@@ -385,37 +399,67 @@ var SilentDataRollupBase = class {
|
|
|
385
399
|
/**
|
|
386
400
|
* Signs a raw delegate header message.
|
|
387
401
|
* This method can be overridden by extending classes to customize the signing process.
|
|
402
|
+
* The signer implementation decides whether to add EIP-191 prefix or not.
|
|
388
403
|
* @param provider - The provider used for signing
|
|
389
404
|
* @param message - The delegate signer message to be signed
|
|
405
|
+
* @param isSWC - Whether signing for smart wallet contract (EIP-1271)
|
|
390
406
|
* @returns A promise that resolves to the signature string
|
|
391
407
|
*/
|
|
392
|
-
async
|
|
393
|
-
log2("
|
|
394
|
-
|
|
395
|
-
|
|
408
|
+
async signDelegateHeader(provider, message, isSWC) {
|
|
409
|
+
log2("signDelegateHeader: Signing delegate header", message);
|
|
410
|
+
let bytesToSign;
|
|
411
|
+
if (isSWC) {
|
|
412
|
+
const messageHash = (0, import_ethers4.keccak256)((0, import_ethers4.toUtf8Bytes)(message));
|
|
413
|
+
bytesToSign = (0, import_ethers4.getBytes)(messageHash);
|
|
414
|
+
log2("Signing hash bytes for SWC", messageHash);
|
|
415
|
+
} else {
|
|
416
|
+
bytesToSign = (0, import_ethers4.toUtf8Bytes)(message);
|
|
417
|
+
log2("Signing message bytes for EOA", message);
|
|
418
|
+
}
|
|
419
|
+
const signature = await provider.signer.signMessage(bytesToSign);
|
|
420
|
+
log2("signDelegateHeader: Signature generated:", signature);
|
|
396
421
|
return signature;
|
|
397
422
|
}
|
|
398
423
|
/**
|
|
399
424
|
* Signs a typed delegate header message.
|
|
400
425
|
* This method can be overridden by extending classes to customize the signing process.
|
|
401
426
|
* @param provider - The provider used for signing
|
|
427
|
+
* @param chainId - The chain ID
|
|
402
428
|
* @param message - The delegate signer message to be signed
|
|
429
|
+
* @param isSWC - Whether signing for smart wallet contract (EIP-1271)
|
|
403
430
|
* @returns A promise that resolves to the signature string
|
|
404
431
|
*/
|
|
405
|
-
async signTypedDelegateHeader(provider, chainId, message) {
|
|
432
|
+
async signTypedDelegateHeader(provider, chainId, message, isSWC) {
|
|
406
433
|
log2("signTypedDelegateHeader: Signing typed delegate header");
|
|
407
434
|
log2(
|
|
408
435
|
"signTypedDelegateHeader: Typed message:",
|
|
409
436
|
JSON.stringify(message, null, 2)
|
|
410
437
|
);
|
|
438
|
+
const domain = { ...eip721Domain, chainId };
|
|
439
|
+
if (isSWC) {
|
|
440
|
+
const messageHash = import_ethers4.TypedDataEncoder.hash(
|
|
441
|
+
domain,
|
|
442
|
+
delegateEIP721Types,
|
|
443
|
+
message
|
|
444
|
+
);
|
|
445
|
+
const hashBytes = (0, import_ethers4.getBytes)(messageHash);
|
|
446
|
+
const signature2 = await provider.signer.signMessage(hashBytes);
|
|
447
|
+
log2("signTypedDelegateHeader: Typed SWC signature generated:", signature2);
|
|
448
|
+
return signature2;
|
|
449
|
+
}
|
|
411
450
|
const signature = await provider.signer.signTypedData(
|
|
412
|
-
|
|
451
|
+
domain,
|
|
413
452
|
delegateEIP721Types,
|
|
414
453
|
message
|
|
415
454
|
);
|
|
416
455
|
log2("signTypedDelegateHeader: Signature generated:", signature);
|
|
417
456
|
return signature;
|
|
418
457
|
}
|
|
458
|
+
/**
|
|
459
|
+
* IMPORTANT: Return the cached promise (currentPromise), not the resolved value.
|
|
460
|
+
* This ensures multiple concurrent callers share the same in-flight request,
|
|
461
|
+
* preventing redundant API calls.
|
|
462
|
+
*/
|
|
419
463
|
async getDelegateHeaders(provider) {
|
|
420
464
|
log2("Getting delegate headers");
|
|
421
465
|
if (!this.delegateHeadersPromise) {
|
|
@@ -423,7 +467,9 @@ var SilentDataRollupBase = class {
|
|
|
423
467
|
}
|
|
424
468
|
const currentPromise = this.delegateHeadersPromise;
|
|
425
469
|
try {
|
|
426
|
-
|
|
470
|
+
const delegateHeaders = await currentPromise;
|
|
471
|
+
log2("Delegate headers:", JSON.stringify(delegateHeaders, null, 2));
|
|
472
|
+
return currentPromise;
|
|
427
473
|
} catch (error) {
|
|
428
474
|
log2("Error getting delegate headers:", error);
|
|
429
475
|
throw new Error("Failed to get delegate headers");
|
|
@@ -454,13 +500,16 @@ var SilentDataRollupBase = class {
|
|
|
454
500
|
[HEADER_DELEGATE]: JSON.stringify(delegateSignerMessage)
|
|
455
501
|
};
|
|
456
502
|
const chainId = (await this.getCachedNetwork(provider)).chainId.toString();
|
|
503
|
+
const isSWC = !!this.config.smartWalletAddress;
|
|
457
504
|
switch (signatureType) {
|
|
505
|
+
case "EIP191" /* EIP191 */:
|
|
458
506
|
case "RAW" /* Raw */: {
|
|
459
|
-
log2("Generating delegate
|
|
507
|
+
log2("Generating delegate signature");
|
|
460
508
|
const delegateMessageToSign = chainId + JSON.stringify(delegateSignerMessage);
|
|
461
|
-
headers[HEADER_DELEGATE_SIGNATURE] = await this.
|
|
509
|
+
headers[HEADER_DELEGATE_SIGNATURE] = await this.signDelegateHeader(
|
|
462
510
|
provider,
|
|
463
|
-
delegateMessageToSign
|
|
511
|
+
delegateMessageToSign,
|
|
512
|
+
isSWC
|
|
464
513
|
);
|
|
465
514
|
break;
|
|
466
515
|
}
|
|
@@ -469,7 +518,8 @@ var SilentDataRollupBase = class {
|
|
|
469
518
|
headers[HEADER_EIP712_DELEGATE_SIGNATURE] = await this.signTypedDelegateHeader(
|
|
470
519
|
provider,
|
|
471
520
|
chainId,
|
|
472
|
-
delegateSignerMessage
|
|
521
|
+
delegateSignerMessage,
|
|
522
|
+
isSWC
|
|
473
523
|
);
|
|
474
524
|
break;
|
|
475
525
|
default:
|
|
@@ -490,24 +540,57 @@ var SilentDataRollupBase = class {
|
|
|
490
540
|
[HEADER_TIMESTAMP]: xTimestamp
|
|
491
541
|
};
|
|
492
542
|
const chainId = (await this.getCachedNetwork(provider)).chainId.toString();
|
|
493
|
-
const signatureType = this.config.authSignatureType
|
|
543
|
+
const signatureType = this.config.authSignatureType ?? "EIP191" /* EIP191 */;
|
|
544
|
+
const isSWC = !!this.config.smartWalletAddress;
|
|
545
|
+
let payloadToSign = payload;
|
|
546
|
+
const isGetUserOperationReceipt = !Array.isArray(payload) && payload.method === "eth_getUserOperationReceipt";
|
|
547
|
+
if (isGetUserOperationReceipt) {
|
|
548
|
+
log2(
|
|
549
|
+
"Detected eth_getUserOperationReceipt, building custom eth_getLogs payload for signing"
|
|
550
|
+
);
|
|
551
|
+
let fromBlock;
|
|
552
|
+
try {
|
|
553
|
+
fromBlock = await this.getFromBlockForUserOperationReceipt(provider);
|
|
554
|
+
headers[HEADER_FROM_BLOCK] = fromBlock.toString();
|
|
555
|
+
log2(`Added ${HEADER_FROM_BLOCK} header:`, fromBlock.toString());
|
|
556
|
+
} catch (error) {
|
|
557
|
+
log2(
|
|
558
|
+
"Error calculating fromBlock for eth_getUserOperationReceipt:",
|
|
559
|
+
error
|
|
560
|
+
);
|
|
561
|
+
throw new Error(
|
|
562
|
+
"Failed to calculate fromBlock for eth_getUserOperationReceipt"
|
|
563
|
+
);
|
|
564
|
+
}
|
|
565
|
+
payloadToSign = this.buildGetUserOperationReceiptSigningPayload(
|
|
566
|
+
payload,
|
|
567
|
+
fromBlock
|
|
568
|
+
);
|
|
569
|
+
log2(
|
|
570
|
+
"Using custom eth_getLogs payload for signing:",
|
|
571
|
+
JSON.stringify(payloadToSign, null, 2)
|
|
572
|
+
);
|
|
573
|
+
}
|
|
494
574
|
switch (signatureType) {
|
|
575
|
+
case "EIP191" /* EIP191 */:
|
|
495
576
|
case "RAW" /* Raw */:
|
|
496
|
-
log2("Generating auth header
|
|
497
|
-
headers[HEADER_SIGNATURE] = await this.
|
|
577
|
+
log2("Generating auth header signature");
|
|
578
|
+
headers[HEADER_SIGNATURE] = await this.signAuthHeader(
|
|
498
579
|
provider,
|
|
499
|
-
|
|
580
|
+
payloadToSign,
|
|
500
581
|
xTimestamp,
|
|
501
|
-
chainId
|
|
582
|
+
chainId,
|
|
583
|
+
isSWC
|
|
502
584
|
);
|
|
503
585
|
break;
|
|
504
586
|
case "EIP712" /* EIP712 */:
|
|
505
|
-
log2("Generating auth
|
|
506
|
-
headers[HEADER_EIP712_SIGNATURE] = await this.
|
|
587
|
+
log2("Generating auth header typed signature");
|
|
588
|
+
headers[HEADER_EIP712_SIGNATURE] = await this.signTypedAuthHeader(
|
|
507
589
|
provider,
|
|
508
|
-
|
|
590
|
+
payloadToSign,
|
|
509
591
|
xTimestamp,
|
|
510
|
-
chainId
|
|
592
|
+
chainId,
|
|
593
|
+
isSWC
|
|
511
594
|
);
|
|
512
595
|
break;
|
|
513
596
|
default:
|
|
@@ -516,26 +599,53 @@ var SilentDataRollupBase = class {
|
|
|
516
599
|
log2("Auth headers:", JSON.stringify(headers, null, 2));
|
|
517
600
|
return headers;
|
|
518
601
|
}
|
|
519
|
-
|
|
520
|
-
|
|
602
|
+
/**
|
|
603
|
+
* Signs auth header.
|
|
604
|
+
*/
|
|
605
|
+
async signAuthHeader(provider, payload, timestamp, chainId, isSWC) {
|
|
606
|
+
const xMessage = this.prepareMessage(chainId, payload, timestamp);
|
|
521
607
|
const delegateSigner = await this.getDelegateSigner(this);
|
|
522
608
|
const signer = delegateSigner ?? provider.signer;
|
|
523
|
-
const
|
|
524
|
-
|
|
609
|
+
const usingDelegate = !!delegateSigner;
|
|
610
|
+
let bytesToSign;
|
|
611
|
+
if (isSWC && !usingDelegate) {
|
|
612
|
+
const messageHash = (0, import_ethers4.keccak256)((0, import_ethers4.toUtf8Bytes)(xMessage));
|
|
613
|
+
bytesToSign = (0, import_ethers4.getBytes)(messageHash);
|
|
614
|
+
log2("Signing hash bytes for SWC");
|
|
615
|
+
} else {
|
|
616
|
+
bytesToSign = (0, import_ethers4.toUtf8Bytes)(xMessage);
|
|
617
|
+
log2("Signing message bytes for EOA");
|
|
618
|
+
}
|
|
619
|
+
const signature = await signer.signMessage(bytesToSign);
|
|
620
|
+
log2("Message signed raw. Signature:", signature);
|
|
525
621
|
return signature;
|
|
526
622
|
}
|
|
527
|
-
|
|
528
|
-
|
|
623
|
+
/**
|
|
624
|
+
* Signs auth header using typed data signature.
|
|
625
|
+
*/
|
|
626
|
+
async signTypedAuthHeader(provider, payload, timestamp, chainId, isSWC) {
|
|
627
|
+
const message = this.prepareTypedData(payload, timestamp);
|
|
529
628
|
const types = getAuthEIP721Types(payload);
|
|
530
629
|
const delegateSigner = await this.getDelegateSigner(this);
|
|
531
630
|
const signer = delegateSigner ?? provider.signer;
|
|
631
|
+
const usingDelegate = !!delegateSigner;
|
|
532
632
|
const domain = { ...eip721Domain, chainId };
|
|
633
|
+
if (isSWC && !usingDelegate) {
|
|
634
|
+
const messageHash2 = import_ethers4.TypedDataEncoder.hash(domain, types, message);
|
|
635
|
+
log2("EIP-712 hash (SWC without delegate):", messageHash2);
|
|
636
|
+
const hashBytes = (0, import_ethers4.getBytes)(messageHash2);
|
|
637
|
+
const signature2 = await signer.signMessage(hashBytes);
|
|
638
|
+
log2("Message signed with EIP-712 for SWC. Signature:", signature2);
|
|
639
|
+
return signature2;
|
|
640
|
+
}
|
|
533
641
|
log2(
|
|
534
642
|
"Signing typed data",
|
|
535
643
|
JSON.stringify({ message, types, domain }, null, 2)
|
|
536
644
|
);
|
|
645
|
+
const messageHash = import_ethers4.TypedDataEncoder.hash(domain, types, message);
|
|
646
|
+
log2("EIP-712 hash (EOA):", messageHash);
|
|
537
647
|
const signature = await this.signTypedData(signer, domain, types, message);
|
|
538
|
-
log2("Message signed. Signature:", signature);
|
|
648
|
+
log2("Message signed with EIP-712. Signature:", signature);
|
|
539
649
|
return signature;
|
|
540
650
|
}
|
|
541
651
|
/**
|
|
@@ -567,10 +677,81 @@ var SilentDataRollupBase = class {
|
|
|
567
677
|
contractMethodsToSign
|
|
568
678
|
});
|
|
569
679
|
}
|
|
680
|
+
/**
|
|
681
|
+
* Calculates the fromBlock value for eth_getUserOperationReceipt requests.
|
|
682
|
+
* Gets the current block number and subtracts the configured userOperationReceiptLookupRange.
|
|
683
|
+
*
|
|
684
|
+
* IMPORTANT: The bundler strictly validates this value and will reject the request if:
|
|
685
|
+
* - The header is missing
|
|
686
|
+
* - The value is < 0
|
|
687
|
+
* - The value is > current block number
|
|
688
|
+
* - The value is too far back (< currentBlock - userOperationReceiptLookupRange)
|
|
689
|
+
*
|
|
690
|
+
* This method ensures the returned value is always within the valid range:
|
|
691
|
+
* max(0, currentBlock - userOperationReceiptLookupRange) <= fromBlock <= currentBlock
|
|
692
|
+
*
|
|
693
|
+
* @param provider - The provider to use for fetching the current block number
|
|
694
|
+
* @returns A promise that resolves to the fromBlock value as a bigint
|
|
695
|
+
* @throws Error if unable to fetch the current block number
|
|
696
|
+
*/
|
|
697
|
+
async getFromBlockForUserOperationReceipt(provider) {
|
|
698
|
+
const lookupRange = BigInt(
|
|
699
|
+
this.config.userOperationReceiptLookupRange ?? DEFAULT_USER_OPERATION_RECEIPT_LOOKUP_RANGE
|
|
700
|
+
);
|
|
701
|
+
log2("User operation receipt lookup range:", lookupRange.toString());
|
|
702
|
+
let currentBlockNumber;
|
|
703
|
+
if (typeof provider.getBlockNumber === "function") {
|
|
704
|
+
currentBlockNumber = BigInt(await provider.getBlockNumber());
|
|
705
|
+
} else if (typeof provider.request === "function") {
|
|
706
|
+
const blockNumberHex = await provider.request({
|
|
707
|
+
method: "eth_blockNumber",
|
|
708
|
+
params: []
|
|
709
|
+
});
|
|
710
|
+
currentBlockNumber = BigInt(blockNumberHex);
|
|
711
|
+
} else {
|
|
712
|
+
throw new Error(
|
|
713
|
+
"Provider does not support getBlockNumber or request method"
|
|
714
|
+
);
|
|
715
|
+
}
|
|
716
|
+
log2("Current block number:", currentBlockNumber.toString());
|
|
717
|
+
const fromBlock = currentBlockNumber > lookupRange ? currentBlockNumber - lookupRange : 0n;
|
|
718
|
+
log2("Calculated fromBlock:", fromBlock.toString());
|
|
719
|
+
return fromBlock;
|
|
720
|
+
}
|
|
721
|
+
/**
|
|
722
|
+
* Builds a custom eth_getLogs payload for signing when the original request is eth_getUserOperationReceipt.
|
|
723
|
+
* This method can be overridden to customize the payload construction.
|
|
724
|
+
*
|
|
725
|
+
* IMPORTANT: The bundler must reconstruct this exact payload to verify the signature.
|
|
726
|
+
* The bundler should use the same `id` from the original eth_getUserOperationReceipt request
|
|
727
|
+
* when constructing the eth_getLogs request to send to the RPC node.
|
|
728
|
+
*
|
|
729
|
+
* @param payload - The original eth_getUserOperationReceipt payload
|
|
730
|
+
* @param fromBlock - The fromBlock value to use in the eth_getLogs filter
|
|
731
|
+
* @returns A JsonRpcPayload with method 'eth_getLogs' to be used for signing
|
|
732
|
+
*/
|
|
733
|
+
buildGetUserOperationReceiptSigningPayload(payload, fromBlock) {
|
|
734
|
+
return {
|
|
735
|
+
jsonrpc: payload.jsonrpc,
|
|
736
|
+
method: "eth_getLogs",
|
|
737
|
+
params: [
|
|
738
|
+
{
|
|
739
|
+
address: ENTRYPOINT_ADDRESS,
|
|
740
|
+
fromBlock: `0x${fromBlock.toString(16)}`,
|
|
741
|
+
topics: [
|
|
742
|
+
PRIVATE_EVENT_SIGNATURE_HASH,
|
|
743
|
+
USER_OPERATION_EVENT_HASH
|
|
744
|
+
// eventType
|
|
745
|
+
]
|
|
746
|
+
}
|
|
747
|
+
],
|
|
748
|
+
id: payload.id ?? 1
|
|
749
|
+
};
|
|
750
|
+
}
|
|
570
751
|
/**
|
|
571
752
|
* Prepares the message to be signed for the x-signature header.
|
|
572
753
|
*/
|
|
573
|
-
|
|
754
|
+
prepareMessage(chainId, payload, timestamp) {
|
|
574
755
|
log2("Preparing raw message for signing", {
|
|
575
756
|
payload: JSON.stringify(payload, null, 2),
|
|
576
757
|
timestamp
|
|
@@ -583,7 +764,7 @@ var SilentDataRollupBase = class {
|
|
|
583
764
|
/**
|
|
584
765
|
* Prepares the message to be signed for the x-eip712-signature header.
|
|
585
766
|
*/
|
|
586
|
-
|
|
767
|
+
prepareTypedData(payload, timestamp) {
|
|
587
768
|
log2("Preparing payload for signTypedData");
|
|
588
769
|
const preparedPayload = Array.isArray(payload) ? payload.map(prepareTypedDataPayload) : prepareTypedDataPayload(payload);
|
|
589
770
|
const message = {
|
|
@@ -596,35 +777,11 @@ var SilentDataRollupBase = class {
|
|
|
596
777
|
};
|
|
597
778
|
|
|
598
779
|
// src/contract.ts
|
|
599
|
-
var
|
|
600
|
-
var
|
|
601
|
-
constructor(provider, signer) {
|
|
602
|
-
this.provider = provider;
|
|
603
|
-
this.signer = signer;
|
|
604
|
-
}
|
|
605
|
-
async sendTransaction(tx) {
|
|
606
|
-
if (!tx.gasLimit) {
|
|
607
|
-
tx.gasLimit = await this.provider.estimateGas(tx);
|
|
608
|
-
}
|
|
609
|
-
return this.signer.sendTransaction(tx);
|
|
610
|
-
}
|
|
611
|
-
};
|
|
612
|
-
function getContractRunner(runner, provider) {
|
|
613
|
-
const runnerIsSigner = typeof runner.sendTransaction === "function";
|
|
614
|
-
if (!runnerIsSigner) {
|
|
615
|
-
return runner;
|
|
616
|
-
}
|
|
617
|
-
const runnerProviderConstructor = runner.provider?.constructor.name ?? "";
|
|
618
|
-
if (!runnerProviderConstructor.includes("SilentDataRollupProvider")) {
|
|
619
|
-
(0, import_ethers2.assertArgument)(provider, "provider is mandatory", "provider", provider);
|
|
620
|
-
return new CustomContractRunner(provider, runner);
|
|
621
|
-
}
|
|
622
|
-
return new CustomContractRunner(runner.provider, runner);
|
|
623
|
-
}
|
|
624
|
-
var SilentDataRollupContract = class extends import_ethers2.Contract {
|
|
780
|
+
var import_ethers5 = require("ethers");
|
|
781
|
+
var SilentDataRollupContract = class extends import_ethers5.Contract {
|
|
625
782
|
constructor(config) {
|
|
626
|
-
const { address, abi, runner, contractMethodsToSign
|
|
627
|
-
const contractInterface = new
|
|
783
|
+
const { address, abi, runner, contractMethodsToSign } = config;
|
|
784
|
+
const contractInterface = new import_ethers5.Interface(abi);
|
|
628
785
|
contractMethodsToSign.forEach((method) => {
|
|
629
786
|
if (!contractInterface.hasFunction(method)) {
|
|
630
787
|
throw new Error(
|
|
@@ -632,36 +789,30 @@ var SilentDataRollupContract = class extends import_ethers2.Contract {
|
|
|
632
789
|
);
|
|
633
790
|
}
|
|
634
791
|
});
|
|
635
|
-
|
|
636
|
-
super(address, abi, contractRunner);
|
|
792
|
+
super(address, abi, runner);
|
|
637
793
|
const baseProvider = runner.baseProvider || runner.provider?.baseProvider;
|
|
638
794
|
if (typeof baseProvider?.setContract === "function") {
|
|
639
795
|
baseProvider.setContract(this, contractMethodsToSign);
|
|
640
796
|
}
|
|
641
797
|
}
|
|
642
798
|
};
|
|
643
|
-
|
|
644
|
-
// src/privateEvents.ts
|
|
645
|
-
var import_ethers3 = require("ethers");
|
|
646
|
-
var PRIVATE_EVENT_SIGNATURE = "PrivateEvent(address[],bytes32,bytes)";
|
|
647
|
-
var PRIVATE_EVENT_SIGNATURE_HASH = (0, import_ethers3.keccak256)(
|
|
648
|
-
(0, import_ethers3.toUtf8Bytes)(PRIVATE_EVENT_SIGNATURE)
|
|
649
|
-
);
|
|
650
|
-
function calculateEventTypeHash(eventSignature) {
|
|
651
|
-
return (0, import_ethers3.keccak256)((0, import_ethers3.toUtf8Bytes)(eventSignature));
|
|
652
|
-
}
|
|
653
799
|
// Annotate the CommonJS export names for ESM import in node:
|
|
654
800
|
0 && (module.exports = {
|
|
655
801
|
ChainId,
|
|
656
802
|
DEBUG_NAMESPACE,
|
|
657
803
|
DEBUG_NAMESPACE_SILENTDATA_INTERCEPTOR,
|
|
658
804
|
DEFAULT_DELEGATE_EXPIRES,
|
|
805
|
+
DEFAULT_USER_OPERATION_RECEIPT_LOOKUP_RANGE,
|
|
659
806
|
DELEGATE_EXPIRATION_THRESHOLD_BUFFER,
|
|
807
|
+
ENTRYPOINT_ADDRESS,
|
|
660
808
|
HEADER_DELEGATE,
|
|
661
809
|
HEADER_DELEGATE_SIGNATURE,
|
|
662
810
|
HEADER_EIP712_DELEGATE_SIGNATURE,
|
|
663
811
|
HEADER_EIP712_SIGNATURE,
|
|
812
|
+
HEADER_FROM_BLOCK,
|
|
664
813
|
HEADER_SIGNATURE,
|
|
814
|
+
HEADER_SIGNATURE_TYPE,
|
|
815
|
+
HEADER_SIGNER_SWC,
|
|
665
816
|
HEADER_TIMESTAMP,
|
|
666
817
|
NetworkName,
|
|
667
818
|
PRIVATE_EVENT_SIGNATURE,
|
|
@@ -670,6 +821,8 @@ function calculateEventTypeHash(eventSignature) {
|
|
|
670
821
|
SignatureType,
|
|
671
822
|
SilentDataRollupBase,
|
|
672
823
|
SilentDataRollupContract,
|
|
824
|
+
USER_OPERATION_EVENT_HASH,
|
|
825
|
+
USER_OPERATION_EVENT_SIGNATURE,
|
|
673
826
|
WHITELISTED_METHODS,
|
|
674
827
|
calculateEventTypeHash,
|
|
675
828
|
defaultGetDelegate,
|
package/dist/index.mjs
CHANGED
|
@@ -3,12 +3,17 @@ import {
|
|
|
3
3
|
DEBUG_NAMESPACE,
|
|
4
4
|
DEBUG_NAMESPACE_SILENTDATA_INTERCEPTOR,
|
|
5
5
|
DEFAULT_DELEGATE_EXPIRES,
|
|
6
|
+
DEFAULT_USER_OPERATION_RECEIPT_LOOKUP_RANGE,
|
|
6
7
|
DELEGATE_EXPIRATION_THRESHOLD_BUFFER,
|
|
8
|
+
ENTRYPOINT_ADDRESS,
|
|
7
9
|
HEADER_DELEGATE,
|
|
8
10
|
HEADER_DELEGATE_SIGNATURE,
|
|
9
11
|
HEADER_EIP712_DELEGATE_SIGNATURE,
|
|
10
12
|
HEADER_EIP712_SIGNATURE,
|
|
13
|
+
HEADER_FROM_BLOCK,
|
|
11
14
|
HEADER_SIGNATURE,
|
|
15
|
+
HEADER_SIGNATURE_TYPE,
|
|
16
|
+
HEADER_SIGNER_SWC,
|
|
12
17
|
HEADER_TIMESTAMP,
|
|
13
18
|
NetworkName,
|
|
14
19
|
PRIVATE_EVENT_SIGNATURE,
|
|
@@ -17,6 +22,8 @@ import {
|
|
|
17
22
|
SignatureType,
|
|
18
23
|
SilentDataRollupBase,
|
|
19
24
|
SilentDataRollupContract,
|
|
25
|
+
USER_OPERATION_EVENT_HASH,
|
|
26
|
+
USER_OPERATION_EVENT_SIGNATURE,
|
|
20
27
|
WHITELISTED_METHODS,
|
|
21
28
|
calculateEventTypeHash,
|
|
22
29
|
defaultGetDelegate,
|
|
@@ -26,18 +33,23 @@ import {
|
|
|
26
33
|
getAuthHeaders,
|
|
27
34
|
isSignableContractCall,
|
|
28
35
|
prepareTypedDataPayload
|
|
29
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-53A5RGL2.mjs";
|
|
30
37
|
export {
|
|
31
38
|
ChainId,
|
|
32
39
|
DEBUG_NAMESPACE,
|
|
33
40
|
DEBUG_NAMESPACE_SILENTDATA_INTERCEPTOR,
|
|
34
41
|
DEFAULT_DELEGATE_EXPIRES,
|
|
42
|
+
DEFAULT_USER_OPERATION_RECEIPT_LOOKUP_RANGE,
|
|
35
43
|
DELEGATE_EXPIRATION_THRESHOLD_BUFFER,
|
|
44
|
+
ENTRYPOINT_ADDRESS,
|
|
36
45
|
HEADER_DELEGATE,
|
|
37
46
|
HEADER_DELEGATE_SIGNATURE,
|
|
38
47
|
HEADER_EIP712_DELEGATE_SIGNATURE,
|
|
39
48
|
HEADER_EIP712_SIGNATURE,
|
|
49
|
+
HEADER_FROM_BLOCK,
|
|
40
50
|
HEADER_SIGNATURE,
|
|
51
|
+
HEADER_SIGNATURE_TYPE,
|
|
52
|
+
HEADER_SIGNER_SWC,
|
|
41
53
|
HEADER_TIMESTAMP,
|
|
42
54
|
NetworkName,
|
|
43
55
|
PRIVATE_EVENT_SIGNATURE,
|
|
@@ -46,6 +58,8 @@ export {
|
|
|
46
58
|
SignatureType,
|
|
47
59
|
SilentDataRollupBase,
|
|
48
60
|
SilentDataRollupContract,
|
|
61
|
+
USER_OPERATION_EVENT_HASH,
|
|
62
|
+
USER_OPERATION_EVENT_SIGNATURE,
|
|
49
63
|
WHITELISTED_METHODS,
|
|
50
64
|
calculateEventTypeHash,
|
|
51
65
|
defaultGetDelegate,
|
package/dist/tests.js
CHANGED
|
@@ -36,28 +36,34 @@ module.exports = __toCommonJS(tests_exports);
|
|
|
36
36
|
|
|
37
37
|
// src/Base.ts
|
|
38
38
|
var import_debug2 = __toESM(require("debug"));
|
|
39
|
+
var import_ethers4 = require("ethers");
|
|
39
40
|
|
|
40
41
|
// src/constants.ts
|
|
42
|
+
var import_ethers = require("ethers");
|
|
41
43
|
var DEBUG_NAMESPACE = "silentdata:core";
|
|
44
|
+
var USER_OPERATION_EVENT_SIGNATURE = "UserOperationEvent(bytes32,address,address,uint256,bool,uint256,uint256)";
|
|
45
|
+
var USER_OPERATION_EVENT_HASH = (0, import_ethers.keccak256)(
|
|
46
|
+
(0, import_ethers.toUtf8Bytes)(USER_OPERATION_EVENT_SIGNATURE)
|
|
47
|
+
);
|
|
42
48
|
var DEFAULT_DELEGATE_EXPIRES = 10 * 60 * 60;
|
|
43
49
|
|
|
50
|
+
// src/privateEvents.ts
|
|
51
|
+
var import_ethers2 = require("ethers");
|
|
52
|
+
var PRIVATE_EVENT_SIGNATURE = "PrivateEvent(address[],bytes32,bytes)";
|
|
53
|
+
var PRIVATE_EVENT_SIGNATURE_HASH = (0, import_ethers2.keccak256)(
|
|
54
|
+
(0, import_ethers2.toUtf8Bytes)(PRIVATE_EVENT_SIGNATURE)
|
|
55
|
+
);
|
|
56
|
+
|
|
44
57
|
// src/utils.ts
|
|
45
58
|
var import_debug = __toESM(require("debug"));
|
|
46
|
-
var
|
|
59
|
+
var import_ethers3 = require("ethers");
|
|
47
60
|
var log = (0, import_debug.default)(DEBUG_NAMESPACE);
|
|
48
61
|
|
|
49
62
|
// src/Base.ts
|
|
50
63
|
var log2 = (0, import_debug2.default)(DEBUG_NAMESPACE);
|
|
51
64
|
|
|
52
65
|
// src/contract.ts
|
|
53
|
-
var
|
|
54
|
-
|
|
55
|
-
// src/privateEvents.ts
|
|
56
|
-
var import_ethers3 = require("ethers");
|
|
57
|
-
var PRIVATE_EVENT_SIGNATURE = "PrivateEvent(address[],bytes32,bytes)";
|
|
58
|
-
var PRIVATE_EVENT_SIGNATURE_HASH = (0, import_ethers3.keccak256)(
|
|
59
|
-
(0, import_ethers3.toUtf8Bytes)(PRIVATE_EVENT_SIGNATURE)
|
|
60
|
-
);
|
|
66
|
+
var import_ethers5 = require("ethers");
|
|
61
67
|
|
|
62
68
|
// tests/utils/mocked-custom-grpc.ts
|
|
63
69
|
var import_http = __toESM(require("http"));
|
package/dist/tests.mjs
CHANGED