@steerprotocol/sdk 1.30.8 → 1.31.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 (54) hide show
  1. package/dist/cjs/base/PoolClient.js +137 -0
  2. package/dist/cjs/base/PoolClient.js.map +1 -1
  3. package/dist/cjs/base/VaultClient.js +111 -2
  4. package/dist/cjs/base/VaultClient.js.map +1 -1
  5. package/dist/cjs/const/feeManagerContracts.js +25 -0
  6. package/dist/cjs/const/feeManagerContracts.js.map +1 -0
  7. package/dist/cjs/const/network.js +7 -0
  8. package/dist/cjs/const/network.js.map +1 -1
  9. package/dist/cjs/const/protocol.js +68 -92
  10. package/dist/cjs/const/protocol.js.map +1 -1
  11. package/dist/cjs/scripts/processDeployments.js +1 -0
  12. package/dist/cjs/scripts/processDeployments.js.map +1 -1
  13. package/dist/esm/base/PoolClient.js +137 -0
  14. package/dist/esm/base/PoolClient.js.map +1 -1
  15. package/dist/esm/base/VaultClient.js +111 -2
  16. package/dist/esm/base/VaultClient.js.map +1 -1
  17. package/dist/esm/const/feeManagerContracts.js +25 -0
  18. package/dist/esm/const/feeManagerContracts.js.map +1 -0
  19. package/dist/esm/const/network.js +7 -0
  20. package/dist/esm/const/network.js.map +1 -1
  21. package/dist/esm/const/protocol.js +68 -92
  22. package/dist/esm/const/protocol.js.map +1 -1
  23. package/dist/esm/scripts/processDeployments.js +1 -0
  24. package/dist/esm/scripts/processDeployments.js.map +1 -1
  25. package/dist/types/base/PoolClient.d.ts +22 -0
  26. package/dist/types/base/PoolClient.d.ts.map +1 -1
  27. package/dist/types/base/VaultClient.d.ts +20 -0
  28. package/dist/types/base/VaultClient.d.ts.map +1 -1
  29. package/dist/types/const/feeManagerContracts.d.ts +6 -0
  30. package/dist/types/const/feeManagerContracts.d.ts.map +1 -0
  31. package/dist/types/const/network.d.ts +1 -0
  32. package/dist/types/const/network.d.ts.map +1 -1
  33. package/dist/types/const/protocol.d.ts +4 -19
  34. package/dist/types/const/protocol.d.ts.map +1 -1
  35. package/package.json +3 -2
  36. package/src/__tests__/base/PoolClient.test.ts +355 -104
  37. package/src/__tests__/base/StakingClient.test.ts +72 -72
  38. package/src/__tests__/base/VaultClient.protocol-filter.test.ts +64 -137
  39. package/src/__tests__/base/VaultClient.test.ts +460 -60
  40. package/src/__tests__/base/vault/single-asset/calculateLimitPrice.test.ts +32 -14
  41. package/src/__tests__/base/vault/single-asset/calculateSwapAmount.test.ts +7 -4
  42. package/src/__tests__/base/vault/single-asset/estimateLpTokens.test.ts +105 -570
  43. package/src/__tests__/base/vault/single-asset/simulateSwap.test.ts +45 -66
  44. package/src/__tests__/base/vault/single-asset/singleAssetDepositClient.test.ts +178 -381
  45. package/src/__tests__/const/network.feeManager.test.ts +47 -0
  46. package/src/__tests__/fixtures/live/single-asset.fixture.json +116 -0
  47. package/src/__tests__/fixtures/live/staking-pools.fixture.json +353 -0
  48. package/src/__tests__/fixtures/live/vaults.fixture.json +5392 -0
  49. package/src/base/PoolClient.ts +200 -1
  50. package/src/base/VaultClient.ts +169 -2
  51. package/src/const/feeManagerContracts.ts +28 -0
  52. package/src/const/network.ts +10 -1
  53. package/src/const/protocol.ts +18 -39
  54. package/src/scripts/processDeployments.ts +1 -0
