@woof-software/contracts-tools-sdk-ethers 0.0.21 → 0.0.23

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.
Files changed (2) hide show
  1. package/README.md +555 -2
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,8 +1,561 @@
1
1
  # @woof-software/contracts-tools-sdk-ethers
2
2
 
3
- Provides logic for ethers interactions.
3
+ ## Description
4
4
 
5
+ **contracts-tools-sdk-ethers** is a lightweight zero-dependency TypeScript library built on top of [ethers.js](https://github.com/ethers-io/ethers.js) designed to simplify **smart contract** interactions and [multicall3](https://www.multicall3.com/) aggregation on the Ethereum blockchain and other EVM-compatible networks.\
6
+ All of these tools are compatible with TypeScript.\
7
+ JSDoc is provided.
5
8
  ---
6
9
 
10
+ ## Installation
7
11
 
8
- ### See original [README](https://github.com/neuroborus/ethers-tools/blob/main/README.md)
12
+ ```bash
13
+ npm install @woof-software/contracts-tools-sdk-ethers ethers
14
+ ```
15
+
16
+ > **Note:** Requires `ethers@^6.0.0` as a peer dependency.
17
+
18
+ ---
19
+
20
+ ## Quickstart
21
+
22
+ ### **MulticallProvider**
23
+
24
+ ```typescript
25
+ import { ethers } from 'ethers';
26
+
27
+ export const PROVIDER = new ethers.WebSocketProvider(RPC_URL);
28
+ // !: Here is an extra step
29
+ export const MULTICALL_PROVIDER = new MulticallProvider(PROVIDER);
30
+ export const WALLET = new ethers.Wallet(
31
+ '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80',
32
+ MULTICALL_PROVIDER
33
+ );
34
+
35
+ export const contract = new ethers.Contract(
36
+ '0xa513E6E4b8f2a923D98304ec87F64353C4D5C853',
37
+ StorageAbi,
38
+ WALLET
39
+ );
40
+
41
+ const [first, second, both, writeCount, setFirstTx, setSecondTx] =
42
+ await Promise.all([
43
+ contract['getFirst'](),
44
+ contract['getSecond'](),
45
+ contract['getBoth'](),
46
+ contract['getWriteCount'](),
47
+ contract['setFirst'](42),
48
+ ]); // All calls for that event loop iteration will execute as a multicall batch.
49
+
50
+ /*
51
+ * Since transactions are managed by the Signer, unlike with a pure MulticallUnit,
52
+ * view calls are typically executed before write transactions.
53
+ * */
54
+
55
+ expect(typeof first).to.be.eq('bigint');
56
+ ```
57
+
58
+ ### **MulticallUnit and BaseContract usage**
59
+
60
+ ```typescript
61
+ import { ethers } from 'ethers';
62
+ import { BaseContract, ContractCall, MulticallUnit } from '@woof-software/contracts-tools-sdk-ethers';
63
+
64
+ /**
65
+ * --- Setup ---
66
+ */
67
+
68
+ const RPC_URL = 'https://eth.llamarpc.com';
69
+ const ADDRESS = '0xbaA999AC55EAce41CcAE355c77809e68Bb345170';
70
+ const PROVIDER = new ethers.WebSocketProvider(RPC_URL);
71
+
72
+ /**
73
+ * --- BaseContract Definition ---
74
+ */
75
+
76
+ const RegistryAbi = '<abi>';
77
+ class RegistryContract extends BaseContract {
78
+ constructor(address: string, provider: Provider) {
79
+ super(RegistryAbi, address, provider);
80
+ }
81
+
82
+ getAddressesProvidersListCall(): ContractCall {
83
+ return this.getCall('getAddressesProvidersList');
84
+ }
85
+
86
+ owner(): Promise<string> {
87
+ return this.call<string>('owner');
88
+ }
89
+ getOwnerCall(): ContractCall {
90
+ return this.getCall('owner');
91
+ }
92
+ }
93
+
94
+ /*
95
+ * Alternatively, it can be created dynamically based on the ABI:
96
+ *
97
+ * const Registry = BaseContract.createAutoClass(RegistryAbi, ADDRESS, PROVIDER);
98
+ * const registry = new Registry(); // Or args can be bypassed for override
99
+ *
100
+ * Or just:
101
+ *
102
+ * const registry = BaseContract.createAutoInstance(RegistryAbi, ADDRESS, PROVIDER);
103
+ * */
104
+
105
+ /**
106
+ * --- Using Multicall ---
107
+ */
108
+
109
+ const registry = new RegistryContract(ADDRESS, PROVIDER);
110
+ const unit = new MulticallUnit(PROVIDER);
111
+
112
+ const addressesProvidersListTag = 'getAddressesProvidersList';
113
+ const ownerTag = 'owner';
114
+
115
+ // Add calls to unit
116
+ unit.add(registry.getAddressesProvidersListCall(), addressesProvidersListTag);
117
+ unit.add(registry.getOwnerCall(), ownerTag);
118
+
119
+ // Execute multicall
120
+ const isSuccess: boolean = await unit.run();
121
+
122
+ // Retrieve results
123
+ const list = unit.getArray<string[]>(addressesProvidersListTag);
124
+ const owner = unit.getSingle<string>(ownerTag);
125
+
126
+ expect(isSuccess).toBe(true);
127
+ const directOwner = await registry.owner();
128
+ expect(owner).toBe(directOwner);
129
+ expect(JSON.stringify(list)).toBe();
130
+ expect(JSON.stringify(list)).toBe(
131
+ "['0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e''0xcfBf336fe147D643B9Cb705648500e101504B16d','0xeBa440B438Ad808101d1c451C1C5322c90BEFCdA']"
132
+ );
133
+ ```
134
+
135
+ ### **Events listening**
136
+
137
+ ```typescript
138
+ import { ContractEventPayload } from 'ethers';
139
+
140
+ /**
141
+ * --- Listening to Events ---
142
+ */
143
+ const data: Map<string, { address: string; id: bigint }> = new Map();
144
+ // Realtime listening
145
+ registry.listenEvent(
146
+ 'AddressesProviderRegistered',
147
+ (addressesProvider: string, id: bigint, payload: ContractEventPayload) => {
148
+ data.set(payload.log.transactionHash, {
149
+ addressesProvider,
150
+ id,
151
+ });
152
+ }
153
+ );
154
+ // Historical logs from last 30,000 blocks
155
+ for await (const cLog of registry.getLogsStream(-30000, [
156
+ 'AddressesProviderRegistered',
157
+ ])) {
158
+ data.set(cLog.log.transactionHash, cLog.description);
159
+ }
160
+ ```
161
+
162
+ ## BaseContract
163
+
164
+ ### Description
165
+
166
+ **BaseContract** is a parent class for contract classes that includes basic state getters and methods for calling the contract directly or obtaining a `ContractCall` for use in **MulticallUnit**. These methods can be parameterized.
167
+
168
+ ### Driver
169
+
170
+ The driver is either a `Signer` or a `Provider`. The contract's ability to make calls depends on it. An error will occur if you try to call the contract without it, especially when making a mutable call without providing an ethers `Signer` (e.g, `Wallet`) as the driver.
171
+
172
+ ### Fields
173
+
174
+ * `.address` // Address of contract.
175
+ * `.isCallable` // Flag that indicates whether calls (static or mutable) can be made.
176
+ * `.isReadonly` // Flag that indicates whether only static calls are allowed (false if mutable calls are possible).
177
+ * `.interface` // Ethers contract interface.
178
+ * `.contract` // 'Bare' ethers Contract.
179
+ * `.provider` // Ethers Provider.
180
+ * `.signer` // Ethers Signer.
181
+
182
+ ### Methods
183
+
184
+ ```typescript
185
+ constructor(
186
+ abi: Interface | InterfaceAbi,
187
+ address?: string,
188
+ driver?: Signer | Provider,
189
+ options?: ContractOptions
190
+ );
191
+ ```
192
+
193
+ * `static createAutoClass( abi: Interface | InterfaceAbi, address?: string, driver?: Provider | Signer, options?: ContractOptions ): DynamicContractConstructor` // Creates a subclass of the BaseContract with dynamically generated methods based on the functions defined in the provided ABI.
194
+ * `static createAutoInstance( abi: Interface | InterfaceAbi, address?: string, driver?: Provider | Signer, options?: ContractOptions ): DynamicContract` // Instantiates a DynamicContract with methods automatically generated from the provided ABI.
195
+ * `call<T = unknown>(methodName: string, args?: any[], options?: CallOptions): Promise<T>` // Performs a single on-chain call for the contract. Throws an error if unable to execute.
196
+ * `estimate(method: string, args?: any[], options?: ContractCallOptions): Promise<bigint>;` // Estimates gas required to execute a contract method.
197
+ * `getCall(methodName: string, args?: any[], callData?: Partial<ContractCall>): ContractCall` // Creates a `ContractCall` for `MulticallUnit`. Throws an error if unable to create. You can do force replacement with a `callData` parameter.
198
+ * `listenEvent(eventName: string, listener: Listener): Promise<Contract>` // Creates event listener on the contract. WebsocketProvider is required.
199
+ * `getLogs(fromBlock: number, eventsNames?: string[], toBlock?: number, options?: ContractGetLogsOptions): Promise<ContractLog[]>` // Synchronous log retrieval. 'fromBlocks' can have a minus sign, which means 'n blocks ago'.
200
+ * `getLogsStream(fromBlock: number, eventsNames?: string[], toBlock?: number, options?: ContractGetLogsOptions): AsyncGenerator<ContractLog, void>` // Asynchronous way to getting logs.
201
+
202
+ **ContractOptions**
203
+
204
+ ```typescript
205
+ export interface ContractOptions {
206
+ forceMutability?: CallMutability; // By default, BaseContract/MulticallUnit automatically detects the mutability of the method(s). You can force it.
207
+ highPriorityTxs?: boolean; // If activated, calls as "high priority tx": multiply gasPrice and gasLimit by multiplier. It takes additional requests to get them.
208
+ priorityOptions?: PriorityCallOptions; // Only matters if `highPriorityTx` is activated.
209
+ logsBlocksStep?: number; // Quantity of processed blocks per iteration during log parsing.
210
+ logsDelayMs?: number; // Delay between log parsing iterations.
211
+ signals?: AbortSignal[]; // Can be passed for abort signal control
212
+ staticCallsTimeoutMs?: number; // Timeout for static calls in ms. DEFAULT: 10000
213
+ mutableCallsTimeoutMs?: number; // Timeout for mutable calls in ms. DEFAULT: 20000
214
+ }
215
+ export interface PriorityCallOptions {
216
+ asynchronous?: boolean; // Can be a little faster if provider allows (simultaneously getting gasPrice & gasLimit).
217
+ chainId?: bigint; // Manually set. (Prevents replay attacks by ensuring the transaction is valid only for the intended blockchain network)
218
+ provideChainId?: boolean; // Automatic - additional async request. (Prevents replay attacks by ensuring the transaction is valid only for the intended blockchain network)
219
+ multiplier?: number; // Multiplier for gasPrise and gasLimit values.
220
+ signals?: AbortSignal[]; // Can be passed for abort signal control
221
+ timeoutMs?: number; // Timeout in milliseconds. If not provided, there is no default option.
222
+ }
223
+ ```
224
+
225
+ **ContractCall**
226
+
227
+ ```typescript
228
+ export type ContractCall = {
229
+ // Optional params are using for the result parsing
230
+ method?: string; // Name of the method.
231
+ contractInterface?: ethers.Interface; // Interface of the callable contract. Uses for answer decoding.
232
+ target: string; // Address of contract.
233
+ allowFailure: boolean; // Failure allowance - false by default (*). DEFAULT: false
234
+ callData: string; // Encoded function data - uses in multicall.
235
+ stateMutability: StateMutability; // Shows mutability of the method.
236
+ };
237
+ export declare enum StateMutability {
238
+ View = 'view',
239
+ Pure = 'pure',
240
+ NonPayable = 'nonpayable',
241
+ Payable = 'payable',
242
+ }
243
+ ```
244
+
245
+ **ContractGetLogsOptions**
246
+
247
+ ```typescript
248
+ export interface ContractGetLogsOptions {
249
+ blocksStep?: number; // Quantity of processed blocks per iteration during log parsing
250
+ delayMs?: number; // Delay between log parsing iterations.
251
+ signals?: AbortSignal[]; // Can be passed for abort signal control
252
+ }
253
+ ```
254
+
255
+ **ContractLog**
256
+
257
+ ```typescript
258
+ export interface ContractLog {
259
+ log: Log; // Info about log
260
+ description: LogDescription; // Parsed data
261
+ }
262
+ ```
263
+
264
+ ## MulticallUnit
265
+
266
+ ### Description
267
+
268
+ **MulticallUnit** is a tool that takes a calls (`ContractCall`). When the `run()` method is invoked, it splits the stored calls into mutable and static, prioritizing mutable calls. It then processes them by stacks. The size of the concurrently processed call stack for mutable and static calls can be adjusted separately via `MulticallOptions`, along with other parameters.
269
+
270
+ ### Tags
271
+
272
+ Tags serve as unique references for your specific calls. They support **single values, arrays, and records**.\
273
+ This can be useful for complex calls.
274
+
275
+ ```typescript
276
+ export type Keyable = string | number | symbol;
277
+ export type Tagable = Keyable | bigint;
278
+
279
+ export type MulticallTags = Tagable | Tagable[] | Record<Keyable, Tagable>;
280
+ ```
281
+
282
+ ### Fields
283
+
284
+ * `.tags` // Array of provided tags.
285
+ * `.calls` // Array of provided calls.
286
+ * `.response` // Array of the whole response.
287
+ * `.success` // Flag that indicates whether all calls were successful.
288
+ * `.static` // Flag that indicates whether all calls are static (not mutable).
289
+ * `.executing` // Flag that indicates if `run()` executing at the moment.
290
+
291
+ ### Methods
292
+
293
+ ```typescript
294
+ constructor(
295
+ driver: Signer | Provider,
296
+ options?: MulticallOptions, // Default options for the each run.
297
+ multicallAddress?: string, // You can use any address. Useful for less popular networks.
298
+ );
299
+ ```
300
+ * `add(contractCall: ContractCall, tags?: MulticallTags): MulticallTags` // Add new call. Returns Tags as reference.
301
+ * `run(options?: MulticallOptions): Promise<boolean>` // Executes the multicall operation.
302
+ * `estimateRun(options?: MulticallOptions): Promise<bigint[]>` // Estimates gas for each batch of mutable calls (estimates .run() method).
303
+
304
+
305
+ * `get<T>(tags: MulticallTags): T | null` // Returns the decoded result for the specified tag.
306
+ * `getOrThrow<T>(tags: MulticallTags): T` // Same as get(), but throws an error if the result is missing or cannot be decoded.
307
+ * `getSingle<T>(tags: MulticallTags): T | undefined` // Get single primitive value as result.
308
+ * `getSingleOrThrow<T>(tags: MulticallTags): T;` // The same but throws an error if not found.
309
+ * `getArray<T>(tags: MulticallTags, deep?: boolean): T | undefined` // Get array as result.
310
+ * `getArrayOrThrow<T>(tags: MulticallTags, deep?: boolean): T` // The same but throws an error if not found.
311
+ * `getObject<T>(tags: MulticallTags, deep?: boolean): T | undefined` // Get object as result. Works with named fields in ABI.
312
+ * `getObjectOrThrow<T>(tags: MulticallTags, deep?: boolean): T` // The same but throws an error if not found.
313
+ * `getRaw(tags: MulticallTags): string | null` // Get the raw call result.
314
+ * `getTxResponse(tags: MulticallTags): TransactionResponse | null` // Returns TransactionResponse for the mutable call.
315
+ * `getTxResponseOrThrow(tags: MulticallTags): TransactionResponse` // Returns TransactionResponse for the mutable call or throws if not found.
316
+ * `getTxReceipt(tags: MulticallTags): TransactionReceipt | null` // Returns TransactionReceipt for the mutable call.
317
+
318
+
319
+ * `wait<T>(tags: MulticallTags, options?: MulticallWaitOptions): Promise<void>` // Waiting for the call execution.
320
+ * `waitFor<T>(tags: MulticallTags, options?: MulticallWaitOptions): Promise<T>` // Waiting for the parsed call result.
321
+ * `waitRaw(tags: MulticallTags, options?: MulticallWaitOptions): Promise<string | null>;` // Waiting for the specific raw data.
322
+ * `waitRawOrThrow(tags: MulticallTags, options?: MulticallWaitOptions): Promise<string>;` // Same as waitRaw, but throws if not found.
323
+ * `waitTx(tags: MulticallTags, options?: MulticallWaitOptions): Promise<string | null>;` // Waiting for the TransactionResponse for the specific call.
324
+ * `waitTxOrThrow(tags: MulticallTags, options?: MulticallWaitOptions): Promise<string>;` // Same as waitTx, but throws if not found.
325
+
326
+
327
+ * `isSuccess(tags: MulticallTags): boolean | undefined` // Check if call finished successfully.
328
+ * `clear(): void` // Completely clears the Unit for reuse.
329
+
330
+ ### **MulticallOptions**
331
+
332
+ ```typescript
333
+ export interface MulticallOptions {
334
+ forceMutability?: CallMutability; // Allows to force mutability. It will try to call as static or mutable if you want to.
335
+ waitForTxs?: boolean; // Wait for every transaction. Turned on by default for nonce safety. DEFAULT: true
336
+ highPriorityTxs?: boolean; // You can make priority transaction when it is necessary. Requires more calls, but will be processed more quickly.
337
+ priorityOptions?: PriorityCallOptions; // Only matters if `highPriorityTxs` is turned on.
338
+ maxStaticCallsStack?: number; // The maximum size of one static execution. If it overfills, the multicall performs additional executions. DEFAULT: 50
339
+ maxMutableCallsStack?: number; // The maximum size of one mutable execution. If it overfills, the multicall performs additional executions. DEFAULT: 10
340
+ signals?: AbortSignal[]; // Can be passed for abort signal control
341
+ staticCallsTimeoutMs?: number; // Timeout for static calls in ms. DEFAULT: 10000
342
+ mutableCallsTimeoutMs?: number; // Timeout for mutable calls in ms. DEFAULT: 20000
343
+ waitCallsTimeoutMs?: number; // Timeout for waiting in ms. DEFAULT: 30000
344
+ batchDelayMs?: number; // Delay between batch calls. DEFAULT: 0
345
+ maxAsyncReadBatches?: number; // Maximum number of read batches to be executed concurrently. DEFAULT: 1
346
+ }
347
+ export enum CallMutability {
348
+ Static = 'STATIC',
349
+ Mutable = 'MUTABLE',
350
+ }
351
+ ```
352
+
353
+ ### MulticallDecodableData
354
+
355
+ ```typescript
356
+ export interface MulticallDecodableData {
357
+ call: ContractCall;
358
+ tags?: Tagable;
359
+ }
360
+ ```
361
+
362
+ **Warning (\*)**
363
+
364
+ Since in the case of a **mutable call**, the result is not returned but rather **a transaction or a receipt**, `getRaw` for a single **calls batch** will provide the same information. As a result, using `allowFailure` will lead to inconsistent results. When using `allowFailure`, _make sure that you do not need to track the outcome of a specific execution_.
365
+
366
+ ## Config
367
+
368
+ Configuration can be set globally or at specific points, such as when creating objects or making calls.
369
+
370
+ ```typescript
371
+ import { config } from '@woof-software/contracts-tools-sdk-ethers';
372
+
373
+ config.multicallUnit.mutableCalls.batchLimit = 3;
374
+ ```
375
+
376
+ ```typescript
377
+ export type Config = {
378
+ multicallUnit: {
379
+ /** Multicall contract address */
380
+ address: string;
381
+
382
+ /** If true, allows individual call failures without failing the entire batch */
383
+ allowFailure: boolean;
384
+
385
+ /** If true, waits for transaction confirmations in mutable calls */
386
+ waitForTxs: boolean;
387
+
388
+ /** Settings for read-only (eth_call) operations */
389
+ staticCalls: {
390
+ /** Maximum number of static calls per batch */
391
+ batchLimit: number;
392
+
393
+ /** Timeout for each static call in milliseconds */
394
+ timeoutMs: number;
395
+ };
396
+
397
+ /** Settings for state-changing (eth_sendTransaction) operations */
398
+ mutableCalls: {
399
+ /** Maximum number of mutable calls per batch */
400
+ batchLimit: number;
401
+
402
+ /** Timeout for each mutable call in milliseconds */
403
+ timeoutMs: number;
404
+ };
405
+
406
+ /** Settings for waiting on call results */
407
+ waitCalls: {
408
+ /** Timeout for awaiting results of batched calls */
409
+ timeoutMs: number;
410
+ };
411
+
412
+ /** Settings for prioritizing certain calls */
413
+ priorityCalls: {
414
+ /** Priority multiplier to determine weight/importance of selected calls */
415
+ multiplier: number;
416
+ };
417
+
418
+ /** Delay between batch calls */
419
+ batchDelayMs: number;
420
+
421
+ /** Maximum number of read batches to be executed concurrently */
422
+ maxAsyncReadBatches: number;
423
+ };
424
+
425
+ contract: {
426
+ /** Global static call timeout for individual contract methods */
427
+ staticCalls: {
428
+ /** Timeout for static contract calls in milliseconds */
429
+ timeoutMs: number;
430
+ };
431
+
432
+ /** Global mutable call timeout for individual contract methods */
433
+ mutableCalls: {
434
+ /** Timeout for mutable contract calls in milliseconds */
435
+ timeoutMs: number;
436
+ };
437
+
438
+ /** Parameters for event log fetching and listening */
439
+ logsGathering: {
440
+ /** Number of blocks to query per log fetch request */
441
+ blocksStep: number;
442
+
443
+ /** Delay between log fetch requests in milliseconds */
444
+ delayMs: number;
445
+ };
446
+ };
447
+
448
+ /** Default priority settings for individual call execution */
449
+ priorityCalls: {
450
+ /** Default multiplier for priority call handling */
451
+ multiplier: number;
452
+ };
453
+ };
454
+ ```
455
+
456
+ ## Other
457
+
458
+ **Helpers**
459
+
460
+ ```typescript
461
+ export declare const priorityCall: (
462
+ // Function that allows making custom priority calls
463
+ provider: Provider,
464
+ signer: Signer,
465
+ contract: Contract,
466
+ method: string,
467
+ args: any[],
468
+ options: PriorityCallOptions
469
+ ) => Promise<TransactionResponse>;
470
+ ```
471
+
472
+ ```typescript
473
+ export declare const priorityCallEstimate: (
474
+ // Function that allows you to estimate gas for your custom priority calls
475
+ provider: Provider,
476
+ signer: Signer,
477
+ contract: Contract,
478
+ method: string,
479
+ args: any[],
480
+ options: PriorityCallOptions
481
+ ) => Promise<bigint>;
482
+ ```
483
+
484
+ ```typescript
485
+ export declare const waitForAddressTxs: (
486
+ // Function that waits for the end of all users transactions
487
+ address: string,
488
+ provider: Provider,
489
+ delayMs?: number
490
+ ) => Promise<void>;
491
+ ```
492
+
493
+ ```typescript
494
+ // Indicates whether the call has all the necessary parameters for parsing
495
+ export declare const isParsable: (call: ContractCall) => boolean;
496
+ ```
497
+
498
+ ```typescript
499
+ // Accepts mutability and says if method is static
500
+ export declare const isStaticMethod: (
501
+ state: StateMutability | string
502
+ ) => boolean;
503
+ ```
504
+
505
+ ```typescript
506
+ // Accepts array of ContractCalls and says if all methods are static
507
+ export declare const isStaticArray: (calls: ContractCall[]) => boolean;
508
+ ```
509
+
510
+ ```typescript
511
+ // Generates Tag for Multicall Unit
512
+ export declare const multicallGenerateTag: () => string;
513
+ ```
514
+
515
+ **Entities**
516
+
517
+ ```typescript
518
+ // Contains more than 250 different chains.
519
+ // Supports JS as struct. All of these chains right now supports multicall3.
520
+ export enum Chain {
521
+ Mainnet = 1,
522
+ Kovan = 42,
523
+ Rinkeby = 4,
524
+ // And other 250+ chains...
525
+ }
526
+ ```
527
+
528
+ **Utilities**
529
+
530
+ ```typescript
531
+ // Check AbortSignal[] and throw if any signal is aborted.
532
+ export declare const checkSignals: (signals: AbortSignal[]) => void;
533
+ ```
534
+
535
+ ```typescript
536
+ // Create a promise for signals to use in race conditions
537
+ export declare const createSignalsPromise: (
538
+ signals: AbortSignal[]
539
+ ) => Promise<never>;
540
+ ```
541
+
542
+ ```typescript
543
+ // Create a signal from a timeout in milliseconds.
544
+ export declare const createTimeoutSignal: (ms: number) => AbortSignal;
545
+ ```
546
+
547
+ ```typescript
548
+ // Race the provided function (racer) with the given signals.
549
+ export declare const raceWithSignals: <T>(
550
+ racer: () => Promise<T>,
551
+ signals?: AbortSignal[]
552
+ ) => Promise<T>;
553
+ ```
554
+
555
+ ```typescript
556
+ // Wait while listening to signals
557
+ export declare const waitWithSignals: (
558
+ ms: number,
559
+ signals?: AbortSignal[]
560
+ ) => Promise<void>;
561
+ ```
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@woof-software/contracts-tools-sdk-ethers",
3
3
  "description": "Module simplify smart contract interactions and multicall3 aggregation on the Ethereum blockchain and other EVM-compatible networks.",
4
- "version": "0.0.21",
4
+ "version": "0.0.23",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/woof-compound/sandbox-sdks.git"