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.
Files changed (76) hide show
  1. package/docs/ai/INDEX.md +41 -0
  2. package/docs/ai/examples/contract-read.spec.ts +44 -0
  3. package/docs/ai/examples/contract-write.spec.ts +16 -0
  4. package/docs/ai/examples/deploy-contract.spec.ts +32 -0
  5. package/docs/ai/examples/erc4337-userop.spec.ts +37 -0
  6. package/docs/ai/examples/explorer-abi.spec.ts +18 -0
  7. package/docs/ai/examples/generate-client.spec.ts +22 -0
  8. package/docs/ai/examples/index-events.spec.ts +27 -0
  9. package/docs/ai/examples/rpc-read.spec.ts +15 -0
  10. package/docs/ai/examples/safe-batch.spec.ts +55 -0
  11. package/docs/ai/examples/send-transaction.spec.ts +22 -0
  12. package/docs/ai/examples/storage-read.spec.ts +27 -0
  13. package/docs/ai/examples/token-transfer.spec.ts +22 -0
  14. package/docs/ai/references/contracts.md +111 -0
  15. package/docs/ai/references/deployments.md +98 -0
  16. package/docs/ai/references/events-indexing.md +97 -0
  17. package/docs/ai/references/explorer.md +77 -0
  18. package/docs/ai/references/generation.md +182 -0
  19. package/docs/ai/references/migration-from-ethers-viem.md +43 -0
  20. package/docs/ai/references/rpc-clients.md +115 -0
  21. package/docs/ai/references/safe-erc4337.md +134 -0
  22. package/docs/ai/references/storage.md +93 -0
  23. package/docs/ai/references/tokens-accounts.md +99 -0
  24. package/docs/ai/references/transactions.md +146 -0
  25. package/docs/ai/skill/dequanto/SKILL.md +59 -0
  26. package/lib/cjs/abi/$abi.js +27 -0
  27. package/lib/cjs/abi/$abi.js.map +1 -0
  28. package/lib/cjs/abi/$abiCoder.js +15 -0
  29. package/lib/cjs/abi/$abiCoder.js.map +1 -1
  30. package/lib/cjs/abi/abi-coder.js +1 -1
  31. package/lib/cjs/abi/abi-coder.js.map +1 -1
  32. package/lib/cjs/clients/Web3Client.js +10 -3
  33. package/lib/cjs/clients/Web3Client.js.map +1 -1
  34. package/lib/cjs/clients/Web3ClientFactory.js.map +1 -1
  35. package/lib/cjs/utils/$abiParser.js +85 -1
  36. package/lib/cjs/utils/$abiParser.js.map +1 -1
  37. package/lib/cjs/utils/$hex.js +1 -0
  38. package/lib/cjs/utils/$hex.js.map +1 -1
  39. package/lib/cjs/utils/$require.js +4 -0
  40. package/lib/cjs/utils/$require.js.map +1 -1
  41. package/lib/esm/abi/$abi.js.map +1 -0
  42. package/lib/esm/abi/$abi.mjs +24 -0
  43. package/lib/esm/abi/$abiCoder.js.map +1 -1
  44. package/lib/esm/abi/$abiCoder.mjs +15 -0
  45. package/lib/esm/abi/abi-coder.js.map +1 -1
  46. package/lib/esm/abi/abi-coder.mjs +1 -1
  47. package/lib/esm/clients/Web3Client.js.map +1 -1
  48. package/lib/esm/clients/Web3Client.mjs +10 -3
  49. package/lib/esm/clients/Web3ClientFactory.js.map +1 -1
  50. package/lib/esm/utils/$abiParser.js.map +1 -1
  51. package/lib/esm/utils/$abiParser.mjs +85 -1
  52. package/lib/esm/utils/$hex.js.map +1 -1
  53. package/lib/esm/utils/$hex.mjs +1 -0
  54. package/lib/esm/utils/$require.js.map +1 -1
  55. package/lib/esm/utils/$require.mjs +4 -0
  56. package/lib/types/abi/$abi.d.ts +15 -0
  57. package/lib/types/abi/$abiCoder.d.ts +13 -10
  58. package/lib/types/clients/Web3Client.d.ts +4 -1
  59. package/lib/types/clients/Web3ClientFactory.d.ts +3 -2
  60. package/lib/types/contracts/ContractBase.d.ts +1 -1
  61. package/lib/types/contracts/wrappers/FnRequestWrapper.d.ts +1 -1
  62. package/lib/types/models/TAccount.d.ts +1 -1
  63. package/lib/types/utils/$abiParser.d.ts +6 -0
  64. package/lib/types/utils/$hex.d.ts +1 -0
  65. package/lib/types/utils/$require.d.ts +4 -4
  66. package/package.json +1 -1
  67. package/src/abi/$abi.ts +36 -0
  68. package/src/abi/$abiCoder.ts +31 -10
  69. package/src/abi/abi-coder.ts +1 -3
  70. package/src/clients/Web3Client.ts +16 -6
  71. package/src/clients/Web3ClientFactory.ts +10 -5
  72. package/src/contracts/wrappers/FnRequestWrapper.ts +1 -1
  73. package/src/models/TAccount.ts +1 -1
  74. package/src/utils/$abiParser.ts +93 -1
  75. package/src/utils/$hex.ts +3 -1
  76. 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 (platform: TPlatform | number, opts?: IWeb3EndpointOptions) {
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 (platform: TPlatform | string | number, opts?: IWeb3EndpointOptions) {
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
 
@@ -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: EoAccount
68
+ operator: IAccount
69
69
  }
70
70
 
71
71
  export type TAccount = string | IAccount | EoAccount | SafeAccount | Erc4337Account;
@@ -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
@@ -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
  }