@appliedblockchain/silentdatarollup-core 1.0.8 → 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/dist/{chunk-5JD3GAHS.mjs → chunk-53A5RGL2.mjs} +238 -64
- package/dist/index.d.mts +94 -7
- package/dist/index.d.ts +94 -7
- package/dist/index.js +238 -63
- package/dist/index.mjs +13 -1
- package/dist/tests.js +15 -9
- package/dist/tests.mjs +1 -1
- package/package.json +7 -8
package/dist/index.js
CHANGED
|
@@ -34,12 +34,16 @@ __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,
|
|
43
47
|
HEADER_SIGNER_SWC: () => HEADER_SIGNER_SWC,
|
|
44
48
|
HEADER_TIMESTAMP: () => HEADER_TIMESTAMP,
|
|
45
49
|
NetworkName: () => NetworkName,
|
|
@@ -49,6 +53,8 @@ __export(index_exports, {
|
|
|
49
53
|
SignatureType: () => SignatureType,
|
|
50
54
|
SilentDataRollupBase: () => SilentDataRollupBase,
|
|
51
55
|
SilentDataRollupContract: () => SilentDataRollupContract,
|
|
56
|
+
USER_OPERATION_EVENT_HASH: () => USER_OPERATION_EVENT_HASH,
|
|
57
|
+
USER_OPERATION_EVENT_SIGNATURE: () => USER_OPERATION_EVENT_SIGNATURE,
|
|
52
58
|
WHITELISTED_METHODS: () => WHITELISTED_METHODS,
|
|
53
59
|
calculateEventTypeHash: () => calculateEventTypeHash,
|
|
54
60
|
defaultGetDelegate: () => defaultGetDelegate,
|
|
@@ -63,13 +69,17 @@ module.exports = __toCommonJS(index_exports);
|
|
|
63
69
|
|
|
64
70
|
// src/Base.ts
|
|
65
71
|
var import_debug2 = __toESM(require("debug"));
|
|
72
|
+
var import_ethers4 = require("ethers");
|
|
66
73
|
|
|
67
74
|
// src/constants.ts
|
|
75
|
+
var import_ethers = require("ethers");
|
|
68
76
|
var SIGN_RPC_METHODS = [
|
|
69
77
|
"eth_estimateGas",
|
|
70
78
|
"eth_getProof",
|
|
71
79
|
"eth_getTransactionByHash",
|
|
72
|
-
"eth_getTransactionReceipt"
|
|
80
|
+
"eth_getTransactionReceipt",
|
|
81
|
+
"eth_getUserOperationReceipt",
|
|
82
|
+
"eth_getUserOperationByHash"
|
|
73
83
|
];
|
|
74
84
|
var eip721Domain = {
|
|
75
85
|
name: "Silent Data [Rollup]",
|
|
@@ -85,11 +95,19 @@ var DEBUG_NAMESPACE = "silentdata:core";
|
|
|
85
95
|
var DEBUG_NAMESPACE_SILENTDATA_INTERCEPTOR = "silentdata:interceptor";
|
|
86
96
|
var HEADER_SIGNATURE = "x-signature";
|
|
87
97
|
var HEADER_TIMESTAMP = "x-timestamp";
|
|
98
|
+
var HEADER_SIGNATURE_TYPE = "x-signature-type";
|
|
88
99
|
var HEADER_EIP712_SIGNATURE = "x-eip712-signature";
|
|
89
100
|
var HEADER_DELEGATE = "x-delegate";
|
|
90
101
|
var HEADER_DELEGATE_SIGNATURE = "x-delegate-signature";
|
|
91
102
|
var HEADER_EIP712_DELEGATE_SIGNATURE = "x-eip712-delegate-signature";
|
|
92
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
|
+
);
|
|
93
111
|
var DEFAULT_DELEGATE_EXPIRES = 10 * 60 * 60;
|
|
94
112
|
var DELEGATE_EXPIRATION_THRESHOLD_BUFFER = 5;
|
|
95
113
|
var WHITELISTED_METHODS = [
|
|
@@ -105,19 +123,15 @@ var WHITELISTED_METHODS = [
|
|
|
105
123
|
"eth_getCode",
|
|
106
124
|
"eth_getFilterChanges",
|
|
107
125
|
"eth_getFilterLogs",
|
|
108
|
-
"eth_getHashrate",
|
|
109
126
|
"eth_getHeaderByHash",
|
|
110
127
|
"eth_getLogs",
|
|
111
128
|
"eth_getProof",
|
|
112
129
|
"eth_getTransactionByHash",
|
|
113
130
|
"eth_getTransactionCount",
|
|
114
131
|
"eth_getTransactionReceipt",
|
|
115
|
-
"eth_hashrate",
|
|
116
132
|
"eth_maxPriorityFeePerGas",
|
|
117
|
-
"eth_mining",
|
|
118
133
|
"eth_newBlockFilter",
|
|
119
134
|
"eth_sendRawTransaction",
|
|
120
|
-
"eth_submitTransaction",
|
|
121
135
|
"eth_syncing",
|
|
122
136
|
"eth_newFilter",
|
|
123
137
|
"eth_newPendingTransactionFilter",
|
|
@@ -125,21 +139,19 @@ var WHITELISTED_METHODS = [
|
|
|
125
139
|
"net_version",
|
|
126
140
|
"net_peerCount",
|
|
127
141
|
"web3_clientVersion",
|
|
128
|
-
"web3_sha3"
|
|
129
|
-
"zkevm_batchNumber",
|
|
130
|
-
"zkevm_batchNumberByBlockNumber",
|
|
131
|
-
"zkevm_consolidatedBlockNumber",
|
|
132
|
-
"zkevm_estimateGasPrice",
|
|
133
|
-
"zkevm_getBatchByNumber",
|
|
134
|
-
"zkevm_getFullBlockByHash",
|
|
135
|
-
"zkevm_getFullBlockByNumber",
|
|
136
|
-
"zkevm_getLatestGlobalExitRoot",
|
|
137
|
-
"zkevm_isBlockConsolidated",
|
|
138
|
-
"zkevm_isBlockVirtualized",
|
|
139
|
-
"zkevm_verifiedBatchNumber",
|
|
140
|
-
"zkevm_virtualBatchNumber"
|
|
142
|
+
"web3_sha3"
|
|
141
143
|
];
|
|
142
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
|
+
|
|
143
155
|
// src/types.ts
|
|
144
156
|
var ChainId = /* @__PURE__ */ ((ChainId2) => {
|
|
145
157
|
ChainId2[ChainId2["MAINNET"] = 380929] = "MAINNET";
|
|
@@ -160,7 +172,7 @@ var SignatureType = /* @__PURE__ */ ((SignatureType2) => {
|
|
|
160
172
|
|
|
161
173
|
// src/utils.ts
|
|
162
174
|
var import_debug = __toESM(require("debug"));
|
|
163
|
-
var
|
|
175
|
+
var import_ethers3 = require("ethers");
|
|
164
176
|
var log = (0, import_debug.default)(DEBUG_NAMESPACE);
|
|
165
177
|
function getAuthEIP721Types(payload) {
|
|
166
178
|
return {
|
|
@@ -282,7 +294,7 @@ function isSignableContractCall(payload, contracts) {
|
|
|
282
294
|
return isSignable;
|
|
283
295
|
}
|
|
284
296
|
var defaultGetDelegate = async (provider) => {
|
|
285
|
-
return
|
|
297
|
+
return import_ethers3.Wallet.createRandom();
|
|
286
298
|
};
|
|
287
299
|
var prepareTypedDataPayload = (p) => ({
|
|
288
300
|
...p,
|
|
@@ -302,7 +314,7 @@ var SilentDataRollupBase = class {
|
|
|
302
314
|
this._cachedNetwork = null;
|
|
303
315
|
this.config = {
|
|
304
316
|
...config,
|
|
305
|
-
authSignatureType: config.authSignatureType ?? "
|
|
317
|
+
authSignatureType: config.authSignatureType ?? "EIP191" /* EIP191 */
|
|
306
318
|
};
|
|
307
319
|
this.delegateConfig = this.resolveDelegateConfig(config);
|
|
308
320
|
log2(
|
|
@@ -387,37 +399,67 @@ var SilentDataRollupBase = class {
|
|
|
387
399
|
/**
|
|
388
400
|
* Signs a raw delegate header message.
|
|
389
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.
|
|
390
403
|
* @param provider - The provider used for signing
|
|
391
404
|
* @param message - The delegate signer message to be signed
|
|
405
|
+
* @param isSWC - Whether signing for smart wallet contract (EIP-1271)
|
|
392
406
|
* @returns A promise that resolves to the signature string
|
|
393
407
|
*/
|
|
394
|
-
async
|
|
395
|
-
log2("
|
|
396
|
-
|
|
397
|
-
|
|
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);
|
|
398
421
|
return signature;
|
|
399
422
|
}
|
|
400
423
|
/**
|
|
401
424
|
* Signs a typed delegate header message.
|
|
402
425
|
* This method can be overridden by extending classes to customize the signing process.
|
|
403
426
|
* @param provider - The provider used for signing
|
|
427
|
+
* @param chainId - The chain ID
|
|
404
428
|
* @param message - The delegate signer message to be signed
|
|
429
|
+
* @param isSWC - Whether signing for smart wallet contract (EIP-1271)
|
|
405
430
|
* @returns A promise that resolves to the signature string
|
|
406
431
|
*/
|
|
407
|
-
async signTypedDelegateHeader(provider, chainId, message) {
|
|
432
|
+
async signTypedDelegateHeader(provider, chainId, message, isSWC) {
|
|
408
433
|
log2("signTypedDelegateHeader: Signing typed delegate header");
|
|
409
434
|
log2(
|
|
410
435
|
"signTypedDelegateHeader: Typed message:",
|
|
411
436
|
JSON.stringify(message, null, 2)
|
|
412
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
|
+
}
|
|
413
450
|
const signature = await provider.signer.signTypedData(
|
|
414
|
-
|
|
451
|
+
domain,
|
|
415
452
|
delegateEIP721Types,
|
|
416
453
|
message
|
|
417
454
|
);
|
|
418
455
|
log2("signTypedDelegateHeader: Signature generated:", signature);
|
|
419
456
|
return signature;
|
|
420
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
|
+
*/
|
|
421
463
|
async getDelegateHeaders(provider) {
|
|
422
464
|
log2("Getting delegate headers");
|
|
423
465
|
if (!this.delegateHeadersPromise) {
|
|
@@ -425,7 +467,9 @@ var SilentDataRollupBase = class {
|
|
|
425
467
|
}
|
|
426
468
|
const currentPromise = this.delegateHeadersPromise;
|
|
427
469
|
try {
|
|
428
|
-
|
|
470
|
+
const delegateHeaders = await currentPromise;
|
|
471
|
+
log2("Delegate headers:", JSON.stringify(delegateHeaders, null, 2));
|
|
472
|
+
return currentPromise;
|
|
429
473
|
} catch (error) {
|
|
430
474
|
log2("Error getting delegate headers:", error);
|
|
431
475
|
throw new Error("Failed to get delegate headers");
|
|
@@ -456,13 +500,16 @@ var SilentDataRollupBase = class {
|
|
|
456
500
|
[HEADER_DELEGATE]: JSON.stringify(delegateSignerMessage)
|
|
457
501
|
};
|
|
458
502
|
const chainId = (await this.getCachedNetwork(provider)).chainId.toString();
|
|
503
|
+
const isSWC = !!this.config.smartWalletAddress;
|
|
459
504
|
switch (signatureType) {
|
|
505
|
+
case "EIP191" /* EIP191 */:
|
|
460
506
|
case "RAW" /* Raw */: {
|
|
461
|
-
log2("Generating delegate
|
|
507
|
+
log2("Generating delegate signature");
|
|
462
508
|
const delegateMessageToSign = chainId + JSON.stringify(delegateSignerMessage);
|
|
463
|
-
headers[HEADER_DELEGATE_SIGNATURE] = await this.
|
|
509
|
+
headers[HEADER_DELEGATE_SIGNATURE] = await this.signDelegateHeader(
|
|
464
510
|
provider,
|
|
465
|
-
delegateMessageToSign
|
|
511
|
+
delegateMessageToSign,
|
|
512
|
+
isSWC
|
|
466
513
|
);
|
|
467
514
|
break;
|
|
468
515
|
}
|
|
@@ -471,7 +518,8 @@ var SilentDataRollupBase = class {
|
|
|
471
518
|
headers[HEADER_EIP712_DELEGATE_SIGNATURE] = await this.signTypedDelegateHeader(
|
|
472
519
|
provider,
|
|
473
520
|
chainId,
|
|
474
|
-
delegateSignerMessage
|
|
521
|
+
delegateSignerMessage,
|
|
522
|
+
isSWC
|
|
475
523
|
);
|
|
476
524
|
break;
|
|
477
525
|
default:
|
|
@@ -492,24 +540,57 @@ var SilentDataRollupBase = class {
|
|
|
492
540
|
[HEADER_TIMESTAMP]: xTimestamp
|
|
493
541
|
};
|
|
494
542
|
const chainId = (await this.getCachedNetwork(provider)).chainId.toString();
|
|
495
|
-
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
|
+
}
|
|
496
574
|
switch (signatureType) {
|
|
575
|
+
case "EIP191" /* EIP191 */:
|
|
497
576
|
case "RAW" /* Raw */:
|
|
498
|
-
log2("Generating auth header
|
|
499
|
-
headers[HEADER_SIGNATURE] = await this.
|
|
577
|
+
log2("Generating auth header signature");
|
|
578
|
+
headers[HEADER_SIGNATURE] = await this.signAuthHeader(
|
|
500
579
|
provider,
|
|
501
|
-
|
|
580
|
+
payloadToSign,
|
|
502
581
|
xTimestamp,
|
|
503
|
-
chainId
|
|
582
|
+
chainId,
|
|
583
|
+
isSWC
|
|
504
584
|
);
|
|
505
585
|
break;
|
|
506
586
|
case "EIP712" /* EIP712 */:
|
|
507
|
-
log2("Generating auth
|
|
508
|
-
headers[HEADER_EIP712_SIGNATURE] = await this.
|
|
587
|
+
log2("Generating auth header typed signature");
|
|
588
|
+
headers[HEADER_EIP712_SIGNATURE] = await this.signTypedAuthHeader(
|
|
509
589
|
provider,
|
|
510
|
-
|
|
590
|
+
payloadToSign,
|
|
511
591
|
xTimestamp,
|
|
512
|
-
chainId
|
|
592
|
+
chainId,
|
|
593
|
+
isSWC
|
|
513
594
|
);
|
|
514
595
|
break;
|
|
515
596
|
default:
|
|
@@ -518,26 +599,53 @@ var SilentDataRollupBase = class {
|
|
|
518
599
|
log2("Auth headers:", JSON.stringify(headers, null, 2));
|
|
519
600
|
return headers;
|
|
520
601
|
}
|
|
521
|
-
|
|
522
|
-
|
|
602
|
+
/**
|
|
603
|
+
* Signs auth header.
|
|
604
|
+
*/
|
|
605
|
+
async signAuthHeader(provider, payload, timestamp, chainId, isSWC) {
|
|
606
|
+
const xMessage = this.prepareMessage(chainId, payload, timestamp);
|
|
523
607
|
const delegateSigner = await this.getDelegateSigner(this);
|
|
524
608
|
const signer = delegateSigner ?? provider.signer;
|
|
525
|
-
const
|
|
526
|
-
|
|
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);
|
|
527
621
|
return signature;
|
|
528
622
|
}
|
|
529
|
-
|
|
530
|
-
|
|
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);
|
|
531
628
|
const types = getAuthEIP721Types(payload);
|
|
532
629
|
const delegateSigner = await this.getDelegateSigner(this);
|
|
533
630
|
const signer = delegateSigner ?? provider.signer;
|
|
631
|
+
const usingDelegate = !!delegateSigner;
|
|
534
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
|
+
}
|
|
535
641
|
log2(
|
|
536
642
|
"Signing typed data",
|
|
537
643
|
JSON.stringify({ message, types, domain }, null, 2)
|
|
538
644
|
);
|
|
645
|
+
const messageHash = import_ethers4.TypedDataEncoder.hash(domain, types, message);
|
|
646
|
+
log2("EIP-712 hash (EOA):", messageHash);
|
|
539
647
|
const signature = await this.signTypedData(signer, domain, types, message);
|
|
540
|
-
log2("Message signed. Signature:", signature);
|
|
648
|
+
log2("Message signed with EIP-712. Signature:", signature);
|
|
541
649
|
return signature;
|
|
542
650
|
}
|
|
543
651
|
/**
|
|
@@ -569,10 +677,81 @@ var SilentDataRollupBase = class {
|
|
|
569
677
|
contractMethodsToSign
|
|
570
678
|
});
|
|
571
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
|
+
}
|
|
572
751
|
/**
|
|
573
752
|
* Prepares the message to be signed for the x-signature header.
|
|
574
753
|
*/
|
|
575
|
-
|
|
754
|
+
prepareMessage(chainId, payload, timestamp) {
|
|
576
755
|
log2("Preparing raw message for signing", {
|
|
577
756
|
payload: JSON.stringify(payload, null, 2),
|
|
578
757
|
timestamp
|
|
@@ -585,7 +764,7 @@ var SilentDataRollupBase = class {
|
|
|
585
764
|
/**
|
|
586
765
|
* Prepares the message to be signed for the x-eip712-signature header.
|
|
587
766
|
*/
|
|
588
|
-
|
|
767
|
+
prepareTypedData(payload, timestamp) {
|
|
589
768
|
log2("Preparing payload for signTypedData");
|
|
590
769
|
const preparedPayload = Array.isArray(payload) ? payload.map(prepareTypedDataPayload) : prepareTypedDataPayload(payload);
|
|
591
770
|
const message = {
|
|
@@ -598,11 +777,11 @@ var SilentDataRollupBase = class {
|
|
|
598
777
|
};
|
|
599
778
|
|
|
600
779
|
// src/contract.ts
|
|
601
|
-
var
|
|
602
|
-
var SilentDataRollupContract = class extends
|
|
780
|
+
var import_ethers5 = require("ethers");
|
|
781
|
+
var SilentDataRollupContract = class extends import_ethers5.Contract {
|
|
603
782
|
constructor(config) {
|
|
604
783
|
const { address, abi, runner, contractMethodsToSign } = config;
|
|
605
|
-
const contractInterface = new
|
|
784
|
+
const contractInterface = new import_ethers5.Interface(abi);
|
|
606
785
|
contractMethodsToSign.forEach((method) => {
|
|
607
786
|
if (!contractInterface.hasFunction(method)) {
|
|
608
787
|
throw new Error(
|
|
@@ -617,28 +796,22 @@ var SilentDataRollupContract = class extends import_ethers2.Contract {
|
|
|
617
796
|
}
|
|
618
797
|
}
|
|
619
798
|
};
|
|
620
|
-
|
|
621
|
-
// src/privateEvents.ts
|
|
622
|
-
var import_ethers3 = require("ethers");
|
|
623
|
-
var PRIVATE_EVENT_SIGNATURE = "PrivateEvent(address[],bytes32,bytes)";
|
|
624
|
-
var PRIVATE_EVENT_SIGNATURE_HASH = (0, import_ethers3.keccak256)(
|
|
625
|
-
(0, import_ethers3.toUtf8Bytes)(PRIVATE_EVENT_SIGNATURE)
|
|
626
|
-
);
|
|
627
|
-
function calculateEventTypeHash(eventSignature) {
|
|
628
|
-
return (0, import_ethers3.keccak256)((0, import_ethers3.toUtf8Bytes)(eventSignature));
|
|
629
|
-
}
|
|
630
799
|
// Annotate the CommonJS export names for ESM import in node:
|
|
631
800
|
0 && (module.exports = {
|
|
632
801
|
ChainId,
|
|
633
802
|
DEBUG_NAMESPACE,
|
|
634
803
|
DEBUG_NAMESPACE_SILENTDATA_INTERCEPTOR,
|
|
635
804
|
DEFAULT_DELEGATE_EXPIRES,
|
|
805
|
+
DEFAULT_USER_OPERATION_RECEIPT_LOOKUP_RANGE,
|
|
636
806
|
DELEGATE_EXPIRATION_THRESHOLD_BUFFER,
|
|
807
|
+
ENTRYPOINT_ADDRESS,
|
|
637
808
|
HEADER_DELEGATE,
|
|
638
809
|
HEADER_DELEGATE_SIGNATURE,
|
|
639
810
|
HEADER_EIP712_DELEGATE_SIGNATURE,
|
|
640
811
|
HEADER_EIP712_SIGNATURE,
|
|
812
|
+
HEADER_FROM_BLOCK,
|
|
641
813
|
HEADER_SIGNATURE,
|
|
814
|
+
HEADER_SIGNATURE_TYPE,
|
|
642
815
|
HEADER_SIGNER_SWC,
|
|
643
816
|
HEADER_TIMESTAMP,
|
|
644
817
|
NetworkName,
|
|
@@ -648,6 +821,8 @@ function calculateEventTypeHash(eventSignature) {
|
|
|
648
821
|
SignatureType,
|
|
649
822
|
SilentDataRollupBase,
|
|
650
823
|
SilentDataRollupContract,
|
|
824
|
+
USER_OPERATION_EVENT_HASH,
|
|
825
|
+
USER_OPERATION_EVENT_SIGNATURE,
|
|
651
826
|
WHITELISTED_METHODS,
|
|
652
827
|
calculateEventTypeHash,
|
|
653
828
|
defaultGetDelegate,
|
package/dist/index.mjs
CHANGED
|
@@ -3,12 +3,16 @@ 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,
|
|
12
16
|
HEADER_SIGNER_SWC,
|
|
13
17
|
HEADER_TIMESTAMP,
|
|
14
18
|
NetworkName,
|
|
@@ -18,6 +22,8 @@ import {
|
|
|
18
22
|
SignatureType,
|
|
19
23
|
SilentDataRollupBase,
|
|
20
24
|
SilentDataRollupContract,
|
|
25
|
+
USER_OPERATION_EVENT_HASH,
|
|
26
|
+
USER_OPERATION_EVENT_SIGNATURE,
|
|
21
27
|
WHITELISTED_METHODS,
|
|
22
28
|
calculateEventTypeHash,
|
|
23
29
|
defaultGetDelegate,
|
|
@@ -27,18 +33,22 @@ import {
|
|
|
27
33
|
getAuthHeaders,
|
|
28
34
|
isSignableContractCall,
|
|
29
35
|
prepareTypedDataPayload
|
|
30
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-53A5RGL2.mjs";
|
|
31
37
|
export {
|
|
32
38
|
ChainId,
|
|
33
39
|
DEBUG_NAMESPACE,
|
|
34
40
|
DEBUG_NAMESPACE_SILENTDATA_INTERCEPTOR,
|
|
35
41
|
DEFAULT_DELEGATE_EXPIRES,
|
|
42
|
+
DEFAULT_USER_OPERATION_RECEIPT_LOOKUP_RANGE,
|
|
36
43
|
DELEGATE_EXPIRATION_THRESHOLD_BUFFER,
|
|
44
|
+
ENTRYPOINT_ADDRESS,
|
|
37
45
|
HEADER_DELEGATE,
|
|
38
46
|
HEADER_DELEGATE_SIGNATURE,
|
|
39
47
|
HEADER_EIP712_DELEGATE_SIGNATURE,
|
|
40
48
|
HEADER_EIP712_SIGNATURE,
|
|
49
|
+
HEADER_FROM_BLOCK,
|
|
41
50
|
HEADER_SIGNATURE,
|
|
51
|
+
HEADER_SIGNATURE_TYPE,
|
|
42
52
|
HEADER_SIGNER_SWC,
|
|
43
53
|
HEADER_TIMESTAMP,
|
|
44
54
|
NetworkName,
|
|
@@ -48,6 +58,8 @@ export {
|
|
|
48
58
|
SignatureType,
|
|
49
59
|
SilentDataRollupBase,
|
|
50
60
|
SilentDataRollupContract,
|
|
61
|
+
USER_OPERATION_EVENT_HASH,
|
|
62
|
+
USER_OPERATION_EVENT_SIGNATURE,
|
|
51
63
|
WHITELISTED_METHODS,
|
|
52
64
|
calculateEventTypeHash,
|
|
53
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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@appliedblockchain/silentdatarollup-core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "Core library for Silent Data",
|
|
5
5
|
"author": "Applied Blockchain",
|
|
6
6
|
"homepage": "https://github.com/appliedblockchain/silent-data-rollup-providers#readme",
|
|
@@ -28,22 +28,21 @@
|
|
|
28
28
|
"files": [
|
|
29
29
|
"dist"
|
|
30
30
|
],
|
|
31
|
-
"scripts": {
|
|
32
|
-
"build": "tsc --noEmit && tsup src/index.ts src/tests.ts --format cjs,esm --dts --clean",
|
|
33
|
-
"check-exports": "attw --pack . --profile node16",
|
|
34
|
-
"prepack": "npm run build"
|
|
35
|
-
},
|
|
36
31
|
"dependencies": {
|
|
37
32
|
"debug": "4.3.7",
|
|
38
33
|
"ethers": "6.13.2"
|
|
39
34
|
},
|
|
40
35
|
"devDependencies": {
|
|
41
36
|
"@types/debug": "4.1.12",
|
|
42
|
-
"@types/node": "
|
|
37
|
+
"@types/node": "24.10.1",
|
|
43
38
|
"ts-node": "10.9.2",
|
|
44
39
|
"typescript": "5.6.2"
|
|
45
40
|
},
|
|
46
41
|
"engines": {
|
|
47
42
|
"node": ">=18.0.0"
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build": "tsc --noEmit && tsup src/index.ts src/tests.ts --format cjs,esm --dts --clean",
|
|
46
|
+
"check-exports": "attw --pack . --profile node16"
|
|
48
47
|
}
|
|
49
|
-
}
|
|
48
|
+
}
|