@@ -1,400 +1,197 @@
1
- import {Chain, createPublicClient, createWalletClient, http, parseEther} from 'viem';
2
- import {polygon} from 'viem/chains';
3
- import {SingleAssetDepositClient} from '../../../../base/vault/single-asset/singleAssetDeposit.js';
4
- import {AMMType, SingleAssetDepositParams} from '../../../../base/vault/single-asset/types.js';
5
-
6
- // Mock all the individual step functions
7
-
8
- import {SteerClient} from '../../../../client.js';
9
-
10
-
11
- const hyperEvmChain: Chain = {
12
- id: 999,
13
- name: 'Hyperevm',
14
- nativeCurrency: {
15
- decimals: 18,
16
- name: 'HYPE',
17
- symbol: 'HYPE',
18
- },
19
- rpcUrls: {
20
- public: { http: ['https://rpc.hyperlend.finance'] },
21
- default: { http: ['https://rpc.hyperliquid.xyz/evm'] }
22
- },
23
- blockExplorers: {
24
- default: { name: 'Hyperevm', url: 'https://hyperevmscan.io' },
25
- },
26
- }
1
+ import { parseEther } from 'viem';
2
+ import { SingleAssetDepositClient } from '../../../../base/vault/single-asset/singleAssetDeposit.js';
3
+ import { AMMType } from '../../../../base/vault/single-asset/types.js';
4
+
5
+ jest.mock('../../../../base/vault/single-asset/calculateSwapAmount.js', () => ({
6
+ calculateSwapAmount: jest.fn(),
7
+ }));
8
+
9
+ jest.mock('../../../../base/vault/single-asset/calculateLimitPrice.js', () => ({
10
+ calculateLimitPrice: jest.fn(),
11
+ }));
12
+
13
+ jest.mock('../../../../base/vault/single-asset/simulateSwap.js', () => ({
14
+ determineSwapDirection: jest.fn((isToken0: boolean) => isToken0),
15
+ simulateSwapWithSlippage: jest.fn(),
16
+ }));
17
+
18
+ jest.mock('../../../../base/vault/single-asset/estimateLpTokens.js', () => ({
19
+ estimateLpTokens: jest.fn(),
20
+ }));
21
+
22
+ import { calculateSwapAmount } from '../../../../base/vault/single-asset/calculateSwapAmount.js';
23
+ import { calculateLimitPrice } from '../../../../base/vault/single-asset/calculateLimitPrice.js';
24
+ import { simulateSwapWithSlippage } from '../../../../base/vault/single-asset/simulateSwap.js';
25
+ import { estimateLpTokens } from '../../../../base/vault/single-asset/estimateLpTokens.js';
27
26
 
