@gauntlet-xyz/sdk 1.0.5 → 2.0.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 (89) hide show
  1. package/dist/constants.d.ts +16 -0
  2. package/dist/constants.d.ts.map +1 -0
  3. package/dist/constants.js +28 -0
  4. package/dist/constants.js.map +1 -0
  5. package/dist/errors.d.ts +18 -3
  6. package/dist/errors.d.ts.map +1 -1
  7. package/dist/errors.js +20 -2
  8. package/dist/errors.js.map +1 -1
  9. package/dist/evm/abis/priceAndFeeCalculatorV2.d.ts +233 -0
  10. package/dist/evm/abis/priceAndFeeCalculatorV2.d.ts.map +1 -0
  11. package/dist/evm/abis/priceAndFeeCalculatorV2.js +119 -0
  12. package/dist/evm/abis/priceAndFeeCalculatorV2.js.map +1 -0
  13. package/dist/evm/abis/provisionerV2.d.ts +460 -0
  14. package/dist/evm/abis/provisionerV2.d.ts.map +1 -0
  15. package/dist/evm/abis/provisionerV2.js +203 -0
  16. package/dist/evm/abis/provisionerV2.js.map +1 -0
  17. package/dist/evm/adapters/aera.d.ts +3 -3
  18. package/dist/evm/adapters/aera.d.ts.map +1 -1
  19. package/dist/evm/adapters/aera.js +179 -103
  20. package/dist/evm/adapters/aera.js.map +1 -1
  21. package/dist/evm/adapters/types.d.ts +12 -1
  22. package/dist/evm/adapters/types.d.ts.map +1 -1
  23. package/dist/evm/aeraContracts/priceAndFeeCalculator.d.ts +41 -0
  24. package/dist/evm/aeraContracts/priceAndFeeCalculator.d.ts.map +1 -0
  25. package/dist/evm/aeraContracts/priceAndFeeCalculator.js +140 -0
  26. package/dist/evm/aeraContracts/priceAndFeeCalculator.js.map +1 -0
  27. package/dist/evm/aeraContracts/v1.d.ts +2317 -0
  28. package/dist/evm/aeraContracts/v1.d.ts.map +1 -0
  29. package/dist/evm/aeraContracts/v1.js +59 -0
  30. package/dist/evm/aeraContracts/v1.js.map +1 -0
  31. package/dist/evm/aeraContracts/v2.d.ts +2802 -0
  32. package/dist/evm/aeraContracts/v2.d.ts.map +1 -0
  33. package/dist/evm/aeraContracts/v2.js +217 -0
  34. package/dist/evm/aeraContracts/v2.js.map +1 -0
  35. package/dist/evm/aeraContracts.d.ts +23 -2316
  36. package/dist/evm/aeraContracts.d.ts.map +1 -1
  37. package/dist/evm/aeraContracts.js +117 -24
  38. package/dist/evm/aeraContracts.js.map +1 -1
  39. package/dist/evm/deposit.d.ts +5 -1
  40. package/dist/evm/deposit.d.ts.map +1 -1
  41. package/dist/evm/deposit.js +28 -14
  42. package/dist/evm/deposit.js.map +1 -1
  43. package/dist/evm/depositReceiverApproval.d.ts +17 -0
  44. package/dist/evm/depositReceiverApproval.d.ts.map +1 -0
  45. package/dist/evm/depositReceiverApproval.js +32 -0
  46. package/dist/evm/depositReceiverApproval.js.map +1 -0
  47. package/dist/evm/index.d.ts +8 -1
  48. package/dist/evm/index.d.ts.map +1 -1
  49. package/dist/evm/index.js +4 -0
  50. package/dist/evm/index.js.map +1 -1
  51. package/dist/evm/operationMode.d.ts +9 -0
  52. package/dist/evm/operationMode.d.ts.map +1 -0
  53. package/dist/evm/operationMode.js +41 -0
  54. package/dist/evm/operationMode.js.map +1 -0
  55. package/dist/evm/types.d.ts +7 -3
  56. package/dist/evm/types.d.ts.map +1 -1
  57. package/dist/evm/types.js +4 -1
  58. package/dist/evm/types.js.map +1 -1
  59. package/dist/evm/userCurrentBalance.d.ts.map +1 -1
  60. package/dist/evm/userCurrentBalance.js +68 -58
  61. package/dist/evm/userCurrentBalance.js.map +1 -1
  62. package/dist/evm/withdraw.d.ts +5 -1
  63. package/dist/evm/withdraw.d.ts.map +1 -1
  64. package/dist/evm/withdraw.js +25 -13
  65. package/dist/evm/withdraw.js.map +1 -1
  66. package/dist/index.d.ts +8 -1
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +5 -1
  69. package/dist/index.js.map +1 -1
  70. package/manifest/vaults.json +31 -139
  71. package/package.json +1 -1
  72. package/src/constants.ts +32 -0
  73. package/src/errors.ts +44 -5
  74. package/src/evm/abis/priceAndFeeCalculatorV2.ts +118 -0
  75. package/src/evm/abis/provisionerV2.ts +202 -0
  76. package/src/evm/adapters/aera.ts +419 -137
  77. package/src/evm/adapters/types.ts +19 -1
  78. package/src/evm/aeraContracts/priceAndFeeCalculator.ts +223 -0
  79. package/src/evm/aeraContracts/v1.ts +157 -0
  80. package/src/evm/aeraContracts/v2.ts +466 -0
  81. package/src/evm/aeraContracts.ts +173 -52
  82. package/src/evm/deposit.ts +48 -16
  83. package/src/evm/depositReceiverApproval.ts +51 -0
  84. package/src/evm/index.ts +23 -1
  85. package/src/evm/operationMode.ts +60 -0
  86. package/src/evm/types.ts +9 -3
  87. package/src/evm/userCurrentBalance.ts +80 -55
  88. package/src/evm/withdraw.ts +42 -15
  89. package/src/index.ts +19 -0
