@lidofinance/lsv-cli 1.7.0 → 1.9.0

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 (202) hide show
  1. package/README.md +9 -1
  2. package/dist/abi/defi-wrapper/GenericStrategy.d.ts +308 -0
  3. package/dist/abi/defi-wrapper/GenericStrategy.js +409 -0
  4. package/dist/abi/defi-wrapper/GenericStrategy.js.map +1 -0
  5. package/dist/abi/defi-wrapper/MellowStrategy.d.ts +429 -0
  6. package/dist/abi/defi-wrapper/MellowStrategy.js +892 -0
  7. package/dist/abi/defi-wrapper/MellowStrategy.js.map +1 -0
  8. package/dist/abi/defi-wrapper/index.d.ts +2 -0
  9. package/dist/abi/defi-wrapper/index.js +2 -0
  10. package/dist/abi/defi-wrapper/index.js.map +1 -1
  11. package/dist/abi/defi-wrapper/sources.d.ts +103 -0
  12. package/dist/abi/defi-wrapper/sources.js +104 -0
  13. package/dist/abi/defi-wrapper/sources.js.map +1 -0
  14. package/dist/configs/constants.d.ts +7 -1
  15. package/dist/configs/deployed.d.ts +5 -0
  16. package/dist/configs/deployed.js +20 -2
  17. package/dist/configs/deployed.js.map +1 -1
  18. package/dist/configs/envs.js +2 -0
  19. package/dist/configs/envs.js.map +1 -1
  20. package/dist/contracts/defi-wrapper/generic-strategy.d.ts +5 -0
  21. package/dist/contracts/defi-wrapper/generic-strategy.js +12 -0
  22. package/dist/contracts/defi-wrapper/generic-strategy.js.map +1 -0
  23. package/dist/contracts/defi-wrapper/index.d.ts +1 -0
  24. package/dist/contracts/defi-wrapper/index.js +1 -0
  25. package/dist/contracts/defi-wrapper/index.js.map +1 -1
  26. package/dist/features/defi-wrapper/defi-wrapper-factory.d.ts +3 -0
  27. package/dist/features/defi-wrapper/defi-wrapper-factory.js +4 -1
  28. package/dist/features/defi-wrapper/defi-wrapper-factory.js.map +1 -1
  29. package/dist/features/defi-wrapper/index.d.ts +1 -0
  30. package/dist/features/defi-wrapper/index.js +1 -0
  31. package/dist/features/defi-wrapper/index.js.map +1 -1
  32. package/dist/features/defi-wrapper/pool-info.d.ts +18 -1
  33. package/dist/features/defi-wrapper/pool-info.js +47 -3
  34. package/dist/features/defi-wrapper/pool-info.js.map +1 -1
  35. package/dist/features/defi-wrapper/timelock-roles.d.ts +5 -0
  36. package/dist/features/defi-wrapper/timelock-roles.js +43 -0
  37. package/dist/features/defi-wrapper/timelock-roles.js.map +1 -0
  38. package/dist/features/defi-wrapper/timelock.d.ts +8929 -8
  39. package/dist/features/defi-wrapper/timelock.js +83 -52
  40. package/dist/features/defi-wrapper/timelock.js.map +1 -1
  41. package/dist/features/defi-wrapper/verify-contracts.d.ts +20 -0
  42. package/dist/features/defi-wrapper/verify-contracts.js +145 -0
  43. package/dist/features/defi-wrapper/verify-contracts.js.map +1 -0
  44. package/dist/features/utils/try-fetch.js +2 -0
  45. package/dist/features/utils/try-fetch.js.map +1 -1
  46. package/dist/programs/account/write.js +2 -1
  47. package/dist/programs/account/write.js.map +1 -1
  48. package/dist/programs/defi-wrapper/contracts/factory/write.js +77 -6
  49. package/dist/programs/defi-wrapper/contracts/factory/write.js.map +1 -1
  50. package/dist/programs/defi-wrapper/contracts/index.d.ts +1 -0
  51. package/dist/programs/defi-wrapper/contracts/index.js +1 -0
  52. package/dist/programs/defi-wrapper/contracts/index.js.map +1 -1
  53. package/dist/programs/defi-wrapper/contracts/strategy/config.d.ts +3 -0
  54. package/dist/programs/defi-wrapper/contracts/strategy/config.js +40 -0
  55. package/dist/programs/defi-wrapper/contracts/strategy/config.js.map +1 -0
  56. package/dist/programs/defi-wrapper/contracts/strategy/index.d.ts +3 -0
  57. package/dist/programs/defi-wrapper/contracts/strategy/index.js +4 -0
  58. package/dist/programs/defi-wrapper/contracts/strategy/index.js.map +1 -0
  59. package/dist/programs/defi-wrapper/contracts/strategy/main.d.ts +1 -0
  60. package/dist/programs/defi-wrapper/contracts/strategy/main.js +6 -0
  61. package/dist/programs/defi-wrapper/contracts/strategy/main.js.map +1 -0
  62. package/dist/programs/defi-wrapper/contracts/strategy/read.d.ts +1 -0
  63. package/dist/programs/defi-wrapper/contracts/strategy/read.js +30 -0
  64. package/dist/programs/defi-wrapper/contracts/strategy/read.js.map +1 -0
  65. package/dist/programs/defi-wrapper/contracts/strategy/write.d.ts +1 -0
  66. package/dist/programs/defi-wrapper/contracts/strategy/write.js +34 -0
  67. package/dist/programs/defi-wrapper/contracts/strategy/write.js.map +1 -0
  68. package/dist/programs/defi-wrapper/contracts/stv-steth-pool/write.js +25 -21
  69. package/dist/programs/defi-wrapper/contracts/stv-steth-pool/write.js.map +1 -1
  70. package/dist/programs/defi-wrapper/contracts/withdrawal-queue/write.js +3 -4
  71. package/dist/programs/defi-wrapper/contracts/withdrawal-queue/write.js.map +1 -1
  72. package/dist/programs/defi-wrapper/use-cases/distributor/write.js +1 -0
  73. package/dist/programs/defi-wrapper/use-cases/distributor/write.js.map +1 -1
  74. package/dist/programs/defi-wrapper/use-cases/timelock-governance/common/read.js +25 -7
  75. package/dist/programs/defi-wrapper/use-cases/timelock-governance/common/read.js.map +1 -1
  76. package/dist/programs/defi-wrapper/use-cases/timelock-governance/common/write.js +195 -17
  77. package/dist/programs/defi-wrapper/use-cases/timelock-governance/common/write.js.map +1 -1
  78. package/dist/programs/defi-wrapper/use-cases/timelock-governance/dashboard/write.js +3 -3
  79. package/dist/programs/defi-wrapper/use-cases/timelock-governance/dashboard/write.js.map +1 -1
  80. package/dist/programs/defi-wrapper/use-cases/timelock-governance/index.d.ts +1 -0
  81. package/dist/programs/defi-wrapper/use-cases/timelock-governance/index.js +1 -0
  82. package/dist/programs/defi-wrapper/use-cases/timelock-governance/index.js.map +1 -1
  83. package/dist/programs/defi-wrapper/use-cases/timelock-governance/pool/write.js +4 -4
  84. package/dist/programs/defi-wrapper/use-cases/timelock-governance/pool/write.js.map +1 -1
  85. package/dist/programs/defi-wrapper/use-cases/timelock-governance/proxy/write.js +3 -3
  86. package/dist/programs/defi-wrapper/use-cases/timelock-governance/proxy/write.js.map +1 -1
  87. package/dist/programs/defi-wrapper/use-cases/timelock-governance/strategy/index.d.ts +2 -0
  88. package/dist/programs/defi-wrapper/use-cases/timelock-governance/strategy/index.js +3 -0
  89. package/dist/programs/defi-wrapper/use-cases/timelock-governance/strategy/index.js.map +1 -0
  90. package/dist/programs/defi-wrapper/use-cases/timelock-governance/strategy/main.d.ts +1 -0
  91. package/dist/programs/defi-wrapper/use-cases/timelock-governance/strategy/main.js +6 -0
  92. package/dist/programs/defi-wrapper/use-cases/timelock-governance/strategy/main.js.map +1 -0
  93. package/dist/programs/defi-wrapper/use-cases/timelock-governance/strategy/write.d.ts +1 -0
  94. package/dist/programs/defi-wrapper/use-cases/timelock-governance/strategy/write.js +57 -0
  95. package/dist/programs/defi-wrapper/use-cases/timelock-governance/strategy/write.js.map +1 -0
  96. package/dist/programs/defi-wrapper/use-cases/timelock-governance/withdrawal-queue/write.js +4 -4
  97. package/dist/programs/defi-wrapper/use-cases/timelock-governance/withdrawal-queue/write.js.map +1 -1
  98. package/dist/programs/defi-wrapper/use-cases/wrapper-operations/read.js +32 -11
  99. package/dist/programs/defi-wrapper/use-cases/wrapper-operations/read.js.map +1 -1
  100. package/dist/programs/defi-wrapper/use-cases/wrapper-operations/write.js +14 -12
  101. package/dist/programs/defi-wrapper/use-cases/wrapper-operations/write.js.map +1 -1
  102. package/dist/programs/use-cases/consolidation/write.js +2 -0
  103. package/dist/programs/use-cases/consolidation/write.js.map +1 -1
  104. package/dist/providers/wallet.d.ts +2936 -8456
  105. package/dist/providers/wallet.js +74 -2
  106. package/dist/providers/wallet.js.map +1 -1
  107. package/dist/tests/integration/gas-estimation.test.d.ts +1 -0
  108. package/dist/tests/integration/gas-estimation.test.js +76 -0
  109. package/dist/tests/integration/gas-estimation.test.js.map +1 -0
  110. package/dist/tests/integration/helpers/test-client.d.ts +2071 -5761
  111. package/dist/tests/utils/arguments-security.test.d.ts +1 -0
  112. package/dist/tests/utils/arguments-security.test.js +34 -0
  113. package/dist/tests/utils/arguments-security.test.js.map +1 -0
  114. package/dist/tests/utils/arguments.test.js +2 -20
  115. package/dist/tests/utils/arguments.test.js.map +1 -1
  116. package/dist/tests/utils/cache-security.test.d.ts +1 -0
  117. package/dist/tests/utils/cache-security.test.js +62 -0
  118. package/dist/tests/utils/cache-security.test.js.map +1 -0
  119. package/dist/tests/utils/contract-write-stateoverride.test.d.ts +1 -0
  120. package/dist/tests/utils/contract-write-stateoverride.test.js +135 -0
  121. package/dist/tests/utils/contract-write-stateoverride.test.js.map +1 -0
  122. package/dist/tests/utils/data-validators.test.js +21 -5
  123. package/dist/tests/utils/data-validators.test.js.map +1 -1
  124. package/dist/tests/utils/deployed-security.test.d.ts +1 -0
  125. package/dist/tests/utils/deployed-security.test.js +51 -0
  126. package/dist/tests/utils/deployed-security.test.js.map +1 -0
  127. package/dist/tests/utils/get-confirmations.test.d.ts +1 -0
  128. package/dist/tests/utils/get-confirmations.test.js +40 -0
  129. package/dist/tests/utils/get-confirmations.test.js.map +1 -0
  130. package/dist/tests/utils/ipfs-security.test.d.ts +1 -0
  131. package/dist/tests/utils/ipfs-security.test.js +232 -0
  132. package/dist/tests/utils/ipfs-security.test.js.map +1 -0
  133. package/dist/tests/utils/ipfs.test.js +8 -8
  134. package/dist/tests/utils/ipfs.test.js.map +1 -1
  135. package/dist/tests/utils/parse-abi-arguments.test.d.ts +1 -0
  136. package/dist/tests/utils/parse-abi-arguments.test.js +399 -0
  137. package/dist/tests/utils/parse-abi-arguments.test.js.map +1 -0
  138. package/dist/tests/utils/public-client-gas-estimation.test.d.ts +1 -0
  139. package/dist/tests/utils/public-client-gas-estimation.test.js +231 -0
  140. package/dist/tests/utils/public-client-gas-estimation.test.js.map +1 -0
  141. package/dist/tests/utils/rate-limit-security.test.d.ts +1 -0
  142. package/dist/tests/utils/rate-limit-security.test.js +82 -0
  143. package/dist/tests/utils/rate-limit-security.test.js.map +1 -0
  144. package/dist/tests/utils/salt.test.d.ts +1 -0
  145. package/dist/tests/utils/salt.test.js +20 -0
  146. package/dist/tests/utils/salt.test.js.map +1 -0
  147. package/dist/tests/utils/stream-helpers.d.ts +1 -0
  148. package/dist/tests/utils/stream-helpers.js +11 -0
  149. package/dist/tests/utils/stream-helpers.js.map +1 -0
  150. package/dist/utils/arguments.d.ts +2 -7
  151. package/dist/utils/arguments.js +21 -17
  152. package/dist/utils/arguments.js.map +1 -1
  153. package/dist/utils/cache.js +15 -13
  154. package/dist/utils/cache.js.map +1 -1
  155. package/dist/utils/data-validators.d.ts +3 -2
  156. package/dist/utils/data-validators.js +8 -11
  157. package/dist/utils/data-validators.js.map +1 -1
  158. package/dist/utils/env.d.ts +1 -0
  159. package/dist/utils/env.js +8 -0
  160. package/dist/utils/env.js.map +1 -0
  161. package/dist/utils/fetch-cl.js +2 -1
  162. package/dist/utils/fetch-cl.js.map +1 -1
  163. package/dist/utils/index.d.ts +6 -5
  164. package/dist/utils/index.js +6 -5
  165. package/dist/utils/index.js.map +1 -1
  166. package/dist/utils/ipfs.d.ts +4 -2
  167. package/dist/utils/ipfs.js +93 -11
  168. package/dist/utils/ipfs.js.map +1 -1
  169. package/dist/utils/logging/console.d.ts +1 -0
  170. package/dist/utils/logging/console.js +23 -2
  171. package/dist/utils/logging/console.js.map +1 -1
  172. package/dist/utils/parse-abi-arguments.d.ts +24 -0
  173. package/dist/utils/parse-abi-arguments.js +159 -0
  174. package/dist/utils/parse-abi-arguments.js.map +1 -0
  175. package/dist/utils/prompts/account.d.ts +1 -0
  176. package/dist/utils/prompts/account.js +13 -0
  177. package/dist/utils/prompts/account.js.map +1 -0
  178. package/dist/utils/prompts/index.d.ts +3 -0
  179. package/dist/utils/prompts/index.js +3 -0
  180. package/dist/utils/prompts/index.js.map +1 -1
  181. package/dist/utils/prompts/strategy.d.ts +15398 -0
  182. package/dist/utils/prompts/strategy.js +10 -0
  183. package/dist/utils/prompts/strategy.js.map +1 -0
  184. package/dist/utils/prompts/timelock-roles.d.ts +1 -0
  185. package/dist/utils/prompts/timelock-roles.js +13 -0
  186. package/dist/utils/prompts/timelock-roles.js.map +1 -0
  187. package/dist/utils/rate-limit.d.ts +6 -0
  188. package/dist/utils/rate-limit.js +22 -5
  189. package/dist/utils/rate-limit.js.map +1 -1
  190. package/dist/utils/salt.d.ts +3 -0
  191. package/dist/utils/salt.js +8 -0
  192. package/dist/utils/salt.js.map +1 -0
  193. package/dist/utils/transactions/tx-private-key.d.ts +2 -1
  194. package/dist/utils/transactions/tx-private-key.js +5 -8
  195. package/dist/utils/transactions/tx-private-key.js.map +1 -1
  196. package/dist/utils/transactions/tx-wc.js +3 -7
  197. package/dist/utils/transactions/tx-wc.js.map +1 -1
  198. package/dist/utils/transactions/utils.d.ts +1 -0
  199. package/dist/utils/transactions/utils.js +12 -0
  200. package/dist/utils/transactions/utils.js.map +1 -1
  201. package/dist/version/index.js +1 -1
  202. package/package.json +10 -9