28
27
  describe('SingleAssetDepositClient', () => {
29
- let client: SingleAssetDepositClient;
30
- let publicClient: any;
31
- let walletClient: any;
32
-
33
- const mockAddresses = {
34
- vault: '0xea102e191687b47d23f1239c6bca03389fd98a32' as `0x${string}`,
35
- pool: '0xba2d4a755982eefbd24c52cea01c9ff5d3813bd4' as `0x${string}`,
36
- contract: '0x3456789012345678901234567890123456789012' as `0x${string}`,
37
- receiver: '0x9876543210987654321098765432109876543210' as `0x${string}`,
38
- user: '0x9876543210987654321098765432109876543210' as `0x${string}`,
39
- token0: '0x7ceb23fd6bc0add59e62ac25578270cff1b9f619' as `0x${string}`,
40
- token1: '0xd1a718f77ab5d22e3955050658d7f65ae857a85e' as `0x${string}`
28
+ let client: SingleAssetDepositClient;
29
+ let publicClient: any;
30
+ let walletClient: any;
31
+
32
+ const addresses = {
33
+ vault: '0xea102e191687b47d23f1239c6bca03389fd98a32' as `0x${string}`,
34
+ pool: '0xba2d4a755982eefbd24c52cea01c9ff5d3813bd4' as `0x${string}`,
35
+ contract: '0x3456789012345678901234567890123456789012' as `0x${string}`,
36
+ receiver: '0x9876543210987654321098765432109876543210' as `0x${string}`,
37
+ user: '0x9876543210987654321098765432109876543210' as `0x${string}`,
38
+ token0: '0x7ceb23fd6bc0add59e62ac25578270cff1b9f619' as `0x${string}`,
39
+ token1: '0xd1a718f77ab5d22e3955050658d7f65ae857a85e' as `0x${string}`,
40
+ };
41
+
42
+ beforeEach(() => {
43
+ jest.clearAllMocks();
44
+
45
+ publicClient = {
46
+ chain: { id: 137 },
47
+ getChainId: jest.fn().mockResolvedValue(137),
48
+ readContract: jest.fn().mockImplementation(async ({ functionName }: { functionName: string }) => {
49
+ if (functionName === 'token0') return addresses.token0;
50
+ if (functionName === 'token1') return addresses.token1;
51
+ if (functionName === 'fee') return 3000;
52
+ if (functionName === 'vaultDetailsByAddress') {
53
+ return { vaultType: 'MultiPositionUniswapV3' };
54
+ }
55
+ return { vaultType: 'MultiPositionUniswapV3' };
56
+ }),
57
+ simulateContract: jest.fn(),
41
58
  };
42
59
 
43
- let realSteerClient: SteerClient;
44
-
45
- beforeEach(() => {
46
- publicClient = createPublicClient({chain: hyperEvmChain, transport: http()});
47
- const walletClient = createWalletClient({chain: hyperEvmChain, transport: http()});
60
+ walletClient = {
61
+ getAddresses: jest.fn().mockResolvedValue([addresses.user]),
62
+ writeContract: jest.fn(),
63
+ };
48
64
 
49
- // Initialize SteerClient with real clients
50
- realSteerClient = new SteerClient({environment: 'production', client: publicClient, walletClient: walletClient});
65
+ client = new SingleAssetDepositClient(publicClient, walletClient);
66
+ });
67
+
68
+ describe('previewDeposit', () => {
69
+ const baseParams = {
70
+ assets: parseEther('100'),
71
+ receiver: addresses.receiver,
72
+ vault: addresses.vault,
73
+ isToken0: true,
74
+ depositSlippagePercent: 5n,
75
+ swapSlippageBP: 500,
76
+ ammType: AMMType.UniswapV3,
77
+ singleAssetDepositContract: addresses.contract,
78
+ };
51
79
 
52
- client = realSteerClient.vaults.singleAssetDepositClient;
53
- // Reset all mocks
54
- jest.clearAllMocks();
80
+ it('successfully previews a complete single-asset deposit', async () => {
81
+ (calculateSwapAmount as jest.Mock).mockResolvedValue({
82
+ success: true,
83
+ status: 200,
84
+ data: {
85
+ swapAmount: parseEther('25'),
86
+ sqrtPrice: 79228162514264337593543950336n,
87
+ },
88
+ });
89
+
90
+ (calculateLimitPrice as jest.Mock).mockResolvedValue({
91
+ success: true,
92
+ status: 200,
93
+ data: 75266754285251620654291905318n,
94
+ });
95
+
96
+ (simulateSwapWithSlippage as jest.Mock).mockResolvedValue({
97
+ success: true,
98
+ status: 200,
99
+ data: {
100
+ swapSimulation: {
101
+ amount0: -parseEther('25'),
102
+ amount1: parseEther('50'),
103
+ sqrtPriceX96After: 75266754285251620654291905318n,
104
+ },
105
+ },
106
+ });
107
+
108
+ (estimateLpTokens as jest.Mock).mockResolvedValue({
109
+ success: true,
110
+ status: 200,
111
+ data: {
112
+ lpTokens: parseEther('95'),
113
+ finalAmount0: parseEther('75'),
114
+ finalAmount1: parseEther('50'),
115
+ },
116
+ });
117
+
118
+ const result = await client.previewDeposit(baseParams, addresses.pool);
119
+
120
+ expect(result.success).toBe(true);
121
+ expect(result.status).toBe(200);
122
+ expect(result.data?.swapAmount).toBe(parseEther('25'));
123
+ expect(result.data?.lpEstimation.lpTokens).toBe(parseEther('95'));
124
+ expect(result.data?.zeroForOne).toBe(true);
55
125
  });
56
126
 
57
- describe('previewDeposit', () => {
58
- const baseParams = {
59
- assets: parseEther('100'),
60
- receiver: mockAddresses.receiver,
61
- vault: mockAddresses.vault,
62
- isToken0: true,
63
- depositSlippagePercent: 5n,
64
- swapSlippageBP: 500,
65
- ammType: AMMType.UniswapV3
66
- };
67
-
68
- it.only('should successfully preview a complete single-asset deposit', async () => {
69
-
70
- // const params: SingleAssetDepositParams = {
71
- // "assets":1000000000000000000n,"receiver":"0x50f72c67ab509dDaFFd35c385ffB904B9E255547","vault":"0xea102e191687b47d23f1239c6bca03389fd98a32","isToken0":true,"depositSlippagePercent":85n,"swapSlippageBP":500,"ammType":0}
72
-
73
- const params: SingleAssetDepositParams = {
74
- ammType: 4,
75
- assets: 1000000000000000000n,
76
- depositSlippagePercent: 85n,
77
- isToken0: false,
78
- receiver: "0x50f72c67ab509dDaFFd35c385ffB904B9E255547",
79
- swapSlippageBP: 500,
80
- vault: "0xbf39c114d2ddf657f26c158a2a04c399c4cb1c2d"
81
- }
82
- const result = await realSteerClient.vaults.previewSingleAssetDeposit(params, '0x51323f313e36a93fac2e1e929e48b961ffce5510');
83
-
84
- console.log('Preview deposit update')
85
-
86
- expect(result.success).toBe(true);
87
- expect(result.status).toBe(200);
88
- expect(result.data).toEqual({
89
- swapAmount: parseEther('25'),
90
- currentSqrtPrice: BigInt('79228162514264337593543950336'),
91
- sqrtPriceLimitX96: BigInt('75266754285251620654291905318'),
92
- swapSimulation: {
93
- amount0: -parseEther('25'),
94
- amount1: parseEther('50')
95
- },
96
- lpEstimation: {
97
- lpTokens: parseEther('95'),
98
- finalAmount0: parseEther('75'),
99
- finalAmount1: parseEther('50')
100
- },
101
- zeroForOne: true
102
- });
103
-
104
- });
105
-
106
- it('should handle token1 deposit', async () => {
107
- const token1Params = {
108
- ... baseParams,
109
- isToken0: false
110
- };
111
-
112
-
113
- const result = await client.previewDeposit(token1Params, mockAddresses.pool);
114
-
115
- expect(result.success).toBe(true);
116
- expect(result.data ?. zeroForOne).toBe(false);
117
- });
118
-
119
- it('should handle calculateSwapAmount failure', async () => {
120
-
121
- const result = await client.previewDeposit(baseParams, mockAddresses.pool);
122
-
123
- expect(result.success).toBe(false);
124
- expect(result.status).toBe(500);
125
- expect(result.error).toBe('Swap calculation failed');
126
- expect(result.data).toBeNull();
127
-
128
- // Should not call subsequent functions
129
- });
127
+ it('returns swap calculation failure', async () => {
128
+ (calculateSwapAmount as jest.Mock).mockResolvedValue({
129
+ success: false,
130
+ status: 500,
131
+ error: 'Swap calculation failed',
132
+ });
133
+
134
+ const result = await client.previewDeposit(baseParams, addresses.pool);
130
135
 
136
+ expect(result.success).toBe(false);
137
+ expect(result.status).toBe(500);
138
+ expect(result.error).toBe('Swap calculation failed');
139
+ expect(result.data).toBeNull();
131
140
  });
141
+ });
142
+
143
+ describe('deposit', () => {
144
+ const baseParams = {
145
+ assets: parseEther('100'),
146
+ receiver: addresses.receiver,
147
+ vault: addresses.vault,
148
+ isToken0: true,
149
+ depositSlippagePercent: 5n,
150
+ swapSlippageBP: 500,
151
+ ammType: AMMType.UniswapV3,
152
+ singleAssetDepositContract: addresses.contract,
153
+ };
154
+
155
+ it('successfully executes deposit', async () => {
156
+ const txHash = `0x${'a'.repeat(64)}` as `0x${string}`;
157
+ publicClient.simulateContract.mockResolvedValue({ request: { to: addresses.contract } });
158
+ walletClient.writeContract.mockResolvedValue(txHash);
159
+
160
+ const result = await client.deposit(baseParams);
132
161
 
133
- describe('deposit', () => {
134
- const baseParams = {
135
- assets: parseEther('100'),
136
- receiver: mockAddresses.receiver,
137
- vault: mockAddresses.vault,
138
- isToken0: true,
139
- depositSlippagePercent: 5n,
140
- swapSlippageBP: 500,
141
- ammType: AMMType.UniswapV3,
142
- singleAssetDepositContract: mockAddresses.contract
143
- };
144
-
145
- it('should successfully execute deposit', async () => {
146
- const mockTxHash = '0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890';
147
-
148
- walletClient.getAddresses = jest.fn().mockResolvedValue([mockAddresses.user]);
149
- publicClient.simulateContract = jest.fn().mockResolvedValue({
150
- request: {
151
- address: mockAddresses.contract,
152
- abi: expect.any(Array),
153
- functionName: 'deposit',
154
- args: [
155
- parseEther('100'),
156
- mockAddresses.receiver,
157
- mockAddresses.vault,
158
- true,
159
- 5n,
160
- 500,
161
- AMMType.UniswapV3
162
- ]
163
- }
164
- });
165
- walletClient.writeContract = jest.fn().mockResolvedValue(mockTxHash);
166
-
167
- const result = await client.deposit(baseParams);
168
-
169
- expect(result.success).toBe(true);
170
- expect(result.status).toBe(200);
171
- expect(result.data).toBe(mockTxHash);
172
-
173
- expect(publicClient.simulateContract).toHaveBeenCalledWith({
174
- address: mockAddresses.contract,
175
- abi: expect.any(Array),
176
- functionName: 'deposit',
177
- args: [
178
- parseEther('100'),
179
- mockAddresses.receiver,
180
- mockAddresses.vault,
181
- true,
182
- 5n,
183
- 500,
184
- AMMType.UniswapV3
185
- ],
186
- account: mockAddresses.user
187
- });
188
-
189
- expect(walletClient.writeContract).toHaveBeenCalled();
190
- });
191
-
192
- it('should handle no account found', async () => {
193
- walletClient.getAddresses = jest.fn().mockResolvedValue([]);
194
-
195
- const result = await client.deposit(baseParams);
196
-
197
- expect(result.success).toBe(false);
198
- expect(result.error).toBe('No account found');
199
- });
200
-
201
- it('should handle simulation failure', async () => {
202
- walletClient.getAddresses = jest.fn().mockResolvedValue([mockAddresses.user]);
203
- publicClient.simulateContract = jest.fn().mockRejectedValue(new Error('Simulation failed'));
204
-
205
- const result = await client.deposit(baseParams);
206
-
207
- expect(result.success).toBe(false);
208
- expect(result.error).toBe('Simulation failed');
209
- });
210
-
211
- it('should handle transaction failure', async () => {
212
- walletClient.getAddresses = jest.fn().mockResolvedValue([mockAddresses.user]);
213
- publicClient.simulateContract = jest.fn().mockResolvedValue({request: {}});
214
- walletClient.writeContract = jest.fn().mockRejectedValue(new Error('Transaction failed'));
215
-
216
- const result = await client.deposit(baseParams);
217
-
218
- expect(result.success).toBe(false);
219
- expect(result.error).toBe('Transaction failed');
220
- });
162
+ expect(result.success).toBe(true);
163
+ expect(result.status).toBe(200);
164
+ expect(result.data).toBe(txHash);
165
+ expect(publicClient.simulateContract).toHaveBeenCalled();
166
+ expect(walletClient.writeContract).toHaveBeenCalled();
221
167
  });
222
168
 
223
- describe('prepareDepositTx', () => {
224
- const baseParams = {
225
- assets: parseEther('100'),
226
- receiver: mockAddresses.receiver,
227
- vault: mockAddresses.vault,
228
- isToken0: true,
229
- depositSlippagePercent: 5n,
230
- swapSlippageBP: 500,
231
- ammType: AMMType.UniswapV3,
232
- singleAssetDepositContract: mockAddresses.contract
233
- };
234
-
235
- it('should successfully prepare deposit transaction', async () => {
236
- walletClient.getAddresses = jest.fn().mockResolvedValue([mockAddresses.user]);
237
- publicClient.simulateContract = jest.fn().mockResolvedValue({
238
- request: {
239
- address: mockAddresses.contract,
240
- functionName: 'deposit',
241
- args: [/* mock args */
242
- ]
243
- }
244
- });
245
-
246
- const result = await client.prepareDepositTx(baseParams);
247
-
248
- expect(result.success).toBe(true);
249
- expect(result.status).toBe(200);
250
- expect(result.data).toEqual({
251
- address: mockAddresses.contract,
252
- abi: expect.any(Array),
253
- functionName: 'deposit',
254
- args: [
255
- parseEther('100'),
256
- mockAddresses.receiver,
257
- mockAddresses.vault,
258
- true,
259
- 5n,
260
- 500,
261
- AMMType.UniswapV3
262
- ]
263
- });
264
- });
265
-
266
- it('should handle preparation errors', async () => {
267
- walletClient.getAddresses = jest.fn().mockResolvedValue([]);
268
-
269
- const result = await client.prepareDepositTx(baseParams);
270
-
271
- expect(result.success).toBe(false);
272
- expect(result.error).toBe('No account found');
273
- });
169
+ it('returns error when no account exists', async () => {
170
+ walletClient.getAddresses.mockResolvedValue([]);
171
+
172
+ const result = await client.deposit(baseParams);
173
+
174
+ expect(result.success).toBe(false);
175
+ expect(result.error).toBe('No account found');
274
176
  });
275
177
 
276
- describe('validateDepositParams', () => {
277
- const validParams = {
278
- assets: parseEther('100'),
279
- receiver: mockAddresses.receiver,
280
- vault: mockAddresses.vault,
281
- isToken0: true,
282
- depositSlippagePercent: 5n,
283
- swapSlippageBP: 500,
284
- ammType: AMMType.UniswapV3,
285
- singleAssetDepositContract: mockAddresses.contract
286
- };
287
-
288
- it('should not throw for valid parameters', () => {
289
- expect(() => client.validateDepositParams(validParams)).not.toThrow();
290
- });
291
-
292
- it('should throw for zero assets', () => {
293
- expect(() => client.validateDepositParams({
294
- ... validParams,
295
- assets: BigInt('0')
296
- })).toThrow('Assets amount must be greater than 0');
297
- });
298
-
299
- it('should throw for invalid vault address', () => {
300
- expect(() => client.validateDepositParams({
301
- ... validParams,
302
- vault: '0x0000000000000000000000000000000000000000'
303
- })).toThrow('Invalid vault address');
304
- });
305
-
306
- it('should throw for invalid receiver address', () => {
307
- expect(() => client.validateDepositParams({
308
- ... validParams,
309
- receiver: '0x0000000000000000000000000000000000000000'
310
- })).toThrow('Invalid receiver address');
311
- });
312
-
313
- it('should throw for invalid contract address', () => {
314
- expect(() => client.validateDepositParams({
315
- ... validParams,
316
- singleAssetDepositContract: '0x0000000000000000000000000000000000000000'
317
- })).toThrow('Invalid single-asset deposit contract address');
318
- });
319
-
320
- it('should throw for excessive deposit slippage', () => {
321
- expect(() => client.validateDepositParams({
322
- ... validParams,
323
- depositSlippagePercent: 101n
324
- })).toThrow('Deposit slippage percent cannot exceed 100%');
325
- });
326
-
327
- it('should throw for excessive swap slippage', () => {
328
- expect(() => client.validateDepositParams({
329
- ... validParams,
330
- swapSlippageBP: 10001
331
- })).toThrow('Swap slippage BP cannot exceed 10000 (100%)');
332
- });
333
-
334
- it('should throw for invalid AMM type', () => {
335
- expect(() => client.validateDepositParams({
336
- ... validParams,
337
- ammType: 999 as AMMType
338
- })).toThrow('Invalid AMM type');
339
- });
340
-
341
- it('should handle edge case values', () => { // Test maximum allowed values
342
- expect(() => client.validateDepositParams({
343
- ... validParams,
344
- depositSlippagePercent: 100n,
345
- swapSlippageBP: 10000
346
- })).not.toThrow();
347
-
348
- // Test minimum values
349
- expect(() => client.validateDepositParams({
350
- ... validParams,
351
- assets: BigInt('1'),
352
- depositSlippagePercent: 0n,
353
- swapSlippageBP: 0
354
- })).not.toThrow();
355
- });
178
+ it('returns simulation failure', async () => {
179
+ publicClient.simulateContract.mockRejectedValue(new Error('Simulation failed'));
180
+
181
+ const result = await client.deposit(baseParams);
182
+
183
+ expect(result.success).toBe(false);
184
+ expect(result.error).toBe('Simulation failed');
356
185
  });
357
186
 
358
- describe('integration scenarios', () => {
359
- it('should handle complete flow for balanced pool', async () => {
360
- const params = {
361
- assets: parseEther('100'),
362
- receiver: mockAddresses.receiver,
363
- vault: mockAddresses.vault,
364
- isToken0: true,
365
- depositSlippagePercent: 3n,
366
- swapSlippageBP: 300,
367
- ammType: AMMType.UniswapV3,
368
- singleAssetDepositContract: mockAddresses.contract
369
- };
370
-
371
-
372
- const result = await client.previewDeposit(params, mockAddresses.pool);
373
-
374
- expect(result.success).toBe(true);
375
- expect(result.data ?. swapAmount).toBe(parseEther('50'));
376
- expect(result.data ?. lpEstimation.finalAmount0).toBe(parseEther('50'));
377
- expect(result.data ?. lpEstimation.finalAmount1).toBe(parseEther('50'));
378
- });
379
-
380
- it('should handle imbalanced pool scenario', async () => {
381
- const params = {
382
- assets: parseEther('100'),
383
- receiver: mockAddresses.receiver,
384
- vault: mockAddresses.vault,
385
- isToken0: true,
386
- depositSlippagePercent: 5n,
387
- swapSlippageBP: 500,
388
- ammType: AMMType.UniswapV3,
389
- singleAssetDepositContract: mockAddresses.contract
390
- };
391
-
392
-
393
- const result = await client.previewDeposit(params, mockAddresses.pool);
394
-
395
- expect(result.success).toBe(true);
396
- expect(result.data ?. swapAmount).toBe(parseEther('80'));
397
- expect(result.data ?. lpEstimation.lpTokens).toBe(parseEther('60'));
398
- });
187
+ it('returns transaction failure', async () => {
188
+ publicClient.simulateContract.mockResolvedValue({ request: { to: addresses.contract } });
189
+ walletClient.writeContract.mockRejectedValue(new Error('Transaction failed'));
190
+
191
+ const result = await client.deposit(baseParams);
192
+
193
+ expect(result.success).toBe(false);
194
+ expect(result.error).toBe('Transaction failed');
399
195
  });
196
+ });
400
197
  });
@@ -0,0 +1,47 @@
1
+ import { ChainId } from '../../const/chain.js';
2
+ import type { NetworkConfig } from '../../const/network.js';
3
+ import { feeManagerContractsByChainId } from '../../const/feeManagerContracts.js';
4
+ import { getContractAddressByChainIdAndContractName, networks } from '../../const/network.js';
5
+
6
+ describe('network FeeManager overlay', () => {
7
+ it('backfills FeeManager for chains missing it in legacy SDK deployment files', () => {
8
+ expect(getContractAddressByChainIdAndContractName(ChainId.Base, 'FeeManager')).toBe(
9
+ feeManagerContractsByChainId[ChainId.Base]?.address
10
+ );
11
+ expect(getContractAddressByChainIdAndContractName(ChainId.Avalanche, 'FeeManager')).toBe(
12
+ feeManagerContractsByChainId[ChainId.Avalanche]?.address
13
+ );
14
+ expect(getContractAddressByChainIdAndContractName(ChainId.Linea, 'FeeManager')).toBe(
15
+ feeManagerContractsByChainId[ChainId.Linea]?.address
16
+ );
17
+ expect(getContractAddressByChainIdAndContractName(ChainId.Scroll, 'FeeManager')).toBe(
18
+ feeManagerContractsByChainId[ChainId.Scroll]?.address
19
+ );
20
+ });
21
+
22
+ it('prefers contracts package FeeManager values when they conflict', () => {
23
+ expect(getContractAddressByChainIdAndContractName(ChainId.BeraChainBartio, 'FeeManager')).toBe(
24
+ feeManagerContractsByChainId[ChainId.BeraChainBartio]?.address
25
+ );
26
+ });
27
+
28
+ it('keeps SDK-only FeeManager entries when contracts map has no chain match', () => {
29
+ expect(feeManagerContractsByChainId[ChainId.Hyperevm]).toBeUndefined();
30
+ expect(getContractAddressByChainIdAndContractName(ChainId.Hyperevm, 'FeeManager')).toBe(
31
+ '0x8BfAdC53bfd06F051685b42690076d9c94aaBCBd'
32
+ );
33
+ });
34
+
35
+ it('exposes materially more FeeManager-enabled networks than legacy baseline', () => {
36
+ const feeManagerEnabledNetworks = (Object.values(networks) as NetworkConfig[]).filter(
37
+ (network) => Boolean(network.FeeManager?.address)
38
+ );
39
+ const chainIds = feeManagerEnabledNetworks.map((network) => network.chainId);
40
+
41
+ expect(feeManagerEnabledNetworks.length).toBeGreaterThan(4);
42
+ expect(chainIds).toContain(ChainId.Base);
43
+ expect(chainIds).toContain(ChainId.Avalanche);
44
+ expect(chainIds).toContain(ChainId.Linea);
45
+ expect(chainIds).toContain(ChainId.Scroll);
46
+ });
47
+ });