@@ -0,0 +1,466 @@
1
+ import {
2
+ type Address,
3
+ type Client,
4
+ type GetContractReturnType,
5
+ type PublicClient,
6
+ getContract,
7
+ } from 'viem';
8
+ import { priceAndFeeCalculatorV2Abi } from '../abis/priceAndFeeCalculatorV2';
9
+ import { provisionerV2Abi } from '../abis/provisionerV2';
10
+ import {
11
+ Rounding,
12
+ convertTokenToUnitsIfActive,
13
+ convertUnitsToTokenIfActive,
14
+ } from './priceAndFeeCalculator';
15
+ import { MAX_BPS } from '../../constants';
16
+ import { StalePriceError } from '../../errors';
17
+ import type { ContractVersion } from '../types';
18
+
19
+ export type PriceAndFeeCalculatorContract<T extends Client> = GetContractReturnType<
20
+ typeof priceAndFeeCalculatorV2Abi,
21
+ T,
22
+ Address
23
+ >;
24
+
25
+ export function getPriceAndFeeCalculator<T extends Client>(
26
+ client: T,
27
+ address: Address
28
+ ): PriceAndFeeCalculatorContract<T> {
29
+ return getContract({
30
+ address,
31
+ abi: priceAndFeeCalculatorV2Abi,
32
+ client,
33
+ });
34
+ }
35
+
36
+ function getProvisioner<T extends Client>(client: T, address: Address) {
37
+ return getContract({
38
+ address,
39
+ abi: provisionerV2Abi,
40
+ client,
41
+ });
42
+ }
43
+
44
+ async function getTokenDetails(client: PublicClient, provisioner: Address, token: Address) {
45
+ return getProvisioner(client, provisioner).read.tokensDetails([token]);
46
+ }
47
+
48
+ async function getDepositUnitsOut({
49
+ client,
50
+ provisioner,
51
+ feeCalculator,
52
+ feeCalculatorVersion,
53
+ vault,
54
+ token,
55
+ tokensIn,
56
+ multiplierIndex,
57
+ }: {
58
+ client: PublicClient;
59
+ provisioner: Address;
60
+ feeCalculator: Address;
61
+ feeCalculatorVersion: ContractVersion;
62
+ vault: Address;
63
+ token: Address;
64
+ tokensIn: bigint;
65
+ multiplierIndex: 4 | 6;
66
+ }): Promise<bigint> {
67
+ const tokenDetails = await getTokenDetails(client, provisioner, token);
68
+ const multiplier = BigInt(tokenDetails[multiplierIndex]);
69
+ const adjustedTokensIn = (tokensIn * multiplier) / MAX_BPS;
70
+
71
+ return convertTokenToUnitsIfActive(
72
+ client,
73
+ feeCalculator,
74
+ feeCalculatorVersion,
75
+ vault,
76
+ token,
77
+ adjustedTokensIn,
78
+ Rounding.Floor
79
+ );
80
+ }
81
+
82
+ async function getRedeemTokenOut({
83
+ client,
84
+ provisioner,
85
+ feeCalculator,
86
+ feeCalculatorVersion,
87
+ vault,
88
+ token,
89
+ unitsIn,
90
+ multiplierIndex,
91
+ }: {
92
+ client: PublicClient;
93
+ provisioner: Address;
94
+ feeCalculator: Address;
95
+ feeCalculatorVersion: ContractVersion;
96
+ vault: Address;
97
+ token: Address;
98
+ unitsIn: bigint;
99
+ multiplierIndex: 5 | 7;
100
+ }): Promise<bigint> {
101
+ const [tokenDetails, tokensOut] = await Promise.all([
102
+ getTokenDetails(client, provisioner, token),
103
+ convertUnitsToTokenIfActive(
104
+ client,
105
+ feeCalculator,
106
+ feeCalculatorVersion,
107
+ vault,
108
+ token,
109
+ unitsIn,
110
+ Rounding.Floor
111
+ ),
112
+ ]);
113
+ const multiplier = BigInt(tokenDetails[multiplierIndex]);
114
+
115
+ return (tokensOut * multiplier) / MAX_BPS;
116
+ }
117
+
118
+ async function getWithdrawUnitsIn({
119
+ client,
120
+ provisioner,
121
+ feeCalculator,
122
+ feeCalculatorVersion,
123
+ vault,
124
+ token,
125
+ tokensOut,
126
+ multiplierIndex,
127
+ }: {
128
+ client: PublicClient;
129
+ provisioner: Address;
130
+ feeCalculator: Address;
131
+ feeCalculatorVersion: ContractVersion;
132
+ vault: Address;
133
+ token: Address;
134
+ tokensOut: bigint;
135
+ multiplierIndex: 5 | 7;
136
+ }): Promise<bigint> {
137
+ const tokenDetails = await getTokenDetails(client, provisioner, token);
138
+ const multiplier = BigInt(tokenDetails[multiplierIndex]);
139
+ const preMultiplierTokens = (tokensOut * MAX_BPS + multiplier - 1n) / multiplier;
140
+
141
+ return convertTokenToUnitsIfActive(
142
+ client,
143
+ feeCalculator,
144
+ feeCalculatorVersion,
145
+ vault,
146
+ token,
147
+ preMultiplierTokens,
148
+ Rounding.Ceil
149
+ );
150
+ }
151
+
152
+ async function getSyncRedeemMultiplier(
153
+ client: PublicClient,
154
+ provisioner: Address,
155
+ vault: Address,
156
+ token: Address,
157
+ feeCalculator: Address
158
+ ): Promise<bigint> {
159
+ const [tokenDetails, syncRedeemDetails, anchorTimestamp] = await client.multicall({
160
+ contracts: [
161
+ {
162
+ address: provisioner,
163
+ abi: provisionerV2Abi,
164
+ functionName: 'tokensDetails',
165
+ args: [token],
166
+ },
167
+ {
168
+ address: provisioner,
169
+ abi: provisionerV2Abi,
170
+ functionName: 'getSyncRedeemDetails',
171
+ },
172
+ {
173
+ address: feeCalculator,
174
+ abi: priceAndFeeCalculatorV2Abi,
175
+ functionName: 'getAnchorTimestamp',
176
+ args: [vault],
177
+ },
178
+ ],
179
+ allowFailure: false,
180
+ });
181
+ const block = await client.getBlock();
182
+ const syncRedeemMultiplier = BigInt(tokenDetails[7]);
183
+ const maxPriceAge = BigInt(syncRedeemDetails[0]);
184
+ const maxDynamicPremiumBps = BigInt(syncRedeemDetails[2]);
185
+ const blockTimestamp = BigInt(block.timestamp);
186
+ const priceTimestamp = BigInt(anchorTimestamp);
187
+
188
+ if (priceTimestamp + maxPriceAge < blockTimestamp) {
189
+ throw new StalePriceError({
190
+ blockTimestamp,
191
+ maxPriceAge,
192
+ priceTimestamp,
193
+ });
194
+ }
195
+
196
+ const dynamicPremiumBps =
197
+ maxDynamicPremiumBps === 0n || maxPriceAge === 0n
198
+ ? 0n
199
+ : ((blockTimestamp - priceTimestamp) * maxDynamicPremiumBps + maxPriceAge - 1n) / maxPriceAge;
200
+
201
+ return syncRedeemMultiplier - dynamicPremiumBps;
202
+ }
203
+
204
+ export async function getSyncRedeemTokenOut(
205
+ client: PublicClient,
206
+ provisioner: Address,
207
+ feeCalculator: Address,
208
+ feeCalculatorVersion: ContractVersion,
209
+ vault: Address,
210
+ token: Address,
211
+ unitsIn: bigint
212
+ ): Promise<bigint> {
213
+ const [tokenAmount, multiplier] = await Promise.all([
214
+ convertUnitsToTokenIfActive(
215
+ client,
216
+ feeCalculator,
217
+ feeCalculatorVersion,
218
+ vault,
219
+ token,
220
+ unitsIn,
221
+ Rounding.Floor
222
+ ),
223
+ getSyncRedeemMultiplier(client, provisioner, vault, token, feeCalculator),
224
+ ]);
225
+
226
+ return (tokenAmount * multiplier) / MAX_BPS;
227
+ }
228
+
229
+ export async function getAsyncDepositUnitsOut(
230
+ client: PublicClient,
231
+ provisioner: Address,
232
+ feeCalculator: Address,
233
+ feeCalculatorVersion: ContractVersion,
234
+ vault: Address,
235
+ token: Address,
236
+ tokensIn: bigint
237
+ ): Promise<bigint> {
238
+ return getDepositUnitsOut({
239
+ client,
240
+ provisioner,
241
+ feeCalculator,
242
+ feeCalculatorVersion,
243
+ vault,
244
+ token,
245
+ tokensIn,
246
+ multiplierIndex: 4,
247
+ });
248
+ }
249
+
250
+ export async function getSyncDepositUnitsOut(
251
+ client: PublicClient,
252
+ provisioner: Address,
253
+ feeCalculator: Address,
254
+ feeCalculatorVersion: ContractVersion,
255
+ vault: Address,
256
+ token: Address,
257
+ tokensIn: bigint
258
+ ): Promise<bigint> {
259
+ return getDepositUnitsOut({
260
+ client,
261
+ provisioner,
262
+ feeCalculator,
263
+ feeCalculatorVersion,
264
+ vault,
265
+ token,
266
+ tokensIn,
267
+ multiplierIndex: 6,
268
+ });
269
+ }
270
+
271
+ export async function getAsyncRedeemTokenOut(
272
+ client: PublicClient,
273
+ provisioner: Address,
274
+ feeCalculator: Address,
275
+ feeCalculatorVersion: ContractVersion,
276
+ vault: Address,
277
+ token: Address,
278
+ unitsIn: bigint
279
+ ): Promise<bigint> {
280
+ return getRedeemTokenOut({
281
+ client,
282
+ provisioner,
283
+ feeCalculator,
284
+ feeCalculatorVersion,
285
+ vault,
286
+ token,
287
+ unitsIn,
288
+ multiplierIndex: 5,
289
+ });
290
+ }
291
+
292
+ export async function getAsyncWithdrawUnitsIn(
293
+ client: PublicClient,
294
+ provisioner: Address,
295
+ feeCalculator: Address,
296
+ feeCalculatorVersion: ContractVersion,
297
+ vault: Address,
298
+ token: Address,
299
+ tokensOut: bigint
300
+ ): Promise<bigint> {
301
+ return getWithdrawUnitsIn({
302
+ client,
303
+ provisioner,
304
+ feeCalculator,
305
+ feeCalculatorVersion,
306
+ vault,
307
+ token,
308
+ tokensOut,
309
+ multiplierIndex: 5,
310
+ });
311
+ }
312
+
313
+ export async function getSyncWithdrawUnitsIn(
314
+ client: PublicClient,
315
+ provisioner: Address,
316
+ feeCalculator: Address,
317
+ feeCalculatorVersion: ContractVersion,
318
+ vault: Address,
319
+ token: Address,
320
+ tokensOut: bigint
321
+ ): Promise<bigint> {
322
+ const multiplier = await getSyncRedeemMultiplier(
323
+ client,
324
+ provisioner,
325
+ vault,
326
+ token,
327
+ feeCalculator
328
+ );
329
+ const prePremiumTokens = (tokensOut * MAX_BPS + multiplier - 1n) / multiplier;
330
+
331
+ return convertTokenToUnitsIfActive(
332
+ client,
333
+ feeCalculator,
334
+ feeCalculatorVersion,
335
+ vault,
336
+ token,
337
+ prePremiumTokens,
338
+ Rounding.Ceil
339
+ );
340
+ }
341
+
342
+ export function depositTxRequest(
343
+ provisioner: Address,
344
+ token: Address,
345
+ tokensIn: bigint,
346
+ minUnitsOut: bigint,
347
+ receiver: Address,
348
+ account: Address
349
+ ) {
350
+ return {
351
+ address: provisioner,
352
+ abi: provisionerV2Abi,
353
+ functionName: 'deposit' as const,
354
+ args: [token, tokensIn, minUnitsOut, receiver] as const,
355
+ account,
356
+ };
357
+ }
358
+
359
+ export function requestDepositTxRequest(
360
+ provisioner: Address,
361
+ token: Address,
362
+ tokensIn: bigint,
363
+ minUnitsOut: bigint,
364
+ solverTip: bigint,
365
+ deadline: bigint,
366
+ maxPriceAge: bigint,
367
+ isFixedPrice: boolean,
368
+ receiver: Address,
369
+ account: Address
370
+ ) {
371
+ return {
372
+ address: provisioner,
373
+ abi: provisionerV2Abi,
374
+ functionName: 'requestDeposit' as const,
375
+ args: [
376
+ token,
377
+ tokensIn,
378
+ minUnitsOut,
379
+ solverTip,
380
+ deadline,
381
+ maxPriceAge,
382
+ isFixedPrice,
383
+ receiver,
384
+ ] as const,
385
+ account,
386
+ };
387
+ }
388
+
389
+ export function setDepositReceiverApprovalTxRequest(
390
+ provisioner: Address,
391
+ depositor: Address,
392
+ approved: boolean,
393
+ receiver: Address
394
+ ) {
395
+ return {
396
+ address: provisioner,
397
+ abi: provisionerV2Abi,
398
+ functionName: 'setDepositReceiverApproval' as const,
399
+ args: [depositor, approved] as const,
400
+ account: receiver,
401
+ };
402
+ }
403
+
404
+ export function requestRedeemTxRequest(
405
+ provisioner: Address,
406
+ token: Address,
407
+ unitsIn: bigint,
408
+ minTokenOut: bigint,
409
+ solverTip: bigint,
410
+ deadline: bigint,
411
+ maxPriceAge: bigint,
412
+ isFixedPrice: boolean,
413
+ receiver: Address,
414
+ account: Address
415
+ ) {
416
+ return {
417
+ address: provisioner,
418
+ abi: provisionerV2Abi,
419
+ functionName: 'requestRedeem' as const,
420
+ args: [
421
+ token,
422
+ unitsIn,
423
+ minTokenOut,
424
+ solverTip,
425
+ deadline,
426
+ maxPriceAge,
427
+ isFixedPrice,
428
+ receiver,
429
+ ] as const,
430
+ account,
431
+ };
432
+ }
433
+
434
+ export function redeemTxRequest(
435
+ provisioner: Address,
436
+ token: Address,
437
+ unitsIn: bigint,
438
+ minTokenOut: bigint,
439
+ receiver: Address,
440
+ account: Address
441
+ ) {
442
+ return {
443
+ address: provisioner,
444
+ abi: provisionerV2Abi,
445
+ functionName: 'redeem' as const,
446
+ args: [token, unitsIn, minTokenOut, receiver] as const,
447
+ account,
448
+ };
449
+ }
450
+
451
+ export function withdrawTxRequest(
452
+ provisioner: Address,
453
+ token: Address,
454
+ tokensOut: bigint,
455
+ maxUnitsIn: bigint,
456
+ receiver: Address,
457
+ account: Address
458
+ ) {
459
+ return {
460
+ address: provisioner,
461
+ abi: provisionerV2Abi,
462
+ functionName: 'withdraw' as const,
463
+ args: [token, tokensOut, maxUnitsIn, receiver] as const,
464
+ account,
465
+ };
466
+ }
@@ -1,11 +1,82 @@
1
- /**
2
- * CODE PULLED FROM AERA-V3-TS-SDK in gauntlet/apps/packages/aera-v3-ts-sdk
3
- * pulled in here with the goal to have this SDK replace the previous
4
- */
5
- import { type Address, type Client, type GetContractReturnType, getContract } from 'viem';
1
+ import {
2
+ ContractFunctionExecutionError,
3
+ ContractFunctionRevertedError,
4
+ ContractFunctionZeroDataError,
5
+ type Address,
6
+ type Client,
7
+ type GetContractReturnType,
8
+ type PublicClient,
9
+ getContract,
10
+ zeroAddress,
11
+ } from 'viem';
12
+ import { UnimplementedFeatureError, UnsupportedFeatureError } from '../errors';
6
13
  import { multiDepositorVaultAbi } from './abis/multiDepositorVault';
