@woof-software/contracts-tools-sdk-ethers 0.0.1

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 (103) hide show
  1. package/README.md +8 -0
  2. package/lib/abis/index.d.ts +2 -0
  3. package/lib/abis/index.js +2 -0
  4. package/lib/abis/multicall.abi.json +440 -0
  5. package/lib/config.d.ts +37 -0
  6. package/lib/config.js +38 -0
  7. package/lib/constant.d.ts +12 -0
  8. package/lib/constant.js +12 -0
  9. package/lib/contract/base-contract.d.ts +23 -0
  10. package/lib/contract/base-contract.js +191 -0
  11. package/lib/contract/contract-create-call-name.d.ts +1 -0
  12. package/lib/contract/contract-create-call-name.js +1 -0
  13. package/lib/contract/index.d.ts +1 -0
  14. package/lib/contract/index.js +1 -0
  15. package/lib/errors/contracts-errors.d.ts +9 -0
  16. package/lib/errors/contracts-errors.js +9 -0
  17. package/lib/errors/index.d.ts +2 -0
  18. package/lib/errors/index.js +2 -0
  19. package/lib/errors/multicall-errors.d.ts +8 -0
  20. package/lib/errors/multicall-errors.js +8 -0
  21. package/lib/helpers/index.d.ts +6 -0
  22. package/lib/helpers/index.js +6 -0
  23. package/lib/helpers/is-parsable.d.ts +2 -0
  24. package/lib/helpers/is-parsable.js +1 -0
  25. package/lib/helpers/is-signer.d.ts +2 -0
  26. package/lib/helpers/is-signer.js +3 -0
  27. package/lib/helpers/is-static-array.d.ts +2 -0
  28. package/lib/helpers/is-static-array.js +2 -0
  29. package/lib/helpers/is-static-method.d.ts +2 -0
  30. package/lib/helpers/is-static-method.js +4 -0
  31. package/lib/helpers/priority-call.d.ts +5 -0
  32. package/lib/helpers/priority-call.js +55 -0
  33. package/lib/helpers/wait-for-address-txs.d.ts +2 -0
  34. package/lib/helpers/wait-for-address-txs.js +9 -0
  35. package/lib/index.d.ts +5 -0
  36. package/lib/index.js +5 -0
  37. package/lib/multicall/index.d.ts +5 -0
  38. package/lib/multicall/index.js +5 -0
  39. package/lib/multicall/multicall-error-event-name.d.ts +2 -0
  40. package/lib/multicall/multicall-error-event-name.js +1 -0
  41. package/lib/multicall/multicall-generate-tag.d.ts +1 -0
  42. package/lib/multicall/multicall-generate-tag.js +1 -0
  43. package/lib/multicall/multicall-normalize-tags.d.ts +2 -0
  44. package/lib/multicall/multicall-normalize-tags.js +6 -0
  45. package/lib/multicall/multicall-result-event-name.d.ts +2 -0
  46. package/lib/multicall/multicall-result-event-name.js +1 -0
  47. package/lib/multicall/multicall-split-calls.d.ts +2 -0
  48. package/lib/multicall/multicall-split-calls.js +19 -0
  49. package/lib/multicall/multicall-unit.d.ts +48 -0
  50. package/lib/multicall/multicall-unit.js +367 -0
  51. package/lib/types/call-mutability.d.ts +4 -0
  52. package/lib/types/call-mutability.js +5 -0
  53. package/lib/types/contract/contract-auto-methods.d.ts +13 -0
  54. package/lib/types/contract/contract-auto-methods.js +1 -0
  55. package/lib/types/contract/contract-call-options.d.ts +9 -0
  56. package/lib/types/contract/contract-call-options.js +1 -0
  57. package/lib/types/contract/contract-call.d.ts +10 -0
  58. package/lib/types/contract/contract-call.js +1 -0
  59. package/lib/types/contract/contract-get-logs-options.d.ts +5 -0
  60. package/lib/types/contract/contract-get-logs-options.js +1 -0
  61. package/lib/types/contract/contract-options.d.ts +12 -0
  62. package/lib/types/contract/contract-options.js +1 -0
  63. package/lib/types/contract/dynamic-contract-constructor-args.d.ts +8 -0
  64. package/lib/types/contract/dynamic-contract-constructor-args.js +1 -0
  65. package/lib/types/contract/dynamic-contract-constructor.d.ts +3 -0
  66. package/lib/types/contract/dynamic-contract-constructor.js +1 -0
  67. package/lib/types/contract/dynamic-contract.d.ts +3 -0
  68. package/lib/types/contract/dynamic-contract.js +1 -0
  69. package/lib/types/contract/index.d.ts +6 -0
  70. package/lib/types/contract/index.js +6 -0
  71. package/lib/types/index.d.ts +6 -0
  72. package/lib/types/index.js +6 -0
  73. package/lib/types/multicall/index.d.ts +5 -0
  74. package/lib/types/multicall/index.js +5 -0
  75. package/lib/types/multicall/multicall-decodable-data.d.ts +5 -0
  76. package/lib/types/multicall/multicall-decodable-data.js +1 -0
  77. package/lib/types/multicall/multicall-options.d.ts +15 -0
  78. package/lib/types/multicall/multicall-options.js +1 -0
  79. package/lib/types/multicall/multicall-response.d.ts +5 -0
  80. package/lib/types/multicall/multicall-response.js +1 -0
  81. package/lib/types/multicall/multicall-tags.d.ts +4 -0
  82. package/lib/types/multicall/multicall-tags.js +1 -0
  83. package/lib/types/multicall/multicall-wait-options.d.ts +5 -0
  84. package/lib/types/multicall/multicall-wait-options.js +1 -0
  85. package/lib/types/priority-call-options.d.ts +8 -0
  86. package/lib/types/priority-call-options.js +1 -0
  87. package/lib/types/split-calls.d.ts +9 -0
  88. package/lib/types/split-calls.js +1 -0
  89. package/lib/types/state-mutabiity.d.ts +6 -0
  90. package/lib/types/state-mutabiity.js +7 -0
  91. package/lib/utils/check-signals.d.ts +1 -0
  92. package/lib/utils/check-signals.js +4 -0
  93. package/lib/utils/create-signals-promise.d.ts +1 -0
  94. package/lib/utils/create-signals-promise.js +8 -0
  95. package/lib/utils/create-timeout-signal.d.ts +1 -0
  96. package/lib/utils/create-timeout-signal.js +5 -0
  97. package/lib/utils/index.d.ts +6 -0
  98. package/lib/utils/index.js +6 -0
  99. package/lib/utils/race-with-signals.d.ts +1 -0
  100. package/lib/utils/race-with-signals.js +9 -0
  101. package/lib/utils/wait-with-signals.d.ts +1 -0
  102. package/lib/utils/wait-with-signals.js +18 -0
  103. package/package.json +44 -0
