dequanto 0.2.49 → 0.2.51

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 (179) hide show
  1. package/contracts/oz/Proxy.sol +1 -0
  2. package/lib/cjs/abi/$abi.js +33 -0
  3. package/lib/cjs/abi/$abi.js.map +1 -1
  4. package/lib/cjs/blocks/BlockDateResolver.js.map +1 -1
  5. package/lib/cjs/clients/Web3Client.js +43 -2
  6. package/lib/cjs/clients/Web3Client.js.map +1 -1
  7. package/lib/cjs/clients/Web3ClientFactory.js +26 -4
  8. package/lib/cjs/clients/Web3ClientFactory.js.map +1 -1
  9. package/lib/cjs/clients/debug/ClientDebugMethods.js +4 -0
  10. package/lib/cjs/clients/debug/ClientDebugMethods.js.map +1 -1
  11. package/lib/cjs/clients/utils/$web3Abi.js +1 -1
  12. package/lib/cjs/clients/utils/$web3Abi.js.map +1 -1
  13. package/lib/cjs/config/Config.js +28 -6
  14. package/lib/cjs/config/Config.js.map +1 -1
  15. package/lib/cjs/config/ConfigDefaults.js +6 -2
  16. package/lib/cjs/config/ConfigDefaults.js.map +1 -1
  17. package/lib/cjs/config/ConfigProvider.js +5 -0
  18. package/lib/cjs/config/ConfigProvider.js.map +1 -1
  19. package/lib/cjs/config/DefaultFactory.js +27 -0
  20. package/lib/cjs/config/DefaultFactory.js.map +1 -0
  21. package/lib/cjs/contracts/ContractBase.js +6 -2
  22. package/lib/cjs/contracts/ContractBase.js.map +1 -1
  23. package/lib/cjs/contracts/ContractReader.js +1 -35
  24. package/lib/cjs/contracts/ContractReader.js.map +1 -1
  25. package/lib/cjs/explorer/BlockchainExplorer.js +9 -9
  26. package/lib/cjs/explorer/BlockchainExplorer.js.map +1 -1
  27. package/lib/cjs/explorer/BlockchainExplorerFactory.js +1 -1
  28. package/lib/cjs/explorer/BlockchainExplorerFactory.js.map +1 -1
  29. package/lib/cjs/explorer/BlockchainExplorerProvider.js +1 -1
  30. package/lib/cjs/explorer/BlockchainExplorerProvider.js.map +1 -1
  31. package/lib/cjs/explorer/BlockchainExplorerStorage.js +2 -2
  32. package/lib/cjs/explorer/BlockchainExplorerStorage.js.map +1 -1
  33. package/lib/cjs/explorer/ContractVerifier.js +10 -10
  34. package/lib/cjs/explorer/ContractVerifier.js.map +1 -1
  35. package/lib/cjs/explorer/verifiers/FsHtmlVerifier.js +1 -1
  36. package/lib/cjs/explorer/verifiers/FsHtmlVerifier.js.map +1 -1
  37. package/lib/cjs/rpc/RpcContract.js +4 -32
  38. package/lib/cjs/rpc/RpcContract.js.map +1 -1
  39. package/lib/cjs/utils/$account.js +5 -0
  40. package/lib/cjs/utils/$account.js.map +1 -1
  41. package/lib/cjs/utils/$config.js +4 -5
  42. package/lib/cjs/utils/$config.js.map +1 -1
  43. package/lib/cjs/utils/$erc20.js +47 -0
  44. package/lib/cjs/utils/$erc20.js.map +1 -0
  45. package/lib/cjs/utils/$require.js +2 -2
  46. package/lib/cjs/utils/$require.js.map +1 -1
  47. package/lib/esm/abi/$abi.js.map +1 -1
  48. package/lib/esm/abi/$abi.mjs +33 -0
  49. package/lib/esm/blocks/BlockDateResolver.js.map +1 -1
  50. package/lib/esm/clients/Web3Client.js.map +1 -1
  51. package/lib/esm/clients/Web3Client.mjs +43 -2
  52. package/lib/esm/clients/Web3ClientFactory.js.map +1 -1
  53. package/lib/esm/clients/Web3ClientFactory.mjs +26 -4
  54. package/lib/esm/clients/debug/ClientDebugMethods.js.map +1 -1
  55. package/lib/esm/clients/debug/ClientDebugMethods.mjs +4 -0
  56. package/lib/esm/clients/utils/$web3Abi.js.map +1 -1
  57. package/lib/esm/clients/utils/$web3Abi.mjs +1 -1
  58. package/lib/esm/config/Config.js.map +1 -1
  59. package/lib/esm/config/Config.mjs +28 -6
  60. package/lib/esm/config/ConfigDefaults.js.map +1 -1
  61. package/lib/esm/config/ConfigDefaults.mjs +6 -2
  62. package/lib/esm/config/ConfigProvider.js.map +1 -1
  63. package/lib/esm/config/ConfigProvider.mjs +5 -0
  64. package/lib/esm/config/DefaultFactory.js.map +1 -0
  65. package/lib/esm/config/DefaultFactory.mjs +23 -0
  66. package/lib/esm/contracts/ContractBase.js.map +1 -1
  67. package/lib/esm/contracts/ContractBase.mjs +6 -2
  68. package/lib/esm/contracts/ContractReader.js.map +1 -1
  69. package/lib/esm/contracts/ContractReader.mjs +1 -35
  70. package/lib/esm/explorer/BlockchainExplorer.js.map +1 -1
  71. package/lib/esm/explorer/BlockchainExplorer.mjs +9 -9
  72. package/lib/esm/explorer/BlockchainExplorerFactory.js.map +1 -1
  73. package/lib/esm/explorer/BlockchainExplorerFactory.mjs +1 -1
  74. package/lib/esm/explorer/BlockchainExplorerProvider.js.map +1 -1
  75. package/lib/esm/explorer/BlockchainExplorerProvider.mjs +1 -1
  76. package/lib/esm/explorer/BlockchainExplorerStorage.js.map +1 -1
  77. package/lib/esm/explorer/BlockchainExplorerStorage.mjs +2 -2
  78. package/lib/esm/explorer/ContractVerifier.js.map +1 -1
  79. package/lib/esm/explorer/ContractVerifier.mjs +10 -10
  80. package/lib/esm/explorer/verifiers/FsHtmlVerifier.js.map +1 -1
  81. package/lib/esm/explorer/verifiers/FsHtmlVerifier.mjs +1 -1
  82. package/lib/esm/rpc/RpcContract.js.map +1 -1
  83. package/lib/esm/rpc/RpcContract.mjs +4 -32
  84. package/lib/esm/utils/$account.js.map +1 -1
  85. package/lib/esm/utils/$account.mjs +5 -0
  86. package/lib/esm/utils/$config.js.map +1 -1
  87. package/lib/esm/utils/$config.mjs +4 -5
  88. package/lib/esm/utils/$erc20.js.map +1 -0
  89. package/lib/esm/utils/$erc20.mjs +41 -0
  90. package/lib/esm/utils/$require.js.map +1 -1
  91. package/lib/esm/utils/$require.mjs +2 -2
  92. package/lib/types/abi/$abi.d.ts +3 -1
  93. package/lib/types/blocks/BlockDateResolver.d.ts +1 -1
  94. package/lib/types/clients/Web3Client.d.ts +1 -1
  95. package/lib/types/clients/Web3ClientFactory.d.ts +10 -2
  96. package/lib/types/clients/debug/ClientDebugMethods.d.ts +1 -1
  97. package/lib/types/config/AConfigBase.d.ts +3 -0
  98. package/lib/types/config/Config.d.ts +2 -1
  99. package/lib/types/config/DefaultFactory.d.ts +2 -0
  100. package/lib/types/config/interface/IConfigData.d.ts +14 -2
  101. package/lib/types/contracts/ContractReader.d.ts +1 -1
  102. package/lib/types/explorer/BlockchainExplorerFactory.d.ts +1 -1
  103. package/lib/types/explorer/IBlockchainExplorer.d.ts +6 -0
  104. package/lib/types/models/TPlatform.d.ts +1 -1
  105. package/lib/types/utils/$account.d.ts +1 -0
  106. package/lib/types/utils/$erc20.d.ts +5 -0
  107. package/lib/types/utils/$require.d.ts +2 -2
  108. package/package.json +1 -1
  109. package/skills/README.md +45 -0
  110. package/{docs/ai → skills/dequanto}/INDEX.md +16 -5
  111. package/skills/dequanto/SKILL.md +73 -0
  112. package/skills/dequanto/examples/config.spec.ts +113 -0
  113. package/skills/dequanto/examples/contract-read.spec.ts +112 -0
  114. package/skills/dequanto/examples/contract-write.spec.ts +68 -0
  115. package/skills/dequanto/examples/deploy-contract.spec.ts +69 -0
  116. package/{docs/ai → skills/dequanto}/examples/erc4337-userop.spec.ts +13 -11
  117. package/skills/dequanto/examples/explorer-abi.spec.ts +21 -0
  118. package/{docs/ai/examples/generate-client.spec.ts → skills/dequanto/examples/generate-contract-class.spec.ts} +7 -4
  119. package/skills/dequanto/examples/hardhat-debug.spec.ts +29 -0
  120. package/skills/dequanto/examples/hardhat-fork.spec.ts +31 -0
  121. package/{docs/ai → skills/dequanto}/examples/index-events.spec.ts +10 -8
  122. package/skills/dequanto/examples/rpc-read.spec.ts +59 -0
  123. package/{docs/ai → skills/dequanto}/examples/safe-batch.spec.ts +10 -9
  124. package/skills/dequanto/examples/send-transaction.spec.ts +34 -0
  125. package/skills/dequanto/examples/storage.spec.ts +58 -0
  126. package/skills/dequanto/examples/token-transfer.spec.ts +29 -0
  127. package/skills/dequanto/examples/utils.spec.ts +63 -0
  128. package/{docs/ai → skills/dequanto}/references/contracts.md +1 -1
  129. package/{docs/ai → skills/dequanto}/references/deployments.md +4 -2
  130. package/{docs/ai → skills/dequanto}/references/events-indexing.md +1 -1
  131. package/{docs/ai → skills/dequanto}/references/explorer.md +1 -1
  132. package/{docs/ai → skills/dequanto}/references/generation.md +36 -13
  133. package/skills/dequanto/references/hardhat.md +113 -0
  134. package/{docs/ai → skills/dequanto}/references/rpc-clients.md +25 -5
  135. package/{docs/ai → skills/dequanto}/references/safe-erc4337.md +2 -2
  136. package/skills/dequanto/references/storage.md +122 -0
  137. package/{docs/ai → skills/dequanto}/references/tokens-accounts.md +12 -6
  138. package/{docs/ai → skills/dequanto}/references/transactions.md +6 -4
  139. package/skills/dequanto/references/utils.md +131 -0
  140. package/src/abi/$abi.ts +34 -1
  141. package/src/blocks/BlockDateResolver.ts +1 -1
  142. package/src/clients/Web3Client.ts +48 -3
  143. package/src/clients/Web3ClientFactory.ts +33 -5
  144. package/src/clients/debug/ClientDebugMethods.ts +5 -1
  145. package/src/clients/utils/$web3Abi.ts +2 -2
  146. package/src/config/AConfigBase.ts +4 -0
  147. package/src/config/Config.ts +30 -8
  148. package/src/config/ConfigDefaults.ts +6 -2
  149. package/src/config/ConfigProvider.ts +5 -1
  150. package/src/config/DefaultFactory.ts +26 -0
  151. package/src/config/interface/IConfigData.ts +15 -2
  152. package/src/contracts/ContractBase.ts +6 -2
  153. package/src/contracts/ContractReader.ts +3 -40
  154. package/src/explorer/BlockchainExplorer.ts +9 -9
  155. package/src/explorer/BlockchainExplorerFactory.ts +1 -2
  156. package/src/explorer/BlockchainExplorerProvider.ts +1 -1
  157. package/src/explorer/BlockchainExplorerStorage.ts +2 -2
  158. package/src/explorer/ContractVerifier.ts +10 -10
  159. package/src/explorer/IBlockchainExplorer.ts +4 -0
  160. package/src/explorer/verifiers/FsHtmlVerifier.ts +1 -1
  161. package/src/models/TPlatform.ts +1 -0
  162. package/src/rpc/RpcContract.ts +5 -33
  163. package/src/utils/$account.ts +5 -0
  164. package/src/utils/$config.ts +4 -6
  165. package/src/utils/$erc20.ts +53 -0
  166. package/src/utils/$require.ts +4 -4
  167. package/tsconfig.json +3 -3
  168. package/tsconfig.umd.json +1 -2
  169. package/docs/ai/examples/contract-read.spec.ts +0 -44
  170. package/docs/ai/examples/contract-write.spec.ts +0 -16
  171. package/docs/ai/examples/deploy-contract.spec.ts +0 -32
  172. package/docs/ai/examples/explorer-abi.spec.ts +0 -18
  173. package/docs/ai/examples/rpc-read.spec.ts +0 -15
  174. package/docs/ai/examples/send-transaction.spec.ts +0 -22
  175. package/docs/ai/examples/storage-read.spec.ts +0 -27
  176. package/docs/ai/examples/token-transfer.spec.ts +0 -22
  177. package/docs/ai/references/storage.md +0 -93
  178. package/docs/ai/skill/dequanto/SKILL.md +0 -59
  179. /package/{docs/ai → skills/dequanto}/references/migration-from-ethers-viem.md +0 -0