7
- import { priceAndFeeCalculatorAbi } from './abis/priceAndFeeCalculator';
8
14
  import { provisionerAbi } from './abis/provisioner';
15
+ import { provisionerV2Abi } from './abis/provisionerV2';
16
+ import { MAX_BPS } from '../constants';
17
+ import { ContractVersion, type EvmVaultDeployment } from './types';
18
+
19
+ const contractVersionCache = new Map<string, ContractVersion>();
20
+
21
+ const contractVersionAbi = [
22
+ {
23
+ type: 'function',
24
+ inputs: [],
25
+ name: 'version',
26
+ outputs: [{ name: '', internalType: 'string', type: 'string' }],
27
+ stateMutability: 'view',
28
+ },
29
+ ] as const;
30
+
31
+ export interface AeraRuntimeContracts {
32
+ provisioner: {
33
+ address: Address;
34
+ version: ContractVersion;
35
+ };
36
+ feeCalculator: {
37
+ address: Address;
38
+ version: ContractVersion;
39
+ };
40
+ }
41
+
42
+ export interface AeraTokenModeSupport {
43
+ asyncDeposit: boolean;
44
+ asyncRedeem: boolean;
45
+ syncDeposit: boolean;
46
+ syncRedeem: boolean;
47
+ }
48
+
49
+ export function applySlippageDown(amount: bigint, slippageBps: number): bigint {
50
+ return (amount * (MAX_BPS - BigInt(slippageBps))) / MAX_BPS;
51
+ }
52
+
53
+ export function applySlippageUp(amount: bigint, slippageBps: number): bigint {
54
+ return (amount * (MAX_BPS + BigInt(slippageBps)) + MAX_BPS - 1n) / MAX_BPS;
55
+ }
56
+
57
+ function contractVersionCacheKey(client: PublicClient, address: Address): string {
58
+ return `${client.chain?.id ?? 'unknown'}:${address.toLowerCase()}`;
59
+ }
60
+
61
+ function isVersionUnavailableError(error: unknown): boolean {
62
+ if (!(error instanceof ContractFunctionExecutionError) || error.functionName !== 'version') {
63
+ return false;
64
+ }
65
+
66
+ if (error.cause instanceof ContractFunctionRevertedError) {
67
+ const hasDecodedError =
68
+ error.cause.signature !== undefined ||
69
+ error.cause.data !== undefined ||
70
+ (error.cause.raw !== undefined && error.cause.raw !== '0x');
71
+
72
+ return (
73
+ !hasDecodedError &&
74
+ (error.cause.reason === undefined || error.cause.reason === 'execution reverted')
75
+ );
76
+ }
77
+
78
+ return error.cause instanceof ContractFunctionZeroDataError;
79
+ }
9
80
 
