@appliedblockchain/silentdatarollup-core 1.0.3 → 1.0.5

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.
@@ -3,11 +3,11 @@ import debug2 from "debug";
3
3
 
4
4
  // src/constants.ts
5
5
  var SIGN_RPC_METHODS = [
6
+ "eth_estimateGas",
7
+ "eth_getProof",
6
8
  "eth_getTransactionByHash",
7
9
  "eth_getTransactionCount",
8
- "eth_getProof",
9
- "eth_getTransactionReceipt",
10
- "eth_estimateGas"
10
+ "eth_getTransactionReceipt"
11
11
  ];
12
12
  var eip721Domain = {
13
13
  name: "Silent Data [Rollup]",
@@ -27,7 +27,7 @@ var HEADER_EIP712_SIGNATURE = "x-eip712-signature";
27
27
  var HEADER_DELEGATE = "x-delegate";
28
28
  var HEADER_DELEGATE_SIGNATURE = "x-delegate-signature";
29
29
  var HEADER_EIP712_DELEGATE_SIGNATURE = "x-eip712-delegate-signature";
30
- var DEFAULT_DELEGATE_EXPIRES = 24 * 60 * 60;
30
+ var DEFAULT_DELEGATE_EXPIRES = 10 * 60 * 60;
31
31
  var DELEGATE_EXPIRATION_THRESHOLD_BUFFER = 5;
32
32
  var WHITELISTED_METHODS = [
33
33
  "eth_blockNumber",
@@ -79,8 +79,8 @@ var WHITELISTED_METHODS = [
79
79
 
80
80
  // src/types.ts
81
81
  var ChainId = /* @__PURE__ */ ((ChainId2) => {
82
- ChainId2[ChainId2["MAINNET"] = 51966] = "MAINNET";
83
- ChainId2[ChainId2["TESTNET"] = 1001] = "TESTNET";
82
+ ChainId2[ChainId2["MAINNET"] = 380929] = "MAINNET";
83
+ ChainId2[ChainId2["TESTNET"] = 381185] = "TESTNET";
84
84
  return ChainId2;
85
85
  })(ChainId || {});
86
86
  var NetworkName = /* @__PURE__ */ ((NetworkName2) => {
@@ -116,7 +116,7 @@ function getAuthEIP721Types(payload) {
116
116
  ]
117
117
  };
118
118
  }
119
- async function signAuthHeaderTypedData(signer, payload, timestamp) {
119
+ async function signAuthHeaderTypedData(signer, payload, timestamp, chainId) {
120
120
  log("Preparing payload for signTypedData");
121
121
  const preparePayload = (p) => ({
122
122
  ...p,
@@ -128,41 +128,22 @@ async function signAuthHeaderTypedData(signer, payload, timestamp) {
128
128
  timestamp
129
129
  };
130
130
  const types = getAuthEIP721Types(payload);
131
- log(
132
- "Signing typed data",
133
- JSON.stringify({ eip721Domain, types, message }, null, 2)
134
- );
135
- const signature = await signer.signTypedData(eip721Domain, types, message);
131
+ const domain = { ...eip721Domain, chainId };
132
+ log("Signing typed data", JSON.stringify({ domain, types, message }, null, 2));
133
+ const signature = await signer.signTypedData(domain, types, message);
136
134
  log("Signature generated:", signature);
137
135
  return signature;
138
136
  }
139
- async function signAuthHeaderRawMessage(signer, payload, timestamp) {
137
+ async function signAuthHeaderRawMessage(signer, payload, timestamp, chainId) {
140
138
  log("Preparing raw message for signing");
141
139
  const serialRequest = JSON.stringify(payload);
142
- const xMessage = serialRequest + timestamp;
140
+ const xMessage = chainId + serialRequest + timestamp;
143
141
  log("Raw message:", xMessage);
144
142
  const signature = await signer.signMessage(xMessage);
145
143
  log("Raw signature generated:", signature);
146
144
  return signature;
147
145
  }
148
- async function signTypedDelegateHeader(signer, message) {
149
- log("Signing typed delegate header");
150
- const signature = await signer.signTypedData(
151
- eip721Domain,
152
- delegateEIP721Types,
153
- message
154
- );
155
- log("Signature generated:", signature);
156
- return signature;
157
- }
158
- async function signRawDelegateHeader(signer, message) {
159
- log("Signing raw delegate header");
160
- log("Raw message:", message);
161
- const signature = await signer.signMessage(JSON.stringify(message));
162
- log("Raw signature generated:", signature);
163
- return signature;
164
- }
165
- async function getAuthHeaders(signer, payload, signatureType) {
146
+ async function getAuthHeaders(signer, payload, chainId, signatureType) {
166
147
  const xTimestamp = (/* @__PURE__ */ new Date()).toISOString();
167
148
  const headers = {
168
149
  [HEADER_TIMESTAMP]: xTimestamp
@@ -173,7 +154,8 @@ async function getAuthHeaders(signer, payload, signatureType) {
173
154
  headers[HEADER_SIGNATURE] = await signAuthHeaderRawMessage(
174
155
  signer,
175
156
  payload,
176
- xTimestamp
157
+ xTimestamp,
158
+ chainId
177
159
  );
178
160
  break;
179
161
  case "EIP712" /* EIP712 */:
@@ -181,7 +163,8 @@ async function getAuthHeaders(signer, payload, signatureType) {
181
163
  headers[HEADER_EIP712_SIGNATURE] = await signAuthHeaderTypedData(
182
164
  signer,
183
165
  payload,
184
- xTimestamp
166
+ xTimestamp,
167
+ chainId
185
168
  );
186
169
  break;
187
170
  default:
@@ -189,12 +172,11 @@ async function getAuthHeaders(signer, payload, signatureType) {
189
172
  }
190
173
  return headers;
191
174
  }
192
- function isSignableContractCall(payload, contractMethodsToSign, contract) {
193
- if (!contractMethodsToSign || !contract) {
175
+ function isSignableContractCall(payload, contracts) {
176
+ if (!contracts || contracts.length === 0) {
194
177
  return false;
195
178
  }
196
179
  log("Checking if contract call is signable");
197
- log("Contract methods to sign:", contractMethodsToSign);
198
180
  if (payload.method !== "eth_call") {
199
181
  log("Payload method is not eth_call, returning false");
200
182
  return false;
@@ -204,8 +186,31 @@ function isSignableContractCall(payload, contractMethodsToSign, contract) {
204
186
  log("Invalid params, returning false");
205
187
  return false;
206
188
  }
207
- const methodSignature = params[0].data.slice(2, 10);
208
- log("Method signature:", methodSignature);
189
+ const callTarget = params[0].to;
190
+ if (!callTarget) {
191
+ log("Missing call target, returning false");
192
+ return false;
193
+ }
194
+ log(`Call target: ${callTarget}`);
195
+ const contractIndex = contracts.findIndex(
196
+ (c) => c.contract.target.toString().toLowerCase() === callTarget.toLowerCase()
197
+ );
198
+ if (contractIndex < 0) {
199
+ log("Contract not found, returning false");
200
+ return false;
201
+ }
202
+ const callData = params[0].data;
203
+ if (!callData) {
204
+ log("Missing call data, returning false");
205
+ return false;
206
+ }
207
+ const methodSignature = callData.slice(2, 10);
208
+ if (!methodSignature) {
209
+ log("Missing method signature, returning false");
210
+ return false;
211
+ }
212
+ log(`Method signature: ${methodSignature}`);
213
+ const { contract, contractMethodsToSign } = contracts[contractIndex];
209
214
  const isSignable = contractMethodsToSign.some((methodName) => {
210
215
  const fragment = contract.interface.getFunction(methodName);
211
216
  return !!fragment && methodSignature.startsWith(fragment.selector.slice(2));
@@ -229,8 +234,9 @@ var SilentDataRollupBase = class {
229
234
  this.delegateSignerExpires = 0;
230
235
  this.cachedDelegateHeaders = null;
231
236
  this.cachedHeadersExpiry = 0;
232
- this.contract = null;
233
- this.contractMethodsToSign = [];
237
+ this.delegateHeadersPromise = null;
238
+ this.contracts = [];
239
+ this._cachedNetwork = null;
234
240
  this.config = {
235
241
  ...config,
236
242
  authSignatureType: config.authSignatureType ?? "RAW" /* Raw */
@@ -255,6 +261,18 @@ var SilentDataRollupBase = class {
255
261
  }
256
262
  return null;
257
263
  }
264
+ /**
265
+ * Get cached network with simple caching
266
+ * @param provider - The provider to get the network from
267
+ * @returns Promise<Network> - The cached or freshly fetched network
268
+ */
269
+ async getCachedNetwork(provider) {
270
+ if (!this._cachedNetwork) {
271
+ this._cachedNetwork = await provider.getNetwork();
272
+ log2("Network cached:", this._cachedNetwork);
273
+ }
274
+ return this._cachedNetwork;
275
+ }
258
276
  async getDelegateSigner(provider) {
259
277
  if (!this.delegateConfig) {
260
278
  log2("getDelegateSigner: No delegate config, returning null");
@@ -311,9 +329,8 @@ var SilentDataRollupBase = class {
311
329
  * @returns A promise that resolves to the signature string
312
330
  */
313
331
  async signRawDelegateHeader(provider, message) {
314
- log2("signRawDelegateHeader: Signing raw delegate header");
315
- log2("signRawDelegateHeader: Raw message:", JSON.stringify(message, null, 2));
316
- const signature = await provider.signer.signMessage(JSON.stringify(message));
332
+ log2("signRawDelegateHeader: Signing raw delegate header", message);
333
+ const signature = await provider.signer.signMessage(message);
317
334
  log2("signRawDelegateHeader: Raw signature generated:", signature);
318
335
  return signature;
319
336
  }
@@ -324,14 +341,14 @@ var SilentDataRollupBase = class {
324
341
  * @param message - The delegate signer message to be signed
325
342
  * @returns A promise that resolves to the signature string
326
343
  */
327
- async signTypedDelegateHeader(provider, message) {
344
+ async signTypedDelegateHeader(provider, chainId, message) {
328
345
  log2("signTypedDelegateHeader: Signing typed delegate header");
329
346
  log2(
330
347
  "signTypedDelegateHeader: Typed message:",
331
348
  JSON.stringify(message, null, 2)
332
349
  );
333
350
  const signature = await provider.signer.signTypedData(
334
- eip721Domain,
351
+ { ...eip721Domain, chainId },
335
352
  delegateEIP721Types,
336
353
  message
337
354
  );
@@ -340,6 +357,22 @@ var SilentDataRollupBase = class {
340
357
  }
341
358
  async getDelegateHeaders(provider) {
342
359
  log2("Getting delegate headers");
360
+ if (!this.delegateHeadersPromise) {
361
+ this.delegateHeadersPromise = this.generateDelegateHeaders(provider);
362
+ }
363
+ const currentPromise = this.delegateHeadersPromise;
364
+ try {
365
+ return await currentPromise;
366
+ } catch (error) {
367
+ log2("Error getting delegate headers:", error);
368
+ throw new Error("Failed to get delegate headers");
369
+ } finally {
370
+ if (this.delegateHeadersPromise === currentPromise) {
371
+ this.delegateHeadersPromise = null;
372
+ }
373
+ }
374
+ }
375
+ async generateDelegateHeaders(provider) {
343
376
  const now = Math.floor(Date.now() / 1e3);
344
377
  const signatureType = this.config.authSignatureType;
345
378
  const isCachedHeadersValid = this.cachedDelegateHeaders && this.cachedHeadersExpiry - DELEGATE_EXPIRATION_THRESHOLD_BUFFER > now;
@@ -359,17 +392,24 @@ var SilentDataRollupBase = class {
359
392
  const headers = {
360
393
  [HEADER_DELEGATE]: JSON.stringify(delegateSignerMessage)
361
394
  };
395
+ const chainId = (await this.getCachedNetwork(provider)).chainId.toString();
362
396
  switch (signatureType) {
363
- case "RAW" /* Raw */:
397
+ case "RAW" /* Raw */: {
364
398
  log2("Generating delegate raw signature");
399
+ const delegateMessageToSign = chainId + JSON.stringify(delegateSignerMessage);
365
400
  headers[HEADER_DELEGATE_SIGNATURE] = await this.signRawDelegateHeader(
366
401
  provider,
367
- delegateSignerMessage
402
+ delegateMessageToSign
368
403
  );
369
404
  break;
405
+ }
370
406
  case "EIP712" /* EIP712 */:
371
407
  log2("Generating delegate EIP712 signature");
372
- headers[HEADER_EIP712_DELEGATE_SIGNATURE] = await this.signTypedDelegateHeader(provider, delegateSignerMessage);
408
+ headers[HEADER_EIP712_DELEGATE_SIGNATURE] = await this.signTypedDelegateHeader(
409
+ provider,
410
+ chainId,
411
+ delegateSignerMessage
412
+ );
373
413
  break;
374
414
  default:
375
415
  throw new Error(`Unsupported signature type: ${signatureType}`);
@@ -388,6 +428,7 @@ var SilentDataRollupBase = class {
388
428
  const headers = {
389
429
  [HEADER_TIMESTAMP]: xTimestamp
390
430
  };
431
+ const chainId = (await this.getCachedNetwork(provider)).chainId.toString();
391
432
  const signatureType = this.config.authSignatureType;
392
433
  switch (signatureType) {
393
434
  case "RAW" /* Raw */:
@@ -395,7 +436,8 @@ var SilentDataRollupBase = class {
395
436
  headers[HEADER_SIGNATURE] = await this.signAuthHeaderRawMessage(
396
437
  provider,
397
438
  payload,
398
- xTimestamp
439
+ xTimestamp,
440
+ chainId
399
441
  );
400
442
  break;
401
443
  case "EIP712" /* EIP712 */:
@@ -403,7 +445,8 @@ var SilentDataRollupBase = class {
403
445
  headers[HEADER_EIP712_SIGNATURE] = await this.signAuthHeaderTypedData(
404
446
  provider,
405
447
  payload,
406
- xTimestamp
448
+ xTimestamp,
449
+ chainId
407
450
  );
408
451
  break;
409
452
  default:
@@ -412,29 +455,25 @@ var SilentDataRollupBase = class {
412
455
  log2("Auth headers:", JSON.stringify(headers, null, 2));
413
456
  return headers;
414
457
  }
415
- async signAuthHeaderRawMessage(provider, payload, timestamp) {
416
- const xMessage = this.prepareSignatureMessage(payload, timestamp);
458
+ async signAuthHeaderRawMessage(provider, payload, timestamp, chainId) {
459
+ const xMessage = this.prepareSignatureMessage(chainId, payload, timestamp);
417
460
  const delegateSigner = await this.getDelegateSigner(this);
418
461
  const signer = delegateSigner ?? provider.signer;
419
462
  const signature = await this.signMessage(signer, xMessage);
420
463
  log2("Message signed. Signature:", signature);
421
464
  return signature;
422
465
  }
423
- async signAuthHeaderTypedData(provider, payload, timestamp) {
466
+ async signAuthHeaderTypedData(provider, payload, timestamp, chainId) {
424
467
  const message = this.prepareSignatureTypedData(payload, timestamp);
425
468
  const types = getAuthEIP721Types(payload);
426
469
  const delegateSigner = await this.getDelegateSigner(this);
427
470
  const signer = delegateSigner ?? provider.signer;
471
+ const domain = { ...eip721Domain, chainId };
428
472
  log2(
429
473
  "Signing typed data",
430
- JSON.stringify({ message, types, eip721Domain }, null, 2)
431
- );
432
- const signature = await this.signTypedData(
433
- signer,
434
- eip721Domain,
435
- types,
436
- message
474
+ JSON.stringify({ message, types, domain }, null, 2)
437
475
  );
476
+ const signature = await this.signTypedData(signer, domain, types, message);
438
477
  log2("Message signed. Signature:", signature);
439
478
  return signature;
440
479
  }
@@ -462,19 +501,21 @@ var SilentDataRollupBase = class {
462
501
  }
463
502
  setContract(contract, contractMethodsToSign) {
464
503
  log2("Setting contract and methods to sign: ", contractMethodsToSign);
465
- this.contract = contract;
466
- this.contractMethodsToSign = contractMethodsToSign;
504
+ this.contracts.push({
505
+ contract,
506
+ contractMethodsToSign
507
+ });
467
508
  }
468
509
  /**
469
510
  * Prepares the message to be signed for the x-signature header.
470
511
  */
471
- prepareSignatureMessage(payload, timestamp) {
512
+ prepareSignatureMessage(chainId, payload, timestamp) {
472
513
  log2("Preparing raw message for signing", {
473
514
  payload: JSON.stringify(payload, null, 2),
474
515
  timestamp
475
516
  });
476
517
  const serialRequest = JSON.stringify(payload);
477
- const xMessage = serialRequest + timestamp;
518
+ const xMessage = chainId + serialRequest + timestamp;
478
519
  log2("Raw message to be signed:", xMessage);
479
520
  return xMessage;
480
521
  }
@@ -495,7 +536,7 @@ var SilentDataRollupBase = class {
495
536
 
496
537
  // src/contract.ts
497
538
  import {
498
- Contract as Contract2,
539
+ Contract,
499
540
  Interface,
500
541
  assertArgument
501
542
  } from "ethers";
@@ -529,7 +570,7 @@ function getContractRunner(runner, provider) {
529
570
  }
530
571
  return new CustomContractRunner(runner.provider, runner);
531
572
  }
532
- var SilentDataRollupContract = class extends Contract2 {
573
+ var SilentDataRollupContract = class extends Contract {
533
574
  constructor(config) {
534
575
  const { address, abi, runner, contractMethodsToSign, provider } = config;
535
576
  const contractInterface = new Interface(abi);
@@ -578,10 +619,6 @@ export {
578
619
  NetworkName,
579
620
  SignatureType,
580
621
  getAuthEIP721Types,
581
- signAuthHeaderTypedData,
582
- signAuthHeaderRawMessage,
583
- signTypedDelegateHeader,
584
- signRawDelegateHeader,
585
622
  getAuthHeaders,
586
623
  isSignableContractCall,
587
624
  defaultGetDelegate,
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { Signer, JsonRpcPayload, InterfaceAbi, ContractRunner, Provider, Contract, TypedDataDomain, TypedDataField } from 'ethers';
1
+ import { Signer, Contract, JsonRpcPayload, InterfaceAbi, ContractRunner, Provider, TypedDataDomain, TypedDataField } from 'ethers';
2
2
 
3
3
  declare const SIGN_RPC_METHODS: string[];
4
4
  declare const eip721Domain: {
@@ -29,8 +29,8 @@ declare const DELEGATE_EXPIRATION_THRESHOLD_BUFFER = 5;
29
29
  declare const WHITELISTED_METHODS: string[];
30
30
 
31
31
  declare enum ChainId {
32
- MAINNET = 51966,
33
- TESTNET = 1001
32
+ MAINNET = 380929,
33
+ TESTNET = 381185
34
34
  }
35
35
  declare enum NetworkName {
36
36
  MAINNET = "sdr",
@@ -101,6 +101,10 @@ type SilentDataRollupContractConfig = {
101
101
  contractMethodsToSign: string[];
102
102
  provider?: Provider;
103
103
  };
104
+ type ContractInfo = {
105
+ contract: Contract;
106
+ contractMethodsToSign: string[];
107
+ };
104
108
 
105
109
  declare class SilentDataRollupBase {
106
110
  config: BaseConfig;
@@ -109,10 +113,17 @@ declare class SilentDataRollupBase {
109
113
  private delegateSignerExpires;
110
114
  private cachedDelegateHeaders;
111
115
  private cachedHeadersExpiry;
112
- contract: Contract | null;
113
- contractMethodsToSign: string[];
116
+ private delegateHeadersPromise;
117
+ contracts: ContractInfo[];
118
+ private _cachedNetwork;
114
119
  constructor(config: BaseConfig);
115
120
  private resolveDelegateConfig;
121
+ /**
122
+ * Get cached network with simple caching
123
+ * @param provider - The provider to get the network from
124
+ * @returns Promise<Network> - The cached or freshly fetched network
125
+ */
126
+ getCachedNetwork(provider: any): Promise<any>;
116
127
  getDelegateSigner(provider: any): Promise<Signer | null>;
117
128
  getDelegateSignerMessage(provider: any): Promise<DelegateSignerMessage | null>;
118
129
  /**
@@ -122,7 +133,7 @@ declare class SilentDataRollupBase {
122
133
  * @param message - The delegate signer message to be signed
123
134
  * @returns A promise that resolves to the signature string
124
135
  */
125
- protected signRawDelegateHeader(provider: any, message: DelegateSignerMessage): Promise<string>;
136
+ protected signRawDelegateHeader(provider: any, message: string): Promise<string>;
126
137
  /**
127
138
  * Signs a typed delegate header message.
128
139
  * This method can be overridden by extending classes to customize the signing process.
@@ -130,11 +141,12 @@ declare class SilentDataRollupBase {
130
141
  * @param message - The delegate signer message to be signed
131
142
  * @returns A promise that resolves to the signature string
132
143
  */
133
- protected signTypedDelegateHeader(provider: any, message: DelegateSignerMessage): Promise<string>;
144
+ protected signTypedDelegateHeader(provider: any, chainId: string, message: DelegateSignerMessage): Promise<string>;
134
145
  getDelegateHeaders(provider: any): Promise<DelegateHeaders>;
146
+ generateDelegateHeaders(provider: any): Promise<DelegateHeaders>;
135
147
  getAuthHeaders(provider: any, payload: JsonRpcPayload | JsonRpcPayload[]): Promise<AuthHeaders>;
136
- signAuthHeaderRawMessage(provider: any, payload: JsonRpcPayload | JsonRpcPayload[], timestamp: string): Promise<string>;
137
- signAuthHeaderTypedData(provider: any, payload: JsonRpcPayload | JsonRpcPayload[], timestamp: string): Promise<string>;
148
+ signAuthHeaderRawMessage(provider: any, payload: JsonRpcPayload | JsonRpcPayload[], timestamp: string, chainId: string): Promise<string>;
149
+ signAuthHeaderTypedData(provider: any, payload: JsonRpcPayload | JsonRpcPayload[], timestamp: string, chainId: string): Promise<string>;
138
150
  /**
139
151
  * Signs a message using the provided signer.
140
152
  * This method can be overridden to customize the signing process.
@@ -157,7 +169,7 @@ declare class SilentDataRollupBase {
157
169
  /**
158
170
  * Prepares the message to be signed for the x-signature header.
159
171
  */
160
- prepareSignatureMessage(payload: JsonRpcPayload | JsonRpcPayload[], timestamp: string): string;
172
+ prepareSignatureMessage(chainId: string, payload: JsonRpcPayload | JsonRpcPayload[], timestamp: string): string;
161
173
  /**
162
174
  * Prepares the message to be signed for the x-eip712-signature header.
163
175
  */
@@ -178,11 +190,7 @@ declare function getAuthEIP721Types(payload: JsonRpcPayload | JsonRpcPayload[]):
178
190
  type: string;
179
191
  }[];
180
192
  };
181
- declare function signAuthHeaderTypedData(signer: any, payload: JsonRpcPayload | JsonRpcPayload[], timestamp: string): Promise<string>;
182
- declare function signAuthHeaderRawMessage(signer: any, payload: JsonRpcPayload | JsonRpcPayload[], timestamp: string): Promise<string>;
183
- declare function signTypedDelegateHeader(signer: any, message: DelegateSignerMessage): Promise<any>;
184
- declare function signRawDelegateHeader(signer: any, message: DelegateSignerMessage): Promise<string>;
185
- declare function getAuthHeaders(signer: Signer, payload: JsonRpcPayload | JsonRpcPayload[], signatureType: SignatureType): Promise<AuthHeaders>;
193
+ declare function getAuthHeaders(signer: Signer, payload: JsonRpcPayload | JsonRpcPayload[], chainId: string, signatureType: SignatureType): Promise<AuthHeaders>;
186
194
  /**
187
195
  * Determines if a given JSON-RPC payload represents a call to a contract method that requires signing.
188
196
  *
@@ -193,19 +201,17 @@ declare function getAuthHeaders(signer: Signer, payload: JsonRpcPayload | JsonRp
193
201
  * The function performs the following checks:
194
202
  * 1. Verifies if the payload is an `eth_call`.
195
203
  * 2. Extracts the method signature from the call data.
196
- * 3. Compares the signature against a provided list of methods requiring signing.
197
- * 4. Uses the contract's ABI to match the method signature with known methods.
204
+ * 3. Compares the signature against the list of contracts and their methods requiring signing.
205
+ * 4. Uses each contract's ABI to match the method signature with known methods.
198
206
  *
199
207
  * By accurately identifying these calls, we can add appropriate authentication headers
200
208
  * to the request, enabling the smart contract to verify the caller's identity.
201
209
  *
202
210
  * @param payload - The JSON-RPC payload to analyze.
203
- * @param contractMethodsToSign - An array of method names that require signing.
204
- * @param contract - The contract instance containing the ABI information.
211
+ * @param contracts - An array of contract information containing contracts and their methods to sign.
205
212
  * @returns {boolean} True if the call is to a method that requires signing, false otherwise.
206
- * @throws {Error} If contractMethodsToSign or contract is not provided.
207
213
  */
208
- declare function isSignableContractCall(payload: JsonRpcPayload, contractMethodsToSign?: string[], contract?: Contract | null): boolean;
214
+ declare function isSignableContractCall(payload: JsonRpcPayload, contracts: ContractInfo[]): boolean;
209
215
  declare const defaultGetDelegate: (provider: any) => Promise<Signer>;
210
216
  declare const prepareTypedDataPayload: (p: JsonRpcPayload) => AuthSignatureMessageRequest;
211
217
 
@@ -235,4 +241,4 @@ interface PrivateEvent {
235
241
  */
236
242
  declare function calculateEventTypeHash(eventSignature: string): string;
237
243
 
238
- export { type AuthHeaders, type AuthSignatureMessage, type AuthSignatureMessageRequest, type BaseConfig, ChainId, DEBUG_NAMESPACE, DEBUG_NAMESPACE_SILENTDATA_INTERCEPTOR, DEFAULT_DELEGATE_EXPIRES, DELEGATE_EXPIRATION_THRESHOLD_BUFFER, type DelegateConfig, type DelegateHeaders, type DelegateSignerMessage, HEADER_DELEGATE, HEADER_DELEGATE_SIGNATURE, HEADER_EIP712_DELEGATE_SIGNATURE, HEADER_EIP712_SIGNATURE, HEADER_SIGNATURE, HEADER_TIMESTAMP, NetworkName, PRIVATE_EVENT_SIGNATURE, PRIVATE_EVENT_SIGNATURE_HASH, type PrivateEvent, SIGN_RPC_METHODS, SignatureType, type SilentDataProviderOptions, SilentDataRollupBase, SilentDataRollupContract, type SilentDataRollupContractConfig, type SilentdataNetworkConfig, WHITELISTED_METHODS, calculateEventTypeHash, defaultGetDelegate, delegateEIP721Types, eip721Domain, getAuthEIP721Types, getAuthHeaders, isSignableContractCall, prepareTypedDataPayload, signAuthHeaderRawMessage, signAuthHeaderTypedData, signRawDelegateHeader, signTypedDelegateHeader };
244
+ export { type AuthHeaders, type AuthSignatureMessage, type AuthSignatureMessageRequest, type BaseConfig, ChainId, type ContractInfo, DEBUG_NAMESPACE, DEBUG_NAMESPACE_SILENTDATA_INTERCEPTOR, DEFAULT_DELEGATE_EXPIRES, DELEGATE_EXPIRATION_THRESHOLD_BUFFER, type DelegateConfig, type DelegateHeaders, type DelegateSignerMessage, HEADER_DELEGATE, HEADER_DELEGATE_SIGNATURE, HEADER_EIP712_DELEGATE_SIGNATURE, HEADER_EIP712_SIGNATURE, HEADER_SIGNATURE, HEADER_TIMESTAMP, NetworkName, PRIVATE_EVENT_SIGNATURE, PRIVATE_EVENT_SIGNATURE_HASH, type PrivateEvent, SIGN_RPC_METHODS, SignatureType, type SilentDataProviderOptions, SilentDataRollupBase, SilentDataRollupContract, type SilentDataRollupContractConfig, type SilentdataNetworkConfig, WHITELISTED_METHODS, calculateEventTypeHash, defaultGetDelegate, delegateEIP721Types, eip721Domain, getAuthEIP721Types, getAuthHeaders, isSignableContractCall, prepareTypedDataPayload };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Signer, JsonRpcPayload, InterfaceAbi, ContractRunner, Provider, Contract, TypedDataDomain, TypedDataField } from 'ethers';
1
+ import { Signer, Contract, JsonRpcPayload, InterfaceAbi, ContractRunner, Provider, TypedDataDomain, TypedDataField } from 'ethers';
2
2
 
3
3
  declare const SIGN_RPC_METHODS: string[];
4
4
  declare const eip721Domain: {
@@ -29,8 +29,8 @@ declare const DELEGATE_EXPIRATION_THRESHOLD_BUFFER = 5;
29
29
  declare const WHITELISTED_METHODS: string[];
30
30
 
31
31
  declare enum ChainId {
32
- MAINNET = 51966,
33
- TESTNET = 1001
32
+ MAINNET = 380929,
33
+ TESTNET = 381185
34
34
  }
35
35
  declare enum NetworkName {
36
36
  MAINNET = "sdr",
@@ -101,6 +101,10 @@ type SilentDataRollupContractConfig = {
101
101
  contractMethodsToSign: string[];
102
102
  provider?: Provider;
103
103
  };
104
+ type ContractInfo = {
105
+ contract: Contract;
106
+ contractMethodsToSign: string[];
107
+ };
104
108
 
105
109
  declare class SilentDataRollupBase {
106
110
  config: BaseConfig;
@@ -109,10 +113,17 @@ declare class SilentDataRollupBase {
109
113
  private delegateSignerExpires;
110
114
  private cachedDelegateHeaders;
111
115
  private cachedHeadersExpiry;
112
- contract: Contract | null;
113
- contractMethodsToSign: string[];
116
+ private delegateHeadersPromise;
117
+ contracts: ContractInfo[];
118
+ private _cachedNetwork;
114
119
  constructor(config: BaseConfig);
115
120
  private resolveDelegateConfig;
121
+ /**
122
+ * Get cached network with simple caching
123
+ * @param provider - The provider to get the network from
124
+ * @returns Promise<Network> - The cached or freshly fetched network
125
+ */
126
+ getCachedNetwork(provider: any): Promise<any>;
116
127
  getDelegateSigner(provider: any): Promise<Signer | null>;
117
128
  getDelegateSignerMessage(provider: any): Promise<DelegateSignerMessage | null>;
118
129
  /**
@@ -122,7 +133,7 @@ declare class SilentDataRollupBase {
122
133
  * @param message - The delegate signer message to be signed
123
134
  * @returns A promise that resolves to the signature string
124
135
  */
125
- protected signRawDelegateHeader(provider: any, message: DelegateSignerMessage): Promise<string>;
136
+ protected signRawDelegateHeader(provider: any, message: string): Promise<string>;
126
137
  /**
127
138
  * Signs a typed delegate header message.
128
139
  * This method can be overridden by extending classes to customize the signing process.
@@ -130,11 +141,12 @@ declare class SilentDataRollupBase {
130
141
  * @param message - The delegate signer message to be signed
131
142
  * @returns A promise that resolves to the signature string
132
143
  */
133
- protected signTypedDelegateHeader(provider: any, message: DelegateSignerMessage): Promise<string>;
144
+ protected signTypedDelegateHeader(provider: any, chainId: string, message: DelegateSignerMessage): Promise<string>;
134
145
  getDelegateHeaders(provider: any): Promise<DelegateHeaders>;
146
+ generateDelegateHeaders(provider: any): Promise<DelegateHeaders>;
135
147
  getAuthHeaders(provider: any, payload: JsonRpcPayload | JsonRpcPayload[]): Promise<AuthHeaders>;
136
- signAuthHeaderRawMessage(provider: any, payload: JsonRpcPayload | JsonRpcPayload[], timestamp: string): Promise<string>;
137
- signAuthHeaderTypedData(provider: any, payload: JsonRpcPayload | JsonRpcPayload[], timestamp: string): Promise<string>;
148
+ signAuthHeaderRawMessage(provider: any, payload: JsonRpcPayload | JsonRpcPayload[], timestamp: string, chainId: string): Promise<string>;
149
+ signAuthHeaderTypedData(provider: any, payload: JsonRpcPayload | JsonRpcPayload[], timestamp: string, chainId: string): Promise<string>;
138
150
  /**
139
151
  * Signs a message using the provided signer.
140
152
  * This method can be overridden to customize the signing process.
@@ -157,7 +169,7 @@ declare class SilentDataRollupBase {
157
169
  /**
158
170
  * Prepares the message to be signed for the x-signature header.
159
171
  */
160
- prepareSignatureMessage(payload: JsonRpcPayload | JsonRpcPayload[], timestamp: string): string;
172
+ prepareSignatureMessage(chainId: string, payload: JsonRpcPayload | JsonRpcPayload[], timestamp: string): string;
161
173
  /**
162
174
  * Prepares the message to be signed for the x-eip712-signature header.
163
175
  */
@@ -178,11 +190,7 @@ declare function getAuthEIP721Types(payload: JsonRpcPayload | JsonRpcPayload[]):
178
190
  type: string;
179
191
  }[];
180
192
  };
181
- declare function signAuthHeaderTypedData(signer: any, payload: JsonRpcPayload | JsonRpcPayload[], timestamp: string): Promise<string>;
182
- declare function signAuthHeaderRawMessage(signer: any, payload: JsonRpcPayload | JsonRpcPayload[], timestamp: string): Promise<string>;
183
- declare function signTypedDelegateHeader(signer: any, message: DelegateSignerMessage): Promise<any>;
184
- declare function signRawDelegateHeader(signer: any, message: DelegateSignerMessage): Promise<string>;
185
- declare function getAuthHeaders(signer: Signer, payload: JsonRpcPayload | JsonRpcPayload[], signatureType: SignatureType): Promise<AuthHeaders>;
193
+ declare function getAuthHeaders(signer: Signer, payload: JsonRpcPayload | JsonRpcPayload[], chainId: string, signatureType: SignatureType): Promise<AuthHeaders>;
186
194
  /**
187
195
  * Determines if a given JSON-RPC payload represents a call to a contract method that requires signing.
188
196
  *
@@ -193,19 +201,17 @@ declare function getAuthHeaders(signer: Signer, payload: JsonRpcPayload | JsonRp
193
201
  * The function performs the following checks:
194
202
  * 1. Verifies if the payload is an `eth_call`.
195
203
  * 2. Extracts the method signature from the call data.
196
- * 3. Compares the signature against a provided list of methods requiring signing.
197
- * 4. Uses the contract's ABI to match the method signature with known methods.
204
+ * 3. Compares the signature against the list of contracts and their methods requiring signing.
205
+ * 4. Uses each contract's ABI to match the method signature with known methods.
198
206
  *
199
207
  * By accurately identifying these calls, we can add appropriate authentication headers
200
208
  * to the request, enabling the smart contract to verify the caller's identity.
201
209
  *
202
210
  * @param payload - The JSON-RPC payload to analyze.
203
- * @param contractMethodsToSign - An array of method names that require signing.
204
- * @param contract - The contract instance containing the ABI information.
211
+ * @param contracts - An array of contract information containing contracts and their methods to sign.
205
212
  * @returns {boolean} True if the call is to a method that requires signing, false otherwise.
206
- * @throws {Error} If contractMethodsToSign or contract is not provided.
207
213
  */
208
- declare function isSignableContractCall(payload: JsonRpcPayload, contractMethodsToSign?: string[], contract?: Contract | null): boolean;
214
+ declare function isSignableContractCall(payload: JsonRpcPayload, contracts: ContractInfo[]): boolean;
209
215
  declare const defaultGetDelegate: (provider: any) => Promise<Signer>;
210
216
  declare const prepareTypedDataPayload: (p: JsonRpcPayload) => AuthSignatureMessageRequest;
211
217
 
@@ -235,4 +241,4 @@ interface PrivateEvent {
235
241
  */
236
242
  declare function calculateEventTypeHash(eventSignature: string): string;
237
243
 
238
- export { type AuthHeaders, type AuthSignatureMessage, type AuthSignatureMessageRequest, type BaseConfig, ChainId, DEBUG_NAMESPACE, DEBUG_NAMESPACE_SILENTDATA_INTERCEPTOR, DEFAULT_DELEGATE_EXPIRES, DELEGATE_EXPIRATION_THRESHOLD_BUFFER, type DelegateConfig, type DelegateHeaders, type DelegateSignerMessage, HEADER_DELEGATE, HEADER_DELEGATE_SIGNATURE, HEADER_EIP712_DELEGATE_SIGNATURE, HEADER_EIP712_SIGNATURE, HEADER_SIGNATURE, HEADER_TIMESTAMP, NetworkName, PRIVATE_EVENT_SIGNATURE, PRIVATE_EVENT_SIGNATURE_HASH, type PrivateEvent, SIGN_RPC_METHODS, SignatureType, type SilentDataProviderOptions, SilentDataRollupBase, SilentDataRollupContract, type SilentDataRollupContractConfig, type SilentdataNetworkConfig, WHITELISTED_METHODS, calculateEventTypeHash, defaultGetDelegate, delegateEIP721Types, eip721Domain, getAuthEIP721Types, getAuthHeaders, isSignableContractCall, prepareTypedDataPayload, signAuthHeaderRawMessage, signAuthHeaderTypedData, signRawDelegateHeader, signTypedDelegateHeader };
244
+ export { type AuthHeaders, type AuthSignatureMessage, type AuthSignatureMessageRequest, type BaseConfig, ChainId, type ContractInfo, DEBUG_NAMESPACE, DEBUG_NAMESPACE_SILENTDATA_INTERCEPTOR, DEFAULT_DELEGATE_EXPIRES, DELEGATE_EXPIRATION_THRESHOLD_BUFFER, type DelegateConfig, type DelegateHeaders, type DelegateSignerMessage, HEADER_DELEGATE, HEADER_DELEGATE_SIGNATURE, HEADER_EIP712_DELEGATE_SIGNATURE, HEADER_EIP712_SIGNATURE, HEADER_SIGNATURE, HEADER_TIMESTAMP, NetworkName, PRIVATE_EVENT_SIGNATURE, PRIVATE_EVENT_SIGNATURE_HASH, type PrivateEvent, SIGN_RPC_METHODS, SignatureType, type SilentDataProviderOptions, SilentDataRollupBase, SilentDataRollupContract, type SilentDataRollupContractConfig, type SilentdataNetworkConfig, WHITELISTED_METHODS, calculateEventTypeHash, defaultGetDelegate, delegateEIP721Types, eip721Domain, getAuthEIP721Types, getAuthHeaders, isSignableContractCall, prepareTypedDataPayload };
package/dist/index.js CHANGED
@@ -56,11 +56,7 @@ __export(index_exports, {
56
56
  getAuthEIP721Types: () => getAuthEIP721Types,
57
57
  getAuthHeaders: () => getAuthHeaders,
58
58
  isSignableContractCall: () => isSignableContractCall,
59
- prepareTypedDataPayload: () => prepareTypedDataPayload,
60
- signAuthHeaderRawMessage: () => signAuthHeaderRawMessage,
61
- signAuthHeaderTypedData: () => signAuthHeaderTypedData,
62
- signRawDelegateHeader: () => signRawDelegateHeader,
63
- signTypedDelegateHeader: () => signTypedDelegateHeader
59
+ prepareTypedDataPayload: () => prepareTypedDataPayload
64
60
  });
65
61
  module.exports = __toCommonJS(index_exports);
66
62
 
@@ -69,11 +65,11 @@ var import_debug2 = __toESM(require("debug"));
69
65
 
70
66
  // src/constants.ts
71
67
  var SIGN_RPC_METHODS = [
68
+ "eth_estimateGas",
69
+ "eth_getProof",
72
70
  "eth_getTransactionByHash",
73
71
  "eth_getTransactionCount",
74
- "eth_getProof",
75
- "eth_getTransactionReceipt",
76
- "eth_estimateGas"
72
+ "eth_getTransactionReceipt"
77
73
  ];
78
74
  var eip721Domain = {
79
75
  name: "Silent Data [Rollup]",
@@ -93,7 +89,7 @@ var HEADER_EIP712_SIGNATURE = "x-eip712-signature";
93
89
  var HEADER_DELEGATE = "x-delegate";
94
90
  var HEADER_DELEGATE_SIGNATURE = "x-delegate-signature";
95
91
  var HEADER_EIP712_DELEGATE_SIGNATURE = "x-eip712-delegate-signature";
96
- var DEFAULT_DELEGATE_EXPIRES = 24 * 60 * 60;
92
+ var DEFAULT_DELEGATE_EXPIRES = 10 * 60 * 60;
97
93
  var DELEGATE_EXPIRATION_THRESHOLD_BUFFER = 5;
98
94
  var WHITELISTED_METHODS = [
99
95
  "eth_blockNumber",
@@ -145,8 +141,8 @@ var WHITELISTED_METHODS = [
145
141
 
146
142
  // src/types.ts
147
143
  var ChainId = /* @__PURE__ */ ((ChainId2) => {
148
- ChainId2[ChainId2["MAINNET"] = 51966] = "MAINNET";
149
- ChainId2[ChainId2["TESTNET"] = 1001] = "TESTNET";
144
+ ChainId2[ChainId2["MAINNET"] = 380929] = "MAINNET";
145
+ ChainId2[ChainId2["TESTNET"] = 381185] = "TESTNET";
150
146
  return ChainId2;
151
147
  })(ChainId || {});
152
148
  var NetworkName = /* @__PURE__ */ ((NetworkName2) => {
@@ -182,7 +178,7 @@ function getAuthEIP721Types(payload) {
182
178
  ]
183
179
  };
184
180
  }
185
- async function signAuthHeaderTypedData(signer, payload, timestamp) {
181
+ async function signAuthHeaderTypedData(signer, payload, timestamp, chainId) {
186
182
  log("Preparing payload for signTypedData");
187
183
  const preparePayload = (p) => ({
188
184
  ...p,
@@ -194,41 +190,22 @@ async function signAuthHeaderTypedData(signer, payload, timestamp) {
194
190
  timestamp
195
191
  };
196
192
  const types = getAuthEIP721Types(payload);
197
- log(
198
- "Signing typed data",
199
- JSON.stringify({ eip721Domain, types, message }, null, 2)
200
- );
201
- const signature = await signer.signTypedData(eip721Domain, types, message);
193
+ const domain = { ...eip721Domain, chainId };
194
+ log("Signing typed data", JSON.stringify({ domain, types, message }, null, 2));
195
+ const signature = await signer.signTypedData(domain, types, message);
202
196
  log("Signature generated:", signature);
203
197
  return signature;
204
198
  }
205
- async function signAuthHeaderRawMessage(signer, payload, timestamp) {
199
+ async function signAuthHeaderRawMessage(signer, payload, timestamp, chainId) {
206
200
  log("Preparing raw message for signing");
207
201
  const serialRequest = JSON.stringify(payload);
208
- const xMessage = serialRequest + timestamp;
202
+ const xMessage = chainId + serialRequest + timestamp;
209
203
  log("Raw message:", xMessage);
210
204
  const signature = await signer.signMessage(xMessage);
211
205
  log("Raw signature generated:", signature);
212
206
  return signature;
213
207
  }
214
- async function signTypedDelegateHeader(signer, message) {
215
- log("Signing typed delegate header");
216
- const signature = await signer.signTypedData(
217
- eip721Domain,
218
- delegateEIP721Types,
219
- message
220
- );
221
- log("Signature generated:", signature);
222
- return signature;
223
- }
224
- async function signRawDelegateHeader(signer, message) {
225
- log("Signing raw delegate header");
226
- log("Raw message:", message);
227
- const signature = await signer.signMessage(JSON.stringify(message));
228
- log("Raw signature generated:", signature);
229
- return signature;
230
- }
231
- async function getAuthHeaders(signer, payload, signatureType) {
208
+ async function getAuthHeaders(signer, payload, chainId, signatureType) {
232
209
  const xTimestamp = (/* @__PURE__ */ new Date()).toISOString();
233
210
  const headers = {
234
211
  [HEADER_TIMESTAMP]: xTimestamp
@@ -239,7 +216,8 @@ async function getAuthHeaders(signer, payload, signatureType) {
239
216
  headers[HEADER_SIGNATURE] = await signAuthHeaderRawMessage(
240
217
  signer,
241
218
  payload,
242
- xTimestamp
219
+ xTimestamp,
220
+ chainId
243
221
  );
244
222
  break;
245
223
  case "EIP712" /* EIP712 */:
@@ -247,7 +225,8 @@ async function getAuthHeaders(signer, payload, signatureType) {
247
225
  headers[HEADER_EIP712_SIGNATURE] = await signAuthHeaderTypedData(
248
226
  signer,
249
227
  payload,
250
- xTimestamp
228
+ xTimestamp,
229
+ chainId
251
230
  );
252
231
  break;
253
232
  default:
@@ -255,12 +234,11 @@ async function getAuthHeaders(signer, payload, signatureType) {
255
234
  }
256
235
  return headers;
257
236
  }
258
- function isSignableContractCall(payload, contractMethodsToSign, contract) {
259
- if (!contractMethodsToSign || !contract) {
237
+ function isSignableContractCall(payload, contracts) {
238
+ if (!contracts || contracts.length === 0) {
260
239
  return false;
261
240
  }
262
241
  log("Checking if contract call is signable");
263
- log("Contract methods to sign:", contractMethodsToSign);
264
242
  if (payload.method !== "eth_call") {
265
243
  log("Payload method is not eth_call, returning false");
266
244
  return false;
@@ -270,8 +248,31 @@ function isSignableContractCall(payload, contractMethodsToSign, contract) {
270
248
  log("Invalid params, returning false");
271
249
  return false;
272
250
  }
273
- const methodSignature = params[0].data.slice(2, 10);
274
- log("Method signature:", methodSignature);
251
+ const callTarget = params[0].to;
252
+ if (!callTarget) {
253
+ log("Missing call target, returning false");
254
+ return false;
255
+ }
256
+ log(`Call target: ${callTarget}`);
257
+ const contractIndex = contracts.findIndex(
258
+ (c) => c.contract.target.toString().toLowerCase() === callTarget.toLowerCase()
259
+ );
260
+ if (contractIndex < 0) {
261
+ log("Contract not found, returning false");
262
+ return false;
263
+ }
264
+ const callData = params[0].data;
265
+ if (!callData) {
266
+ log("Missing call data, returning false");
267
+ return false;
268
+ }
269
+ const methodSignature = callData.slice(2, 10);
270
+ if (!methodSignature) {
271
+ log("Missing method signature, returning false");
272
+ return false;
273
+ }
274
+ log(`Method signature: ${methodSignature}`);
275
+ const { contract, contractMethodsToSign } = contracts[contractIndex];
275
276
  const isSignable = contractMethodsToSign.some((methodName) => {
276
277
  const fragment = contract.interface.getFunction(methodName);
277
278
  return !!fragment && methodSignature.startsWith(fragment.selector.slice(2));
@@ -295,8 +296,9 @@ var SilentDataRollupBase = class {
295
296
  this.delegateSignerExpires = 0;
296
297
  this.cachedDelegateHeaders = null;
297
298
  this.cachedHeadersExpiry = 0;
298
- this.contract = null;
299
- this.contractMethodsToSign = [];
299
+ this.delegateHeadersPromise = null;
300
+ this.contracts = [];
301
+ this._cachedNetwork = null;
300
302
  this.config = {
301
303
  ...config,
302
304
  authSignatureType: config.authSignatureType ?? "RAW" /* Raw */
@@ -321,6 +323,18 @@ var SilentDataRollupBase = class {
321
323
  }
322
324
  return null;
323
325
  }
326
+ /**
327
+ * Get cached network with simple caching
328
+ * @param provider - The provider to get the network from
329
+ * @returns Promise<Network> - The cached or freshly fetched network
330
+ */
331
+ async getCachedNetwork(provider) {
332
+ if (!this._cachedNetwork) {
333
+ this._cachedNetwork = await provider.getNetwork();
334
+ log2("Network cached:", this._cachedNetwork);
335
+ }
336
+ return this._cachedNetwork;
337
+ }
324
338
  async getDelegateSigner(provider) {
325
339
  if (!this.delegateConfig) {
326
340
  log2("getDelegateSigner: No delegate config, returning null");
@@ -377,9 +391,8 @@ var SilentDataRollupBase = class {
377
391
  * @returns A promise that resolves to the signature string
378
392
  */
379
393
  async signRawDelegateHeader(provider, message) {
380
- log2("signRawDelegateHeader: Signing raw delegate header");
381
- log2("signRawDelegateHeader: Raw message:", JSON.stringify(message, null, 2));
382
- const signature = await provider.signer.signMessage(JSON.stringify(message));
394
+ log2("signRawDelegateHeader: Signing raw delegate header", message);
395
+ const signature = await provider.signer.signMessage(message);
383
396
  log2("signRawDelegateHeader: Raw signature generated:", signature);
384
397
  return signature;
385
398
  }
@@ -390,14 +403,14 @@ var SilentDataRollupBase = class {
390
403
  * @param message - The delegate signer message to be signed
391
404
  * @returns A promise that resolves to the signature string
392
405
  */
393
- async signTypedDelegateHeader(provider, message) {
406
+ async signTypedDelegateHeader(provider, chainId, message) {
394
407
  log2("signTypedDelegateHeader: Signing typed delegate header");
395
408
  log2(
396
409
  "signTypedDelegateHeader: Typed message:",
397
410
  JSON.stringify(message, null, 2)
398
411
  );
399
412
  const signature = await provider.signer.signTypedData(
400
- eip721Domain,
413
+ { ...eip721Domain, chainId },
401
414
  delegateEIP721Types,
402
415
  message
403
416
  );
@@ -406,6 +419,22 @@ var SilentDataRollupBase = class {
406
419
  }
407
420
  async getDelegateHeaders(provider) {
408
421
  log2("Getting delegate headers");
422
+ if (!this.delegateHeadersPromise) {
423
+ this.delegateHeadersPromise = this.generateDelegateHeaders(provider);
424
+ }
425
+ const currentPromise = this.delegateHeadersPromise;
426
+ try {
427
+ return await currentPromise;
428
+ } catch (error) {
429
+ log2("Error getting delegate headers:", error);
430
+ throw new Error("Failed to get delegate headers");
431
+ } finally {
432
+ if (this.delegateHeadersPromise === currentPromise) {
433
+ this.delegateHeadersPromise = null;
434
+ }
435
+ }
436
+ }
437
+ async generateDelegateHeaders(provider) {
409
438
  const now = Math.floor(Date.now() / 1e3);
410
439
  const signatureType = this.config.authSignatureType;
411
440
  const isCachedHeadersValid = this.cachedDelegateHeaders && this.cachedHeadersExpiry - DELEGATE_EXPIRATION_THRESHOLD_BUFFER > now;
@@ -425,17 +454,24 @@ var SilentDataRollupBase = class {
425
454
  const headers = {
426
455
  [HEADER_DELEGATE]: JSON.stringify(delegateSignerMessage)
427
456
  };
457
+ const chainId = (await this.getCachedNetwork(provider)).chainId.toString();
428
458
  switch (signatureType) {
429
- case "RAW" /* Raw */:
459
+ case "RAW" /* Raw */: {
430
460
  log2("Generating delegate raw signature");
461
+ const delegateMessageToSign = chainId + JSON.stringify(delegateSignerMessage);
431
462
  headers[HEADER_DELEGATE_SIGNATURE] = await this.signRawDelegateHeader(
432
463
  provider,
433
- delegateSignerMessage
464
+ delegateMessageToSign
434
465
  );
435
466
  break;
467
+ }
436
468
  case "EIP712" /* EIP712 */:
437
469
  log2("Generating delegate EIP712 signature");
438
- headers[HEADER_EIP712_DELEGATE_SIGNATURE] = await this.signTypedDelegateHeader(provider, delegateSignerMessage);
470
+ headers[HEADER_EIP712_DELEGATE_SIGNATURE] = await this.signTypedDelegateHeader(
471
+ provider,
472
+ chainId,
473
+ delegateSignerMessage
474
+ );
439
475
  break;
440
476
  default:
441
477
  throw new Error(`Unsupported signature type: ${signatureType}`);
@@ -454,6 +490,7 @@ var SilentDataRollupBase = class {
454
490
  const headers = {
455
491
  [HEADER_TIMESTAMP]: xTimestamp
456
492
  };
493
+ const chainId = (await this.getCachedNetwork(provider)).chainId.toString();
457
494
  const signatureType = this.config.authSignatureType;
458
495
  switch (signatureType) {
459
496
  case "RAW" /* Raw */:
@@ -461,7 +498,8 @@ var SilentDataRollupBase = class {
461
498
  headers[HEADER_SIGNATURE] = await this.signAuthHeaderRawMessage(
462
499
  provider,
463
500
  payload,
464
- xTimestamp
501
+ xTimestamp,
502
+ chainId
465
503
  );
466
504
  break;
467
505
  case "EIP712" /* EIP712 */:
@@ -469,7 +507,8 @@ var SilentDataRollupBase = class {
469
507
  headers[HEADER_EIP712_SIGNATURE] = await this.signAuthHeaderTypedData(
470
508
  provider,
471
509
  payload,
472
- xTimestamp
510
+ xTimestamp,
511
+ chainId
473
512
  );
474
513
  break;
475
514
  default:
@@ -478,29 +517,25 @@ var SilentDataRollupBase = class {
478
517
  log2("Auth headers:", JSON.stringify(headers, null, 2));
479
518
  return headers;
480
519
  }
481
- async signAuthHeaderRawMessage(provider, payload, timestamp) {
482
- const xMessage = this.prepareSignatureMessage(payload, timestamp);
520
+ async signAuthHeaderRawMessage(provider, payload, timestamp, chainId) {
521
+ const xMessage = this.prepareSignatureMessage(chainId, payload, timestamp);
483
522
  const delegateSigner = await this.getDelegateSigner(this);
484
523
  const signer = delegateSigner ?? provider.signer;
485
524
  const signature = await this.signMessage(signer, xMessage);
486
525
  log2("Message signed. Signature:", signature);
487
526
  return signature;
488
527
  }
489
- async signAuthHeaderTypedData(provider, payload, timestamp) {
528
+ async signAuthHeaderTypedData(provider, payload, timestamp, chainId) {
490
529
  const message = this.prepareSignatureTypedData(payload, timestamp);
491
530
  const types = getAuthEIP721Types(payload);
492
531
  const delegateSigner = await this.getDelegateSigner(this);
493
532
  const signer = delegateSigner ?? provider.signer;
533
+ const domain = { ...eip721Domain, chainId };
494
534
  log2(
495
535
  "Signing typed data",
496
- JSON.stringify({ message, types, eip721Domain }, null, 2)
497
- );
498
- const signature = await this.signTypedData(
499
- signer,
500
- eip721Domain,
501
- types,
502
- message
536
+ JSON.stringify({ message, types, domain }, null, 2)
503
537
  );
538
+ const signature = await this.signTypedData(signer, domain, types, message);
504
539
  log2("Message signed. Signature:", signature);
505
540
  return signature;
506
541
  }
@@ -528,19 +563,21 @@ var SilentDataRollupBase = class {
528
563
  }
529
564
  setContract(contract, contractMethodsToSign) {
530
565
  log2("Setting contract and methods to sign: ", contractMethodsToSign);
531
- this.contract = contract;
532
- this.contractMethodsToSign = contractMethodsToSign;
566
+ this.contracts.push({
567
+ contract,
568
+ contractMethodsToSign
569
+ });
533
570
  }
534
571
  /**
535
572
  * Prepares the message to be signed for the x-signature header.
536
573
  */
537
- prepareSignatureMessage(payload, timestamp) {
574
+ prepareSignatureMessage(chainId, payload, timestamp) {
538
575
  log2("Preparing raw message for signing", {
539
576
  payload: JSON.stringify(payload, null, 2),
540
577
  timestamp
541
578
  });
542
579
  const serialRequest = JSON.stringify(payload);
543
- const xMessage = serialRequest + timestamp;
580
+ const xMessage = chainId + serialRequest + timestamp;
544
581
  log2("Raw message to be signed:", xMessage);
545
582
  return xMessage;
546
583
  }
@@ -648,9 +685,5 @@ function calculateEventTypeHash(eventSignature) {
648
685
  getAuthEIP721Types,
649
686
  getAuthHeaders,
650
687
  isSignableContractCall,
651
- prepareTypedDataPayload,
652
- signAuthHeaderRawMessage,
653
- signAuthHeaderTypedData,
654
- signRawDelegateHeader,
655
- signTypedDelegateHeader
688
+ prepareTypedDataPayload
656
689
  });
package/dist/index.mjs CHANGED
@@ -25,12 +25,8 @@ import {
25
25
  getAuthEIP721Types,
26
26
  getAuthHeaders,
27
27
  isSignableContractCall,
28
- prepareTypedDataPayload,
29
- signAuthHeaderRawMessage,
30
- signAuthHeaderTypedData,
31
- signRawDelegateHeader,
32
- signTypedDelegateHeader
33
- } from "./chunk-LTOM4BOX.mjs";
28
+ prepareTypedDataPayload
29
+ } from "./chunk-PTTWND7Y.mjs";
34
30
  export {
35
31
  ChainId,
36
32
  DEBUG_NAMESPACE,
@@ -58,9 +54,5 @@ export {
58
54
  getAuthEIP721Types,
59
55
  getAuthHeaders,
60
56
  isSignableContractCall,
61
- prepareTypedDataPayload,
62
- signAuthHeaderRawMessage,
63
- signAuthHeaderTypedData,
64
- signRawDelegateHeader,
65
- signTypedDelegateHeader
57
+ prepareTypedDataPayload
66
58
  };
package/dist/tests.js CHANGED
@@ -39,7 +39,7 @@ var import_debug2 = __toESM(require("debug"));
39
39
 
40
40
  // src/constants.ts
41
41
  var DEBUG_NAMESPACE = "silentdata:core";
42
- var DEFAULT_DELEGATE_EXPIRES = 24 * 60 * 60;
42
+ var DEFAULT_DELEGATE_EXPIRES = 10 * 60 * 60;
43
43
 
44
44
  // src/utils.ts
45
45
  var import_debug = __toESM(require("debug"));
@@ -62,7 +62,7 @@ var PRIVATE_EVENT_SIGNATURE_HASH = (0, import_ethers3.keccak256)(
62
62
  // tests/utils/mocked-custom-grpc.ts
63
63
  var import_http = __toESM(require("http"));
64
64
  var currentPort = 3e3;
65
- var CHAIN_ID = 1001 /* TESTNET */;
65
+ var CHAIN_ID = 381185 /* TESTNET */;
66
66
  function createCustomRpcServer(callback) {
67
67
  const port = currentPort++;
68
68
  const customRpcUrl = `http://localhost:${port}`;
package/dist/tests.mjs CHANGED
@@ -1,9 +1,9 @@
1
- import "./chunk-LTOM4BOX.mjs";
1
+ import "./chunk-PTTWND7Y.mjs";
2
2
 
3
3
  // tests/utils/mocked-custom-grpc.ts
4
4
  import http from "http";
5
5
  var currentPort = 3e3;
6
- var CHAIN_ID = 1001 /* TESTNET */;
6
+ var CHAIN_ID = 381185 /* TESTNET */;
7
7
  function createCustomRpcServer(callback) {
8
8
  const port = currentPort++;
9
9
  const customRpcUrl = `http://localhost:${port}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appliedblockchain/silentdatarollup-core",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Core library for Silent Data [Rollup]",
5
5
  "author": "Applied Blockchain",
6
6
  "homepage": "https://github.com/appliedblockchain/silent-data-rollup-providers#readme",
@@ -29,7 +29,7 @@
29
29
  "dist"
30
30
  ],
31
31
  "scripts": {
32
- "build": "tsup src/index.ts src/tests.ts --format cjs,esm --dts --clean",
32
+ "build": "tsc --noEmit && tsup src/index.ts src/tests.ts --format cjs,esm --dts --clean",
33
33
  "check-exports": "attw --pack . --profile node16",
34
34
  "prepack": "npm run build"
35
35
  },