@@ -2,11 +2,12 @@ import di from 'a-di';
2
2
  import alot from 'alot';
3
3
  import { Rpc, RpcTypes } from './Rpc';
4
4
 
5
- import { TAbiItem, TAbiOutput } from '@dequanto/types/TAbi';
5
+ import { TAbiItem } from '@dequanto/types/TAbi';
6
6
  import { TAddress } from '@dequanto/models/TAddress';
7
7
  import { $require } from '@dequanto/utils/$require';
8
8
  import { $abiUtils } from '@dequanto/utils/$abiUtils';
9
9
  import { $abiCoder } from '@dequanto/abi/$abiCoder';
10
+ import { $abi } from '@dequanto/abi/$abi';
10
11
  import { RpcError } from './RpcError';
11
12
  import { $hex } from '@dequanto/utils/$hex';
12
13
  import { TEth } from '@dequanto/models/TEth';
@@ -54,7 +55,7 @@ export class RpcContract {
54
55
  if (methodAbi == null) {
55
56
  return hex;
56
57
  }
57
- return utils.deserializeOutput(hex, methodAbi.outputs);
58
+ return $abi.decodeReturn(methodAbi, hex);
58
59
  } catch (err) {
59
60
  if (err instanceof RpcError) {
60
61
  err.message = `RpcCall ${req.method} (${JSON.stringify(req.params)}) ${err.message}`;
@@ -82,7 +83,7 @@ export class RpcContract {
82
83
  let defaults = null;
83
84
  try {
84
85
  const defaultHex = $abiCoder.encode(returnABI, [null]);
85
- defaults = utils.deserializeOutput(defaultHex, returnABI);
86
+ defaults = $abi.decodeReturn(abi, defaultHex);
86
87
  } catch (error) {}
87
88
  return {
88
89
  defaults,
@@ -90,7 +91,7 @@ export class RpcContract {
90
91
  };
91
92
  }
92
93
  let hex = typeof resp === 'string' ? resp : resp.data;
93
- let result = utils.deserializeOutput(hex, returnABI);
94
+ let result = $abi.decodeReturn(abi, hex);
94
95
  return result;
95
96
  });
96
97
 
@@ -191,32 +192,3 @@ export class RpcContract {
191
192
  // }
192
193
  }
193
194
 
194
-
195
- namespace utils {
196
- export function deserializeOutput(hex: string, outputs: TAbiOutput[]) {
197
-
198
- let abi = outputs;
199
- let isDynamic: boolean = null;
200
- if (outputs.length > 1) {
201
- let isNamedTuple = outputs.every(x => x.name != null && x.name !== '');
202
- if (isNamedTuple) {
203
- // Return as an object
204
- abi = [ { type: 'tuple', components: outputs, name: null } ];
205
- isDynamic = false;
206
- }
207
- }
208
-
209
- try {
210
- let arr = $abiCoder.decode(abi as any, hex, {
211
- dynamic: isDynamic
212
- });
213
- let value = abi.length === 1 ? arr[0] : arr;
214
- return value;
215
- } catch (error) {
216
- if (outputs.length === 1 && abi.length === 1) {
217
- return $abiCoder.decodeSingle(abi[0], hex);
218
- }
219
- throw error;
220
- }
221
- }
222
- }
@@ -1,6 +1,7 @@
1
1
  import { EoAccount, Erc4337Account, SafeAccount, TAccount, TimelockAccount } from "@dequanto/models/TAccount";
2
2
  import { $address } from './$address';
3
3
  import { $require } from './$require';
4
+ import { $sig } from './$sig';
4
5
 
5
6
  export namespace $account {
6
7
 
@@ -64,4 +65,8 @@ export namespace $account {
64
65
  // Optimistic match by pattern "timelock/";
65
66
  return rgx.test(account.name);
66
67
  }
68
+
69
+ export function generate(name: string): EoAccount {
70
+ return $sig.$account.generate({ name });
71
+ }
67
72
  }
@@ -16,8 +16,8 @@ export namespace $config {
16
16
  let envOptions = null;
17
17
 
18
18
  export function get <T = any> (path: string, $default?: T): T {
19
- let value = (typeof $global.app !== 'undefined' ? $global.app.config?.$get?.(path) : null)
20
- ?? obj_getProperty(config, path)
19
+ let value = obj_getProperty(config, path)
20
+ ?? (typeof $global.app !== 'undefined' ? $global.app.config?.$get?.(path) : null)
21
21
  ?? obj_getProperty(envOptions, path);
22
22
 
23
23
  if (value == null && envOptions == null) {
@@ -79,11 +79,10 @@ export namespace $config {
79
79
  let explorer = $config.get<IConfigData['blockchainExplorer']>(`blockchainExplorer`);
80
80
  let chains = $config.get<IConfigData['chains']>('chains', []);
81
81
 
82
-
83
82
  let explorerConfig = explorer[platform];
84
83
  let chainConfig = chains.find(x => x.platform === platform || x.aliases?.includes(platform));
85
84
 
86
- $require.notNull(explorerConfig || chainConfig, `Unsupported platform ${platform} for web3 client`);
85
+ $require.notNull(explorerConfig || chainConfig, `Unsupported platform ${platform} for blockchain explorer`);
87
86
  return {
88
87
  platform,
89
88
  ...(chainConfig?.explorers?.[0] ?? {}),
@@ -92,11 +91,10 @@ export namespace $config {
92
91
  }
93
92
 
94
93
  export function set <T = any> (path: string, value: T) {
94
+ obj_setProperty(config, path, value);
95
95
  if (typeof $global.app?.config?.$set === 'function') {
96
96
  $global.app.config.$set(path, value);
97
- return;
98
97
  }
99
- obj_setProperty(config, path, value);
100
98
  }
101
99
 
102
100
  /**
@@ -0,0 +1,53 @@
1
+ import alot from 'alot';
2
+ import { $require } from './$require';
3
+ import { $hex } from './$hex';
4
+ import { $bigint } from './$bigint';
5
+ import { TEth } from '@dequanto/models/TEth';
6
+ import { Web3Client } from '@dequanto/clients/Web3Client';
7
+ import { ERC20 } from '@dequanto/prebuilt/openzeppelin/ERC20';
8
+
9
+ export namespace $erc20 {
10
+ export async function setBalanceAny(client: Web3Client, token: TEth.Address, account: TEth.Address, amount: bigint | number) {
11
+ $require.eq(client.platform, 'hardhat', `Set Balance available only on Hardhat/Forked network`);
12
+ const erc20 = new ERC20(token, client);
13
+ const rpc = await client.getRpc();
14
+
15
+ const req = await (erc20.$data() as any).balanceOf(account);
16
+ const balanceTrace = await rpc.request({
17
+ method: 'debug_traceCall',
18
+ params: [
19
+ req,
20
+ 'latest',
21
+ {
22
+ disableMemory: true,
23
+ disableStack: true,
24
+ disableStorage: false,
25
+ }
26
+ ]
27
+ }) as {
28
+ returnValue: TEth.Hex
29
+ failed: boolean
30
+ structLogs: {
31
+ "op": "RETURN",
32
+ "pc": 1698,
33
+ "storage": Record<string, TEth.Hex>
34
+ }[]
35
+ };
36
+
37
+ $require.True(balanceTrace.failed === false, `erc20 balance retrieval failed for ${await erc20.symbol()}`);
38
+ let returnOp = alot(balanceTrace.structLogs.reverse()).find(x => x.op === 'RETURN');
39
+ $require.notNull(returnOp, `RETURN opcode not found`);
40
+ $require.notNull(returnOp.storage, `Storage not found`);
41
+
42
+ let returnValue = $hex.raw(balanceTrace.returnValue);
43
+ let slots = alot.fromObject(returnOp.storage).filter(x => x.value === returnValue).toArray();
44
+ $require.gt(slots.length, 0, `Slot not found`);
45
+ let SLOT = $hex.ensure(slots[slots.length - 1].key);
46
+
47
+ let balance = typeof amount === 'number'
48
+ ? await $bigint.toWei(amount, await erc20.decimals())
49
+ : amount;
50
+
51
+ await client.debug.setStorageAt(erc20.address, SLOT, $bigint.toHex(balance));
52
+ }
53
+ }
@@ -61,17 +61,17 @@ export namespace $require {
61
61
  }
62
62
  return val;
63
63
  }
64
- export function notNull<T> (val: T, message: string, ...logs): NonNullable<T> {
64
+ export function notNull<T> (val: T, message?: string, ...logs): NonNullable<T> {
65
65
  if (val == null) {
66
66
  logs?.forEach(log => console.error(log));
67
- throw new Error(`Value is undefined. ${message}`);
67
+ throw new Error(`Value is undefined. ${message ?? ''}`);
68
68
  }
69
69
  return val;
70
70
  }
71
- export function Null<T> (val: T, message: string, ...logs): T {
71
+ export function Null<T> (val: T, message?: string, ...logs): T {
72
72
  if (val != null) {
73
73
  logs?.forEach(log => console.error(log));
74
- throw new Error(`Value ${val} expects to be undefined. ${message}`);
74
+ throw new Error(`Value ${val} expects to be undefined. ${message ?? ''}`);
75
75
  }
76
76
  return val;
77
77
  }
package/tsconfig.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "exclude": [
3
- "exports/core.lib.ts"
3
+ "exports/core.lib.ts",
4
+ "ts-temp"
4
5
  ],
5
6
  "compilerOptions": {
6
7
  "baseUrl": "./",
7
8
  "paths": {
8
9
  "@dequanto/*": [ "src/*" ],
9
- "dequanto/*": [ "src/*" ],
10
- "@dequanto-contracts/*": [ "src/prebuilt/*" ]
10
+ "dequanto/*": [ "src/*" ]
11
11
  },
12
12
  "typeRoots": [
13
13
  "node_modules/@types",
package/tsconfig.umd.json CHANGED
@@ -6,8 +6,7 @@
6
6
  "compilerOptions": {
7
7
  "baseUrl": "./",
8
8
  "paths": {
9
- "@dequanto/*": [ "src/*" ],
10
- "@dequanto-contracts/*": [ "src/prebuilt/*" ]
9
+ "@dequanto/*": [ "src/*" ]
11
10
  },
12
11
  "lib": [ "ES2019", "dom" ],
13
12
  "typeRoots": [
@@ -1,44 +0,0 @@
1
- import { Web3ClientFactory } from '@dequanto/clients/Web3ClientFactory';
2
- // dequanto ships prebuilt TypeScript clients for all OpenZeppelin contracts.
3
- import { ERC20 } from '@dequanto/prebuilt/openzeppelin/ERC20';
4
- // Use 0xweb CLI to download and generate simple TypeScript clients for verified contracts from Etherscan-compatible explorers:
5
- // 0xweb install <address> --name AavePool --chain eth --save-sources false
6
- import { AavePool } from '../../../0xc/eth/AavePool/AavePool';
7
-
8
- const USDC = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48' as const;
9
-
10
- UTest({
11
- async 'read stable USDC metadata from live Ethereum RPC' () {
12
- const client = await Web3ClientFactory.getAsync('eth');
13
- const usdc = new ERC20(USDC, client);
14
-
15
- const [symbol, decimals, balance] = await Promise.all([
16
- usdc.symbol(),
17
- usdc.decimals(),
18
- usdc.balanceOf('0x0000000000000000000000000000000000000000')
19
- ]);
20
-
21
- eq_(symbol, 'USDC');
22
- eq_(Number(decimals), 6);
23
- gte_(balance, 0n);
24
- },
25
-
26
- async 'read generated Aave Pool data from live Ethereum RPC' () {
27
- const client = await Web3ClientFactory.getAsync('eth');
28
- const pool = new AavePool(undefined, client);
29
-
30
- const [addressesProvider, maxReserves, reserves, reserveData] = await Promise.all([
31
- pool.ADDRESSES_PROVIDER(),
32
- pool.MAX_NUMBER_RESERVES(),
33
- pool.getReservesList(),
34
- pool.getReserveData(USDC)
35
- ]);
36
-
37
- has_(addressesProvider, /^0x[a-fA-F0-9]{40}$/);
38
- gt_(Number(maxReserves), 0);
39
- eq_(reserves.some(x => x.toLowerCase() === USDC.toLowerCase()), true);
40
- has_(reserveData.aTokenAddress, /^0x[a-fA-F0-9]{40}$/);
41
- has_(reserveData.variableDebtTokenAddress, /^0x[a-fA-F0-9]{40}$/);
42
- gte_(reserveData.liquidityIndex, 1n);
43
- }
44
- });
@@ -1,16 +0,0 @@
1
- import { Web3ClientFactory } from '@dequanto/clients/Web3ClientFactory';
2
- import { ERC20 } from '@dequanto-contracts/openzeppelin/ERC20';
3
-
4
- UTest({
5
- async 'build ERC20 transfer tx data without submitting' () {
6
- const client = await Web3ClientFactory.getAsync('eth');
7
- const usdc = new ERC20('0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', client);
8
- const sender = { address: '0x0000000000000000000000000000000000000001' as const };
9
- const receiver = '0x0000000000000000000000000000000000000002' as const;
10
-
11
- const tx = await usdc.$data().transfer(sender, receiver, 1_000_000n);
12
-
13
- eq_(tx.to.toLowerCase(), usdc.address.toLowerCase());
14
- has_(tx.data, /^0xa9059cbb/);
15
- }
16
- });
@@ -1,32 +0,0 @@
1
- import { Deployments } from '@dequanto/contracts/deploy/Deployments';
2
- import { Generator } from '@dequanto/gen/Generator';
3
- import { HardhatProvider } from '@dequanto/hardhat/HardhatProvider';
4
- import { File } from 'atma-io';
5
-
6
- declare const include: any;
7
-
8
- UTest({
9
- async 'deploy a generated contract with Deployments.ensure' () {
10
- const hh = new HardhatProvider();
11
- const client = hh.client();
12
- const deployer = hh.deployer(0);
13
- const deploymentsFile = './test/tmp/ai-examples/deployments-hardhat.json';
14
-
15
- await File.removeAsync(deploymentsFile);
16
-
17
- const generated = await Generator.generateFromSol('./test/fixtures/deployments/DeploymentsFoo.sol');
18
- const module = await include.instance().js(generated.main);
19
- const Ctor = module.DeploymentsFoo.DeploymentsFoo;
20
-
21
- const deployments = new Deployments(client, deployer, {
22
- directory: './test/tmp/ai-examples/',
23
- verification: false
24
- });
25
-
26
- const { contract } = await deployments.ensure(Ctor, { arguments: [] });
27
- const value = await (contract as any).getValue();
28
-
29
- has_(contract.address, /^0x[a-fA-F0-9]{40}$/);
30
- eq_(value, 4n);
31
- }
32
- });
@@ -1,18 +0,0 @@
1
- import { BlockchainExplorerFactory } from '@dequanto/explorer/BlockchainExplorerFactory';
2
-
3
- UTest({
4
- async 'fetch stable USDC ABI and source from configured Ethereum explorer' () {
5
- const explorer = await BlockchainExplorerFactory.getAsync('eth');
6
- const address = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48';
7
-
8
- const { abi, implementation } = await explorer.getContractAbi(address);
9
- const source = await explorer.getContractSource(implementation);
10
- const creation = await explorer.getContractCreation(address);
11
-
12
- eq_(implementation.toLowerCase(), address);
13
- gt_(JSON.parse(abi).length, 0);
14
- has_(source.ContractName, /FiatToken|Proxy|USDC/i);
15
- has_(creation.creator, /^0x[a-fA-F0-9]{40}$/);
16
- has_(creation.txHash, /^0x[a-fA-F0-9]{64}$/);
17
- }
18
- });
@@ -1,15 +0,0 @@
1
- import { Web3ClientFactory } from '@dequanto/clients/Web3ClientFactory';
2
-
3
- UTest({
4
- async 'read latest block and zero-address balance from live Ethereum RPC' () {
5
- const client = await Web3ClientFactory.getAsync('eth');
6
-
7
- const latest = await client.getBlockNumber();
8
- const block = await client.getBlock('latest');
9
- const balance = await client.getBalance('0x0000000000000000000000000000000000000000');
10
-
11
- gt_(Number(latest), 0);
12
- gt_(Number(block.timestamp), 0);
13
- gte_(balance, 0n);
14
- }
15
- });
@@ -1,22 +0,0 @@
1
- import { Web3ClientFactory } from '@dequanto/clients/Web3ClientFactory';
2
- import { TxDataBuilder } from '@dequanto/txs/TxDataBuilder';
3
-
4
- UTest({
5
- async 'build native transfer tx data with gas fields' () {
6
- const client = await Web3ClientFactory.getAsync('eth');
7
- const sender = { address: '0x0000000000000000000000000000000000000001' as const };
8
- const receiver = '0x0000000000000000000000000000000000000002' as const;
9
-
10
- const builder = new TxDataBuilder(client, sender, {
11
- to: receiver
12
- });
13
-
14
- builder.setValue(10n ** 16n);
15
- await builder.setGas({ gasEstimation: false, gasLimit: 21_000 });
16
-
17
- eq_(builder.data.to, receiver);
18
- eq_(builder.data.value, '0x2386f26fc10000');
19
- eq_(Number(builder.data.gas), 21_000);
20
- notEq_(builder.data.maxFeePerGas ?? builder.data.gasPrice, null);
21
- }
22
- });
@@ -1,27 +0,0 @@
1
- import { HardhatProvider } from '@dequanto/hardhat/HardhatProvider';
2
- import { SlotsParser } from '@dequanto/solidity/SlotsParser';
3
- import { SlotsStorage } from '@dequanto/solidity/SlotsStorage';
4
-
5
- UTest({
6
- async 'read Solidity storage with SlotsParser and SlotsStorage' () {
7
- const code = `
8
- contract Vault {
9
- uint256 public count = 123;
10
- mapping(address => uint256) balances;
11
-
12
- constructor () {
13
- balances[address(0x1000000000000000000000000000000000000001)] = 7;
14
- }
15
- }
16
- `;
17
- const provider = new HardhatProvider();
18
- const client = provider.client();
19
- const { contract } = await provider.deployCode(code, { client });
20
-
21
- const slots = await SlotsParser.slots({ path: '', code }, 'Vault');
22
- const storage = SlotsStorage.createWithClient(client, contract.address, slots);
23
-
24
- eq_(await storage.get('count'), 123n);
25
- eq_(await storage.get('balances["0x1000000000000000000000000000000000000001"]'), 7n);
26
- }
27
- });
@@ -1,22 +0,0 @@
1
- import { Web3ClientFactory } from '@dequanto/clients/Web3ClientFactory';
2
- import { TokenTransferService } from '@dequanto/tokens/TokenTransferService';
3
- import { TokensService } from '@dequanto/tokens/TokensService';
4
-
5
- UTest({
6
- async 'load known token metadata and read a live token balance' () {
7
- const client = await Web3ClientFactory.getAsync('eth');
8
- const tokens = new TokensService('eth');
9
- const usdc = await tokens.getKnownToken('USDC');
10
- const service = new TokenTransferService(client);
11
-
12
- const balance = await service.getBalance(
13
- '0x0000000000000000000000000000000000000000',
14
- usdc
15
- );
16
-
17
- eq_(usdc.symbol, 'USDC');
18
- eq_(usdc.decimals, 6);
19
- eq_(usdc.address.toLowerCase(), '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48');
20
- gte_(balance, 0n);
21
- }
22
- });
@@ -1,93 +0,0 @@
1
- # Solidity Storage
2
-
3
- Use `SlotsParser` to derive layout and `SlotsStorage` to read or write slots. Do not decode raw storage words as ABI payloads.
4
-
5
- Key source files:
6
-
7
- - `src/solidity/SlotsParser.ts`
8
- - `src/solidity/SlotsStorage.ts`
9
- - `src/solidity/storage/handlers/SlotStructHandler.ts`
10
- - `src/solidity/storage/handlers/SlotMappingHandler.ts`
11
- - `src/solidity/storage/handlers/SlotDynamicArrayHandler.ts`
12
- - `src/solidity/storage/SlotsStorageTransport.ts`
13
- - `src/gen/GeneratorStorageReader.ts`
14
-
15
- Useful tests:
16
-
17
- - `test/solidity/SlotsReader.spec.ts`
18
- - `test/solidity/Storage.spec.ts`
19
- - `test/solidity/SlotsParser.spec.ts`
20
- - `test/generate/slotreader.spec.ts`
21
-
22
- ## Parse Slots From Solidity
23
-
24
- ```ts
25
- import { SlotsParser } from '@dequanto/solidity/SlotsParser';
26
-
27
- const slots = await SlotsParser.slots({
28
- path: './contracts/Vault.sol'
29
- }, 'Vault');
30
- ```
31
-
32
- For inline code:
33
-
34
- ```ts
35
- const slots = await SlotsParser.slots({ path: '', code }, 'Foo');
36
- ```
37
-
38
- ## Parse Slots From ABI Inputs
39
-
40
- Use this for standalone struct or tuple ABI data:
41
-
42
- ```ts
43
- const slots = await SlotsParser.slotsFromAbi(
44
- '(uint256 foo, address owner, bool enabled)'
45
- );
46
- ```
47
-
48
- ## Read Contract Storage
49
-
50
- ```ts
51
- import { SlotsStorage } from '@dequanto/solidity/SlotsStorage';
52
-
53
- const storage = SlotsStorage.createWithClient(client, contract.address, slots);
54
-
55
- const owner = await storage.get('owner');
56
- const user = await storage.get('users[0]');
57
- const balance = await storage.get(`balances["${account}"]`);
58
- ```
59
-
60
- Supported path forms include:
61
-
62
- - `field`
63
- - `struct.field`
64
- - `array[0]`
65
- - `mapping["0x..."]`
66
- - `mapping["0x..."].field`
67
- - `nested[0].balances[1]`
68
- - breadcrumb arrays such as `['users', account, 'balance']`
69
-
70
- ## Read Diamond Or Offset Storage
71
-
72
- For library-selected storage roots:
73
-
74
- ```ts
75
- const storage = SlotsStorage.createWithClient(client, contract.address, slots, {
76
- storageOffset: $contract.keccak256('diamond.app.storage')
77
- });
78
- ```
79
-
80
- ## Write Storage In Tests
81
-
82
- `SlotsStorage.set(...)` exists and is useful in Hardhat/debug contexts:
83
-
84
- ```ts
85
- await storage.set('user.balance', 1000n);
86
- ```
87
-
88
- Do not use storage writes in production code unless the transport explicitly supports it and the task requires test/debug mutation.
89
-
90
- ## Raw Slot Reads
91
-
92
- Use `client.getStorageAt(address, slot)` or `client.getStorageAtBatched(address, slots)` only when raw words are needed.
93
-
@@ -1,59 +0,0 @@
1
- ---
2
- name: dequanto
3
- description: Use when implementing EVM, blockchain, smart-contract, token, RPC, event-indexing, Safe, ERC-4337, storage, deployment, or ABI work in TypeScript projects that use the dequanto framework. Prefer dequanto APIs over ethers, viem, web3.js, raw JSON-RPC, manual explorer HTTP calls, or hand-written ABI encoding unless the user explicitly asks otherwise.
4
- ---
5
-
6
- # Dequanto
7
-
8
- Use dequanto as the primary EVM toolkit.
9
-
10
- ## Workflow
11
-
12
- 1. Identify the requested blockchain task.
13
- 2. Read `../../INDEX.md` to choose the dequanto surface.
14
- 3. Read the matching file in `../../references/`.
15
- 4. Reuse the nearest example from `../../examples/`.
16
- 5. Verify unfamiliar APIs in `src/` or `lib/types/` before writing code.
17
- 6. After TypeScript edits in the dequanto repo, run `npm run typecheck -- --pretty false`.
18
-
19
- ## Defaults
20
-
21
- - Use `await Web3ClientFactory.getAsync(platform)` for chain clients so configuration is loaded before RPC, explorer, and chain services are used.
22
- - Use generated contract classes for ABI calls and transactions: call read-only ABI methods directly as normal TypeScript methods, and call writable ABI methods through `contract.$receipt().someFunction(sender, ...args)`.
23
- - Use generated `$data()` for calldata.
24
- - Treat `$receipt()` as a completed `TxWriter` flow that waits for the transaction receipt. The first writable-method argument is an `IAccount`.
25
- - Read account shapes in `src/models/TAccount.ts` when composing transaction senders:
26
- - EOA with only `address`: the RPC provider/node is responsible for signing.
27
- - EOA with `key`: dequanto signs directly; encrypted `p1:0x...` keys require the PIN from environment configuration.
28
- - `safe`: wrap calldata into a Gnosis Safe transaction. Provide `address` and an `operator`; if enough owners/signers are available, dequanto signs and submits on-chain, otherwise it submits to the Gnosis Safe service for later signing.
29
- - `timelock`: wrap calldata into an OpenZeppelin Timelock transaction and submit it via `operator`.
30
- - `erc4337`: wrap calldata into an ERC-4337 user operation and submit it via `operator`.
31
- - Account agents can be chained. For example, a Timelock account can use a Safe account as `operator`, so the initial calldata is wrapped first as Timelock calldata and then as Safe transaction calldata.
32
- - Use `EventsIndexer` for resumable historical event indexing.
33
- - Use `BlockchainExplorerFactory` for explorer ABI, source, creation, transactions, and transfers.
34
- - Use `SlotsParser` and `SlotsStorage` for Solidity storage decoding.
35
- - Use `Deployments` for idempotent deployments, proxy deployments, beacon deployments, and verification.
36
- - Use dequanto account-agent flows when the account type says `safe`, `timelock`, or `erc4337`.
37
-
38
- ## Reference Routing
39
-
40
- - Contract reads, writes, generated helper facets: `../../references/contracts.md`
41
- - RPC clients, blocks, balances, raw logs, subscriptions: `../../references/rpc-clients.md`
42
- - Transaction builders, tx writer lifecycle, receipts, nonces: `../../references/transactions.md`
43
- - Contract generation: `../../references/generation.md`
44
- - Deployment and proxy flows: `../../references/deployments.md`
45
- - Historical events and indexing: `../../references/events-indexing.md`
46
- - Explorer integration: `../../references/explorer.md`
47
- - Solidity storage: `../../references/storage.md`
48
- - Tokens and accounts: `../../references/tokens-accounts.md`
49
- - Safe and ERC-4337: `../../references/safe-erc4337.md`
50
- - Translating ethers/viem habits: `../../references/migration-from-ethers-viem.md`
51
-
52
- ## Rules
53
-
54
- - Never guess a dequanto API signature.
55
- - Inspect generated contract classes before using generated method names or event helper names.
56
- - Do not add ethers, viem, web3.js, or external Safe/account-abstraction SDKs when dequanto already has a suitable API.
57
- - Keep code version-specific to the installed dequanto package.
58
- - Prefer examples that compile in the target project over abstract snippets.
59
-