@@ -0,0 +1,191 @@
1
+ import { Contract as EthersContract, Wallet, WebSocketProvider, } from "ethers";
2
+ import { config } from "../config";
3
+ import { CONTRACTS_ERRORS } from "../errors";
4
+ import { isSigner, isStaticMethod } from "../helpers";
5
+ import { CallMutability, } from "../types";
6
+ import { checkSignals, createTimeoutSignal, priorityCall, raceWithSignals, waitWithSignals, } from "../utils";
7
+ import { contractCreateCallName } from "./contract-create-call-name";
8
+ export class BaseContract {
9
+ static createAutoClass(abi, address, driver, options) {
10
+ return class extends this {
11
+ constructor(args) {
12
+ super(args?.abi || abi, args?.address || address, args?.driver || driver, args?.options || options);
13
+ for (const fragment of Object.values(this.interface.fragments)) {
14
+ if (fragment.type === "function") {
15
+ const funcFragment = fragment;
16
+ const name = funcFragment.name;
17
+ if (!(name in this)) {
18
+ Object.defineProperty(this, name, {
19
+ value: async (args = [], options) => this.call(name, args, options),
20
+ writable: true,
21
+ enumerable: true,
22
+ });
23
+ }
24
+ const getCallName = contractCreateCallName(name);
25
+ if (!(getCallName in this)) {
26
+ Object.defineProperty(this, getCallName, {
27
+ value: (args = [], callData = {}) => this.getCall(name, args, callData),
28
+ writable: true,
29
+ enumerable: true,
30
+ });
31
+ }
32
+ }
33
+ }
34
+ }
35
+ };
36
+ }
37
+ static createAutoInstance(abi, address, driver, options) {
38
+ const AutoClass = this.createAutoClass(abi, address, driver, options);
39
+ return new AutoClass({ abi, address, driver, options });
40
+ }
41
+ constructor(abi, address = "0x0000000000000000000000000000000000000000", driver, options = {}) {
42
+ this.contractOptions = {};
43
+ this.address = address;
44
+ this.driver = driver;
45
+ this.isCallable = !!address && !!driver;
46
+ this.isReadonly = !this.isCallable || !(driver instanceof Wallet);
47
+ this.contract = new EthersContract(address, abi, driver);
48
+ this.contractOptions = {
49
+ staticCallsTimeoutMs: config.contract.staticCalls.timeoutMs,
50
+ mutableCallsTimeoutMs: config.contract.mutableCalls.timeoutMs,
51
+ ...options,
52
+ };
53
+ }
54
+ get provider() {
55
+ if (!this.driver)
56
+ return null;
57
+ return this.driver.provider;
58
+ }
59
+ get signer() {
60
+ if (isSigner(this.driver))
61
+ return this.driver;
62
+ return null;
63
+ }
64
+ get interface() {
65
+ return this.contract.interface;
66
+ }
67
+ async call(method, args = [], options = {}) {
68
+ if (!this.isCallable)
69
+ throw CONTRACTS_ERRORS.NON_CALLABLE_CONTRACT_INVOCATION;
70
+ const methodFn = this.contract[method];
71
+ if (!methodFn)
72
+ throw CONTRACTS_ERRORS.METHOD_NOT_DEFINED(method);
73
+ const functionFragment = this.contract.interface.getFunction(method);
74
+ if (!functionFragment)
75
+ throw CONTRACTS_ERRORS.FRAGMENT_NOT_DEFINED(method);
76
+ const callOptions = {
77
+ forceMutability: this.contractOptions.forceMutability,
78
+ highPriorityTx: this.contractOptions.highPriorityTxs,
79
+ priorityOptions: this.contractOptions.priorityOptions,
80
+ ...options,
81
+ };
82
+ const isStatic = callOptions.forceMutability
83
+ ? callOptions.forceMutability === CallMutability.Static
84
+ : isStaticMethod(functionFragment.stateMutability);
85
+ const localSignals = [];
86
+ if (callOptions.signals)
87
+ localSignals.push(...callOptions.signals);
88
+ if (callOptions.timeoutMs)
89
+ localSignals.push(this.getTimeoutSignal(isStatic, callOptions.timeoutMs));
90
+ if (isStatic) {
91
+ return raceWithSignals(() => methodFn.staticCall(...args), localSignals);
92
+ }
93
+ else {
94
+ if (this.isReadonly)
95
+ throw CONTRACTS_ERRORS.READ_ONLY_CONTRACT_MUTATION;
96
+ let tx;
97
+ if (callOptions.highPriorityTx) {
98
+ const provider = this.driver?.provider;
99
+ tx = await raceWithSignals(() => priorityCall(provider, this.driver, this.contract, method, args, {
100
+ signals: localSignals,
101
+ ...options.priorityOptions,
102
+ }), localSignals);
103
+ }
104
+ else {
105
+ tx = await raceWithSignals(() => methodFn(...args), localSignals);
106
+ }
107
+ return tx;
108
+ }
109
+ }
110
+ getCall(methodName, args = [], callData = {}) {
111
+ if (!this.address)
112
+ throw CONTRACTS_ERRORS.NON_CALLABLE_CONTRACT_INVOCATION;
113
+ const functionFragment = this.interface.getFunction(methodName);
114
+ if (!functionFragment)
115
+ throw CONTRACTS_ERRORS.FRAGMENT_NOT_DEFINED(methodName);
116
+ return {
117
+ method: methodName,
118
+ target: this.address,
119
+ allowFailure: config.multicallUnit.allowFailure,
120
+ callData: this.interface.encodeFunctionData(methodName, args),
121
+ stateMutability: functionFragment.stateMutability,
122
+ contractInterface: this.interface,
123
+ ...callData,
124
+ };
125
+ }
126
+ async listenEvent(eventName, listener) {
127
+ if (!this.isCallable)
128
+ throw CONTRACTS_ERRORS.NON_CALLABLE_CONTRACT_INVOCATION;
129
+ if (!(this.provider instanceof WebSocketProvider))
130
+ throw CONTRACTS_ERRORS.MISSING_WEBSOCKET_PROVIDER;
131
+ return this.contract.on(eventName, listener);
132
+ }
133
+ async getLogs(fromBlock, eventsNames = [], toBlock = 0, options = {}) {
134
+ const descriptions = [];
135
+ for await (const description of this.getLogsStream(fromBlock, eventsNames, toBlock, options)) {
136
+ descriptions.push(description);
137
+ }
138
+ return descriptions;
139
+ }
140
+ async *getLogsStream(fromBlock, eventsNames = [], toBlock = 0, // Latest by default
141
+ options = {}) {
142
+ if (!this.isCallable)
143
+ throw CONTRACTS_ERRORS.NON_CALLABLE_CONTRACT_INVOCATION;
144
+ const streamOptions = {
145
+ blocksStep: this.contractOptions.logsBlocksStep ||
146
+ config.contract.logsGathering.blocksStep,
147
+ delayMs: this.contractOptions.logsDelayMs ||
148
+ config.contract.logsGathering.delayMs,
149
+ ...options,
150
+ };
151
+ const topics = eventsNames.map((event) => this.contract.getEvent(event).fragment.topicHash);
152
+ checkSignals(options.signals);
153
+ const finToBlock = toBlock
154
+ ? toBlock
155
+ : await this.provider.getBlockNumber();
156
+ const finFromBlock = fromBlock < 0 ? finToBlock + fromBlock : fromBlock;
157
+ for (let from = finFromBlock; from < finToBlock; from += streamOptions.blocksStep) {
158
+ checkSignals(options.signals);
159
+ const to = Math.min(from + streamOptions.blocksStep, finToBlock);
160
+ const localLogs = await this.provider.getLogs({
161
+ fromBlock: from,
162
+ toBlock: to,
163
+ address: this.address,
164
+ topics: topics.length ? [topics] : undefined,
165
+ });
166
+ for (const log of localLogs) {
167
+ checkSignals(options.signals);
168
+ const description = this.interface.parseLog(log);
169
+ if (!description)
170
+ continue;
171
+ yield description;
172
+ }
173
+ await waitWithSignals(streamOptions.delayMs, options.signals);
174
+ }
175
+ }
176
+ getTimeoutSignal(isStatic, timeoutMs) {
177
+ let timeout;
178
+ if (timeoutMs) {
179
+ timeout = timeoutMs;
180
+ }
181
+ else {
182
+ if (isStatic) {
183
+ timeout = this.contractOptions.staticCallsTimeoutMs;
184
+ }
185
+ else {
186
+ timeout = this.contractOptions.mutableCallsTimeoutMs;
187
+ }
188
+ }
189
+ return createTimeoutSignal(timeout);
190
+ }
191
+ }
@@ -0,0 +1 @@
1
+ export declare const contractCreateCallName: (name: string) => string;
@@ -0,0 +1 @@
1
+ export const contractCreateCallName = (name) => `${name.startsWith("get") ? name : `get${name[0].toUpperCase()}${name.slice(1)}`}Call`;
@@ -0,0 +1 @@
1
+ export * from "./base-contract";
@@ -0,0 +1 @@
1
+ export * from "./base-contract";
@@ -0,0 +1,9 @@
1
+ export declare const CONTRACTS_ERRORS: {
2
+ NON_CALLABLE_CONTRACT_INVOCATION: Error;
3
+ READ_ONLY_CONTRACT_MUTATION: Error;
4
+ MISSING_CONTRACT_ADDRESS: Error;
5
+ METHOD_NOT_DEFINED: (methodName: any) => Error;
6
+ FRAGMENT_NOT_DEFINED: (methodName: any) => Error;
7
+ MISSING_WEBSOCKET_PROVIDER: Error;
8
+ MISSING_PROVIDER: Error;
9
+ };
@@ -0,0 +1,9 @@
1
+ export const CONTRACTS_ERRORS = {
2
+ NON_CALLABLE_CONTRACT_INVOCATION: new Error("The contract was created as non-callable, but an attempt was made to call it!"),
3
+ READ_ONLY_CONTRACT_MUTATION: new Error("The contract was created as read-only, but an attempt was made to call mutable method!"),
4
+ MISSING_CONTRACT_ADDRESS: new Error("A contract address was not provided!"),
5
+ METHOD_NOT_DEFINED: (methodName) => new Error(`Method "${methodName}" was not found on the contract!`),
6
+ FRAGMENT_NOT_DEFINED: (methodName) => new Error(`Fragment for method "${methodName}" was not found on the contract!`),
7
+ MISSING_WEBSOCKET_PROVIDER: new Error("Attempted to listen for contract events, but no WebSocketProvider was provided!"),
8
+ MISSING_PROVIDER: new Error("A provider is required, but none was provided!"),
9
+ };
@@ -0,0 +1,2 @@
1
+ export * from "./multicall-errors";
2
+ export * from "./contracts-errors";
@@ -0,0 +1,2 @@
1
+ export * from "./multicall-errors";
2
+ export * from "./contracts-errors";
@@ -0,0 +1,8 @@
1
+ export declare const MULTICALL_ERRORS: {
2
+ SIMULTANEOUS_INVOCATIONS: Error;
3
+ RESULT_NOT_FOUND: Error;
4
+ RESPONSE_NOT_FOUND: Error;
5
+ RECEIPT_NOT_FOUND: Error;
6
+ MISSING_PROVIDER_INTERFACE: Error;
7
+ MISSING_PROVIDER_CALL_DATA: Error;
8
+ };
@@ -0,0 +1,8 @@
1
+ export const MULTICALL_ERRORS = {
2
+ SIMULTANEOUS_INVOCATIONS: new Error("Multicall -> Another execution was triggered during processing."),
3
+ RESULT_NOT_FOUND: new Error("Multicall result not found."),
4
+ RESPONSE_NOT_FOUND: new Error("Multicall response not found."),
5
+ RECEIPT_NOT_FOUND: new Error("Multicall receipt not received."),
6
+ MISSING_PROVIDER_INTERFACE: new Error("MulticallProvider -> Missing contractInterface in customData."),
7
+ MISSING_PROVIDER_CALL_DATA: new Error('MulticallProvider -> Missing "to" or "data".'),
8
+ };
@@ -0,0 +1,6 @@
1
+ export * from "./is-static-array";
2
+ export * from "./is-static-method";
3
+ export * from "./wait-for-address-txs";
4
+ export * from "./is-signer";
5
+ export * from "./is-parsable";
6
+ export * from "./priority-call";
@@ -0,0 +1,6 @@
1
+ export * from "./is-static-array";
2
+ export * from "./is-static-method";
3
+ export * from "./wait-for-address-txs";
4
+ export * from "./is-signer";
5
+ export * from "./is-parsable";
6
+ export * from "./priority-call";
@@ -0,0 +1,2 @@
1
+ import type { ContractCall } from "../types";
2
+ export declare const isParsable: (call: ContractCall) => boolean;
@@ -0,0 +1 @@
1
+ export const isParsable = (call) => call.method !== undefined && call.contractInterface !== undefined;
@@ -0,0 +1,2 @@
1
+ import type { Signer } from "ethers";
2
+ export declare const isSigner: (driver: Signer) => boolean;
@@ -0,0 +1,3 @@
1
+ export const isSigner = (driver) => {
2
+ return typeof driver?.getAddress === "function";
3
+ };
@@ -0,0 +1,2 @@
1
+ import type { ContractCall } from "../types";
2
+ export declare const isStaticArray: (calls: ContractCall[]) => boolean;
@@ -0,0 +1,2 @@
1
+ import { isStaticMethod } from "./is-static-method";
2
+ export const isStaticArray = (calls) => !calls.some((call) => !isStaticMethod(call.stateMutability));
@@ -0,0 +1,2 @@
1
+ import { StateMutability } from "../types";
2
+ export declare const isStaticMethod: (state: StateMutability | string) => boolean;
@@ -0,0 +1,4 @@
1
+ import { StateMutability } from "../types";
2
+ export const isStaticMethod = (state) => {
3
+ return state === StateMutability.View || state === StateMutability.Pure;
4
+ };
@@ -0,0 +1,5 @@
1
+ import type { Contract, Provider, TransactionRequest } from "ethers";
2
+ import type { PriorityCallOptions } from "../types";
3
+ export declare function priorityCall(provider: Provider, signer: {
4
+ sendTransaction: (txn: TransactionRequest) => Promise<any>;
5
+ }, contract: Contract, method: string, args?: any[], options?: PriorityCallOptions): Promise<any>;
@@ -0,0 +1,55 @@
1
+ import { DEFAULT_PRIORITY_CALL_MULTIPLIER } from "../constant";
2
+ import { checkSignals, createTimeoutSignal } from "../utils";
3
+ export async function priorityCall(provider, signer, contract, method, args = [], options = {}) {
4
+ const localOptions = {
5
+ multiplier: DEFAULT_PRIORITY_CALL_MULTIPLIER,
6
+ ...options,
7
+ };
8
+ const localSignals = [];
9
+ if (localOptions.signals)
10
+ localSignals.push(...localOptions.signals);
11
+ if (localOptions.timeoutMs)
12
+ localSignals.push(createTimeoutSignal(localOptions.timeoutMs));
13
+ checkSignals(localSignals);
14
+ const [originalFeeData, originalGasLimit] = await gatherOriginalData(provider, contract, method, args, localOptions.asynchronous ?? false, localSignals);
15
+ const maxFeePerGas = Math.ceil(localOptions.multiplier * Number(originalFeeData.maxFeePerGas));
16
+ const maxPriorityFeePerGas = Math.ceil(localOptions.multiplier * Number(originalFeeData.maxPriorityFeePerGas));
17
+ const gasLimit = Math.ceil(localOptions.multiplier * Number(originalGasLimit));
18
+ checkSignals(localSignals);
19
+ const txn = await contract
20
+ .getFunction(method)
21
+ .populateTransaction(...args, {
22
+ gasLimit,
23
+ maxFeePerGas,
24
+ maxPriorityFeePerGas,
25
+ });
26
+ // Prevents conflicts when using signer.sendTransaction(txn), as the signer should determine the from address.
27
+ // Avoids potential issues if from is incorrectly set or differs from the signer's address.
28
+ delete txn.from;
29
+ if (localOptions.provideChainId) {
30
+ checkSignals(localSignals);
31
+ const network = await provider.getNetwork();
32
+ txn.chainId = network.chainId;
33
+ }
34
+ else if (localOptions.chainId) {
35
+ txn.chainId = localOptions.chainId;
36
+ }
37
+ checkSignals(localSignals);
38
+ return signer.sendTransaction(txn);
39
+ }
40
+ async function gatherOriginalData(provider, contract, method, args = [], asynchronous, signals) {
41
+ let originalFeeData;
42
+ let originalGasLimit;
43
+ checkSignals(signals);
44
+ if (asynchronous) {
45
+ [originalFeeData, originalGasLimit] = await Promise.all([
46
+ provider.getFeeData(),
47
+ contract.getFunction(method).estimateGas(...args),
48
+ ]);
49
+ return [originalFeeData, originalGasLimit];
50
+ }
51
+ originalFeeData = await provider.getFeeData();
52
+ checkSignals(signals);
53
+ originalGasLimit = await contract.getFunction(method).estimateGas(...args);
54
+ return [originalFeeData, originalGasLimit];
55
+ }
@@ -0,0 +1,2 @@
1
+ import type { Provider } from "ethers";
2
+ export declare const waitForAddressTxs: (address: string, provider: Provider, delayMs?: number) => Promise<void>;
@@ -0,0 +1,9 @@
1
+ export const waitForAddressTxs = async (address, provider, delayMs = 1000) => {
2
+ let flag = true;
3
+ while (flag) {
4
+ const pendingNonce = await provider.getTransactionCount(address, "pending");
5
+ const latestNonce = await provider.getTransactionCount(address, "latest");
6
+ flag = pendingNonce > latestNonce;
7
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
8
+ }
9
+ };
package/lib/index.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export * from "./contract";
2
+ export * from "./multicall";
3
+ export * from "./config";
4
+ export * from "./helpers";
5
+ export * from "./types";
package/lib/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export * from "./contract";
2
+ export * from "./multicall";
3
+ export * from "./config";
4
+ export * from "./helpers";
5
+ export * from "./types";
@@ -0,0 +1,5 @@
1
+ export * from "./multicall-normalize-tags";
2
+ export * from "./multicall-split-calls";
3
+ export * from "./multicall-unit";
4
+ export * from "./multicall-normalize-tags";
5
+ export * from "./multicall-split-calls";
@@ -0,0 +1,5 @@
1
+ export * from "./multicall-normalize-tags";
2
+ export * from "./multicall-split-calls";
3
+ export * from "./multicall-unit";
4
+ export * from "./multicall-normalize-tags";
5
+ export * from "./multicall-split-calls";
@@ -0,0 +1,2 @@
1
+ import type { Tagable } from "../types";
2
+ export declare const multicallErrorEventName: (normalizedTags: Tagable) => string;
@@ -0,0 +1 @@
1
+ export const multicallErrorEventName = (normalizedTags) => `error:${String(normalizedTags)}`;
@@ -0,0 +1 @@
1
+ export declare const multicallGenerateTag: () => string;
@@ -0,0 +1 @@
1
+ export const multicallGenerateTag = () => `tag:${Date.now()}:${crypto.randomUUID()}`;
@@ -0,0 +1,2 @@
1
+ import type { MulticallTags, Tagable } from "../types";
2
+ export declare const multicallNormalizeTags: (tags: MulticallTags) => Tagable;
@@ -0,0 +1,6 @@
1
+ export const multicallNormalizeTags = (tags) => {
2
+ if (typeof tags === "object" || Array.isArray(tags)) {
3
+ return JSON.stringify(tags, (_, value) => typeof value === "bigint" ? value.toString() : value);
4
+ }
5
+ return tags;
6
+ };
@@ -0,0 +1,2 @@
1
+ import type { Tagable } from "../types";
2
+ export declare const multicallResultEventName: (normalizedTags: Tagable) => string;
@@ -0,0 +1 @@
1
+ export const multicallResultEventName = (normalizedTags) => `result:${String(normalizedTags)}`;
@@ -0,0 +1,2 @@
1
+ import type { ContractCall, SplitCalls, Tagable } from "../types";
2
+ export declare const multicallSplitCalls: (calls: ContractCall[], tags: Tagable[]) => SplitCalls;
@@ -0,0 +1,19 @@
1
+ import { isStaticMethod } from "../helpers";
2
+ export const multicallSplitCalls = (calls, tags) => calls.reduce((acc, call, index) => {
3
+ if (isStaticMethod(call.stateMutability)) {
4
+ acc.staticCalls.push(call);
5
+ acc.staticIndexes.push(index);
6
+ }
7
+ else {
8
+ acc.mutableCalls.push(call);
9
+ acc.mutableTags.push(tags[index]);
10
+ acc.mutableIndexes.push(index);
11
+ }
12
+ return acc;
13
+ }, {
14
+ staticCalls: [],
15
+ staticIndexes: [],
16
+ mutableCalls: [],
17
+ mutableTags: [],
18
+ mutableIndexes: [],
19
+ });
@@ -0,0 +1,48 @@
1
+ import { EventEmitter } from "node:events";
2
+ import type { Provider, Signer, TransactionReceipt, TransactionResponse } from "ethers";
3
+ import { BaseContract } from "../contract";
4
+ import { type ContractCall, type MulticallOptions, type MulticallTags, type MulticallWaitOptions, type Tagable } from "../types";
5
+ export type Response = [success: boolean, rawData: string];
6
+ export declare class MulticallUnit extends BaseContract {
7
+ protected _units: Map<Tagable, ContractCall>;
8
+ protected _response: Response[];
9
+ protected _rawData: Map<Tagable, string>;
10
+ protected _callsSuccess: Map<Tagable, boolean>;
11
+ protected _lastSuccess: boolean | undefined;
12
+ protected _isExecuting: boolean;
13
+ protected _emitter: EventEmitter<[never]>;
14
+ protected _multicallOptions: MulticallOptions;
15
+ protected _txResponses: Map<any, any>;
16
+ protected _txReceipts: Map<any, any>;
17
+ constructor(driver: Signer | Provider, options?: MulticallOptions, multicallAddress?: string);
18
+ clear(): void;
19
+ add(contractCall: ContractCall, tags: MulticallTags): MulticallTags;
20
+ get tags(): Tagable[];
21
+ get calls(): ContractCall[];
22
+ get response(): Response[];
23
+ get success(): boolean | undefined;
24
+ get static(): boolean;
25
+ get executing(): boolean;
26
+ isSuccess(tags: MulticallTags): boolean | undefined;
27
+ getRaw(tags: MulticallTags): string | null;
28
+ getSingle<T>(tags: MulticallTags): T | null;
29
+ getArray<T>(tags: MulticallTags, deep?: boolean): T | null;
30
+ run(options?: Partial<MulticallOptions>): Promise<boolean>;
31
+ private processStaticCalls;
32
+ private processMutableCalls;
33
+ private saveResponse;
34
+ getOrThrow<T>(tags: MulticallTags, deep?: boolean): T;
35
+ get<T>(tags: MulticallTags, deep?: boolean): T | null;
36
+ private getDecodableData;
37
+ waitRawOrThrow(tags: MulticallTags, options?: MulticallWaitOptions): Promise<string>;
38
+ waitRaw(tags: MulticallTags, options?: MulticallWaitOptions): Promise<string | null>;
39
+ wait(tags: MulticallTags, options?: MulticallWaitOptions): Promise<void>;
40
+ waitTxOrThrow(tags: MulticallTags, options?: MulticallWaitOptions): Promise<TransactionResponse>;
41
+ waitTx(tags: MulticallTags, options?: MulticallWaitOptions): Promise<TransactionResponse | null>;
42
+ getTxResponse(tags: MulticallTags): TransactionResponse | null;
43
+ getTxResponseOrThrow(tags: MulticallTags): TransactionResponse;
44
+ getTxReceipt(tags: MulticallTags): TransactionReceipt | null;
45
+ getObjectOrThrow<T>(tags: MulticallTags, deep?: boolean): T;
46
+ getObject<T>(tags: MulticallTags, deep?: boolean): T | null;
47
+ waitFor<T>(tags: MulticallTags, options?: MulticallWaitOptions): Promise<T>;
48
+ }