@paxoslabs/amplify-sdk 0.0.1-alpha.1

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 (80) hide show
  1. package/CHANGELOG.md +112 -0
  2. package/LICENSE +28 -0
  3. package/README.md +533 -0
  4. package/dist/amplify-sdk-api-B5hBTGrB.d.ts +258 -0
  5. package/dist/amplify-sdk-api-DPrRhynk.d.mts +258 -0
  6. package/dist/chunk-3I3PYX2F.js +45 -0
  7. package/dist/chunk-3I3PYX2F.js.map +1 -0
  8. package/dist/chunk-7RWWVUHP.mjs +39 -0
  9. package/dist/chunk-7RWWVUHP.mjs.map +1 -0
  10. package/dist/chunk-AFWUOS3M.js +15 -0
  11. package/dist/chunk-AFWUOS3M.js.map +1 -0
  12. package/dist/chunk-BDXS57YH.js +828 -0
  13. package/dist/chunk-BDXS57YH.js.map +1 -0
  14. package/dist/chunk-FYNPQXCR.mjs +46 -0
  15. package/dist/chunk-FYNPQXCR.mjs.map +1 -0
  16. package/dist/chunk-GE2VQUPP.mjs +228 -0
  17. package/dist/chunk-GE2VQUPP.mjs.map +1 -0
  18. package/dist/chunk-ICKDAKVS.js +16 -0
  19. package/dist/chunk-ICKDAKVS.js.map +1 -0
  20. package/dist/chunk-ISO6Z7LD.mjs +809 -0
  21. package/dist/chunk-ISO6Z7LD.mjs.map +1 -0
  22. package/dist/chunk-ITB7FXG4.js +14 -0
  23. package/dist/chunk-ITB7FXG4.js.map +1 -0
  24. package/dist/chunk-J3662HYT.mjs +29 -0
  25. package/dist/chunk-J3662HYT.mjs.map +1 -0
  26. package/dist/chunk-JLXNOGZB.js +2061 -0
  27. package/dist/chunk-JLXNOGZB.js.map +1 -0
  28. package/dist/chunk-O5P6SP2O.js +233 -0
  29. package/dist/chunk-O5P6SP2O.js.map +1 -0
  30. package/dist/chunk-R663BFAZ.mjs +14 -0
  31. package/dist/chunk-R663BFAZ.mjs.map +1 -0
  32. package/dist/chunk-RUIAH5HY.js +32 -0
  33. package/dist/chunk-RUIAH5HY.js.map +1 -0
  34. package/dist/chunk-SIR2TCAR.mjs +13 -0
  35. package/dist/chunk-SIR2TCAR.mjs.map +1 -0
  36. package/dist/chunk-XXHRCCZS.mjs +11 -0
  37. package/dist/chunk-XXHRCCZS.mjs.map +1 -0
  38. package/dist/chunk-ZSFIOWWT.js +49 -0
  39. package/dist/chunk-ZSFIOWWT.js.map +1 -0
  40. package/dist/chunk-ZZBZIDZP.mjs +2050 -0
  41. package/dist/chunk-ZZBZIDZP.mjs.map +1 -0
  42. package/dist/config-B-u3VqEX.d.mts +21 -0
  43. package/dist/config-B-u3VqEX.d.ts +21 -0
  44. package/dist/config-BQynVNDC.d.mts +101 -0
  45. package/dist/config-BQynVNDC.d.ts +101 -0
  46. package/dist/core.d.mts +152 -0
  47. package/dist/core.d.ts +152 -0
  48. package/dist/core.js +187 -0
  49. package/dist/core.js.map +1 -0
  50. package/dist/core.mjs +150 -0
  51. package/dist/core.mjs.map +1 -0
  52. package/dist/display.d.mts +25 -0
  53. package/dist/display.d.ts +25 -0
  54. package/dist/display.js +124 -0
  55. package/dist/display.js.map +1 -0
  56. package/dist/display.mjs +105 -0
  57. package/dist/display.mjs.map +1 -0
  58. package/dist/exchange-rate-CRA_CMaX.d.mts +65 -0
  59. package/dist/exchange-rate-D3_FVgqa.d.ts +65 -0
  60. package/dist/index.d.mts +3236 -0
  61. package/dist/index.d.ts +3236 -0
  62. package/dist/index.js +1115 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/index.mjs +1047 -0
  65. package/dist/index.mjs.map +1 -0
  66. package/dist/utils.d.mts +111 -0
  67. package/dist/utils.d.ts +111 -0
  68. package/dist/utils.js +51 -0
  69. package/dist/utils.js.map +1 -0
  70. package/dist/utils.mjs +17 -0
  71. package/dist/utils.mjs.map +1 -0
  72. package/dist/vault-config-BNzhv3QV.d.ts +15 -0
  73. package/dist/vault-config-BjSE7oL8.d.mts +15 -0
  74. package/dist/vaults.d.mts +6 -0
  75. package/dist/vaults.d.ts +6 -0
  76. package/dist/vaults.js +13 -0
  77. package/dist/vaults.js.map +1 -0
  78. package/dist/vaults.mjs +4 -0
  79. package/dist/vaults.mjs.map +1 -0
  80. package/package.json +142 -0
