dequanto 0.2.47 → 0.2.49
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/docs/ai/INDEX.md +41 -0
- package/docs/ai/examples/contract-read.spec.ts +44 -0
- package/docs/ai/examples/contract-write.spec.ts +16 -0
- package/docs/ai/examples/deploy-contract.spec.ts +32 -0
- package/docs/ai/examples/erc4337-userop.spec.ts +37 -0
- package/docs/ai/examples/explorer-abi.spec.ts +18 -0
- package/docs/ai/examples/generate-client.spec.ts +22 -0
- package/docs/ai/examples/index-events.spec.ts +27 -0
- package/docs/ai/examples/rpc-read.spec.ts +15 -0
- package/docs/ai/examples/safe-batch.spec.ts +55 -0
- package/docs/ai/examples/send-transaction.spec.ts +22 -0
- package/docs/ai/examples/storage-read.spec.ts +27 -0
- package/docs/ai/examples/token-transfer.spec.ts +22 -0
- package/docs/ai/references/contracts.md +111 -0
- package/docs/ai/references/deployments.md +98 -0
- package/docs/ai/references/events-indexing.md +97 -0
- package/docs/ai/references/explorer.md +77 -0
- package/docs/ai/references/generation.md +182 -0
- package/docs/ai/references/migration-from-ethers-viem.md +43 -0
- package/docs/ai/references/rpc-clients.md +115 -0
- package/docs/ai/references/safe-erc4337.md +134 -0
- package/docs/ai/references/storage.md +93 -0
- package/docs/ai/references/tokens-accounts.md +99 -0
- package/docs/ai/references/transactions.md +146 -0
- package/docs/ai/skill/dequanto/SKILL.md +59 -0
- package/lib/cjs/abi/$abi.js +27 -0
- package/lib/cjs/abi/$abi.js.map +1 -0
- package/lib/cjs/abi/$abiCoder.js +15 -0
- package/lib/cjs/abi/$abiCoder.js.map +1 -1
- package/lib/cjs/abi/abi-coder.js +1 -1
- package/lib/cjs/abi/abi-coder.js.map +1 -1
- package/lib/cjs/clients/Web3Client.js +10 -3
- package/lib/cjs/clients/Web3Client.js.map +1 -1
- package/lib/cjs/clients/Web3ClientFactory.js.map +1 -1
- package/lib/cjs/utils/$abiParser.js +85 -1
- package/lib/cjs/utils/$abiParser.js.map +1 -1
- package/lib/cjs/utils/$hex.js +1 -0
- package/lib/cjs/utils/$hex.js.map +1 -1
- package/lib/cjs/utils/$require.js +4 -0
- package/lib/cjs/utils/$require.js.map +1 -1
- package/lib/esm/abi/$abi.js.map +1 -0
- package/lib/esm/abi/$abi.mjs +24 -0
- package/lib/esm/abi/$abiCoder.js.map +1 -1
- package/lib/esm/abi/$abiCoder.mjs +15 -0
- package/lib/esm/abi/abi-coder.js.map +1 -1
- package/lib/esm/abi/abi-coder.mjs +1 -1
- package/lib/esm/clients/Web3Client.js.map +1 -1
- package/lib/esm/clients/Web3Client.mjs +10 -3
- package/lib/esm/clients/Web3ClientFactory.js.map +1 -1
- package/lib/esm/utils/$abiParser.js.map +1 -1
- package/lib/esm/utils/$abiParser.mjs +85 -1
- package/lib/esm/utils/$hex.js.map +1 -1
- package/lib/esm/utils/$hex.mjs +1 -0
- package/lib/esm/utils/$require.js.map +1 -1
- package/lib/esm/utils/$require.mjs +4 -0
- package/lib/types/abi/$abi.d.ts +15 -0
- package/lib/types/abi/$abiCoder.d.ts +13 -10
- package/lib/types/clients/Web3Client.d.ts +4 -1
- package/lib/types/clients/Web3ClientFactory.d.ts +3 -2
- package/lib/types/contracts/ContractBase.d.ts +1 -1
- package/lib/types/contracts/wrappers/FnRequestWrapper.d.ts +1 -1
- package/lib/types/models/TAccount.d.ts +1 -1
- package/lib/types/utils/$abiParser.d.ts +6 -0
- package/lib/types/utils/$hex.d.ts +1 -0
- package/lib/types/utils/$require.d.ts +4 -4
- package/package.json +1 -1
- package/src/abi/$abi.ts +36 -0
- package/src/abi/$abiCoder.ts +31 -10
- package/src/abi/abi-coder.ts +1 -3
- package/src/clients/Web3Client.ts +16 -6
- package/src/clients/Web3ClientFactory.ts +10 -5
- package/src/contracts/wrappers/FnRequestWrapper.ts +1 -1
- package/src/models/TAccount.ts +1 -1
- package/src/utils/$abiParser.ts +93 -1
- package/src/utils/$hex.ts +3 -1
- package/src/utils/$require.ts +4 -0
|
@@ -6,16 +6,19 @@ import { Config } from '@dequanto/config/Config';
|
|
|
6
6
|
import { EvmWeb3Client } from './EvmWeb3Client';
|
|
7
7
|
import { $require } from '@dequanto/utils/$require';
|
|
8
8
|
import { $config } from '@dequanto/utils/$config';
|
|
9
|
+
import type { HardhatWeb3Client } from '@dequanto/hardhat/HardhatWeb3Client';
|
|
9
10
|
|
|
10
11
|
export namespace Web3ClientFactory {
|
|
11
12
|
|
|
12
|
-
export function get
|
|
13
|
+
export function get <
|
|
14
|
+
TClient extends EvmWeb3Client | HardhatWeb3Client = EvmWeb3Client
|
|
15
|
+
> (platform: TPlatform | number, opts?: IWeb3EndpointOptions): TClient {
|
|
13
16
|
if (typeof platform === 'string' && (platform === 'hardhat' || platform.startsWith('hh:'))) {
|
|
14
17
|
let client = di.resolve(HardhatProvider).client('localhost', opts);
|
|
15
18
|
if (platform.startsWith('hh:')) {
|
|
16
19
|
client.configureFork(platform.slice(3));
|
|
17
20
|
}
|
|
18
|
-
return client;
|
|
21
|
+
return client as TClient;
|
|
19
22
|
}
|
|
20
23
|
|
|
21
24
|
let options = $config.getWeb3Options(platform);
|
|
@@ -23,12 +26,14 @@ export namespace Web3ClientFactory {
|
|
|
23
26
|
return new EvmWeb3Client({
|
|
24
27
|
...options,
|
|
25
28
|
...(opts ?? {})
|
|
26
|
-
});
|
|
29
|
+
}) as TClient;
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
/** Same as the sync variant, but ensures the config is fetched */
|
|
30
|
-
export async function getAsync
|
|
33
|
+
export async function getAsync <
|
|
34
|
+
TClient extends EvmWeb3Client | HardhatWeb3Client = EvmWeb3Client
|
|
35
|
+
> (platform: TPlatform | string | number, opts?: IWeb3EndpointOptions): Promise<TClient> {
|
|
31
36
|
let cfg = await Config.get();
|
|
32
|
-
return get(platform, opts);
|
|
37
|
+
return get<TClient>(platform, opts);
|
|
33
38
|
}
|
|
34
39
|
}
|
|
@@ -9,7 +9,7 @@ export namespace FnRequestWrapper {
|
|
|
9
9
|
|
|
10
10
|
type TRequests<T extends ContractBase> = {
|
|
11
11
|
[K in keyof T]: T[K] extends (...any) => Promise<any>
|
|
12
|
-
? (...params: Parameters<T[K]>) => ContractReaderUtils.IContractReadParams<Awaited<ReturnType<T[K]
|
|
12
|
+
? (...params: Parameters<T[K]>) => Promise<ContractReaderUtils.IContractReadParams<Awaited<ReturnType<T[K]>>>>
|
|
13
13
|
: never
|
|
14
14
|
}
|
|
15
15
|
|
package/src/models/TAccount.ts
CHANGED
|
@@ -65,7 +65,7 @@ export interface TimelockAccount extends IAccount {
|
|
|
65
65
|
// Erc4337 account must include platform information
|
|
66
66
|
platform: TPlatform
|
|
67
67
|
|
|
68
|
-
operator:
|
|
68
|
+
operator: IAccount
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
export type TAccount = string | IAccount | EoAccount | SafeAccount | Erc4337Account;
|
package/src/utils/$abiParser.ts
CHANGED
|
@@ -86,6 +86,69 @@ export namespace $abiParser {
|
|
|
86
86
|
};
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Parses Solidity struct declarations into a tuple ABI component.
|
|
92
|
+
* Supports multiple declarations so later structs can reference earlier ones,
|
|
93
|
+
* and returns the ABI component for the last struct in the input.
|
|
94
|
+
*/
|
|
95
|
+
export function parseStruct (struct: string): TAbiItem {
|
|
96
|
+
let structs = Parse.structs(struct);
|
|
97
|
+
$require.gt(structs.length, 0, `No structs found in ${struct}`);
|
|
98
|
+
|
|
99
|
+
let byName = new Map(structs.map(x => [ x.name, x ]));
|
|
100
|
+
let cache = new Map<string, TAbiInput>();
|
|
101
|
+
|
|
102
|
+
function toTuple (name: string): TAbiInput {
|
|
103
|
+
let cached = cache.get(name);
|
|
104
|
+
if (cached != null) {
|
|
105
|
+
return cached;
|
|
106
|
+
}
|
|
107
|
+
let def = byName.get(name);
|
|
108
|
+
$require.notNull(def, `Struct ${name} is not found`);
|
|
109
|
+
|
|
110
|
+
let tuple: TAbiInput = {
|
|
111
|
+
name: '',
|
|
112
|
+
type: 'tuple',
|
|
113
|
+
internalType: `struct ${name}`,
|
|
114
|
+
components: []
|
|
115
|
+
};
|
|
116
|
+
cache.set(name, tuple);
|
|
117
|
+
tuple.components = Parse.splitByDelimiter(def.body, ';')
|
|
118
|
+
.map(field => $abiParser.parseArguments(field)[0])
|
|
119
|
+
.map(resolveStructs);
|
|
120
|
+
|
|
121
|
+
return tuple;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function resolveStructs (param: TAbiInput): TAbiInput {
|
|
125
|
+
let { type, array } = Parse.extractArray(param.type);
|
|
126
|
+
if (byName.has(type) === false) {
|
|
127
|
+
if (param.components != null) {
|
|
128
|
+
return {
|
|
129
|
+
...param,
|
|
130
|
+
components: param.components.map(resolveStructs)
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
return param;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
let tuple = toTuple(type);
|
|
137
|
+
return {
|
|
138
|
+
name: param.name,
|
|
139
|
+
type: `tuple${array}`,
|
|
140
|
+
internalType: `struct ${type}${array}`,
|
|
141
|
+
components: tuple.components
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
let last = structs[structs.length - 1];
|
|
146
|
+
return {
|
|
147
|
+
...toTuple(last.name),
|
|
148
|
+
name: last.name
|
|
149
|
+
} as any as TAbiItem;
|
|
150
|
+
}
|
|
151
|
+
|
|
89
152
|
// uint256
|
|
90
153
|
// address[]
|
|
91
154
|
// (uint256, uint256)
|
|
@@ -247,6 +310,35 @@ namespace Parse {
|
|
|
247
310
|
|
|
248
311
|
const CLOSE_CHARS = {
|
|
249
312
|
'[': ']',
|
|
250
|
-
'(': ')'
|
|
313
|
+
'(': ')',
|
|
314
|
+
'{': '}'
|
|
251
315
|
};
|
|
316
|
+
|
|
317
|
+
export function structs (source: string) {
|
|
318
|
+
let rgx = /\bstruct\s+(?<name>[\w_$]+)\s*\{/g;
|
|
319
|
+
let arr: { name: string, body: string }[] = [];
|
|
320
|
+
let match: RegExpExecArray;
|
|
321
|
+
while ((match = rgx.exec(source)) != null) {
|
|
322
|
+
let openI = source.indexOf('{', match.index);
|
|
323
|
+
let closeI = goToClosing(source, openI, '{');
|
|
324
|
+
arr.push({
|
|
325
|
+
name: match.groups.name,
|
|
326
|
+
body: source.substring(openI + 1, closeI).trim()
|
|
327
|
+
});
|
|
328
|
+
rgx.lastIndex = closeI + 1;
|
|
329
|
+
}
|
|
330
|
+
return arr;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
export function extractArray (type: string) {
|
|
334
|
+
let array = '';
|
|
335
|
+
while (true) {
|
|
336
|
+
let match = /^(?<type>.+?)(?<array>\[[^\]]*\])$/.exec(type);
|
|
337
|
+
if (match == null) {
|
|
338
|
+
return { type, array };
|
|
339
|
+
}
|
|
340
|
+
type = match.groups.type;
|
|
341
|
+
array = `${match.groups.array}${array}`;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
252
344
|
}
|
package/src/utils/$hex.ts
CHANGED
|
@@ -3,7 +3,9 @@ import { $buffer } from './$buffer';
|
|
|
3
3
|
import { $require } from './$require';
|
|
4
4
|
export namespace $hex {
|
|
5
5
|
|
|
6
|
-
export const ZERO = '0x'
|
|
6
|
+
export const ZERO = '0x';
|
|
7
|
+
|
|
8
|
+
export const ZERO_Bytes32 = '0x0000000000000000000000000000000000000000000000000000000000000000';
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* Adds '00' bytes to the hex string
|
package/src/utils/$require.ts
CHANGED
|
@@ -200,6 +200,7 @@ export namespace $require {
|
|
|
200
200
|
if (a <= b) {
|
|
201
201
|
throw new Error(`Expected a(${a}) > b(${b}). ${message}`);
|
|
202
202
|
}
|
|
203
|
+
return a;
|
|
203
204
|
}
|
|
204
205
|
export function gte<T = number | bigint> (a: T, b: T, message: string = '') {
|
|
205
206
|
Numeric(a);
|
|
@@ -207,6 +208,7 @@ export namespace $require {
|
|
|
207
208
|
if (a < b) {
|
|
208
209
|
throw new Error(`Expected a(${a}) > b(${b}). ${message}`);
|
|
209
210
|
}
|
|
211
|
+
return a;
|
|
210
212
|
}
|
|
211
213
|
|
|
212
214
|
/**
|
|
@@ -218,6 +220,7 @@ export namespace $require {
|
|
|
218
220
|
if (a >= b) {
|
|
219
221
|
throw new Error(`Expected a(${a}) > b(${b}). ${message}`);
|
|
220
222
|
}
|
|
223
|
+
return a;
|
|
221
224
|
}
|
|
222
225
|
export function lte<T = number | bigint> (a: T, b: T, message: string = '') {
|
|
223
226
|
Numeric(a);
|
|
@@ -225,5 +228,6 @@ export namespace $require {
|
|
|
225
228
|
if (a > b) {
|
|
226
229
|
throw new Error(`Expected a(${a}) > b(${b}). ${message}`);
|
|
227
230
|
}
|
|
231
|
+
return a;
|
|
228
232
|
}
|
|
229
233
|
}
|