@@ -0,0 +1,399 @@
1
+ import { describe, test, expect } from 'vitest';
2
+ import { parseAbiArguments } from '../../utils/parse-abi-arguments.js';
3
+ const fn = (inputs) => ({
4
+ type: 'function',
5
+ name: 'test',
6
+ inputs,
7
+ outputs: [],
8
+ stateMutability: 'nonpayable',
9
+ });
10
+ const ADDR = '0x0000000000000000000000000000000000000001';
11
+ // --- parseAbiArguments (top-level) ---
12
+ describe('parseAbiArguments', () => {
13
+ test('throws on argument count mismatch (too few)', () => {
14
+ const abi = fn([{ name: 'a', type: 'uint256' }]);
15
+ expect(() => parseAbiArguments(abi, [])).toThrow(/argument count mismatch/i);
16
+ });
17
+ test('throws on argument count mismatch (too many)', () => {
18
+ const abi = fn([]);
19
+ expect(() => parseAbiArguments(abi, ['1'])).toThrow(/argument count mismatch/i);
20
+ });
21
+ test('returns empty array for zero-arg function', () => {
22
+ expect(parseAbiArguments(fn([]), [])).toEqual([]);
23
+ });
24
+ test('parses multiple inputs of different types', () => {
25
+ const abi = fn([
26
+ { name: 'to', type: 'address' },
27
+ { name: 'amount', type: 'uint256' },
28
+ { name: 'flag', type: 'bool' },
29
+ ]);
30
+ expect(parseAbiArguments(abi, [ADDR, '1000', 'true'])).toEqual([
31
+ ADDR,
32
+ 1000n,
33
+ true,
34
+ ]);
35
+ });
36
+ });
37
+ // --- address ---
38
+ describe('address', () => {
39
+ test('valid address passes through', () => {
40
+ const abi = fn([{ name: 'x', type: 'address' }]);
41
+ expect(parseAbiArguments(abi, [ADDR])).toEqual([ADDR]);
42
+ });
43
+ test('invalid address throws', () => {
44
+ const abi = fn([{ name: 'x', type: 'address' }]);
45
+ expect(() => parseAbiArguments(abi, ['0x123'])).toThrow(/invalid address/i);
46
+ });
47
+ test('non-hex string throws', () => {
48
+ const abi = fn([{ name: 'x', type: 'address' }]);
49
+ expect(() => parseAbiArguments(abi, ['notanaddress'])).toThrow();
50
+ });
51
+ });
52
+ // --- bool ---
53
+ describe('bool', () => {
54
+ test('"true" parses to boolean true', () => {
55
+ const abi = fn([{ name: 'x', type: 'bool' }]);
56
+ expect(parseAbiArguments(abi, ['true'])).toEqual([true]);
57
+ });
58
+ test('"false" parses to boolean false', () => {
59
+ const abi = fn([{ name: 'x', type: 'bool' }]);
60
+ expect(parseAbiArguments(abi, ['false'])).toEqual([false]);
61
+ });
62
+ test('invalid bool value throws', () => {
63
+ const abi = fn([{ name: 'x', type: 'bool' }]);
64
+ expect(() => parseAbiArguments(abi, ['yes'])).toThrow(/invalid bool/i);
65
+ });
66
+ test('"1" is not accepted as bool', () => {
67
+ const abi = fn([{ name: 'x', type: 'bool' }]);
68
+ expect(() => parseAbiArguments(abi, ['1'])).toThrow();
69
+ });
70
+ });
71
+ // --- uint / int ---
72
+ describe('uint / int', () => {
73
+ test('uint256: positive integer', () => {
74
+ const abi = fn([{ name: 'x', type: 'uint256' }]);
75
+ expect(parseAbiArguments(abi, ['42'])).toEqual([42n]);
76
+ });
77
+ test('uint256: zero is valid', () => {
78
+ const abi = fn([{ name: 'x', type: 'uint256' }]);
79
+ expect(parseAbiArguments(abi, ['0'])).toEqual([0n]);
80
+ });
81
+ test('uint256: large value stays precise', () => {
82
+ const abi = fn([{ name: 'x', type: 'uint256' }]);
83
+ const big = '1000000000000000000';
84
+ expect(parseAbiArguments(abi, [big])).toEqual([1000000000000000000n]);
85
+ });
86
+ test('uint256: negative value throws', () => {
87
+ const abi = fn([{ name: 'x', type: 'uint256' }]);
88
+ expect(() => parseAbiArguments(abi, ['-1'])).toThrow(/unsigned integer cannot be negative/i);
89
+ });
90
+ test('uint8: alias works (startsWith uint)', () => {
91
+ const abi = fn([{ name: 'x', type: 'uint8' }]);
92
+ expect(parseAbiArguments(abi, ['255'])).toEqual([255n]);
93
+ });
94
+ test('int256: negative value is valid', () => {
95
+ const abi = fn([{ name: 'x', type: 'int256' }]);
96
+ expect(parseAbiArguments(abi, ['-1000'])).toEqual([-1000n]);
97
+ });
98
+ test('int8: positive and negative', () => {
99
+ const abi = fn([{ name: 'x', type: 'int8' }]);
100
+ expect(parseAbiArguments(abi, ['-128'])).toEqual([-128n]);
101
+ });
102
+ test('non-numeric string throws', () => {
103
+ const abi = fn([{ name: 'x', type: 'uint256' }]);
104
+ expect(() => parseAbiArguments(abi, ['abc'])).toThrow();
105
+ });
106
+ });
107
+ // --- bytesN (fixed-size) ---
108
+ describe('bytesN', () => {
109
+ test('bytes32: correct-size hex passes', () => {
110
+ const value = `0x${'aa'.repeat(32)}`;
111
+ const abi = fn([{ name: 'x', type: 'bytes32' }]);
112
+ expect(parseAbiArguments(abi, [value])).toEqual([value]);
113
+ });
114
+ test('bytes1: single byte passes', () => {
115
+ const abi = fn([{ name: 'x', type: 'bytes1' }]);
116
+ expect(parseAbiArguments(abi, ['0xff'])).toEqual(['0xff']);
117
+ });
118
+ test('bytes32: wrong size throws', () => {
119
+ const abi = fn([{ name: 'x', type: 'bytes32' }]);
120
+ expect(() => parseAbiArguments(abi, ['0xdead'])).toThrow(/expected 32 bytes/i);
121
+ });
122
+ test('bytes32: non-hex throws', () => {
123
+ const abi = fn([{ name: 'x', type: 'bytes32' }]);
124
+ expect(() => parseAbiArguments(abi, ['notahex'])).toThrow(/invalid hex/i);
125
+ });
126
+ test('bytes4: correct size', () => {
127
+ const abi = fn([{ name: 'x', type: 'bytes4' }]);
128
+ expect(parseAbiArguments(abi, ['0xdeadbeef'])).toEqual(['0xdeadbeef']);
129
+ });
130
+ });
131
+ // --- bytes (dynamic) ---
132
+ describe('bytes', () => {
133
+ test('valid hex passes', () => {
134
+ const abi = fn([{ name: 'x', type: 'bytes' }]);
135
+ expect(parseAbiArguments(abi, ['0xdeadbeef'])).toEqual(['0xdeadbeef']);
136
+ });
137
+ test('empty bytes (0x) is valid', () => {
138
+ const abi = fn([{ name: 'x', type: 'bytes' }]);
139
+ expect(parseAbiArguments(abi, ['0x'])).toEqual(['0x']);
140
+ });
141
+ test('non-hex string throws', () => {
142
+ const abi = fn([{ name: 'x', type: 'bytes' }]);
143
+ expect(() => parseAbiArguments(abi, ['hello'])).toThrow(/invalid hex/i);
144
+ });
145
+ });
146
+ // --- string ---
147
+ describe('string', () => {
148
+ test('any string passes through unchanged', () => {
149
+ const abi = fn([{ name: 'x', type: 'string' }]);
150
+ expect(parseAbiArguments(abi, ['hello world'])).toEqual(['hello world']);
151
+ });
152
+ test('empty string is valid', () => {
153
+ const abi = fn([{ name: 'x', type: 'string' }]);
154
+ expect(parseAbiArguments(abi, [''])).toEqual(['']);
155
+ });
156
+ });
157
+ // --- fixed-size arrays ---
158
+ describe('fixed-size array', () => {
159
+ test('uint256[3]: correct elements parsed as bigints', () => {
160
+ const abi = fn([{ name: 'x', type: 'uint256[3]' }]);
161
+ expect(parseAbiArguments(abi, ['[1,2,3]'])).toEqual([[1n, 2n, 3n]]);
162
+ });
163
+ test('uint256[3]: wrong length throws', () => {
164
+ const abi = fn([{ name: 'x', type: 'uint256[3]' }]);
165
+ expect(() => parseAbiArguments(abi, ['[1,2]'])).toThrow(/length/i);
166
+ });
167
+ test('address[2]: elements parsed as addresses', () => {
168
+ const abi = fn([{ name: 'x', type: 'address[2]' }]);
169
+ expect(parseAbiArguments(abi, [
170
+ `[${JSON.stringify(ADDR)},${JSON.stringify(ADDR)}]`,
171
+ ])).toEqual([[ADDR, ADDR]]);
172
+ });
173
+ test('bool[2]: elements parsed as booleans', () => {
174
+ const abi = fn([{ name: 'x', type: 'bool[2]' }]);
175
+ expect(parseAbiArguments(abi, ['[true,false]'])).toEqual([[true, false]]);
176
+ });
177
+ // Acceptance test — exposes String([]) bug
178
+ test('uint256[2][2]: nested fixed array parsed correctly', () => {
179
+ const abi = fn([{ name: 'x', type: 'uint256[2][2]' }]);
180
+ expect(parseAbiArguments(abi, ['[[1,2],[3,4]]'])).toEqual([
181
+ [
182
+ [1n, 2n],
183
+ [3n, 4n],
184
+ ],
185
+ ]);
186
+ });
187
+ test('non-array JSON value throws (line 78)', () => {
188
+ const abi = fn([{ name: 'x', type: 'uint256[3]' }]);
189
+ expect(() => parseAbiArguments(abi, ['42'])).toThrow(/expected a json array/i);
190
+ });
191
+ });
192
+ // --- dynamic arrays ---
193
+ describe('dynamic array', () => {
194
+ test('uint256[]: empty array', () => {
195
+ const abi = fn([{ name: 'x', type: 'uint256[]' }]);
196
+ expect(parseAbiArguments(abi, ['[]'])).toEqual([[]]);
197
+ });
198
+ test('uint256[]: multiple elements', () => {
199
+ const abi = fn([{ name: 'x', type: 'uint256[]' }]);
200
+ expect(parseAbiArguments(abi, ['[10,20,30]'])).toEqual([[10n, 20n, 30n]]);
201
+ });
202
+ test('address[]: array of addresses', () => {
203
+ const abi = fn([{ name: 'x', type: 'address[]' }]);
204
+ expect(parseAbiArguments(abi, [`[${JSON.stringify(ADDR)}]`])).toEqual([
205
+ [ADDR],
206
+ ]);
207
+ });
208
+ test('string[]: array of strings', () => {
209
+ const abi = fn([{ name: 'x', type: 'string[]' }]);
210
+ expect(parseAbiArguments(abi, ['["foo","bar"]'])).toEqual([['foo', 'bar']]);
211
+ });
212
+ test('non-array JSON value throws (line 101)', () => {
213
+ const abi = fn([{ name: 'x', type: 'uint256[]' }]);
214
+ expect(() => parseAbiArguments(abi, ['"notanarray"'])).toThrow(/expected a json array/i);
215
+ });
216
+ // Acceptance test — exposes String([]) bug
217
+ test('uint256[][]: nested dynamic array parsed correctly', () => {
218
+ const abi = fn([{ name: 'x', type: 'uint256[][]' }]);
219
+ expect(parseAbiArguments(abi, ['[[1,2],[3,4,5]]'])).toEqual([
220
+ [
221
+ [1n, 2n],
222
+ [3n, 4n, 5n],
223
+ ],
224
+ ]);
225
+ });
226
+ // Acceptance test — exposes String([]) bug
227
+ test('uint256[2][]: mixed fixed/dynamic nested array', () => {
228
+ const abi = fn([{ name: 'x', type: 'uint256[2][]' }]);
229
+ expect(parseAbiArguments(abi, ['[[1,2],[3,4]]'])).toEqual([
230
+ [
231
+ [1n, 2n],
232
+ [3n, 4n],
233
+ ],
234
+ ]);
235
+ });
236
+ });
237
+ // --- tuple ---
238
+ describe('tuple (struct)', () => {
239
+ const tupleParam = {
240
+ name: 'data',
241
+ type: 'tuple',
242
+ components: [
243
+ { name: 'addr', type: 'address' },
244
+ { name: 'amount', type: 'uint256' },
245
+ { name: 'flag', type: 'bool' },
246
+ ],
247
+ };
248
+ test('object representation: all fields parsed', () => {
249
+ const abi = fn([tupleParam]);
250
+ const input = JSON.stringify({ addr: ADDR, amount: '999', flag: 'true' });
251
+ expect(parseAbiArguments(abi, [input])).toEqual([
252
+ { addr: ADDR, amount: 999n, flag: true },
253
+ ]);
254
+ });
255
+ test('array representation: positional fields parsed', () => {
256
+ const abi = fn([tupleParam]);
257
+ const input = JSON.stringify([ADDR, '50', 'false']);
258
+ expect(parseAbiArguments(abi, [input])).toEqual([
259
+ { addr: ADDR, amount: 50n, flag: false },
260
+ ]);
261
+ });
262
+ test('array representation: wrong field count throws', () => {
263
+ const abi = fn([tupleParam]);
264
+ expect(() => parseAbiArguments(abi, [`[${JSON.stringify(ADDR)}]`])).toThrow(/expects.*fields/i);
265
+ });
266
+ test('object representation: missing field throws', () => {
267
+ const abi = fn([tupleParam]);
268
+ const input = JSON.stringify({ addr: ADDR, amount: '1' });
269
+ expect(() => parseAbiArguments(abi, [input])).toThrow(/missing field/i);
270
+ });
271
+ test('invalid JSON throws', () => {
272
+ const abi = fn([tupleParam]);
273
+ expect(() => parseAbiArguments(abi, ['{not json'])).toThrow(/invalid json/i);
274
+ });
275
+ test('non-array non-object value throws', () => {
276
+ const abi = fn([tupleParam]);
277
+ expect(() => parseAbiArguments(abi, ['42'])).toThrow(/expected json object or array/i);
278
+ });
279
+ test('array representation with unnamed component uses numeric index key (line 140)', () => {
280
+ const param = {
281
+ name: 'data',
282
+ type: 'tuple',
283
+ components: [{ type: 'uint256' }, { type: 'bool' }],
284
+ };
285
+ const abi = fn([param]);
286
+ // Component has no name — array form should use index as key
287
+ expect(parseAbiArguments(abi, ['[42, true]'])).toEqual([
288
+ { 0: 42n, 1: true },
289
+ ]);
290
+ });
291
+ test('tuple with no components throws', () => {
292
+ const bare = { name: 'x', type: 'tuple' };
293
+ const abi = fn([bare]);
294
+ expect(() => parseAbiArguments(abi, ['{}'])).toThrow(/no components/i);
295
+ });
296
+ test('tuple component with no name throws when using object form (line 153)', () => {
297
+ const param = {
298
+ name: 'data',
299
+ type: 'tuple',
300
+ components: [{ type: 'uint256' }],
301
+ };
302
+ const abi = fn([param]);
303
+ expect(() => parseAbiArguments(abi, ['{"": 1}'])).toThrow(/tuple component has no name/i);
304
+ });
305
+ // Acceptance test — exposes String({}) bug
306
+ test('tuple[]: array of tuples parsed correctly', () => {
307
+ const param = {
308
+ name: 'items',
309
+ type: 'tuple[]',
310
+ components: [
311
+ { name: 'id', type: 'uint256' },
312
+ { name: 'owner', type: 'address' },
313
+ ],
314
+ };
315
+ const abi = fn([param]);
316
+ const input = JSON.stringify([
317
+ { id: '1', owner: ADDR },
318
+ { id: '2', owner: ADDR },
319
+ ]);
320
+ expect(parseAbiArguments(abi, [input])).toEqual([
321
+ [
322
+ { id: 1n, owner: ADDR },
323
+ { id: 2n, owner: ADDR },
324
+ ],
325
+ ]);
326
+ });
327
+ // Acceptance test — exposes String({}) bug on nested tuple
328
+ test('nested tuple (tuple within tuple) parsed correctly', () => {
329
+ const param = {
330
+ name: 'outer',
331
+ type: 'tuple',
332
+ components: [
333
+ { name: 'value', type: 'uint256' },
334
+ {
335
+ name: 'inner',
336
+ type: 'tuple',
337
+ components: [
338
+ { name: 'x', type: 'uint256' },
339
+ { name: 'y', type: 'uint256' },
340
+ ],
341
+ },
342
+ ],
343
+ };
344
+ const abi = fn([param]);
345
+ const input = JSON.stringify({ value: '10', inner: { x: '1', y: '2' } });
346
+ expect(parseAbiArguments(abi, [input])).toEqual([
347
+ { value: 10n, inner: { x: 1n, y: 2n } },
348
+ ]);
349
+ });
350
+ });
351
+ // --- unsupported type ---
352
+ describe('unsupported type', () => {
353
+ test('unknown type throws', () => {
354
+ const abi = fn([{ name: 'x', type: 'function' }]);
355
+ expect(() => parseAbiArguments(abi, ['0x'])).toThrow(/unsupported abi type/i);
356
+ });
357
+ });
358
+ // --- error message format ---
359
+ describe('error message wrapping', () => {
360
+ test('error includes param name and type', () => {
361
+ const abi = fn([{ name: 'myParam', type: 'uint256' }]);
362
+ let caught;
363
+ try {
364
+ parseAbiArguments(abi, ['notanumber']);
365
+ }
366
+ catch (e) {
367
+ caught = e;
368
+ }
369
+ expect(caught?.message).toMatch(/param.*myParam/i);
370
+ expect(caught?.message).toMatch(/type.*uint256/i);
371
+ });
372
+ test('unnamed param falls back to <unnamed> in error message (line 179)', () => {
373
+ // Directly exercise the unnamed-param branch by passing a nameless input
374
+ const abi = {
375
+ type: 'function',
376
+ name: 'test',
377
+ inputs: [{ type: 'uint256' }],
378
+ outputs: [],
379
+ stateMutability: 'nonpayable',
380
+ };
381
+ expect(() => parseAbiArguments(abi, ['abc'])).toThrow(/<unnamed>/);
382
+ });
383
+ test('already-wrapped error is re-thrown without double-wrapping (line 182)', () => {
384
+ // uint256[][] with an invalid leaf value: the innermost error gets wrapped once,
385
+ // then re-thrown (not re-wrapped) by each outer level.
386
+ const abi = fn([{ name: 'x', type: 'uint256[][]' }]);
387
+ let caught;
388
+ try {
389
+ parseAbiArguments(abi, ['[["abc"]]']);
390
+ }
391
+ catch (e) {
392
+ caught = e;
393
+ }
394
+ // Should contain exactly one [param: block, not nested duplicates
395
+ const matches = caught?.message.match(/\[param:/g);
396
+ expect(matches).toHaveLength(1);
397
+ });
398
+ });
399
+ //# sourceMappingURL=parse-abi-arguments.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-abi-arguments.test.js","sourceRoot":"","sources":["../../../tests/utils/parse-abi-arguments.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,231 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ const MAX_UINT256_HEX = '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff';
3
+ const MOCK_CHAIN = { id: 560048, name: 'hoodi' };
4
+ const MOCK_EL_URL = 'http://localhost:8545';
5
+ const MOCK_FROM = '0x1234567890abcdef1234567890abcdef12345678';
6
+ // Represents the raw RPC handler underneath the balanceAwareTransport wrapper
7
+ const mockRpcRequest = vi.fn();
8
+ vi.mock('viem', async (importOriginal) => {
9
+ const actual = (await importOriginal());
10
+ return {
11
+ ...actual,
12
+ // Return a minimal transport factory whose `request` we control
13
+ http: () => {
14
+ const factory = Object.assign(() => ({ request: mockRpcRequest }), {
15
+ config: { key: 'http' },
16
+ value: undefined,
17
+ });
18
+ return factory;
19
+ },
20
+ // Expose the transport's wrapped `request` directly on the client
21
+ createPublicClient: ({ transport }) => {
22
+ const instance = transport({ chain: MOCK_CHAIN });
23
+ return { chain: MOCK_CHAIN, request: instance.request };
24
+ },
25
+ };
26
+ });
27
+ vi.mock('command', () => ({
28
+ program: { opts: () => ({}) },
29
+ }));
30
+ vi.mock('../../configs/index.js', () => ({
31
+ getConfig: () => ({
32
+ PRIVATE_KEY: '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80',
33
+ }),
34
+ getChainId: async () => 560048,
35
+ getElUrl: () => MOCK_EL_URL,
36
+ getChain: async () => MOCK_CHAIN,
37
+ envs: {},
38
+ }));
39
+ vi.mock('../../utils/index.js', () => ({
40
+ createWalletConnectClient: vi.fn(),
41
+ }));
42
+ vi.mock('ox', () => ({
43
+ Keystore: {},
44
+ }));
45
+ /**
46
+ * Tests for balanceAwareTransport — the transport-level wrapper that injects
47
+ * stateOverride into every eth_estimateGas RPC call to bypass the node's
48
+ * balance pre-check.
49
+ *
50
+ * We mock viem's http() transport so that `base.request` is our mockRpcRequest,
51
+ * then call the wrapped `request` directly to verify interception logic.
52
+ *
53
+ * vi.resetModules() in beforeEach ensures each test gets a fresh module with
54
+ * a clean nodeSupportsStateOverride cache.
55
+ */
56
+ describe('balanceAwareTransport (transport-level gas estimation fix)', () => {
57
+ beforeEach(() => {
58
+ vi.clearAllMocks();
59
+ vi.resetModules();
60
+ });
61
+ it('injects stateOverride with max balance into eth_estimateGas', async () => {
62
+ mockRpcRequest.mockResolvedValue('0x5208');
63
+ const { getPublicClient } = await import('../../providers/wallet.js');
64
+ const client = await getPublicClient();
65
+ await client.request({
66
+ method: 'eth_estimateGas',
67
+ params: [{ from: MOCK_FROM, to: '0xdead', data: '0x1234' }],
68
+ });
69
+ expect(mockRpcRequest).toHaveBeenCalledTimes(1);
70
+ const [[rpcCall]] = mockRpcRequest.mock.calls;
71
+ expect(rpcCall.method).toBe('eth_estimateGas');
72
+ expect(rpcCall.params).toHaveLength(3);
73
+ expect(rpcCall.params[0]).toEqual({
74
+ from: MOCK_FROM,
75
+ to: '0xdead',
76
+ data: '0x1234',
77
+ });
78
+ expect(rpcCall.params[1]).toBe('latest');
79
+ expect(rpcCall.params[2]).toEqual({
80
+ [MOCK_FROM]: { balance: MAX_UINT256_HEX },
81
+ });
82
+ });
83
+ it('preserves existing stateOverride entries and custom blockTag', async () => {
84
+ mockRpcRequest.mockResolvedValue('0x5208');
85
+ const { getPublicClient } = await import('../../providers/wallet.js');
86
+ const client = await getPublicClient();
87
+ const existing = {
88
+ '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa': { balance: '0x3e7' },
89
+ };
90
+ await client.request({
91
+ method: 'eth_estimateGas',
92
+ params: [{ from: MOCK_FROM, to: '0xdead' }, 'pending', existing],
93
+ });
94
+ const [[rpcCall]] = mockRpcRequest.mock.calls;
95
+ expect(rpcCall.params[1]).toBe('pending');
96
+ expect(rpcCall.params[2]).toEqual({
97
+ ...existing,
98
+ [MOCK_FROM]: { balance: MAX_UINT256_HEX },
99
+ });
100
+ });
101
+ it('falls back when RPC rejects stateOverride', async () => {
102
+ mockRpcRequest
103
+ .mockRejectedValueOnce(new Error('invalid argument 2: stateOverride'))
104
+ .mockResolvedValueOnce('0x5208');
105
+ const { getPublicClient } = await import('../../providers/wallet.js');
106
+ const client = await getPublicClient();
107
+ const result = await client.request({
108
+ method: 'eth_estimateGas',
109
+ params: [{ from: MOCK_FROM, to: '0xdead' }],
110
+ });
111
+ expect(result).toBe('0x5208');
112
+ expect(mockRpcRequest).toHaveBeenCalledTimes(2);
113
+ // Second call: original args without stateOverride
114
+ const [, [fallbackCall]] = mockRpcRequest.mock.calls;
115
+ expect(fallbackCall.params).toHaveLength(1);
116
+ });
117
+ it('falls back on "too many arguments"', async () => {
118
+ mockRpcRequest
119
+ .mockRejectedValueOnce(new Error('too many arguments, want at most 2'))
120
+ .mockResolvedValueOnce('0x5208');
121
+ const { getPublicClient } = await import('../../providers/wallet.js');
122
+ const client = await getPublicClient();
123
+ const result = await client.request({
124
+ method: 'eth_estimateGas',
125
+ params: [{ from: MOCK_FROM, to: '0xdead' }],
126
+ });
127
+ expect(result).toBe('0x5208');
128
+ expect(mockRpcRequest).toHaveBeenCalledTimes(2);
129
+ });
130
+ it('falls back on "invalid argument 2"', async () => {
131
+ mockRpcRequest
132
+ .mockRejectedValueOnce(new Error('invalid argument 2'))
133
+ .mockResolvedValueOnce('0x5208');
134
+ const { getPublicClient } = await import('../../providers/wallet.js');
135
+ const client = await getPublicClient();
136
+ const result = await client.request({
137
+ method: 'eth_estimateGas',
138
+ params: [{ from: MOCK_FROM, to: '0xdead' }],
139
+ });
140
+ expect(result).toBe('0x5208');
141
+ expect(mockRpcRequest).toHaveBeenCalledTimes(2);
142
+ });
143
+ it('re-throws real contract errors (not swallowed)', async () => {
144
+ mockRpcRequest.mockRejectedValue(new Error('execution reverted: ERC20: transfer amount exceeds balance'));
145
+ const { getPublicClient } = await import('../../providers/wallet.js');
146
+ const client = await getPublicClient();
147
+ await expect(client.request({
148
+ method: 'eth_estimateGas',
149
+ params: [{ from: MOCK_FROM, to: '0xdead' }],
150
+ })).rejects.toThrow('execution reverted');
151
+ // Should NOT retry — only 1 call
152
+ expect(mockRpcRequest).toHaveBeenCalledTimes(1);
153
+ });
154
+ it('skips override when no from address in params', async () => {
155
+ mockRpcRequest.mockResolvedValue('0x5208');
156
+ const { getPublicClient } = await import('../../providers/wallet.js');
157
+ const client = await getPublicClient();
158
+ await client.request({
159
+ method: 'eth_estimateGas',
160
+ params: [{ to: '0xdead', data: '0x1234' }],
161
+ });
162
+ expect(mockRpcRequest).toHaveBeenCalledTimes(1);
163
+ // Passed through unchanged — no stateOverride injected
164
+ const [[rpcCall]] = mockRpcRequest.mock.calls;
165
+ expect(rpcCall).toEqual({
166
+ method: 'eth_estimateGas',
167
+ params: [{ to: '0xdead', data: '0x1234' }],
168
+ });
169
+ });
170
+ it('passes non-estimateGas calls through unchanged', async () => {
171
+ mockRpcRequest.mockResolvedValue('0x1');
172
+ const { getPublicClient } = await import('../../providers/wallet.js');
173
+ const client = await getPublicClient();
174
+ await client.request({
175
+ method: 'eth_blockNumber',
176
+ params: [],
177
+ });
178
+ expect(mockRpcRequest).toHaveBeenCalledTimes(1);
179
+ const [[rpcCall]] = mockRpcRequest.mock.calls;
180
+ expect(rpcCall).toEqual({
181
+ method: 'eth_blockNumber',
182
+ params: [],
183
+ });
184
+ });
185
+ it('caches stateOverride support after first successful call', async () => {
186
+ mockRpcRequest.mockResolvedValue('0x5208');
187
+ const { getPublicClient } = await import('../../providers/wallet.js');
188
+ const client = await getPublicClient();
189
+ // First call — probes stateOverride support
190
+ await client.request({
191
+ method: 'eth_estimateGas',
192
+ params: [{ from: MOCK_FROM, to: '0xdead' }],
193
+ });
194
+ // Second call — should still inject stateOverride (cached: supported)
195
+ await client.request({
196
+ method: 'eth_estimateGas',
197
+ params: [{ from: MOCK_FROM, to: '0xbeef' }],
198
+ });
199
+ expect(mockRpcRequest).toHaveBeenCalledTimes(2);
200
+ // Both calls include stateOverride (3 params each)
201
+ const [[firstCall], [secondCall]] = mockRpcRequest.mock.calls;
202
+ expect(firstCall.params).toHaveLength(3);
203
+ expect(secondCall.params).toHaveLength(3);
204
+ });
205
+ it('skips stateOverride on subsequent calls after fallback (cached: unsupported)', async () => {
206
+ // First call: stateOverride fails → fallback
207
+ mockRpcRequest
208
+ .mockRejectedValueOnce(new Error('too many arguments, want at most 2'))
209
+ .mockResolvedValueOnce('0x5208');
210
+ const { getPublicClient } = await import('../../providers/wallet.js');
211
+ const client = await getPublicClient();
212
+ await client.request({
213
+ method: 'eth_estimateGas',
214
+ params: [{ from: MOCK_FROM, to: '0xdead' }],
215
+ });
216
+ expect(mockRpcRequest).toHaveBeenCalledTimes(2); // try + fallback
217
+ // Second call: should go directly to original (no stateOverride attempt)
218
+ mockRpcRequest.mockResolvedValueOnce('0x7530');
219
+ await client.request({
220
+ method: 'eth_estimateGas',
221
+ params: [{ from: MOCK_FROM, to: '0xbeef' }],
222
+ });
223
+ expect(mockRpcRequest).toHaveBeenCalledTimes(3); // 2 from first + 1 direct
224
+ // Third RPC call: original args, no stateOverride
225
+ // .at(-1) is safe here — we just asserted toHaveBeenCalledTimes(3)
226
+ const directCall = mockRpcRequest.mock.calls.at(-1)[0];
227
+ expect(directCall.params).toHaveLength(1);
228
+ expect(directCall.params[0]).toEqual({ from: MOCK_FROM, to: '0xbeef' });
229
+ });
230
+ });
231
+ //# sourceMappingURL=public-client-gas-estimation.test.js.map