package/dist/index.mjs ADDED
@@ -0,0 +1,1047 @@
1
+ import { DEFAULT_SLIPPAGE_BPS } from './chunk-XXHRCCZS.mjs';
2
+ export { YieldType } from './chunk-XXHRCCZS.mjs';
3
+ export { getDepositExchangeRate, getWithdrawExchangeRate, isDepositSpendApproved, isWithdrawalSpendApproved } from './chunk-GE2VQUPP.mjs';
4
+ import { getRateInQuoteWithAssetDecimals, TellerAbi, getClient, BoringVaultAbi, getRateInQuoteAndSharesAndWantAssetDecimals } from './chunk-ZZBZIDZP.mjs';
5
+ import './chunk-R663BFAZ.mjs';
6
+ import { toChainId } from './chunk-J3662HYT.mjs';
7
+ import { calculateDeadline } from './chunk-SIR2TCAR.mjs';
8
+ import { WAD } from './chunk-7RWWVUHP.mjs';
9
+ import { findVaultByConfig, APIError, getAssetsFromCache, DEFAULT_APPROVAL_AMOUNT, fetchSupportedAssets, ATOMIC_QUEUE_CONTRACT_ADDRESS, DEFAULT_DEADLINE } from './chunk-ISO6Z7LD.mjs';
10
+ export { APIError, fetchSupportedAssets, fetchVaults, findVaultByConfig, getAssetsFromCache, getCache, getWithdrawSupportedAssets, initAmplifySDK, initializeCache, refreshVaultCache } from './chunk-ISO6Z7LD.mjs';
11
+ import { parseUnits, erc20Abi, hexToSignature } from 'viem';
12
+
13
+ async function prepareApproveDepositTokenTxData({
14
+ yieldType,
15
+ depositToken,
16
+ approvalAmount,
17
+ chainId
18
+ }) {
19
+ const normalizedChainId = toChainId(chainId);
20
+ try {
21
+ const config = await findVaultByConfig({
22
+ assetAddress: depositToken,
23
+ yieldType,
24
+ chainId: normalizedChainId
25
+ });
26
+ if (!config) {
27
+ throw new APIError(
28
+ `No vault found for token address ${depositToken} with yield type '${yieldType}' on chain ${normalizedChainId}. This combination may not be supported.`,
29
+ { endpoint: "prepareApproveDepositToken" }
30
+ );
31
+ }
32
+ const boringVaultAddress = config.vault.boringVaultAddress;
33
+ if (!boringVaultAddress) {
34
+ throw new APIError(
35
+ `BoringVault contract address not configured for vault ${config.id}`,
36
+ { endpoint: "prepareApproveDepositToken" }
37
+ );
38
+ }
39
+ const assets = await getAssetsFromCache({ address: depositToken });
40
+ if (assets.length === 0) {
41
+ throw new APIError(
42
+ `Asset metadata not found for token ${depositToken} on chain ${normalizedChainId}`,
43
+ { endpoint: "prepareApproveDepositToken" }
44
+ );
45
+ }
46
+ const decimals = assets[0].decimals;
47
+ const amount = approvalAmount ? parseUnits(approvalAmount, decimals) : DEFAULT_APPROVAL_AMOUNT;
48
+ return {
49
+ abi: erc20Abi,
50
+ address: depositToken,
51
+ functionName: "approve",
52
+ args: [boringVaultAddress, amount]
53
+ };
54
+ } catch (error) {
55
+ if (error instanceof APIError) {
56
+ throw error;
57
+ }
58
+ throw new APIError(
59
+ `Failed to prepare approval transaction: ${error instanceof Error ? error.message : String(error)}`,
60
+ {
61
+ endpoint: "prepareApproveDepositToken",
62
+ cause: error
63
+ }
64
+ );
65
+ }
66
+ }
67
+
68
+ // src/vaults/deposit/utils.ts
69
+ var calculateMinimumMint = (depositAmount, rate, vaultTokenDecimals, slippage) => {
70
+ const slippageValue = slippage ?? DEFAULT_SLIPPAGE_BPS;
71
+ const slippageAsBigInt = BigInt(slippageValue) * WAD.bigint / BigInt(1e4);
72
+ const minimumMint = depositAmount * WAD.bigint / rate;
73
+ const slippageAmount = minimumMint * slippageAsBigInt / WAD.bigint;
74
+ if (vaultTokenDecimals > 18) {
75
+ return (minimumMint - slippageAmount) * BigInt(10) ** (BigInt(vaultTokenDecimals) - BigInt(18));
76
+ }
77
+ return (minimumMint - slippageAmount) / BigInt(10) ** (BigInt(18) - BigInt(vaultTokenDecimals));
78
+ };
79
+
80
+ // src/vaults/deposit/deposit.ts
81
+ async function prepareDepositTxData(params) {
82
+ const {
83
+ yieldType,
84
+ depositToken,
85
+ depositAmount,
86
+ chainId,
87
+ slippage = DEFAULT_SLIPPAGE_BPS
88
+ } = params;
89
+ try {
90
+ const normalizedChainId = toChainId(chainId);
91
+ let vault;
92
+ try {
93
+ vault = await findVaultByConfig({
94
+ assetAddress: depositToken,
95
+ yieldType,
96
+ chainId: normalizedChainId
97
+ });
98
+ } catch (error) {
99
+ throw new APIError(
100
+ `Failed to resolve vault for token ${depositToken} with yield type ${yieldType} on chain ${normalizedChainId}: ${error instanceof Error ? error.message : "Unknown error"}`,
101
+ {
102
+ endpoint: "prepareDepositTransactionData",
103
+ cause: error
104
+ }
105
+ );
106
+ }
107
+ if (!vault) {
108
+ throw new APIError(
109
+ `No vault found for token address ${depositToken} with yield type '${yieldType}' on chain ${normalizedChainId}. This combination may not be supported.`,
110
+ {
111
+ endpoint: "prepareDepositTransactionData"
112
+ }
113
+ );
114
+ }
115
+ let asset = null;
116
+ const assets = await getAssetsFromCache({ address: depositToken });
117
+ if (assets.length > 0) {
118
+ asset = assets.find((a) => a.chains.includes(normalizedChainId)) || assets[0] || null;
119
+ }
120
+ if (!asset) {
121
+ throw new APIError(
122
+ `Asset metadata not found for token ${depositToken} on chain ${normalizedChainId}`,
123
+ {
124
+ endpoint: "prepareDepositTransactionData"
125
+ }
126
+ );
127
+ }
128
+ const tellerAddress = vault.vault.tellerAddress;
129
+ const accountantAddress = vault.vault.accountantAddress;
130
+ const depositAssetAddress = asset.address;
131
+ const [depositAssetDecimalsResult, rateInQuoteResult] = await getRateInQuoteWithAssetDecimals({
132
+ assetAddress: depositAssetAddress,
133
+ accountantAddress,
134
+ chainId: normalizedChainId
135
+ });
136
+ if (depositAssetDecimalsResult.status === "failure") {
137
+ throw new APIError(
138
+ `Failed to get asset decimals: ${depositAssetDecimalsResult.error?.message || "Unknown error"}`,
139
+ {
140
+ endpoint: "prepareDepositTransactionData",
141
+ cause: depositAssetDecimalsResult.error
142
+ }
143
+ );
144
+ }
145
+ if (rateInQuoteResult.status === "failure") {
146
+ throw new APIError(
147
+ `Failed to get exchange rate: ${rateInQuoteResult.error?.message || "Unknown error"}`,
148
+ {
149
+ endpoint: "prepareDepositTransactionData",
150
+ cause: rateInQuoteResult.error
151
+ }
152
+ );
153
+ }
154
+ const depositAmountAsBigInt = parseUnits(
155
+ depositAmount,
156
+ depositAssetDecimalsResult.result
157
+ );
158
+ const vaultSharesAssets = await fetchSupportedAssets({
159
+ address: vault.vault.boringVaultAddress
160
+ });
161
+ if (vaultSharesAssets.length === 0) {
162
+ throw new APIError(
163
+ `Vault shares token not found in supported assets: ${vault.vault.boringVaultAddress}`,
164
+ { endpoint: "prepareDepositTransactionData" }
165
+ );
166
+ }
167
+ const minimumMint = calculateMinimumMint(
168
+ depositAmountAsBigInt,
169
+ rateInQuoteResult.result,
170
+ depositAssetDecimalsResult.result,
171
+ slippage
172
+ );
173
+ return {
174
+ abi: TellerAbi,
175
+ address: tellerAddress,
176
+ functionName: "deposit",
177
+ args: [depositAssetAddress, depositAmountAsBigInt, minimumMint],
178
+ chainId: normalizedChainId
179
+ };
180
+ } catch (error) {
181
+ if (error instanceof APIError) {
182
+ throw error;
183
+ }
184
+ throw new APIError(
185
+ `Failed to prepare deposit transaction: ${error instanceof Error ? error.message : String(error)}`,
186
+ {
187
+ endpoint: "prepareDepositTransactionData",
188
+ cause: error
189
+ }
190
+ );
191
+ }
192
+ }
193
+
194
+ // src/abi/erc2612-abi.ts
195
+ var erc2612Abi = [
196
+ // Standard ERC20 functions (subset needed for permit flow)
197
+ {
198
+ constant: true,
199
+ inputs: [{ name: "_owner", type: "address" }],
200
+ name: "nonces",
201
+ outputs: [{ name: "", type: "uint256" }],
202
+ type: "function"
203
+ },
204
+ {
205
+ constant: true,
206
+ inputs: [],
207
+ name: "DOMAIN_SEPARATOR",
208
+ outputs: [{ name: "", type: "bytes32" }],
209
+ type: "function"
210
+ },
211
+ {
212
+ constant: false,
213
+ inputs: [
214
+ { name: "owner", type: "address" },
215
+ { name: "spender", type: "address" },
216
+ { name: "value", type: "uint256" },
217
+ { name: "deadline", type: "uint256" },
218
+ { name: "v", type: "uint8" },
219
+ { name: "r", type: "bytes32" },
220
+ { name: "s", type: "bytes32" }
221
+ ],
222
+ name: "permit",
223
+ outputs: [],
224
+ type: "function"
225
+ },
226
+ {
227
+ constant: true,
228
+ inputs: [],
229
+ name: "name",
230
+ outputs: [{ name: "", type: "string" }],
231
+ type: "function"
232
+ },
233
+ {
234
+ constant: true,
235
+ inputs: [],
236
+ name: "version",
237
+ outputs: [{ name: "", type: "string" }],
238
+ type: "function"
239
+ }
240
+ ];
241
+
242
+ // src/vaults/deposit/deposit-with-permit.ts
243
+ var PERMIT_TYPES = {
244
+ Permit: [
245
+ { name: "owner", type: "address" },
246
+ { name: "spender", type: "address" },
247
+ { name: "value", type: "uint256" },
248
+ { name: "nonce", type: "uint256" },
249
+ { name: "deadline", type: "uint256" }
250
+ ]
251
+ };
252
+ async function prepareDepositPermitSignature(params) {
253
+ const {
254
+ yieldType,
255
+ depositToken,
256
+ depositAmount,
257
+ recipientAddress,
258
+ chainId,
259
+ deadline
260
+ } = params;
261
+ try {
262
+ const normalizedChainId = toChainId(chainId);
263
+ let vault;
264
+ try {
265
+ vault = await findVaultByConfig({
266
+ assetAddress: depositToken,
267
+ yieldType,
268
+ chainId: normalizedChainId
269
+ });
270
+ } catch (error) {
271
+ throw new APIError(
272
+ `Failed to resolve vault for token ${depositToken} with yield type ${yieldType} on chain ${normalizedChainId}: ${error instanceof Error ? error.message : "Unknown error"}`,
273
+ {
274
+ endpoint: "prepareDepositPermitSignature",
275
+ cause: error
276
+ }
277
+ );
278
+ }
279
+ if (!vault) {
280
+ throw new APIError(
281
+ `No vault found for token address ${depositToken} with yield type '${yieldType}' on chain ${normalizedChainId}. This combination may not be supported.`,
282
+ {
283
+ endpoint: "prepareDepositPermitSignature"
284
+ }
285
+ );
286
+ }
287
+ const tellerAddress = vault.vault.tellerAddress;
288
+ const client = await getClient(normalizedChainId);
289
+ let tokenName;
290
+ let tokenVersion;
291
+ let nonce;
292
+ try {
293
+ const [nameResult, versionResult, nonceResult] = await Promise.allSettled(
294
+ [
295
+ client.readContract({
296
+ address: depositToken,
297
+ abi: erc2612Abi,
298
+ functionName: "name"
299
+ }),
300
+ client.readContract({
301
+ address: depositToken,
302
+ abi: erc2612Abi,
303
+ functionName: "version"
304
+ }),
305
+ client.readContract({
306
+ address: depositToken,
307
+ abi: erc2612Abi,
308
+ functionName: "nonces",
309
+ args: [recipientAddress]
310
+ })
311
+ ]
312
+ );
313
+ if (nameResult.status === "fulfilled") {
314
+ tokenName = nameResult.value;
315
+ } else {
316
+ throw new APIError(`Failed to read token name from ${depositToken}`, {
317
+ endpoint: "prepareDepositPermitSignature",
318
+ cause: nameResult.reason
319
+ });
320
+ }
321
+ if (versionResult.status === "fulfilled") {
322
+ tokenVersion = versionResult.value;
323
+ } else {
324
+ tokenVersion = "1";
325
+ }
326
+ if (nonceResult.status === "fulfilled") {
327
+ nonce = nonceResult.value;
328
+ } else {
329
+ throw new APIError(
330
+ `Token ${depositToken} does not support EIP-2612 permit. Missing required function: nonces()`,
331
+ {
332
+ endpoint: "prepareDepositPermitSignature",
333
+ cause: nonceResult.reason
334
+ }
335
+ );
336
+ }
337
+ } catch (error) {
338
+ if (error instanceof APIError) {
339
+ throw error;
340
+ }
341
+ throw new APIError(
342
+ `Failed to read token metadata: ${error instanceof Error ? error.message : "Unknown error"}`,
343
+ {
344
+ endpoint: "prepareDepositPermitSignature",
345
+ cause: error
346
+ }
347
+ );
348
+ }
349
+ const permitDeadline = deadline ?? BigInt(Math.floor(Date.now() / 1e3) + 3600);
350
+ const assets = await fetchSupportedAssets({ address: depositToken });
351
+ if (assets.length === 0) {
352
+ throw new APIError(`Asset metadata not found for token ${depositToken}`, {
353
+ endpoint: "prepareDepositPermitSignature"
354
+ });
355
+ }
356
+ const asset = assets[0];
357
+ const value = parseUnits(depositAmount, asset.decimals);
358
+ const domain = {
359
+ name: tokenName,
360
+ version: tokenVersion,
361
+ chainId: normalizedChainId,
362
+ verifyingContract: depositToken
363
+ };
364
+ const message = {
365
+ owner: recipientAddress,
366
+ spender: tellerAddress,
367
+ value,
368
+ nonce,
369
+ deadline: permitDeadline
370
+ };
371
+ return {
372
+ domain,
373
+ message,
374
+ primaryType: "Permit",
375
+ types: PERMIT_TYPES
376
+ };
377
+ } catch (error) {
378
+ if (error instanceof APIError) {
379
+ throw error;
380
+ }
381
+ throw new APIError(
382
+ `Failed to prepare permit signature: ${error instanceof Error ? error.message : String(error)}`,
383
+ {
384
+ endpoint: "prepareDepositPermitSignature",
385
+ cause: error
386
+ }
387
+ );
388
+ }
389
+ }
390
+ function parsePermitSignature(signature) {
391
+ try {
392
+ const parsed = hexToSignature(signature);
393
+ let v;
394
+ if (parsed.v !== void 0) {
395
+ v = Number(parsed.v);
396
+ } else if (parsed.yParity !== void 0) {
397
+ v = parsed.yParity + 27;
398
+ } else {
399
+ v = 27;
400
+ }
401
+ return {
402
+ v,
403
+ r: parsed.r,
404
+ s: parsed.s
405
+ };
406
+ } catch (error) {
407
+ throw new APIError(
408
+ `Invalid permit signature format. Expected hex string but received: ${signature}. ${error instanceof Error ? error.message : "Unknown error"}`,
409
+ {
410
+ endpoint: "parsePermitSignature",
411
+ cause: error
412
+ }
413
+ );
414
+ }
415
+ }
416
+ async function prepareDepositWithPermitTransactionData(params) {
417
+ const {
418
+ yieldType,
419
+ depositToken,
420
+ depositAmount,
421
+ chainId,
422
+ signature,
423
+ deadline,
424
+ slippage = DEFAULT_SLIPPAGE_BPS
425
+ } = params;
426
+ try {
427
+ const { v, r, s } = parsePermitSignature(signature);
428
+ if (slippage < 0 || slippage > 1e4) {
429
+ throw new APIError(
430
+ `Invalid slippage value: ${slippage}. Slippage must be between 0 and 10000 basis points.`,
431
+ {
432
+ endpoint: "prepareDepositWithPermitTransactionData"
433
+ }
434
+ );
435
+ }
436
+ const normalizedChainId = toChainId(chainId);
437
+ let vault;
438
+ try {
439
+ vault = await findVaultByConfig({
440
+ assetAddress: depositToken,
441
+ yieldType,
442
+ chainId: normalizedChainId
443
+ });
444
+ } catch (error) {
445
+ throw new APIError(
446
+ `Failed to resolve vault for token ${depositToken} with yield type ${yieldType} on chain ${normalizedChainId}: ${error instanceof Error ? error.message : "Unknown error"}`,
447
+ {
448
+ endpoint: "prepareDepositWithPermitTransactionData",
449
+ cause: error
450
+ }
451
+ );
452
+ }
453
+ if (!vault) {
454
+ throw new APIError(
455
+ `No vault found for token address ${depositToken} with yield type '${yieldType}' on chain ${normalizedChainId}. This combination may not be supported.`,
456
+ {
457
+ endpoint: "prepareDepositWithPermitTransactionData"
458
+ }
459
+ );
460
+ }
461
+ let asset = null;
462
+ const assets = await fetchSupportedAssets({ address: depositToken });
463
+ if (assets.length > 0) {
464
+ asset = assets.find((a) => a.chains.includes(normalizedChainId)) || assets[0] || null;
465
+ }
466
+ if (!asset) {
467
+ throw new APIError(
468
+ `Asset metadata not found for token ${depositToken} on chain ${normalizedChainId}`,
469
+ {
470
+ endpoint: "prepareDepositWithPermitTransactionData"
471
+ }
472
+ );
473
+ }
474
+ if (!asset.chains || !asset.chains.includes(normalizedChainId)) {
475
+ throw new APIError(
476
+ `Token ${asset.symbol || depositToken} not supported on chain ${normalizedChainId}`,
477
+ {
478
+ endpoint: "prepareDepositWithPermitTransactionData"
479
+ }
480
+ );
481
+ }
482
+ const tellerAddress = vault.vault.tellerAddress;
483
+ const accountantAddress = vault.vault.accountantAddress;
484
+ const depositAssetAddress = asset.address;
485
+ const [depositAssetDecimalsResult, rateInQuoteResult] = await getRateInQuoteWithAssetDecimals({
486
+ assetAddress: depositAssetAddress,
487
+ accountantAddress,
488
+ chainId: normalizedChainId
489
+ });
490
+ if (depositAssetDecimalsResult.status === "failure") {
491
+ throw new APIError(
492
+ `Failed to get asset decimals: ${depositAssetDecimalsResult.error?.message || "Unknown error"}`,
493
+ {
494
+ endpoint: "prepareDepositWithPermitTransactionData",
495
+ cause: depositAssetDecimalsResult.error
496
+ }
497
+ );
498
+ }
499
+ if (rateInQuoteResult.status === "failure") {
500
+ throw new APIError(
501
+ `Failed to get exchange rate: ${rateInQuoteResult.error?.message || "Unknown error"}`,
502
+ {
503
+ endpoint: "prepareDepositWithPermitTransactionData",
504
+ cause: rateInQuoteResult.error
505
+ }
506
+ );
507
+ }
508
+ const depositAmountAsBigInt = parseUnits(depositAmount, asset.decimals);
509
+ const vaultSharesAssets = await fetchSupportedAssets({
510
+ address: vault.vault.boringVaultAddress
511
+ });
512
+ if (vaultSharesAssets.length === 0) {
513
+ throw new APIError(
514
+ `Vault shares token not found in supported assets: ${vault.vault.boringVaultAddress}`,
515
+ { endpoint: "prepareDepositWithPermitTransactionData" }
516
+ );
517
+ }
518
+ const minimumMint = calculateMinimumMint(
519
+ depositAmountAsBigInt,
520
+ rateInQuoteResult.result,
521
+ vaultSharesAssets[0].decimals,
522
+ slippage
523
+ );
524
+ return {
525
+ data: {
526
+ abi: TellerAbi,
527
+ functionName: "depositWithPermit",
528
+ args: [
529
+ depositAssetAddress,
530
+ depositAmountAsBigInt,
531
+ minimumMint,
532
+ deadline,
533
+ v,
534
+ r,
535
+ s
536
+ ]
537
+ },
538
+ address: tellerAddress,
539
+ chainId: normalizedChainId
540
+ };
541
+ } catch (error) {
542
+ if (error instanceof APIError) {
543
+ throw error;
544
+ }
545
+ throw new APIError(
546
+ `Failed to prepare deposit with permit transaction: ${error instanceof Error ? error.message : String(error)}`,
547
+ {
548
+ endpoint: "prepareDepositWithPermitTransactionData",
549
+ cause: error
550
+ }
551
+ );
552
+ }
553
+ }
554
+ async function prepareApproveWithdrawTxData({
555
+ yieldType,
556
+ wantAssetAddress,
557
+ withdrawAmount,
558
+ chainId
559
+ }) {
560
+ try {
561
+ const normalizedChainId = toChainId(chainId);
562
+ const config = await findVaultByConfig({
563
+ assetAddress: wantAssetAddress,
564
+ yieldType,
565
+ chainId: normalizedChainId
566
+ });
567
+ if (!config || config.chainId !== normalizedChainId) {
568
+ throw new APIError(
569
+ `Vault chain mismatch: vault is on chain ${config?.chainId}, requested chain ${normalizedChainId}`,
570
+ { endpoint: "prepareApproveWithdrawToken" }
571
+ );
572
+ }
573
+ if (!config.vault.boringVaultAddress) {
574
+ throw new APIError(
575
+ `BoringVault contract address not configured for vault ${config.id}`,
576
+ { endpoint: "prepareApproveWithdrawToken" }
577
+ );
578
+ }
579
+ const boringVaultAddress = config.vault.boringVaultAddress;
580
+ const vaultSharesAssets = await getAssetsFromCache({
581
+ address: boringVaultAddress
582
+ });
583
+ if (vaultSharesAssets.length === 0) {
584
+ throw new APIError(
585
+ `Vault shares token not found in supported assets: ${boringVaultAddress}`,
586
+ { endpoint: "prepareApproveWithdrawToken" }
587
+ );
588
+ }
589
+ const withdrawAmountAsBigInt = withdrawAmount ? parseUnits(withdrawAmount, vaultSharesAssets[0].decimals) : DEFAULT_APPROVAL_AMOUNT;
590
+ return {
591
+ abi: BoringVaultAbi,
592
+ address: boringVaultAddress,
593
+ functionName: "approve",
594
+ args: [ATOMIC_QUEUE_CONTRACT_ADDRESS, withdrawAmountAsBigInt]
595
+ };
596
+ } catch (error) {
597
+ if (error instanceof APIError) {
598
+ throw error;
599
+ }
600
+ throw new APIError(
601
+ `Failed to prepare approval transaction: ${error instanceof Error ? error.message : String(error)}`,
602
+ {
603
+ endpoint: "prepareApproveWithdrawToken",
604
+ cause: error
605
+ }
606
+ );
607
+ }
608
+ }
609
+
610
+ // src/vaults/withdraw/utils.ts
611
+ var prepareUserRequest = (offerAmount, atomicPrice, deadline) => {
612
+ const deadlineTimeStamp = calculateDeadline(deadline);
613
+ return {
614
+ deadline: deadlineTimeStamp,
615
+ atomicPrice,
616
+ offerAmount,
617
+ inSolve: false
618
+ };
619
+ };
620
+ var calculateAtomicPrice = (rateInQuote, wantAssetDecimals, slippage) => {
621
+ const wantPrecision = BigInt(10 ** wantAssetDecimals);
622
+ const slippageAsBigInt = BigInt(slippage) * wantPrecision / BigInt(1e4);
623
+ return rateInQuote * (wantPrecision - slippageAsBigInt) / wantPrecision;
624
+ };
625
+
626
+ // src/vaults/withdraw/bulk-withdraw.ts
627
+ async function prepareBulkWithdrawTxData(params) {
628
+ const {
629
+ yieldType,
630
+ wantAssetAddress,
631
+ shareAmount,
632
+ chainId,
633
+ slippage = DEFAULT_SLIPPAGE_BPS,
634
+ userAddress
635
+ } = params;
636
+ try {
637
+ const normalizedChainId = toChainId(chainId);
638
+ const vault = await findVaultByConfig({
639
+ assetAddress: wantAssetAddress,
640
+ yieldType,
641
+ chainId: normalizedChainId
642
+ });
643
+ if (vault && vault.chainId !== normalizedChainId) {
644
+ throw new APIError(
645
+ `Vault chain mismatch: vault is on chain ${vault.chainId}, requested chain ${normalizedChainId}`,
646
+ { endpoint: "prepareBulkWithdrawTransactionData" }
647
+ );
648
+ }
649
+ if (!vault || !vault.vault.boringVaultAddress) {
650
+ throw new APIError(
651
+ `BoringVault contract address not configured for vault ${vault?.vault.boringVaultAddress}`,
652
+ { endpoint: "prepareBulkWithdrawTransactionData" }
653
+ );
654
+ }
655
+ const boringVaultAddress = vault.vault.boringVaultAddress;
656
+ const accountantAddress = vault.vault.accountantAddress;
657
+ const wantAsset = await getAssetsFromCache({
658
+ address: wantAssetAddress
659
+ });
660
+ if (wantAsset.length === 0) {
661
+ throw new APIError(
662
+ `Vault shares token not found in supported assets: ${boringVaultAddress}`,
663
+ { endpoint: "prepareBulkWithdrawTransactionData" }
664
+ );
665
+ }
666
+ const [
667
+ wantAssetDecimalsResult,
668
+ sharesAssetDecimalsResult,
669
+ rateInQuoteResult
670
+ ] = await getRateInQuoteAndSharesAndWantAssetDecimals({
671
+ sharesAssetAddress: boringVaultAddress,
672
+ wantAssetAddress,
673
+ accountantAddress,
674
+ chainId: normalizedChainId
675
+ });
676
+ if (rateInQuoteResult.status === "failure" || wantAssetDecimalsResult.status === "failure" || sharesAssetDecimalsResult.status === "failure") {
677
+ throw new APIError(
678
+ `Failed to get exchange rate: ${rateInQuoteResult?.error?.message || wantAssetDecimalsResult?.error?.message || sharesAssetDecimalsResult?.error?.message}`,
679
+ {
680
+ endpoint: "prepareBulkWithdrawTransactionData",
681
+ cause: rateInQuoteResult?.error || wantAssetDecimalsResult?.error || sharesAssetDecimalsResult?.error
682
+ }
683
+ );
684
+ }
685
+ const offerAmountAsBigInt = parseUnits(
686
+ shareAmount,
687
+ sharesAssetDecimalsResult.result
688
+ );
689
+ const atomicPrice = calculateAtomicPrice(
690
+ rateInQuoteResult.result,
691
+ // rateInQuote bigint
692
+ wantAssetDecimalsResult.result,
693
+ // Want asset decimals from API
694
+ slippage
695
+ );
696
+ const minimumAssets = atomicPrice * offerAmountAsBigInt / BigInt(10 ** sharesAssetDecimalsResult.result);
697
+ return {
698
+ abi: TellerAbi,
699
+ address: vault.vault.tellerAddress,
700
+ functionName: "bulkWithdraw",
701
+ args: [wantAssetAddress, offerAmountAsBigInt, minimumAssets, userAddress],
702
+ chainId: normalizedChainId
703
+ };
704
+ } catch (error) {
705
+ if (error instanceof APIError) {
706
+ throw error;
707
+ }
708
+ throw new APIError(
709
+ `Failed to prepare withdrawal transaction: ${error instanceof Error ? error.message : String(error)}`,
710
+ {
711
+ endpoint: "prepareBulkWithdrawTransactionData",
712
+ cause: error
713
+ }
714
+ );
715
+ }
716
+ }
717
+
718
+ // src/abi/atomic-queue-abi.ts
719
+ var AtomicQueueAbi = [
720
+ {
721
+ type: "function",
722
+ name: "getUserAtomicRequest",
723
+ inputs: [
724
+ { name: "user", type: "address", internalType: "address" },
725
+ { name: "offer", type: "address", internalType: "contract ERC20" },
726
+ { name: "want", type: "address", internalType: "contract ERC20" }
727
+ ],
728
+ outputs: [
729
+ {
730
+ name: "",
731
+ type: "tuple",
732
+ internalType: "struct AtomicQueue.AtomicRequest",
733
+ components: [
734
+ { name: "deadline", type: "uint64", internalType: "uint64" },
735
+ { name: "atomicPrice", type: "uint88", internalType: "uint88" },
736
+ { name: "offerAmount", type: "uint96", internalType: "uint96" },
737
+ { name: "inSolve", type: "bool", internalType: "bool" }
738
+ ]
739
+ }
740
+ ],
741
+ stateMutability: "view"
742
+ },
743
+ {
744
+ type: "function",
745
+ name: "isAtomicRequestValid",
746
+ inputs: [
747
+ { name: "offer", type: "address", internalType: "contract ERC20" },
748
+ { name: "user", type: "address", internalType: "address" },
749
+ {
750
+ name: "userRequest",
751
+ type: "tuple",
752
+ internalType: "struct AtomicQueue.AtomicRequest",
753
+ components: [
754
+ { name: "deadline", type: "uint64", internalType: "uint64" },
755
+ { name: "atomicPrice", type: "uint88", internalType: "uint88" },
756
+ { name: "offerAmount", type: "uint96", internalType: "uint96" },
757
+ { name: "inSolve", type: "bool", internalType: "bool" }
758
+ ]
759
+ }
760
+ ],
761
+ outputs: [{ name: "", type: "bool", internalType: "bool" }],
762
+ stateMutability: "view"
763
+ },
764
+ {
765
+ type: "function",
766
+ name: "solve",
767
+ inputs: [
768
+ { name: "offer", type: "address", internalType: "contract ERC20" },
769
+ { name: "want", type: "address", internalType: "contract ERC20" },
770
+ { name: "users", type: "address[]", internalType: "address[]" },
771
+ { name: "runData", type: "bytes", internalType: "bytes" },
772
+ { name: "solver", type: "address", internalType: "address" }
773
+ ],
774
+ outputs: [],
775
+ stateMutability: "nonpayable"
776
+ },
777
+ {
778
+ type: "function",
779
+ name: "updateAtomicRequest",
780
+ inputs: [
781
+ { name: "offer", type: "address", internalType: "contract ERC20" },
782
+ { name: "want", type: "address", internalType: "contract ERC20" },
783
+ {
784
+ name: "userRequest",
785
+ type: "tuple",
786
+ internalType: "struct AtomicQueue.AtomicRequest",
787
+ components: [
788
+ { name: "deadline", type: "uint64", internalType: "uint64" },
789
+ { name: "atomicPrice", type: "uint88", internalType: "uint88" },
790
+ { name: "offerAmount", type: "uint96", internalType: "uint96" },
791
+ { name: "inSolve", type: "bool", internalType: "bool" }
792
+ ]
793
+ }
794
+ ],
795
+ outputs: [],
796
+ stateMutability: "nonpayable"
797
+ },
798
+ {
799
+ type: "function",
800
+ name: "userAtomicRequest",
801
+ inputs: [
802
+ { name: "", type: "address", internalType: "address" },
803
+ { name: "", type: "address", internalType: "contract ERC20" },
804
+ { name: "", type: "address", internalType: "contract ERC20" }
805
+ ],
806
+ outputs: [
807
+ { name: "deadline", type: "uint64", internalType: "uint64" },
808
+ { name: "atomicPrice", type: "uint88", internalType: "uint88" },
809
+ { name: "offerAmount", type: "uint96", internalType: "uint96" },
810
+ { name: "inSolve", type: "bool", internalType: "bool" }
811
+ ],
812
+ stateMutability: "view"
813
+ },
814
+ {
815
+ type: "function",
816
+ name: "viewSolveMetaData",
817
+ inputs: [
818
+ { name: "offer", type: "address", internalType: "contract ERC20" },
819
+ { name: "want", type: "address", internalType: "contract ERC20" },
820
+ { name: "users", type: "address[]", internalType: "address[]" }
821
+ ],
822
+ outputs: [
823
+ {
824
+ name: "metaData",
825
+ type: "tuple[]",
826
+ internalType: "struct AtomicQueue.SolveMetaData[]",
827
+ components: [
828
+ { name: "user", type: "address", internalType: "address" },
829
+ { name: "flags", type: "uint8", internalType: "uint8" },
830
+ { name: "assetsToOffer", type: "uint256", internalType: "uint256" },
831
+ { name: "assetsForWant", type: "uint256", internalType: "uint256" }
832
+ ]
833
+ },
834
+ { name: "totalAssetsForWant", type: "uint256", internalType: "uint256" },
835
+ { name: "totalAssetsToOffer", type: "uint256", internalType: "uint256" }
836
+ ],
837
+ stateMutability: "view"
838
+ },
839
+ {
840
+ type: "event",
841
+ name: "AtomicRequestFulfilled",
842
+ inputs: [
843
+ {
844
+ name: "user",
845
+ type: "address",
846
+ indexed: false,
847
+ internalType: "address"
848
+ },
849
+ {
850
+ name: "offerToken",
851
+ type: "address",
852
+ indexed: false,
853
+ internalType: "address"
854
+ },
855
+ {
856
+ name: "wantToken",
857
+ type: "address",
858
+ indexed: false,
859
+ internalType: "address"
860
+ },
861
+ {
862
+ name: "offerAmountSpent",
863
+ type: "uint256",
864
+ indexed: false,
865
+ internalType: "uint256"
866
+ },
867
+ {
868
+ name: "wantAmountReceived",
869
+ type: "uint256",
870
+ indexed: false,
871
+ internalType: "uint256"
872
+ },
873
+ {
874
+ name: "timestamp",
875
+ type: "uint256",
876
+ indexed: false,
877
+ internalType: "uint256"
878
+ }
879
+ ],
880
+ anonymous: false
881
+ },
882
+ {
883
+ type: "event",
884
+ name: "AtomicRequestUpdated",
885
+ inputs: [
886
+ {
887
+ name: "user",
888
+ type: "address",
889
+ indexed: false,
890
+ internalType: "address"
891
+ },
892
+ {
893
+ name: "offerToken",
894
+ type: "address",
895
+ indexed: false,
896
+ internalType: "address"
897
+ },
898
+ {
899
+ name: "wantToken",
900
+ type: "address",
901
+ indexed: false,
902
+ internalType: "address"
903
+ },
904
+ {
905
+ name: "amount",
906
+ type: "uint256",
907
+ indexed: false,
908
+ internalType: "uint256"
909
+ },
910
+ {
911
+ name: "deadline",
912
+ type: "uint256",
913
+ indexed: false,
914
+ internalType: "uint256"
915
+ },
916
+ {
917
+ name: "minPrice",
918
+ type: "uint256",
919
+ indexed: false,
920
+ internalType: "uint256"
921
+ },
922
+ {
923
+ name: "timestamp",
924
+ type: "uint256",
925
+ indexed: false,
926
+ internalType: "uint256"
927
+ }
928
+ ],
929
+ anonymous: false
930
+ },
931
+ {
932
+ type: "error",
933
+ name: "AtomicQueue__RequestDeadlineExceeded",
934
+ inputs: [{ name: "user", type: "address", internalType: "address" }]
935
+ },
936
+ {
937
+ type: "error",
938
+ name: "AtomicQueue__UserNotInSolve",
939
+ inputs: [{ name: "user", type: "address", internalType: "address" }]
940
+ },
941
+ {
942
+ type: "error",
943
+ name: "AtomicQueue__UserRepeated",
944
+ inputs: [{ name: "user", type: "address", internalType: "address" }]
945
+ },
946
+ {
947
+ type: "error",
948
+ name: "AtomicQueue__ZeroOfferAmount",
949
+ inputs: [{ name: "user", type: "address", internalType: "address" }]
950
+ }
951
+ ];
952
+
953
+ // src/vaults/withdraw/withdraw.ts
954
+ var prepareWithdrawTxData = async ({
955
+ yieldType,
956
+ wantAssetAddress,
957
+ chainId,
958
+ offerAmount,
959
+ deadline = DEFAULT_DEADLINE,
960
+ slippage = DEFAULT_SLIPPAGE_BPS
961
+ }) => {
962
+ try {
963
+ const normalizedChainId = toChainId(chainId);
964
+ const config = await findVaultByConfig({
965
+ assetAddress: wantAssetAddress,
966
+ yieldType,
967
+ chainId: normalizedChainId
968
+ });
969
+ if (config && config.chainId !== normalizedChainId) {
970
+ throw new APIError(
971
+ `Vault chain mismatch: vault is on chain ${config.chainId}, requested chain ${normalizedChainId}`,
972
+ { endpoint: "prepareWithdrawTransactionData" }
973
+ );
974
+ }
975
+ if (!config || !config.vault.boringVaultAddress) {
976
+ throw new APIError(
977
+ `BoringVault contract address not configured for vault ${config?.id}`,
978
+ { endpoint: "prepareWithdrawTransactionData" }
979
+ );
980
+ }
981
+ if (!config.vault.accountantAddress) {
982
+ throw new APIError(
983
+ `Accountant contract address not configured for vault ${config.id}`,
984
+ { endpoint: "prepareWithdrawTransactionData" }
985
+ );
986
+ }
987
+ const boringVaultAddress = config.vault.boringVaultAddress;
988
+ const accountantAddress = config.vault.accountantAddress;
989
+ const [
990
+ wantAssetDecimalsResult,
991
+ sharesAssetDecimalsResult,
992
+ rateInQuoteResult
993
+ ] = await getRateInQuoteAndSharesAndWantAssetDecimals({
994
+ sharesAssetAddress: boringVaultAddress,
995
+ wantAssetAddress,
996
+ accountantAddress,
997
+ chainId: normalizedChainId
998
+ });
999
+ if (rateInQuoteResult?.status === "failure" || wantAssetDecimalsResult?.status === "failure" || sharesAssetDecimalsResult?.status === "failure") {
1000
+ throw new APIError(
1001
+ `Failed to get exchange rate: ${rateInQuoteResult?.error?.message || wantAssetDecimalsResult?.error?.message || sharesAssetDecimalsResult?.error?.message}`,
1002
+ {
1003
+ endpoint: "prepareWithdrawTransactionData",
1004
+ cause: rateInQuoteResult?.error || wantAssetDecimalsResult?.error || sharesAssetDecimalsResult?.error
1005
+ }
1006
+ );
1007
+ }
1008
+ const atomicPrice = calculateAtomicPrice(
1009
+ rateInQuoteResult.result,
1010
+ // rateInQuote bigint
1011
+ wantAssetDecimalsResult.result,
1012
+ // Want asset decimals from API
1013
+ slippage
1014
+ );
1015
+ const formattedOfferAmount = parseUnits(
1016
+ offerAmount,
1017
+ sharesAssetDecimalsResult.result
1018
+ );
1019
+ const userRequest = prepareUserRequest(
1020
+ formattedOfferAmount,
1021
+ atomicPrice,
1022
+ deadline
1023
+ );
1024
+ return {
1025
+ abi: AtomicQueueAbi,
1026
+ address: ATOMIC_QUEUE_CONTRACT_ADDRESS,
1027
+ functionName: "updateAtomicRequest",
1028
+ args: [boringVaultAddress, wantAssetAddress, userRequest],
1029
+ chainId: normalizedChainId
1030
+ };
1031
+ } catch (error) {
1032
+ if (error instanceof APIError) {
1033
+ throw error;
1034
+ }
1035
+ throw new APIError(
1036
+ `Failed to prepare withdrawal transaction: ${error instanceof Error ? error.message : String(error)}`,
1037
+ {
1038
+ endpoint: "prepareWithdrawTransactionData",
1039
+ cause: error
1040
+ }
1041
+ );
1042
+ }
1043
+ };
1044
+
1045
+ export { PERMIT_TYPES, parsePermitSignature, prepareApproveDepositTokenTxData, prepareApproveWithdrawTxData, prepareBulkWithdrawTxData, prepareDepositPermitSignature, prepareDepositTxData, prepareDepositWithPermitTransactionData, prepareWithdrawTxData };
1046
+ //# sourceMappingURL=index.mjs.map
1047
+ //# sourceMappingURL=index.mjs.map