@appliedblockchain/silentdatarollup-ethers-provider 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 +69 -6
- package/dist/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +86 -19
- package/dist/index.mjs +82 -8
- package/package.json +12 -12
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Applied Blockchain Ltd.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Silent Data
|
|
1
|
+
# Silent Data Providers - Ethers Provider Package
|
|
2
2
|
|
|
3
3
|
## Table of Contents
|
|
4
4
|
|
|
@@ -15,18 +15,21 @@
|
|
|
15
15
|
- [Overview](#overview)
|
|
16
16
|
- [Using the SDInterface](#using-the-sdinterface)
|
|
17
17
|
- [Private Events Example](#private-events-example)
|
|
18
|
+
- [Smart Account Support](#smart-account-support)
|
|
19
|
+
- [Smart Account Overview](#smart-account-overview)
|
|
20
|
+
- [Smart Account Example](#smart-account-example)
|
|
18
21
|
- [Troubleshooting](#troubleshooting)
|
|
19
22
|
- [License](#license)
|
|
20
23
|
- [Additional Resources](#additional-resources)
|
|
21
24
|
|
|
22
25
|
## Introduction
|
|
23
26
|
|
|
24
|
-
Custom providers for Silent Data
|
|
27
|
+
Custom providers for Silent Data, compatible with ethers.js.
|
|
25
28
|
|
|
26
29
|
## Prerequisites
|
|
27
30
|
|
|
28
31
|
- Node.js (version 18 or higher)
|
|
29
|
-
-
|
|
32
|
+
- pnpm
|
|
30
33
|
- Basic knowledge of Ethereum and smart contracts
|
|
31
34
|
- Ethers.js v6
|
|
32
35
|
|
|
@@ -37,7 +40,7 @@ Custom providers for Silent Data [Rollup], compatible with ethers.js.
|
|
|
37
40
|
#### Installing Basic Usage Dependencies
|
|
38
41
|
|
|
39
42
|
```bash
|
|
40
|
-
|
|
43
|
+
pnpm add @appliedblockchain/silentdatarollup-core @appliedblockchain/silentdatarollup-ethers-provider ethers@6
|
|
41
44
|
```
|
|
42
45
|
|
|
43
46
|
#### Basic Usage Example
|
|
@@ -67,7 +70,7 @@ console.log(balance)
|
|
|
67
70
|
#### Installing Usage with a Contract Dependencies
|
|
68
71
|
|
|
69
72
|
```bash
|
|
70
|
-
|
|
73
|
+
pnpm add @appliedblockchain/silentdatarollup-core @appliedblockchain/silentdatarollup-ethers-provider ethers@6
|
|
71
74
|
```
|
|
72
75
|
|
|
73
76
|
#### Usage with a Contract Example
|
|
@@ -216,6 +219,66 @@ for (const log of privateEvents) {
|
|
|
216
219
|
}
|
|
217
220
|
```
|
|
218
221
|
|
|
222
|
+
### Smart Account Support
|
|
223
|
+
|
|
224
|
+
#### Smart Account Overview
|
|
225
|
+
|
|
226
|
+
Silent Data Rollup supports smart accounts (smart wallet contracts) that implement [EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) for signature verification. When using a smart account, you provide the `smartWalletAddress` in the provider configuration, and the provider automatically handles signature verification through the smart contract.
|
|
227
|
+
|
|
228
|
+
**Key features:**
|
|
229
|
+
|
|
230
|
+
- **EIP-1271 Compatibility**: Your smart account contract must implement the `isValidSignature(bytes32 hash, bytes signature)` function
|
|
231
|
+
- **Automatic Hash Signing**: When `smartWalletAddress` is provided, the provider signs the hash of messages for proper EIP-1271 verification
|
|
232
|
+
- **Flexible Signer Support**: Works with any signer implementation, including passkey signers, browser wallets, and more
|
|
233
|
+
|
|
234
|
+
#### Smart Account Example
|
|
235
|
+
|
|
236
|
+
This example shows how to use the provider with a passkey signer and smart account. For a complete passkey implementation, see the [Giano repository](https://github.com/appliedblockchain/giano).
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
import { SilentDataRollupProvider } from '@appliedblockchain/silentdatarollup-ethers-provider'
|
|
240
|
+
import { NetworkName } from '@appliedblockchain/silentdatarollup-core'
|
|
241
|
+
// Example: Using Giano passkey signer
|
|
242
|
+
// See https://github.com/appliedblockchain/giano for full implementation
|
|
243
|
+
import { GianoSigner } from '@appliedblockchain/giano-client'
|
|
244
|
+
|
|
245
|
+
// Initialize your Giano passkey signer
|
|
246
|
+
const gianoSigner = await GianoSigner.create({
|
|
247
|
+
// Passkey configuration
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
// Configure provider with smart account
|
|
251
|
+
const providerConfig = {
|
|
252
|
+
rpcUrl: 'SILENT_DATA_ROLLUP_RPC_URL',
|
|
253
|
+
network: NetworkName.TESTNET,
|
|
254
|
+
signer: gianoSigner,
|
|
255
|
+
// Provide your EIP-1271 compatible smart account address
|
|
256
|
+
smartWalletAddress: '0xYOUR_SMART_ACCOUNT_ADDRESS',
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const provider = new SilentDataRollupProvider(providerConfig)
|
|
260
|
+
|
|
261
|
+
// Use the provider as normal
|
|
262
|
+
// All signatures will be verified via your smart account's EIP-1271 implementation
|
|
263
|
+
const balance = await provider.getBalance('YOUR_ADDRESS')
|
|
264
|
+
console.log(balance)
|
|
265
|
+
|
|
266
|
+
// Works with contracts too
|
|
267
|
+
const contractConfig = {
|
|
268
|
+
contractAddress: 'YOUR_CONTRACT_ADDRESS',
|
|
269
|
+
abi: [
|
|
270
|
+
/* Your contract ABI */
|
|
271
|
+
],
|
|
272
|
+
runner: provider,
|
|
273
|
+
methodsToSign: ['privateMethod'],
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const contract = new SilentDataRollupContract(contractConfig)
|
|
277
|
+
const result = await contract.privateMethod('param')
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
**Note**: Your smart account contract must implement EIP-1271's `isValidSignature` function to verify signatures. The provider will automatically sign message hashes when `smartWalletAddress` is configured, ensuring compatibility with the EIP-1271 standard.
|
|
281
|
+
|
|
219
282
|
## License
|
|
220
283
|
|
|
221
284
|
This project is licensed under the [MIT License](LICENSE).
|
|
@@ -230,5 +293,5 @@ If you encounter any issues, please check the following:
|
|
|
230
293
|
|
|
231
294
|
## Additional Resources
|
|
232
295
|
|
|
233
|
-
- [Silent Data
|
|
296
|
+
- [Silent Data Documentation](https://docs.silentdata.com)
|
|
234
297
|
- [Ethers.js Documentation](https://docs.ethers.org/v6/)
|
package/dist/index.d.mts
CHANGED
|
@@ -10,6 +10,12 @@ interface SilentDataRollupProviderConfig extends BaseConfig {
|
|
|
10
10
|
privateKey?: string;
|
|
11
11
|
signer?: Signer;
|
|
12
12
|
options?: JsonRpcApiProviderOptions;
|
|
13
|
+
smartWalletAddress?: string;
|
|
14
|
+
/**
|
|
15
|
+
* When set to true, all eth_call requests will be signed
|
|
16
|
+
* with authentication headers, regardless of whether they match signable contracts
|
|
17
|
+
*/
|
|
18
|
+
alwaysSignEthCalls?: boolean;
|
|
13
19
|
}
|
|
14
20
|
/**
|
|
15
21
|
* Extended filter type that includes a special flag for private events
|
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,12 @@ interface SilentDataRollupProviderConfig extends BaseConfig {
|
|
|
10
10
|
privateKey?: string;
|
|
11
11
|
signer?: Signer;
|
|
12
12
|
options?: JsonRpcApiProviderOptions;
|
|
13
|
+
smartWalletAddress?: string;
|
|
14
|
+
/**
|
|
15
|
+
* When set to true, all eth_call requests will be signed
|
|
16
|
+
* with authentication headers, regardless of whether they match signable contracts
|
|
17
|
+
*/
|
|
18
|
+
alwaysSignEthCalls?: boolean;
|
|
13
19
|
}
|
|
14
20
|
/**
|
|
15
21
|
* Extended filter type that includes a special flag for private events
|
package/dist/index.js
CHANGED
|
@@ -40,28 +40,77 @@ module.exports = __toCommonJS(index_exports);
|
|
|
40
40
|
var DEBUG_NAMESPACE = "silentdata:ethers-provider";
|
|
41
41
|
|
|
42
42
|
// src/provider.ts
|
|
43
|
+
var import_debug = __toESM(require("debug"));
|
|
43
44
|
var import_silentdatarollup_core = require("@appliedblockchain/silentdatarollup-core");
|
|
45
|
+
var import_ethers2 = require("ethers");
|
|
46
|
+
|
|
47
|
+
// src/signer.ts
|
|
44
48
|
var import_ethers = require("ethers");
|
|
49
|
+
var SilentDataRollupSigner = class extends import_ethers.AbstractSigner {
|
|
50
|
+
constructor(provider, signer) {
|
|
51
|
+
if (!provider) {
|
|
52
|
+
throw new Error("Provider is required");
|
|
53
|
+
}
|
|
54
|
+
if (!signer) {
|
|
55
|
+
throw new Error("Signer is required");
|
|
56
|
+
}
|
|
57
|
+
super(provider);
|
|
58
|
+
this.signer = signer;
|
|
59
|
+
}
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
61
|
+
connect(provider) {
|
|
62
|
+
(0, import_ethers.assert)(
|
|
63
|
+
false,
|
|
64
|
+
"cannot reconnect SilentDataRollupSigner",
|
|
65
|
+
"UNSUPPORTED_OPERATION",
|
|
66
|
+
{
|
|
67
|
+
operation: "signer.connect"
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
async getAddress() {
|
|
72
|
+
return this.signer.getAddress();
|
|
73
|
+
}
|
|
74
|
+
async signTransaction(tx) {
|
|
75
|
+
return this.signer.signTransaction(tx);
|
|
76
|
+
}
|
|
77
|
+
async signMessage(message) {
|
|
78
|
+
return this.signer.signMessage(message);
|
|
79
|
+
}
|
|
80
|
+
signTypedData(domain, types, value) {
|
|
81
|
+
return this.signer.signTypedData(domain, types, value);
|
|
82
|
+
}
|
|
83
|
+
async sendTransaction(tx) {
|
|
84
|
+
let gasLimit = tx.gasLimit;
|
|
85
|
+
if (!gasLimit) {
|
|
86
|
+
gasLimit = await this.estimateGas(tx);
|
|
87
|
+
}
|
|
88
|
+
return this.signer.sendTransaction({ ...tx, gasLimit });
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// src/provider.ts
|
|
93
|
+
var log = (0, import_debug.default)(import_silentdatarollup_core.DEBUG_NAMESPACE);
|
|
45
94
|
function isPromise(value) {
|
|
46
95
|
return value && typeof value.then === "function";
|
|
47
96
|
}
|
|
48
97
|
function getNetwork(networkName, chainId) {
|
|
49
98
|
if (chainId) {
|
|
50
|
-
return new
|
|
99
|
+
return new import_ethers2.Network(networkName ?? "custom", chainId);
|
|
51
100
|
}
|
|
52
101
|
if (networkName === import_silentdatarollup_core.NetworkName.MAINNET) {
|
|
53
|
-
return new
|
|
102
|
+
return new import_ethers2.Network(networkName, import_silentdatarollup_core.ChainId.MAINNET);
|
|
54
103
|
} else if (networkName === import_silentdatarollup_core.NetworkName.TESTNET) {
|
|
55
|
-
return new
|
|
104
|
+
return new import_ethers2.Network(networkName, import_silentdatarollup_core.ChainId.TESTNET);
|
|
56
105
|
}
|
|
57
106
|
return void 0;
|
|
58
107
|
}
|
|
59
108
|
var providerDefaultOptions = {
|
|
60
109
|
batchMaxCount: 1
|
|
61
110
|
};
|
|
62
|
-
var SilentDataRollupProvider = class _SilentDataRollupProvider extends
|
|
111
|
+
var SilentDataRollupProvider = class _SilentDataRollupProvider extends import_ethers2.JsonRpcProvider {
|
|
63
112
|
constructor(config) {
|
|
64
|
-
(0,
|
|
113
|
+
(0, import_ethers2.assertArgument)(config.rpcUrl, "rpcUrl is mandatory", "config", config);
|
|
65
114
|
const network = getNetwork(config.network, config.chainId);
|
|
66
115
|
const request = _SilentDataRollupProvider.getRequest({
|
|
67
116
|
rpcUrl: config.rpcUrl
|
|
@@ -71,23 +120,26 @@ var SilentDataRollupProvider = class _SilentDataRollupProvider extends import_et
|
|
|
71
120
|
...config.options
|
|
72
121
|
};
|
|
73
122
|
super(request, network, combinedOptions);
|
|
74
|
-
(0,
|
|
123
|
+
(0, import_ethers2.assertArgument)(
|
|
75
124
|
config.signer || config.privateKey,
|
|
76
125
|
"signer or privateKey is mandatory",
|
|
77
126
|
"config",
|
|
78
127
|
config
|
|
79
128
|
);
|
|
80
|
-
this.baseProvider = new import_silentdatarollup_core.SilentDataRollupBase(
|
|
129
|
+
this.baseProvider = new import_silentdatarollup_core.SilentDataRollupBase({
|
|
130
|
+
...config,
|
|
131
|
+
smartWalletAddress: config.smartWalletAddress
|
|
132
|
+
});
|
|
81
133
|
this.config = config;
|
|
82
134
|
this.config.authSignatureType = config.authSignatureType || import_silentdatarollup_core.SignatureType.Raw;
|
|
83
135
|
if (config.signer) {
|
|
84
136
|
try {
|
|
85
137
|
this.signer = config.signer.connect(this);
|
|
86
138
|
} catch {
|
|
87
|
-
this.signer = config.signer;
|
|
139
|
+
this.signer = new SilentDataRollupSigner(this, config.signer);
|
|
88
140
|
}
|
|
89
141
|
} else {
|
|
90
|
-
const wallet = new
|
|
142
|
+
const wallet = new import_ethers2.Wallet(config.privateKey);
|
|
91
143
|
this.signer = wallet.connect(this);
|
|
92
144
|
}
|
|
93
145
|
}
|
|
@@ -95,6 +147,9 @@ var SilentDataRollupProvider = class _SilentDataRollupProvider extends import_et
|
|
|
95
147
|
if (Array.isArray(payload)) {
|
|
96
148
|
throw new Error("Batch requests are not currently supported");
|
|
97
149
|
}
|
|
150
|
+
if (["eth_getBlockByNumber", "eth_getBlockByHash"].includes(payload.method) && Array.isArray(payload.params) && payload.params.length > 1) {
|
|
151
|
+
payload.params[1] = false;
|
|
152
|
+
}
|
|
98
153
|
const isEthCallOrEstimateGas = payload.method === "eth_call" || payload.method === "eth_estimateGas";
|
|
99
154
|
if (isEthCallOrEstimateGas && Array.isArray(payload.params)) {
|
|
100
155
|
const txParams = payload.params[0];
|
|
@@ -116,7 +171,7 @@ var SilentDataRollupProvider = class _SilentDataRollupProvider extends import_et
|
|
|
116
171
|
const request = this._getConnection();
|
|
117
172
|
request.body = JSON.stringify(payload);
|
|
118
173
|
request.setHeader("content-type", "application/json");
|
|
119
|
-
const requiresAuthHeaders = isPrivateLogsRequest || import_silentdatarollup_core.SIGN_RPC_METHODS.includes(payload.method) || (0, import_silentdatarollup_core.isSignableContractCall)(payload, this.baseProvider.contracts);
|
|
174
|
+
const requiresAuthHeaders = isPrivateLogsRequest || import_silentdatarollup_core.SIGN_RPC_METHODS.includes(payload.method) || (0, import_silentdatarollup_core.isSignableContractCall)(payload, this.baseProvider.contracts) || this.config.alwaysSignEthCalls && payload.method === "eth_call";
|
|
120
175
|
if (requiresAuthHeaders) {
|
|
121
176
|
if (this.config.delegate) {
|
|
122
177
|
const {
|
|
@@ -135,10 +190,15 @@ var SilentDataRollupProvider = class _SilentDataRollupProvider extends import_et
|
|
|
135
190
|
);
|
|
136
191
|
}
|
|
137
192
|
}
|
|
193
|
+
if (this.config.smartWalletAddress) {
|
|
194
|
+
log("Setting smart wallet header:", this.config.smartWalletAddress);
|
|
195
|
+
request.setHeader(import_silentdatarollup_core.HEADER_SIGNER_SWC, this.config.smartWalletAddress);
|
|
196
|
+
}
|
|
138
197
|
const {
|
|
139
198
|
[import_silentdatarollup_core.HEADER_TIMESTAMP]: xTimestamp,
|
|
140
199
|
[import_silentdatarollup_core.HEADER_SIGNATURE]: xSignature,
|
|
141
|
-
[import_silentdatarollup_core.HEADER_EIP712_SIGNATURE]: xEip712Signature
|
|
200
|
+
[import_silentdatarollup_core.HEADER_EIP712_SIGNATURE]: xEip712Signature,
|
|
201
|
+
[import_silentdatarollup_core.HEADER_FROM_BLOCK]: xFromBlock
|
|
142
202
|
} = await this.baseProvider.getAuthHeaders(this, payload);
|
|
143
203
|
request.setHeader(import_silentdatarollup_core.HEADER_TIMESTAMP, xTimestamp);
|
|
144
204
|
if (xSignature) {
|
|
@@ -147,6 +207,13 @@ var SilentDataRollupProvider = class _SilentDataRollupProvider extends import_et
|
|
|
147
207
|
if (xEip712Signature) {
|
|
148
208
|
request.setHeader(import_silentdatarollup_core.HEADER_EIP712_SIGNATURE, xEip712Signature);
|
|
149
209
|
}
|
|
210
|
+
if (xFromBlock) {
|
|
211
|
+
request.setHeader(import_silentdatarollup_core.HEADER_FROM_BLOCK, xFromBlock);
|
|
212
|
+
}
|
|
213
|
+
const signatureType = this.config.authSignatureType ?? import_silentdatarollup_core.SignatureType.EIP191;
|
|
214
|
+
if (signatureType) {
|
|
215
|
+
request.setHeader(import_silentdatarollup_core.HEADER_SIGNATURE_TYPE, signatureType);
|
|
216
|
+
}
|
|
150
217
|
}
|
|
151
218
|
const response = await request.send();
|
|
152
219
|
response.assertOk();
|
|
@@ -157,7 +224,7 @@ var SilentDataRollupProvider = class _SilentDataRollupProvider extends import_et
|
|
|
157
224
|
return resp;
|
|
158
225
|
}
|
|
159
226
|
static getRequest({ rpcUrl }) {
|
|
160
|
-
const request = new
|
|
227
|
+
const request = new import_ethers2.FetchRequest(rpcUrl);
|
|
161
228
|
request.allowGzip = true;
|
|
162
229
|
return request;
|
|
163
230
|
}
|
|
@@ -253,7 +320,7 @@ var SilentDataRollupProvider = class _SilentDataRollupProvider extends import_et
|
|
|
253
320
|
enumerable: false
|
|
254
321
|
});
|
|
255
322
|
}
|
|
256
|
-
const { network, params } = await (0,
|
|
323
|
+
const { network, params } = await (0, import_ethers2.resolveProperties)({
|
|
257
324
|
network: this.getNetwork(),
|
|
258
325
|
params: this._perform({ method: "getLogs", filter })
|
|
259
326
|
});
|
|
@@ -262,17 +329,17 @@ var SilentDataRollupProvider = class _SilentDataRollupProvider extends import_et
|
|
|
262
329
|
};
|
|
263
330
|
|
|
264
331
|
// src/sdInterface.ts
|
|
265
|
-
var
|
|
266
|
-
var
|
|
267
|
-
var debugLog = (0,
|
|
268
|
-
var SDInterface = class extends
|
|
332
|
+
var import_debug2 = __toESM(require("debug"));
|
|
333
|
+
var import_ethers3 = require("ethers");
|
|
334
|
+
var debugLog = (0, import_debug2.default)(DEBUG_NAMESPACE);
|
|
335
|
+
var SDInterface = class extends import_ethers3.Interface {
|
|
269
336
|
/**
|
|
270
337
|
* Extends the parseLog method to handle PrivateEvent logs
|
|
271
338
|
* @param log - The log to parse
|
|
272
339
|
* @returns The parsed log description with additional private event details if applicable
|
|
273
340
|
*/
|
|
274
|
-
parseLog(
|
|
275
|
-
const parsedLog = super.parseLog(
|
|
341
|
+
parseLog(log2) {
|
|
342
|
+
const parsedLog = super.parseLog(log2);
|
|
276
343
|
if (!parsedLog) {
|
|
277
344
|
debugLog(
|
|
278
345
|
"Failed to parse log - no matching event found or event is anonymous"
|
package/dist/index.mjs
CHANGED
|
@@ -2,14 +2,19 @@
|
|
|
2
2
|
var DEBUG_NAMESPACE = "silentdata:ethers-provider";
|
|
3
3
|
|
|
4
4
|
// src/provider.ts
|
|
5
|
+
import debug from "debug";
|
|
5
6
|
import {
|
|
6
7
|
calculateEventTypeHash,
|
|
7
8
|
ChainId,
|
|
9
|
+
DEBUG_NAMESPACE as DEBUG_NAMESPACE2,
|
|
8
10
|
HEADER_DELEGATE,
|
|
9
11
|
HEADER_DELEGATE_SIGNATURE,
|
|
10
12
|
HEADER_EIP712_DELEGATE_SIGNATURE,
|
|
11
13
|
HEADER_EIP712_SIGNATURE,
|
|
14
|
+
HEADER_FROM_BLOCK,
|
|
12
15
|
HEADER_SIGNATURE,
|
|
16
|
+
HEADER_SIGNATURE_TYPE,
|
|
17
|
+
HEADER_SIGNER_SWC,
|
|
13
18
|
HEADER_TIMESTAMP,
|
|
14
19
|
isSignableContractCall,
|
|
15
20
|
NetworkName,
|
|
@@ -26,6 +31,57 @@ import {
|
|
|
26
31
|
resolveProperties,
|
|
27
32
|
Wallet
|
|
28
33
|
} from "ethers";
|
|
34
|
+
|
|
35
|
+
// src/signer.ts
|
|
36
|
+
import {
|
|
37
|
+
AbstractSigner,
|
|
38
|
+
assert
|
|
39
|
+
} from "ethers";
|
|
40
|
+
var SilentDataRollupSigner = class extends AbstractSigner {
|
|
41
|
+
constructor(provider, signer) {
|
|
42
|
+
if (!provider) {
|
|
43
|
+
throw new Error("Provider is required");
|
|
44
|
+
}
|
|
45
|
+
if (!signer) {
|
|
46
|
+
throw new Error("Signer is required");
|
|
47
|
+
}
|
|
48
|
+
super(provider);
|
|
49
|
+
this.signer = signer;
|
|
50
|
+
}
|
|
51
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
52
|
+
connect(provider) {
|
|
53
|
+
assert(
|
|
54
|
+
false,
|
|
55
|
+
"cannot reconnect SilentDataRollupSigner",
|
|
56
|
+
"UNSUPPORTED_OPERATION",
|
|
57
|
+
{
|
|
58
|
+
operation: "signer.connect"
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
async getAddress() {
|
|
63
|
+
return this.signer.getAddress();
|
|
64
|
+
}
|
|
65
|
+
async signTransaction(tx) {
|
|
66
|
+
return this.signer.signTransaction(tx);
|
|
67
|
+
}
|
|
68
|
+
async signMessage(message) {
|
|
69
|
+
return this.signer.signMessage(message);
|
|
70
|
+
}
|
|
71
|
+
signTypedData(domain, types, value) {
|
|
72
|
+
return this.signer.signTypedData(domain, types, value);
|
|
73
|
+
}
|
|
74
|
+
async sendTransaction(tx) {
|
|
75
|
+
let gasLimit = tx.gasLimit;
|
|
76
|
+
if (!gasLimit) {
|
|
77
|
+
gasLimit = await this.estimateGas(tx);
|
|
78
|
+
}
|
|
79
|
+
return this.signer.sendTransaction({ ...tx, gasLimit });
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// src/provider.ts
|
|
84
|
+
var log = debug(DEBUG_NAMESPACE2);
|
|
29
85
|
function isPromise(value) {
|
|
30
86
|
return value && typeof value.then === "function";
|
|
31
87
|
}
|
|
@@ -61,14 +117,17 @@ var SilentDataRollupProvider = class _SilentDataRollupProvider extends JsonRpcPr
|
|
|
61
117
|
"config",
|
|
62
118
|
config
|
|
63
119
|
);
|
|
64
|
-
this.baseProvider = new SilentDataRollupBase(
|
|
120
|
+
this.baseProvider = new SilentDataRollupBase({
|
|
121
|
+
...config,
|
|
122
|
+
smartWalletAddress: config.smartWalletAddress
|
|
123
|
+
});
|
|
65
124
|
this.config = config;
|
|
66
125
|
this.config.authSignatureType = config.authSignatureType || SignatureType.Raw;
|
|
67
126
|
if (config.signer) {
|
|
68
127
|
try {
|
|
69
128
|
this.signer = config.signer.connect(this);
|
|
70
129
|
} catch {
|
|
71
|
-
this.signer = config.signer;
|
|
130
|
+
this.signer = new SilentDataRollupSigner(this, config.signer);
|
|
72
131
|
}
|
|
73
132
|
} else {
|
|
74
133
|
const wallet = new Wallet(config.privateKey);
|
|
@@ -79,6 +138,9 @@ var SilentDataRollupProvider = class _SilentDataRollupProvider extends JsonRpcPr
|
|
|
79
138
|
if (Array.isArray(payload)) {
|
|
80
139
|
throw new Error("Batch requests are not currently supported");
|
|
81
140
|
}
|
|
141
|
+
if (["eth_getBlockByNumber", "eth_getBlockByHash"].includes(payload.method) && Array.isArray(payload.params) && payload.params.length > 1) {
|
|
142
|
+
payload.params[1] = false;
|
|
143
|
+
}
|
|
82
144
|
const isEthCallOrEstimateGas = payload.method === "eth_call" || payload.method === "eth_estimateGas";
|
|
83
145
|
if (isEthCallOrEstimateGas && Array.isArray(payload.params)) {
|
|
84
146
|
const txParams = payload.params[0];
|
|
@@ -100,7 +162,7 @@ var SilentDataRollupProvider = class _SilentDataRollupProvider extends JsonRpcPr
|
|
|
100
162
|
const request = this._getConnection();
|
|
101
163
|
request.body = JSON.stringify(payload);
|
|
102
164
|
request.setHeader("content-type", "application/json");
|
|
103
|
-
const requiresAuthHeaders = isPrivateLogsRequest || SIGN_RPC_METHODS.includes(payload.method) || isSignableContractCall(payload, this.baseProvider.contracts);
|
|
165
|
+
const requiresAuthHeaders = isPrivateLogsRequest || SIGN_RPC_METHODS.includes(payload.method) || isSignableContractCall(payload, this.baseProvider.contracts) || this.config.alwaysSignEthCalls && payload.method === "eth_call";
|
|
104
166
|
if (requiresAuthHeaders) {
|
|
105
167
|
if (this.config.delegate) {
|
|
106
168
|
const {
|
|
@@ -119,10 +181,15 @@ var SilentDataRollupProvider = class _SilentDataRollupProvider extends JsonRpcPr
|
|
|
119
181
|
);
|
|
120
182
|
}
|
|
121
183
|
}
|
|
184
|
+
if (this.config.smartWalletAddress) {
|
|
185
|
+
log("Setting smart wallet header:", this.config.smartWalletAddress);
|
|
186
|
+
request.setHeader(HEADER_SIGNER_SWC, this.config.smartWalletAddress);
|
|
187
|
+
}
|
|
122
188
|
const {
|
|
123
189
|
[HEADER_TIMESTAMP]: xTimestamp,
|
|
124
190
|
[HEADER_SIGNATURE]: xSignature,
|
|
125
|
-
[HEADER_EIP712_SIGNATURE]: xEip712Signature
|
|
191
|
+
[HEADER_EIP712_SIGNATURE]: xEip712Signature,
|
|
192
|
+
[HEADER_FROM_BLOCK]: xFromBlock
|
|
126
193
|
} = await this.baseProvider.getAuthHeaders(this, payload);
|
|
127
194
|
request.setHeader(HEADER_TIMESTAMP, xTimestamp);
|
|
128
195
|
if (xSignature) {
|
|
@@ -131,6 +198,13 @@ var SilentDataRollupProvider = class _SilentDataRollupProvider extends JsonRpcPr
|
|
|
131
198
|
if (xEip712Signature) {
|
|
132
199
|
request.setHeader(HEADER_EIP712_SIGNATURE, xEip712Signature);
|
|
133
200
|
}
|
|
201
|
+
if (xFromBlock) {
|
|
202
|
+
request.setHeader(HEADER_FROM_BLOCK, xFromBlock);
|
|
203
|
+
}
|
|
204
|
+
const signatureType = this.config.authSignatureType ?? SignatureType.EIP191;
|
|
205
|
+
if (signatureType) {
|
|
206
|
+
request.setHeader(HEADER_SIGNATURE_TYPE, signatureType);
|
|
207
|
+
}
|
|
134
208
|
}
|
|
135
209
|
const response = await request.send();
|
|
136
210
|
response.assertOk();
|
|
@@ -246,17 +320,17 @@ var SilentDataRollupProvider = class _SilentDataRollupProvider extends JsonRpcPr
|
|
|
246
320
|
};
|
|
247
321
|
|
|
248
322
|
// src/sdInterface.ts
|
|
249
|
-
import
|
|
323
|
+
import debug2 from "debug";
|
|
250
324
|
import { Interface } from "ethers";
|
|
251
|
-
var debugLog =
|
|
325
|
+
var debugLog = debug2(DEBUG_NAMESPACE);
|
|
252
326
|
var SDInterface = class extends Interface {
|
|
253
327
|
/**
|
|
254
328
|
* Extends the parseLog method to handle PrivateEvent logs
|
|
255
329
|
* @param log - The log to parse
|
|
256
330
|
* @returns The parsed log description with additional private event details if applicable
|
|
257
331
|
*/
|
|
258
|
-
parseLog(
|
|
259
|
-
const parsedLog = super.parseLog(
|
|
332
|
+
parseLog(log2) {
|
|
333
|
+
const parsedLog = super.parseLog(log2);
|
|
260
334
|
if (!parsedLog) {
|
|
261
335
|
debugLog(
|
|
262
336
|
"Failed to parse log - no matching event found or event is anonymous"
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@appliedblockchain/silentdatarollup-ethers-provider",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Ethers.js provider for Silent Data
|
|
3
|
+
"version": "1.0.9",
|
|
4
|
+
"description": "Ethers.js provider for Silent Data",
|
|
5
5
|
"author": "Applied Blockchain",
|
|
6
6
|
"homepage": "https://github.com/appliedblockchain/silent-data-rollup-providers#readme",
|
|
7
7
|
"keywords": [
|
|
@@ -25,23 +25,23 @@
|
|
|
25
25
|
"files": [
|
|
26
26
|
"dist"
|
|
27
27
|
],
|
|
28
|
-
"scripts": {
|
|
29
|
-
"build": "tsc --noEmit && tsup src/index.ts --format cjs,esm --dts --clean",
|
|
30
|
-
"check-exports": "attw --pack . --profile node16",
|
|
31
|
-
"prepack": "npm run build",
|
|
32
|
-
"test": "jest"
|
|
33
|
-
},
|
|
34
28
|
"dependencies": {
|
|
35
|
-
"@appliedblockchain/silentdatarollup-core": "1.0.7",
|
|
36
29
|
"debug": "4.3.7",
|
|
37
|
-
"ethers": "6.13.2"
|
|
30
|
+
"ethers": "6.13.2",
|
|
31
|
+
"@appliedblockchain/silentdatarollup-core": "1.0.9"
|
|
38
32
|
},
|
|
39
33
|
"devDependencies": {
|
|
40
|
-
"@types/
|
|
34
|
+
"@types/debug": "4.1.12",
|
|
35
|
+
"@types/node": "24.10.1",
|
|
41
36
|
"ts-node": "10.9.2",
|
|
42
37
|
"typescript": "5.6.2"
|
|
43
38
|
},
|
|
44
39
|
"engines": {
|
|
45
40
|
"node": ">=18.0.0"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsc --noEmit && tsup src/index.ts --format cjs,esm --dts --clean",
|
|
44
|
+
"check-exports": "attw --pack . --profile node16",
|
|
45
|
+
"test": "jest"
|
|
46
46
|
}
|
|
47
|
-
}
|
|
47
|
+
}
|