10
81
  export type MultiDepositorVaultContract<T extends Client> = GetContractReturnType<
11
82
  typeof multiDepositorVaultAbi,
@@ -24,59 +95,109 @@ export function getMultiDepositorVault<T extends Client>(
24
95
  });
25
96
  }
26
97
 
27
- export type PriceAndFeeCalculatorContract<T extends Client> = GetContractReturnType<
28
- typeof priceAndFeeCalculatorAbi,
29
- T,
30
- Address
31
- >;
32
-
33
- export function getPriceAndFeeCalculator<T extends Client>(
34
- client: T,
98
+ export async function resolveContractVersion(
99
+ client: PublicClient,
35
100
  address: Address
36
- ): PriceAndFeeCalculatorContract<T> {
37
- return getContract({
38
- address,
39
- abi: priceAndFeeCalculatorAbi,
40
- client,
41
- });
101
+ ): Promise<ContractVersion> {
102
+ const cacheKey = contractVersionCacheKey(client, address);
103
+ const cached = contractVersionCache.get(cacheKey);
104
+ if (cached) return cached;
105
+
106
+ try {
107
+ const versionString = await client.readContract({
108
+ address,
109
+ abi: contractVersionAbi,
110
+ functionName: 'version',
111
+ });
112
+ const version = versionString.startsWith('2.') ? ContractVersion.V2 : ContractVersion.V1;
113
+ contractVersionCache.set(cacheKey, version);
114
+
115
+ return version;
116
+ } catch (error) {
117
+ if (!isVersionUnavailableError(error)) throw error;
118
+
119
+ contractVersionCache.set(cacheKey, ContractVersion.V1);
120
+ return ContractVersion.V1;
121
+ }
42
122
  }
43
123
 
44
- export function requestDepositTxRequest(
45
- provisioner: Address,
46
- token: Address,
47
- tokensIn: bigint,
48
- minUnitsOut: bigint,
49
- solverTip: bigint,
50
- deadline: bigint,
51
- maxPriceAge: bigint,
52
- isFixedPrice: boolean,
53
- account: Address
54
- ) {
124
+ export async function resolveAeraRuntimeContracts(
125
+ client: PublicClient,
126
+ vault: EvmVaultDeployment
127
+ ): Promise<AeraRuntimeContracts> {
128
+ if (vault.vaultType !== 'multi-depositor') {
129
+ throw new UnimplementedFeatureError('Aera: single depositor vaults');
130
+ }
131
+
132
+ const [provisionerAddress, feeCalculatorAddress] = await Promise.all([
133
+ client.readContract({
134
+ address: vault.vaultAddress,
135
+ abi: multiDepositorVaultAbi,
136
+ functionName: 'provisioner',
137
+ }),
138
+ client.readContract({
139
+ address: vault.vaultAddress,
140
+ abi: multiDepositorVaultAbi,
141
+ functionName: 'feeCalculator',
142
+ }),
143
+ ]);
144
+
145
+ if (provisionerAddress === zeroAddress) {
146
+ throw new UnsupportedFeatureError('Aera: vault without provisioner');
147
+ }
148
+ if (feeCalculatorAddress === zeroAddress) {
149
+ throw new UnsupportedFeatureError('Aera: vault without price and fee calculator');
150
+ }
151
+
152
+ const [provisionerVersion, feeCalculatorVersion] = await Promise.all([
153
+ resolveContractVersion(client, provisionerAddress),
154
+ resolveContractVersion(client, feeCalculatorAddress),
155
+ ]);
156
+
55
157
  return {
56
- address: provisioner,
57
- abi: provisionerAbi,
58
- functionName: 'requestDeposit' as const,
59
- args: [token, tokensIn, minUnitsOut, solverTip, deadline, maxPriceAge, isFixedPrice] as const,
60
- account,
158
+ provisioner: {
159
+ address: provisionerAddress,
160
+ version: provisionerVersion,
161
+ },
162
+ feeCalculator: {
163
+ address: feeCalculatorAddress,
164
+ version: feeCalculatorVersion,
165
+ },
61
166
  };
62
167
  }
63
168
 
64
- export function requestRedeemTxRequest(
65
- provisioner: Address,
66
- token: Address,
67
- unitsIn: bigint,
68
- minTokenOut: bigint,
69
- solverTip: bigint,
70
- deadline: bigint,
71
- maxPriceAge: bigint,
72
- isFixedPrice: boolean,
73
- account: Address
74
- ) {
75
- return {
76
- address: provisioner,
169
+ export async function resolveAeraTokenModeSupport(
170
+ client: PublicClient,
171
+ runtime: AeraRuntimeContracts,
172
+ token: Address
173
+ ): Promise<AeraTokenModeSupport> {
174
+ if (runtime.provisioner.version === ContractVersion.V2) {
175
+ const tokenDetails = await client.readContract({
176
+ address: runtime.provisioner.address,
177
+ abi: provisionerV2Abi,
178
+ functionName: 'tokensDetails',
179
+ args: [token],
180
+ });
181
+
182
+ return {
183
+ asyncDeposit: Boolean(tokenDetails[0]),
184
+ asyncRedeem: Boolean(tokenDetails[1]),
185
+ syncDeposit: Boolean(tokenDetails[2]),
186
+ syncRedeem: Boolean(tokenDetails[3]),
187
+ };
188
+ }
189
+
190
+ const tokenDetails = await client.readContract({
191
+ address: runtime.provisioner.address,
77
192
  abi: provisionerAbi,
78
- functionName: 'requestRedeem' as const,
79
- args: [token, unitsIn, minTokenOut, solverTip, deadline, maxPriceAge, isFixedPrice] as const,
80
- account,
193
+ functionName: 'tokensDetails',
194
+ args: [token],
195
+ });
196
+
197
+ return {
198
+ asyncDeposit: Boolean(tokenDetails[0]),
199
+ asyncRedeem: Boolean(tokenDetails[1]),
200
+ syncDeposit: false,
201
+ syncRedeem: false,
81
202
  };
82
203
  }