@augustdigital/sdk 4.24.10 → 4.25.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 (91) hide show
  1. package/lib/adapters/solana/getters.d.ts +2 -2
  2. package/lib/adapters/solana/getters.js +36 -100
  3. package/lib/adapters/solana/getters.js.map +1 -1
  4. package/lib/adapters/solana/index.d.ts +2 -2
  5. package/lib/adapters/solana/utils.d.ts +2 -2
  6. package/lib/adapters/solana/utils.js +1 -8
  7. package/lib/adapters/solana/utils.js.map +1 -1
  8. package/lib/adapters/stellar/actions.d.ts +3 -0
  9. package/lib/adapters/stellar/actions.js +43 -0
  10. package/lib/adapters/stellar/actions.js.map +1 -0
  11. package/lib/adapters/stellar/constants.d.ts +15 -0
  12. package/lib/adapters/stellar/constants.js +22 -0
  13. package/lib/adapters/stellar/constants.js.map +1 -0
  14. package/lib/adapters/stellar/getters.d.ts +6 -0
  15. package/lib/adapters/stellar/getters.js +193 -0
  16. package/lib/adapters/stellar/getters.js.map +1 -0
  17. package/lib/adapters/stellar/index.d.ts +29 -0
  18. package/lib/adapters/stellar/index.js +85 -0
  19. package/lib/adapters/stellar/index.js.map +1 -0
  20. package/lib/adapters/stellar/soroban.d.ts +11 -0
  21. package/lib/adapters/stellar/soroban.js +106 -0
  22. package/lib/adapters/stellar/soroban.js.map +1 -0
  23. package/lib/adapters/stellar/submit.d.ts +2 -0
  24. package/lib/adapters/stellar/submit.js +50 -0
  25. package/lib/adapters/stellar/submit.js.map +1 -0
  26. package/lib/adapters/stellar/types.d.ts +19 -0
  27. package/lib/adapters/stellar/types.js +3 -0
  28. package/lib/adapters/stellar/types.js.map +1 -0
  29. package/lib/adapters/stellar/utils.d.ts +13 -0
  30. package/lib/adapters/stellar/utils.js +32 -0
  31. package/lib/adapters/stellar/utils.js.map +1 -0
  32. package/lib/adapters/sui/transformer.js +4 -9
  33. package/lib/adapters/sui/transformer.js.map +1 -1
  34. package/lib/core/base.class.d.ts +3 -2
  35. package/lib/core/base.class.js +14 -7
  36. package/lib/core/base.class.js.map +1 -1
  37. package/lib/core/constants/core.d.ts +7 -3
  38. package/lib/core/constants/core.js +4 -0
  39. package/lib/core/constants/core.js.map +1 -1
  40. package/lib/core/constants/vaults.d.ts +2 -1
  41. package/lib/core/constants/vaults.js +4 -1
  42. package/lib/core/constants/vaults.js.map +1 -1
  43. package/lib/core/constants/web3.d.ts +5 -0
  44. package/lib/core/constants/web3.js +9 -0
  45. package/lib/core/constants/web3.js.map +1 -1
  46. package/lib/core/fetcher.d.ts +5 -4
  47. package/lib/core/fetcher.js +23 -2
  48. package/lib/core/fetcher.js.map +1 -1
  49. package/lib/core/helpers/vaults.js +42 -29
  50. package/lib/core/helpers/vaults.js.map +1 -1
  51. package/lib/core/helpers/web3.d.ts +3 -2
  52. package/lib/core/helpers/web3.js +20 -4
  53. package/lib/core/helpers/web3.js.map +1 -1
  54. package/lib/index.d.ts +2 -1
  55. package/lib/index.js +1 -0
  56. package/lib/index.js.map +1 -1
  57. package/lib/main.d.ts +3 -0
  58. package/lib/main.js +3 -2
  59. package/lib/main.js.map +1 -1
  60. package/lib/modules/vaults/getters.d.ts +32 -3
  61. package/lib/modules/vaults/getters.js +651 -82
  62. package/lib/modules/vaults/getters.js.map +1 -1
  63. package/lib/modules/vaults/main.d.ts +12 -1
  64. package/lib/modules/vaults/main.js +130 -39
  65. package/lib/modules/vaults/main.js.map +1 -1
  66. package/lib/modules/vaults/types.d.ts +1 -0
  67. package/lib/modules/vaults/utils/call-data-decoder.d.ts +14 -0
  68. package/lib/modules/vaults/utils/call-data-decoder.js +138 -0
  69. package/lib/modules/vaults/utils/call-data-decoder.js.map +1 -0
  70. package/lib/modules/vaults/utils/date-utils.d.ts +11 -0
  71. package/lib/modules/vaults/utils/date-utils.js +39 -0
  72. package/lib/modules/vaults/utils/date-utils.js.map +1 -0
  73. package/lib/modules/vaults/utils.d.ts +2 -0
  74. package/lib/modules/vaults/utils.js +119 -1
  75. package/lib/modules/vaults/utils.js.map +1 -1
  76. package/lib/modules/vaults/write.actions.js +16 -2
  77. package/lib/modules/vaults/write.actions.js.map +1 -1
  78. package/lib/services/layerzero/deposits.d.ts +6 -0
  79. package/lib/services/layerzero/deposits.js +20 -2
  80. package/lib/services/layerzero/deposits.js.map +1 -1
  81. package/lib/services/layerzero/redeems.js +2 -2
  82. package/lib/services/layerzero/redeems.js.map +1 -1
  83. package/lib/services/subgraph/vaults.js +110 -50
  84. package/lib/services/subgraph/vaults.js.map +1 -1
  85. package/lib/types/vaults.d.ts +41 -8
  86. package/lib/types/vaults.js.map +1 -1
  87. package/lib/types/web3.d.ts +5 -0
  88. package/lib/types/web3.js +10 -0
  89. package/lib/types/web3.js.map +1 -1
  90. package/lib/types/webserver.d.ts +12 -2
  91. package/package.json +5 -2
@@ -38,6 +38,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.getVault = getVault;
40
40
  exports.getVaultLoans = getVaultLoans;
41
+ exports.getVaultSubaccountLoans = getVaultSubaccountLoans;
41
42
  exports.getVaultAllocations = getVaultAllocations;
42
43
  exports.getVaultAvailableRedemptions = getVaultAvailableRedemptions;
43
44
  exports.getVaultRedemptionHistory = getVaultRedemptionHistory;
@@ -57,22 +58,32 @@ exports.getVaultHistoricalTimeseries = getVaultHistoricalTimeseries;
57
58
  exports.getVaultAnnualizedApy = getVaultAnnualizedApy;
58
59
  exports.getVaultSummary = getVaultSummary;
59
60
  exports.getVaultWithdrawals = getVaultWithdrawals;
61
+ exports.getVaultPendingRedemptions = getVaultPendingRedemptions;
60
62
  exports.getPreviewRedemption = getPreviewRedemption;
63
+ exports.getWithdrawalRequestsWithStatus = getWithdrawalRequestsWithStatus;
61
64
  const abis_1 = require("../../abis");
62
65
  const types_1 = require("../../types");
63
66
  const core_1 = require("../../core");
64
67
  const ethers_1 = require("ethers");
68
+ const utils_1 = require("./utils");
65
69
  const subgraph_1 = require("../../services/subgraph");
66
70
  const vaults_1 = require("../../services/subgraph/vaults");
67
71
  const debank_1 = require("../../services/debank");
68
- const utils_1 = require("../../adapters/solana/utils");
72
+ const utils_2 = require("../../adapters/solana/utils");
69
73
  const SolanaGetters = __importStar(require("../../adapters/solana/getters"));
70
74
  const SolanaConstants = __importStar(require("../../adapters/solana/constants"));
75
+ const StellarGetters = __importStar(require("../../adapters/stellar/getters"));
76
+ const utils_3 = require("../../adapters/stellar/utils");
77
+ const constants_1 = require("../../adapters/stellar/constants");
71
78
  const EVM = __importStar(require("../../adapters/evm"));
72
79
  const TokenizedVaultV2_1 = require("../../abis/TokenizedVaultV2");
73
80
  const TokenizedVaultV2Receipt_1 = require("../../abis/TokenizedVaultV2Receipt");
74
81
  const ethereum_block_by_date_1 = __importDefault(require("ethereum-block-by-date"));
75
82
  const octavfi_1 = require("../../services/octavfi");
83
+ const date_utils_1 = require("./utils/date-utils");
84
+ const call_data_decoder_1 = require("./utils/call-data-decoder");
85
+ const deposits_1 = require("../../services/layerzero/deposits");
86
+ const redeems_1 = require("../../services/layerzero/redeems");
76
87
  async function getVault({ vault, loans = false, allocations = false, options, loadSubaccounts, loadSnapshots, }) {
77
88
  let returnedVault;
78
89
  try {
@@ -81,7 +92,12 @@ async function getVault({ vault, loans = false, allocations = false, options, lo
81
92
  const vaultVersion = (0, core_1.getVaultVersionV2)(tokenizedVault);
82
93
  switch (vaultVersion) {
83
94
  case 'sol-0': {
84
- return await SolanaGetters.getSolanaVault(tokenizedVault, options);
95
+ returnedVault = await SolanaGetters.getSolanaVault(tokenizedVault, options);
96
+ break;
97
+ }
98
+ case 'stellar-0': {
99
+ returnedVault = await StellarGetters.getStellarVault(tokenizedVault, options);
100
+ break;
85
101
  }
86
102
  case 'evm-2': {
87
103
  returnedVault = await EVM.getEvmVaultV2(tokenizedVault, options);
@@ -100,7 +116,13 @@ async function getVault({ vault, loans = false, allocations = false, options, lo
100
116
  core_1.Logger.log.error('getVault', err, { vault });
101
117
  throw new Error(`#getVault::${vault}: ${err?.message}`);
102
118
  }
103
- if (!(0, core_1.isBadVault)(vault)) {
119
+ const isEvmVault = returnedVault.version !== 'sol-0' &&
120
+ returnedVault.version !== 'stellar-0' &&
121
+ returnedVault.version !== 'sui-0';
122
+ if (!isEvmVault && (loans || allocations)) {
123
+ core_1.Logger.log.warn('getVault', 'Loans/allocations enrichment is not supported for non-EVM vaults — skipping', { vault, version: returnedVault.version });
124
+ }
125
+ if (isEvmVault && !(0, core_1.isBadVault)(vault)) {
104
126
  if (loans) {
105
127
  try {
106
128
  returnedVault = {
@@ -200,6 +222,74 @@ async function getVaultLoans(vault, options) {
200
222
  throw new Error(`#getVaultLoans::${vault}:${e?.message}`);
201
223
  }
202
224
  }
225
+ async function getVaultSubaccountLoans(vault, options) {
226
+ const vaultAddress = typeof vault === 'string' ? vault : vault.address;
227
+ const tokenizedVault = (await (0, core_1.fetchTokenizedVault)(vaultAddress))?.[0];
228
+ const vaultVersion = (0, core_1.getVaultVersionV2)(tokenizedVault);
229
+ if (vaultVersion !== 'evm-0')
230
+ return [];
231
+ try {
232
+ let poolTotalSupply;
233
+ let poolDecimals;
234
+ const tokenizedVault = (await (0, core_1.fetchTokenizedVault)(vaultAddress, options?.headers))?.[0];
235
+ const chainId = options?.chainId || tokenizedVault?.chain;
236
+ const provider = (0, core_1.createProvider)(options.rpcUrl);
237
+ const tokenizedVaultLoans = await (0, core_1.fetchTokenizedVaultSubaccountLoans)(vaultAddress, chainId);
238
+ if (typeof vault === 'string') {
239
+ const poolContract = (0, core_1.createContract)({
240
+ provider,
241
+ address: vaultAddress,
242
+ abi: abis_1.ABI_LENDING_POOL_V2,
243
+ });
244
+ [poolTotalSupply, poolDecimals] = await Promise.all([
245
+ poolContract.totalSupply(),
246
+ (0, core_1.getDecimals)(provider, vaultAddress),
247
+ ]);
248
+ poolTotalSupply = BigInt(poolTotalSupply).toString();
249
+ poolDecimals = Number(poolDecimals);
250
+ }
251
+ else {
252
+ poolTotalSupply = vault.totalSupply.raw;
253
+ poolDecimals = vault.decimals;
254
+ }
255
+ const newLoans = (await Promise.all((Array.isArray(tokenizedVaultLoans) ? tokenizedVaultLoans : [])?.map(async (l) => {
256
+ const borrower = l.borrower;
257
+ const allocation = l.principal_amount /
258
+ Number((0, ethers_1.formatUnits)(poolTotalSupply, poolDecimals));
259
+ const loanFeeRate = await (0, core_1.getLoanOracleFeeRate)(provider, 'LOAN.REPAY.INTERESTS', l.address, chainId);
260
+ const loanApr = Number(l.apr || 0) / 100;
261
+ const loanAprAfterFees = loanApr * (1 - loanFeeRate / 100);
262
+ const isIdleCapital = core_1.IDLE_CAPITAL_BORROWER_ADDRESS.includes(borrower);
263
+ const newLoanObj = {
264
+ vault: vaultAddress,
265
+ address: l.address,
266
+ lender: l.lender,
267
+ borrower: l.borrower,
268
+ state: l.state,
269
+ totalRepaid: l.total_repaid,
270
+ principalToken: l.principal_token,
271
+ principalAmount: l.principal_amount,
272
+ interestAmount: l.interest_amount,
273
+ upcomingPayment: {
274
+ amount: l.upcoming_payment.amount,
275
+ dueDate: l.upcoming_payment.due_date,
276
+ },
277
+ apr: loanAprAfterFees,
278
+ initialPrincipalAmount: l.initial_principal_amount,
279
+ deployedDate: l.deployed_date,
280
+ isIdleCapital,
281
+ paymentInterval: l.payment_interval,
282
+ allocation,
283
+ };
284
+ return newLoanObj;
285
+ }))).filter((l) => l !== undefined);
286
+ return newLoans;
287
+ }
288
+ catch (e) {
289
+ core_1.Logger.log.error('getVaultSubaccountLoans', e, { vault });
290
+ throw new Error(`#getVaultSubaccountLoans::${vault}:${e?.message}`);
291
+ }
292
+ }
203
293
  async function getVaultAllocations(vault, options) {
204
294
  const protocolExposure = [];
205
295
  const tokenExposure = [];
@@ -321,7 +411,10 @@ async function getVaultAllocations(vault, options) {
321
411
  try {
322
412
  const cefiResponse = await (0, core_1.fetchAugustWithKey)(options.augustKey, core_1.WEBSERVER_ENDPOINTS.subaccount.cefi(borrower), { headers: options?.headers });
323
413
  if (cefiResponse.status !== 200) {
324
- console.error('#getVaultAllocations::cefi:', cefiResponse.status, cefiResponse.statusText);
414
+ core_1.Logger.log.error('getVaultAllocations:cefi', cefiResponse.statusText, {
415
+ borrower,
416
+ status: cefiResponse.status,
417
+ });
325
418
  }
326
419
  if (cefiResponse.status === 200) {
327
420
  const cefiRes = (await cefiResponse.json());
@@ -329,12 +422,15 @@ async function getVaultAllocations(vault, options) {
329
422
  }
330
423
  }
331
424
  catch (e) {
332
- console.error('#getVaultAllocations::cefi:', e);
425
+ core_1.Logger.log.error('getVaultAllocations:cefi', e, { borrower });
333
426
  }
334
427
  try {
335
428
  const otcResponse = await (0, core_1.fetchAugustWithKey)(options.augustKey, core_1.WEBSERVER_ENDPOINTS.subaccount.otc_positions(borrower), { headers: options?.headers });
336
429
  if (otcResponse.status !== 200) {
337
- console.error('#getVaultAllocations::otc:', otcResponse.status, otcResponse.statusText);
430
+ core_1.Logger.log.error('getVaultAllocations:otc', otcResponse.statusText, {
431
+ borrower,
432
+ status: otcResponse.status,
433
+ });
338
434
  }
339
435
  if (otcResponse.status === 200) {
340
436
  const otcRes = (await otcResponse.json());
@@ -342,7 +438,7 @@ async function getVaultAllocations(vault, options) {
342
438
  }
343
439
  }
344
440
  catch (e) {
345
- console.error('#getVaultAllocations::otc:', e);
441
+ core_1.Logger.log.error('getVaultAllocations:otc', e, { borrower });
346
442
  }
347
443
  }
348
444
  }
@@ -369,6 +465,17 @@ async function getVaultAllocations(vault, options) {
369
465
  }
370
466
  async function getVaultAvailableRedemptions({ vault, wallet, options, }) {
371
467
  try {
468
+ if ((0, utils_3.isStellarAddress)(vault)) {
469
+ core_1.Logger.log.warn('getVaultAvailableRedemptions', `Available redemptions is not yet supported for Stellar vaults: ${vault}`);
470
+ return {
471
+ availableRedemptions: [],
472
+ pendingRedemptions: [],
473
+ ...(options.verbose && {
474
+ processedWithdrawals: [],
475
+ requestedWithdrawals: [],
476
+ }),
477
+ };
478
+ }
372
479
  const provider = (0, core_1.createProvider)(options.rpcUrl);
373
480
  const tokenizedVault = (await (0, core_1.fetchTokenizedVault)(vault, options?.headers, false, false))?.[0];
374
481
  if (!tokenizedVault) {
@@ -406,14 +513,14 @@ async function getVaultAvailableRedemptions({ vault, wallet, options, }) {
406
513
  core_1.Logger.log.warn('getVaultAvailableRedemptions', `Skipping invalid event: ${ev}`);
407
514
  continue;
408
515
  }
409
- const date = new Date(Number(ev.timestamp_) * 1000);
410
516
  let month;
411
517
  let day;
412
518
  let year;
413
519
  if (version === 'evm-2') {
414
- month = date.getMonth() + 1;
415
- day = date.getDate();
416
- year = date.getFullYear();
520
+ const claimable = (0, date_utils_1.computeClaimableDate)(Number(ev.timestamp_), lagDuration);
521
+ year = claimable.year;
522
+ month = claimable.month;
523
+ day = claimable.day;
417
524
  }
418
525
  if (!ev.year || !ev.month || !ev.day || !ev.receiverAddr) {
419
526
  if (version !== 'evm-2') {
@@ -430,22 +537,34 @@ async function getVaultAvailableRedemptions({ vault, wallet, options, }) {
430
537
  }
431
538
  }
432
539
  const fullDate = version === 'evm-2'
433
- ? new Date(Number(ev.timestamp_) * 1000)
540
+ ? new Date(Date.UTC(year, month - 1, day))
434
541
  : new Date(Number(ev.year), Number(ev.month) - 1, Number(ev.day));
435
- const foundRedemptionAgainstClaim = withdrawalProcesseds.find((h) => version === 'evm-2'
436
- ? new Date(h.timestamp_).toDateString() === fullDate.toDateString() &&
437
- h.receiverAddr === ev.receiverAddr
438
- : new Date(h.processedOn).toDateString() === fullDate.toDateString() &&
439
- h.receiverAddr === ev.receiverAddr);
542
+ const requestDateKey = version === 'evm-2'
543
+ ? (0, date_utils_1.formatDateKey)(year, month, day)
544
+ : (0, date_utils_1.formatDateKey)(Number(ev.year), Number(ev.month), Number(ev.day));
545
+ const foundRedemptionAgainstClaim = withdrawalProcesseds.find((h) => {
546
+ const proc = h;
547
+ if (proc.receiverAddr !== ev.receiverAddr)
548
+ return false;
549
+ if (version === 'evm-2') {
550
+ const procDate = new Date(Number(proc.timestamp_) * 1000);
551
+ const procKey = (0, date_utils_1.formatDateKey)(procDate.getUTCFullYear(), procDate.getUTCMonth() + 1, procDate.getUTCDate());
552
+ return procKey === requestDateKey;
553
+ }
554
+ const procDate = new Date(proc.processedOn);
555
+ const procKey = (0, date_utils_1.formatDateKey)(procDate.getUTCFullYear(), procDate.getUTCMonth() + 1, procDate.getUTCDate());
556
+ return procKey === requestDateKey;
557
+ });
440
558
  if (wallet && (0, ethers_1.isAddress)(wallet)) {
441
559
  if (ev?.receiverAddr?.toLowerCase() === wallet.toLowerCase()) {
442
560
  const alreadyRedeemed = version === 'evm-2'
443
561
  ? withdrawalProcesseds.find((red) => {
444
- if (Number(ev.timestamp_) * 1000 + lagDuration * 1000 <=
445
- 1000 * Number(red.timestamp_) &&
446
- red.receiverAddr.toLowerCase() === wallet.toLowerCase()) {
447
- return red;
562
+ if (red.receiverAddr.toLowerCase() !== wallet.toLowerCase()) {
563
+ return false;
448
564
  }
565
+ const redDate = new Date(Number(red.timestamp_) * 1000);
566
+ const redKey = (0, date_utils_1.formatDateKey)(redDate.getUTCFullYear(), redDate.getUTCMonth() + 1, redDate.getUTCDate());
567
+ return redKey === requestDateKey;
449
568
  })
450
569
  : availableRedemptions.find((red) => BigInt(red.day.raw) === BigInt(ev.day) &&
451
570
  BigInt(red.month.raw) === BigInt(ev.month) &&
@@ -461,14 +580,9 @@ async function getVaultAvailableRedemptions({ vault, wallet, options, }) {
461
580
  }
462
581
  }
463
582
  if (!alreadyRedeemed) {
464
- const pendingCondition = Number(ev.timestamp_) * 1000 + 1000 * lagDuration <
465
- Date.now();
583
+ const claimable = (0, date_utils_1.computeClaimableDate)(Number(ev.timestamp_), lagDuration);
584
+ const pendingCondition = (0, date_utils_1.isClaimableNow)(claimable.epoch, Math.floor(Date.now() / 1000));
466
585
  if (pendingCondition) {
467
- const date = new Date(Number(year), Number(month) - 1, Number(day));
468
- date.setDate(date.getDate() + lagDuration / (24 * 60 * 60));
469
- year = date.getFullYear();
470
- month = date.getMonth() + 1;
471
- day = date.getDate();
472
586
  try {
473
587
  const burnableAmount = (await vaultContract?.getBurnableAmountByReceiver?.(BigInt(year), BigInt(month), BigInt(day), (0, ethers_1.getAddress)(ev.receiverAddr))) || BigInt(0);
474
588
  const claimAmount = BigInt(ev.shares) || BigInt(0);
@@ -513,15 +627,13 @@ async function getVaultAvailableRedemptions({ vault, wallet, options, }) {
513
627
  default: {
514
628
  const trueClaimableAmount = await vaultContract?.getClaimableAmountByReceiver?.(BigInt(ev.year), BigInt(ev.month), BigInt(ev.day), (0, ethers_1.getAddress)(wallet));
515
629
  if (trueClaimableAmount > BigInt(0)) {
516
- const pendingCondition = Number(ev.timestamp_) * 1000 + 1000 * lagDuration <
517
- Date.now();
630
+ const v1Claimable = (0, date_utils_1.computeClaimableDate)(Number(ev.timestamp_), lagDuration);
631
+ const pendingCondition = (0, date_utils_1.isClaimableNow)(v1Claimable.epoch, Math.floor(Date.now() / 1000));
518
632
  if (pendingCondition) {
519
633
  try {
520
- const date = new Date(Number(ev.year), Number(ev.month) - 1, Number(ev.day));
521
- date.setDate(date.getDate() + lagDuration / (24 * 60 * 60));
522
- year = date.getFullYear();
523
- month = date.getMonth() + 1;
524
- day = date.getDate();
634
+ year = v1Claimable.year;
635
+ month = v1Claimable.month;
636
+ day = v1Claimable.day;
525
637
  const burnableAmount = (await vaultContract?.getBurnableAmountByReceiver?.(BigInt(year), BigInt(month), BigInt(day), (0, ethers_1.getAddress)(ev.receiverAddr))) || BigInt(0);
526
638
  const claimAmount = trueClaimableAmount || BigInt(0);
527
639
  if (burnableAmount >= claimAmount) {
@@ -615,58 +727,114 @@ async function getVaultAvailableRedemptions({ vault, wallet, options, }) {
615
727
  }
616
728
  async function getVaultRedemptionHistory({ vault, wallet, options, }) {
617
729
  try {
730
+ if ((0, utils_3.isStellarAddress)(vault)) {
731
+ core_1.Logger.log.warn('getVaultRedemptionHistory', `Redemption history is not yet supported for Stellar vaults: ${vault}`);
732
+ return [];
733
+ }
618
734
  const provider = (0, core_1.createProvider)(options.rpcUrl);
619
- const tokenizedVault = (await (0, core_1.fetchTokenizedVault)(vault, options?.headers))?.[0];
735
+ const tokenizedVault = (await (0, core_1.fetchTokenizedVault)(vault, options?.headers, false, false))?.[0];
620
736
  if (!tokenizedVault) {
737
+ core_1.Logger.log.warn('getVaultRedemptionHistory', `Vault not found in backend: ${vault}`);
621
738
  return [];
622
739
  }
623
740
  const chainId = tokenizedVault.chain;
741
+ const version = (0, core_1.getVaultVersionV2)(tokenizedVault);
742
+ const isV2 = version === 'evm-2';
743
+ const vaultAbi = isV2 ? TokenizedVaultV2_1.ABI_TOKENIZED_VAULT_V2 : abis_1.ABI_LENDING_POOL_V2;
624
744
  const poolContract = (0, core_1.createContract)({
625
745
  address: vault,
626
- abi: abis_1.ABI_LENDING_POOL_V2,
746
+ abi: vaultAbi,
627
747
  provider,
628
748
  });
629
- const logPromises = [];
630
749
  const currentBlock = await provider.getBlockNumber();
631
- let startingBlock = currentBlock - (0, core_1.determineBlockSkipInternal)(chainId);
632
- let endBlock = currentBlock;
750
+ const blockSkip = (0, core_1.determineBlockSkipInternal)(chainId);
633
751
  const cutoffBlock = currentBlock - (0, core_1.determineBlockCutoff)(chainId);
752
+ const BATCH_SIZE = 20;
753
+ core_1.Logger.log.info('getVaultRedemptionHistory', {
754
+ vault,
755
+ version,
756
+ isV2,
757
+ chainId,
758
+ currentBlock,
759
+ cutoffBlock,
760
+ blockSkip,
761
+ totalRangeBlocks: currentBlock - cutoffBlock,
762
+ });
763
+ const ranges = [];
764
+ let endBlock = currentBlock;
634
765
  while (endBlock >= cutoffBlock) {
635
- const logBloomsPromises = poolContract.queryFilter('WithdrawalProcessed', BigInt(startingBlock), BigInt(endBlock));
636
- logPromises.push(logBloomsPromises);
637
- startingBlock -= (0, core_1.determineBlockSkipInternal)(chainId);
638
- endBlock -= (0, core_1.determineBlockSkipInternal)(chainId);
639
- }
640
- const logs = (await Promise.all(logPromises.flat())).flat();
641
- const iface = new ethers_1.ethers.Interface([
642
- 'event WithdrawalProcessed (uint256 assetsAmount, uint256 processedOn, address receiverAddr, uint256 requestedOn)',
643
- ]);
644
- const events = logs.map((log) => iface.parseLog(log));
766
+ const fromBlock = Math.max(endBlock - blockSkip, cutoffBlock);
767
+ ranges.push({ from: fromBlock, to: endBlock });
768
+ endBlock = fromBlock - 1;
769
+ }
770
+ core_1.Logger.log.info('getVaultRedemptionHistory', {
771
+ totalBatches: Math.ceil(ranges.length / BATCH_SIZE),
772
+ totalChunks: ranges.length,
773
+ firstRange: ranges[0],
774
+ lastRange: ranges[ranges.length - 1],
775
+ });
776
+ const logs = [];
777
+ for (let i = 0; i < ranges.length; i += BATCH_SIZE) {
778
+ const batch = ranges.slice(i, i + BATCH_SIZE);
779
+ const batchResults = await Promise.all(batch.map((r) => poolContract.queryFilter('WithdrawalProcessed', BigInt(r.from), BigInt(r.to))));
780
+ const batchLogs = batchResults.flat();
781
+ logs.push(...batchLogs);
782
+ }
783
+ const iface = new ethers_1.ethers.Interface(isV2
784
+ ? [
785
+ 'event WithdrawalProcessed(uint256 assetsAmount, address indexed receiverAddr)',
786
+ ]
787
+ : [
788
+ 'event WithdrawalProcessed(uint256 assetsAmount, uint256 processedOn, address receiverAddr, uint256 requestedOn)',
789
+ ]);
645
790
  const decimals = await (0, core_1.getDecimals)(provider, vault);
791
+ let blockTimestamps;
792
+ if (isV2 && logs.length > 0) {
793
+ const uniqueBlocks = [...new Set(logs.map((l) => l.blockNumber))];
794
+ const blockResults = await Promise.all(uniqueBlocks.map((bn) => provider.getBlock(bn)));
795
+ blockTimestamps = new Map();
796
+ blockResults.forEach((block) => {
797
+ if (block)
798
+ blockTimestamps.set(block.number, block.timestamp);
799
+ });
800
+ }
646
801
  const redemptions = [];
647
- events?.forEach((ev) => {
802
+ logs.forEach((log) => {
803
+ const ev = iface.parseLog(log);
648
804
  if (!ev?.args)
649
805
  return;
650
- const [assetsAmount, processedOn, receiverAddr, requestedOn] = ev.args;
651
- if (wallet) {
652
- if (String(receiverAddr)?.toLowerCase() === wallet.toLowerCase()) {
653
- redemptions.push({
654
- receiver: receiverAddr,
655
- amount: (0, core_1.toNormalizedBn)(assetsAmount, decimals),
656
- processed: new Date(Number(processedOn) * 1000),
657
- requested: new Date(Number(requestedOn) * 1000),
658
- vault,
659
- });
660
- }
806
+ let item;
807
+ if (isV2) {
808
+ const [assetsAmount, receiverAddr] = ev.args;
809
+ const blockTs = blockTimestamps?.get(log.blockNumber) ?? 0;
810
+ const blockDate = new Date(blockTs * 1000);
811
+ item = {
812
+ receiver: receiverAddr,
813
+ amount: (0, core_1.toNormalizedBn)(assetsAmount, decimals),
814
+ processed: blockDate,
815
+ requested: new Date(0),
816
+ vault,
817
+ transactionHash: log.transactionHash,
818
+ };
661
819
  }
662
820
  else {
663
- redemptions.push({
821
+ const [assetsAmount, processedOn, receiverAddr, requestedOn] = ev.args;
822
+ item = {
664
823
  receiver: receiverAddr,
665
824
  amount: (0, core_1.toNormalizedBn)(assetsAmount, decimals),
666
825
  processed: new Date(Number(processedOn) * 1000),
667
826
  requested: new Date(Number(requestedOn) * 1000),
668
827
  vault,
669
- });
828
+ transactionHash: log.transactionHash,
829
+ };
830
+ }
831
+ if (wallet) {
832
+ if (item.receiver?.toLowerCase() === wallet.toLowerCase()) {
833
+ redemptions.push(item);
834
+ }
835
+ }
836
+ else {
837
+ redemptions.push(item);
670
838
  }
671
839
  });
672
840
  core_1.Logger.log.info('getVaultRedemptionHistory', redemptions.slice(0, 1));
@@ -677,7 +845,7 @@ async function getVaultRedemptionHistory({ vault, wallet, options, }) {
677
845
  return [];
678
846
  }
679
847
  }
680
- async function getVaultPositions({ vault, wallet, solanaWallet, options, }) {
848
+ async function getVaultPositions({ vault, wallet, solanaWallet, stellarWallet, options, }) {
681
849
  try {
682
850
  const tokenizedVaults = await (0, core_1.fetchTokenizedVault)(vault ? vault : undefined, options?.headers, false, false);
683
851
  if (!tokenizedVaults || tokenizedVaults.length === 0) {
@@ -692,10 +860,10 @@ async function getVaultPositions({ vault, wallet, solanaWallet, options, }) {
692
860
  }
693
861
  const promises = await Promise.all(tokenizedVaults.map(async (v) => {
694
862
  try {
695
- if (utils_1.SolanaUtils.isSolanaAddress(v.address)) {
863
+ if (utils_2.SolanaUtils.isSolanaAddress(v.address)) {
696
864
  let balance = (0, core_1.toNormalizedBn)(0);
697
- if (utils_1.SolanaUtils.isSolanaAddress(solanaWallet)) {
698
- const vaultProgramId = utils_1.SolanaUtils.resolveProgramId(String(v.address), v.solana_vault_metadata);
865
+ if (utils_2.SolanaUtils.isSolanaAddress(solanaWallet)) {
866
+ const vaultProgramId = utils_2.SolanaUtils.resolveProgramId(String(v.address), v.solana_vault_metadata);
699
867
  const vaultStateRes = await options.solanaService.getVaultState(vaultProgramId, SolanaConstants.vaultIdl, v.solana_vault_metadata?.vault_state_pda ?? undefined);
700
868
  if (vaultStateRes &&
701
869
  vaultStateRes?.vaultState?.shareMint) {
@@ -711,6 +879,30 @@ async function getVaultPositions({ vault, wallet, solanaWallet, options, }) {
711
879
  walletBalance: balance,
712
880
  };
713
881
  }
882
+ if ((0, utils_3.isStellarAddress)(v.address)) {
883
+ let balance = (0, core_1.toNormalizedBn)(0);
884
+ if (stellarWallet && (0, utils_3.isStellarAddress)(stellarWallet)) {
885
+ const stellarNetwork = v.stellar_vault_metadata?.network_name ?? 'mainnet';
886
+ const position = await StellarGetters.getStellarUserPosition(v.address, stellarWallet, stellarNetwork);
887
+ if (position) {
888
+ balance = (0, core_1.toNormalizedBn)(BigInt(position.shares), position.decimals);
889
+ }
890
+ else {
891
+ core_1.Logger.log.warn('getVaultPositions', 'Stellar position query failed — showing zero balance', { vault: v.address, wallet: stellarWallet });
892
+ }
893
+ }
894
+ else if (stellarWallet) {
895
+ core_1.Logger.log.warn('getVaultPositions', 'Invalid stellarWallet address format', { vault: v.address, stellarWallet });
896
+ }
897
+ return {
898
+ vault: v.address,
899
+ status: renderStatus([], balance),
900
+ availableRedemptions: [],
901
+ pendingRedemptions: [],
902
+ redeemable: (0, core_1.toNormalizedBn)(0),
903
+ walletBalance: balance,
904
+ };
905
+ }
714
906
  const provider = (0, core_1.createProvider)(options.rpcUrl);
715
907
  let decimals;
716
908
  const version = (0, core_1.getVaultVersionV2)(v);
@@ -768,7 +960,12 @@ async function getVaultPositions({ vault, wallet, solanaWallet, options, }) {
768
960
  return promises.flat();
769
961
  }
770
962
  catch (e) {
771
- core_1.Logger.log.error('getVaultPositions', e, { vault, wallet, solanaWallet });
963
+ core_1.Logger.log.error('getVaultPositions', e, {
964
+ vault,
965
+ wallet,
966
+ solanaWallet,
967
+ stellarWallet,
968
+ });
772
969
  throw new Error(`#getVaultPositions::${vault}:${e?.message}`);
773
970
  }
774
971
  }
@@ -931,6 +1128,24 @@ async function getVaultTvl({ vault, options, historical, }) {
931
1128
  }
932
1129
  if (!historical) {
933
1130
  const version = (0, core_1.getVaultVersionV2)(_vaultExists);
1131
+ if (version === 'sol-0') {
1132
+ return [
1133
+ {
1134
+ value: (0, core_1.toNormalizedBn)(0),
1135
+ timestamp: new Date().toISOString(),
1136
+ },
1137
+ ];
1138
+ }
1139
+ if (version === 'stellar-0') {
1140
+ const stellarDecimals = _vaultExists?.stellar_vault_metadata?.deposit_token_decimals ??
1141
+ constants_1.STELLAR_FALLBACK_DECIMALS;
1142
+ return [
1143
+ {
1144
+ value: (0, utils_1.backendTvlToNormalizedBn)(_vaultExists?.latest_reported_tvl, stellarDecimals),
1145
+ timestamp: new Date().toISOString(),
1146
+ },
1147
+ ];
1148
+ }
934
1149
  const provider = (0, core_1.createProvider)(options.rpcUrl);
935
1150
  switch (version) {
936
1151
  case 'evm-2': {
@@ -949,14 +1164,6 @@ async function getVaultTvl({ vault, options, historical, }) {
949
1164
  },
950
1165
  ];
951
1166
  }
952
- case 'sol-0': {
953
- return [
954
- {
955
- value: (0, core_1.toNormalizedBn)(0),
956
- timestamp: new Date().toISOString(),
957
- },
958
- ];
959
- }
960
1167
  default: {
961
1168
  const vaultContract = (0, core_1.createContract)({
962
1169
  address: vault,
@@ -975,12 +1182,16 @@ async function getVaultTvl({ vault, options, historical, }) {
975
1182
  }
976
1183
  }
977
1184
  else {
1185
+ const version = (0, core_1.getVaultVersionV2)(_vaultExists);
1186
+ if (version === 'stellar-0' || version === 'sol-0') {
1187
+ core_1.Logger.log.warn('getVaultTvl:historical', 'Historical TVL not supported for non-EVM vaults', { vault, version });
1188
+ return [];
1189
+ }
978
1190
  if (typeof historical !== 'undefined' && !historical.order)
979
1191
  historical.order = 'desc';
980
1192
  if (typeof historical !== 'undefined' && !historical.interval)
981
1193
  historical.interval = 'days';
982
1194
  const provider = (0, core_1.createProvider)(options.rpcUrl);
983
- const version = (0, core_1.getVaultVersionV2)(_vaultExists);
984
1195
  const vaultContract = (0, core_1.createContract)({
985
1196
  address: vault,
986
1197
  abi: version === 'evm-2' ? TokenizedVaultV2_1.ABI_TOKENIZED_VAULT_V2 : abis_1.ABI_LENDING_POOL_V2,
@@ -1195,7 +1406,8 @@ async function getYieldLastRealizedOn({ vault, options, }) {
1195
1406
  assetsUpdatedOn = await contract.assetsUpdatedOn();
1196
1407
  break;
1197
1408
  }
1198
- case 'sol-0': {
1409
+ case 'sol-0':
1410
+ case 'stellar-0': {
1199
1411
  return 0;
1200
1412
  }
1201
1413
  default: {
@@ -1216,6 +1428,7 @@ async function getVaultUserLifetimePnl({ vault, wallet, options, }) {
1216
1428
  throw new Error('Vault input parameter is undefined.');
1217
1429
  if (!wallet)
1218
1430
  throw new Error('Wallet input parameter is undefined.');
1431
+ (0, utils_3.assertNotStellar)(vault, 'Lifetime PnL');
1219
1432
  if (!(0, ethers_1.isAddress)(vault))
1220
1433
  throw new Error(`Vault input parameter is not an address: ${String(vault)}`);
1221
1434
  if (!(0, ethers_1.isAddress)(wallet))
@@ -1235,6 +1448,30 @@ async function getVaultUserLifetimePnl({ vault, wallet, options, }) {
1235
1448
  if (!tokenizedVault) {
1236
1449
  throw new Error(`Vault ${vault} not found`);
1237
1450
  }
1451
+ const lzVaultKey = (0, deposits_1.isLayerZeroVault)(vault);
1452
+ let lzDeposits = [];
1453
+ let lzRedeems = [];
1454
+ if (lzVaultKey) {
1455
+ const lzPromises = [
1456
+ (0, deposits_1.queryLayerZeroDeposits)(lzVaultKey, wallet)
1457
+ .then((d) => {
1458
+ lzDeposits = d;
1459
+ })
1460
+ .catch((e) => {
1461
+ core_1.Logger.log.warn('getVaultUserLifetimePnl:lzDeposits', `Failed to fetch LZ deposits for ${lzVaultKey}: ${e}`);
1462
+ }),
1463
+ ];
1464
+ if (lzVaultKey === 'earnAUSD') {
1465
+ lzPromises.push((0, redeems_1.queryLayerZeroRedeems)(wallet)
1466
+ .then((r) => {
1467
+ lzRedeems = r;
1468
+ })
1469
+ .catch((e) => {
1470
+ core_1.Logger.log.warn('getVaultUserLifetimePnl:lzRedeems', `Failed to fetch LZ redeems for ${lzVaultKey}: ${e}`);
1471
+ }));
1472
+ }
1473
+ await Promise.all(lzPromises);
1474
+ }
1238
1475
  const version = (0, core_1.getVaultVersionV2)(tokenizedVault);
1239
1476
  const currentPosition = positions.find((pos) => pos.vault?.toLowerCase() === vault.toLowerCase());
1240
1477
  const underlyingSymbolPromise = (async () => {
@@ -1291,9 +1528,22 @@ async function getVaultUserLifetimePnl({ vault, wallet, options, }) {
1291
1528
  totalWithdrawalsInAssets += amount;
1292
1529
  }
1293
1530
  }
1531
+ if (lzVaultKey && lzDeposits.length > 0) {
1532
+ for (const lzDeposit of lzDeposits) {
1533
+ const assetKey = 'lz-default';
1534
+ const amount = BigInt(lzDeposit.assetAmt);
1535
+ const current = depositsByAsset.get(assetKey) ?? BigInt(0);
1536
+ depositsByAsset.set(assetKey, current + amount);
1537
+ }
1538
+ }
1539
+ if (lzVaultKey && lzRedeems.length > 0) {
1540
+ for (const lzRedeem of lzRedeems) {
1541
+ totalWithdrawalsInShares += BigInt(lzRedeem.shareAmt);
1542
+ }
1543
+ }
1294
1544
  const assetDecimals = new Map();
1295
1545
  await Promise.all(Array.from(depositsByAsset.keys()).map(async (assetAddress) => {
1296
- if (assetAddress === 'default') {
1546
+ if (assetAddress === 'default' || assetAddress === 'lz-default') {
1297
1547
  assetDecimals.set(assetAddress, decimals);
1298
1548
  }
1299
1549
  else {
@@ -1309,7 +1559,7 @@ async function getVaultUserLifetimePnl({ vault, wallet, options, }) {
1309
1559
  const assetPrices = new Map();
1310
1560
  if (tokenizedVault.chain) {
1311
1561
  await Promise.all(Array.from(depositsByAsset.keys()).map(async (assetAddress) => {
1312
- if (assetAddress === 'default') {
1562
+ if (assetAddress === 'default' || assetAddress === 'lz-default') {
1313
1563
  assetPrices.set(assetAddress, 0);
1314
1564
  }
1315
1565
  else {
@@ -1351,6 +1601,71 @@ async function getVaultUserLifetimePnl({ vault, wallet, options, }) {
1351
1601
  else {
1352
1602
  currentShares = await vaultContract.balanceOf(wallet);
1353
1603
  }
1604
+ if (lzVaultKey) {
1605
+ const remoteChains = [];
1606
+ if (tokenizedVault.receipt_token_integrations?.length) {
1607
+ for (const rti of tokenizedVault.receipt_token_integrations) {
1608
+ if (rti.chain !== tokenizedVault.chain &&
1609
+ rti.address &&
1610
+ rti.chain) {
1611
+ remoteChains.push({
1612
+ chain: rti.chain,
1613
+ address: rti.address,
1614
+ });
1615
+ }
1616
+ }
1617
+ }
1618
+ else {
1619
+ const lzVaultConfig = deposits_1.LAYERZERO_VAULTS[lzVaultKey];
1620
+ if (lzVaultConfig.spokeChains) {
1621
+ for (const [chainIdStr, address] of Object.entries(lzVaultConfig.spokeChains)) {
1622
+ const chainId = Number(chainIdStr);
1623
+ if (chainId !== tokenizedVault.chain) {
1624
+ remoteChains.push({
1625
+ chain: chainId,
1626
+ address: address,
1627
+ });
1628
+ }
1629
+ }
1630
+ }
1631
+ }
1632
+ if (remoteChains.length > 0) {
1633
+ const remoteBalances = await Promise.all(remoteChains.map(async ({ chain, address }) => {
1634
+ try {
1635
+ const rpcUrls = (0, core_1.getFallbackRpcUrls)(chain);
1636
+ if (!rpcUrls.length) {
1637
+ core_1.Logger.log.warn('getVaultUserLifetimePnl:lzRemoteBalance', `No RPC URL for chain ${chain}, skipping balance check`);
1638
+ return BigInt(0);
1639
+ }
1640
+ const remoteProvider = (0, core_1.createProvider)(rpcUrls[0]);
1641
+ const remoteTokenContract = (0, core_1.createContract)({
1642
+ provider: remoteProvider,
1643
+ address,
1644
+ abi: abis_1.ABI_ERC20,
1645
+ });
1646
+ const [rawBalance, remoteDecimals] = await Promise.all([
1647
+ remoteTokenContract.balanceOf(wallet),
1648
+ remoteTokenContract.decimals(),
1649
+ ]);
1650
+ const remDec = Number(remoteDecimals) || decimals;
1651
+ if (remDec > decimals) {
1652
+ return rawBalance / BigInt(10 ** (remDec - decimals));
1653
+ }
1654
+ else if (remDec < decimals) {
1655
+ return rawBalance * BigInt(10 ** (decimals - remDec));
1656
+ }
1657
+ return rawBalance;
1658
+ }
1659
+ catch (e) {
1660
+ core_1.Logger.log.warn('getVaultUserLifetimePnl:lzRemoteBalance', `Failed to fetch balance on chain ${chain}: ${e}`);
1661
+ return BigInt(0);
1662
+ }
1663
+ }));
1664
+ for (const bal of remoteBalances) {
1665
+ currentShares += bal;
1666
+ }
1667
+ }
1668
+ }
1354
1669
  if (version === 'evm-2') {
1355
1670
  sharePriceRaw = await vaultContract.getSharePrice();
1356
1671
  }
@@ -1391,7 +1706,7 @@ async function getVaultUserLifetimePnl({ vault, wallet, options, }) {
1391
1706
  }
1392
1707
  let totalDepositedUsd = 0;
1393
1708
  for (const [assetAddress, normalizedAmount] of totalDepositedRaw) {
1394
- const assetPrice = assetAddress === 'default'
1709
+ const assetPrice = assetAddress === 'default' || assetAddress === 'lz-default'
1395
1710
  ? effectiveTokenPrice
1396
1711
  : assetPrices.get(assetAddress) || effectiveTokenPrice;
1397
1712
  totalDepositedUsd += Number(normalizedAmount.normalized) * assetPrice;
@@ -1437,6 +1752,7 @@ async function getVaultPnl({ vault, options, }) {
1437
1752
  try {
1438
1753
  if (!vault)
1439
1754
  throw new Error('Vault input parameter is undefined.');
1755
+ (0, utils_3.assertNotStellar)(vault, 'Vault PnL');
1440
1756
  if (!(0, ethers_1.isAddress)(vault))
1441
1757
  throw new Error(`Vault input parameter is not an address: ${String(vault)}`);
1442
1758
  const vaultData = await getVault({
@@ -1558,6 +1874,7 @@ async function getVaultSummary({ vault, options, }) {
1558
1874
  if (!vault) {
1559
1875
  throw new Error('Vault address parameter is undefined.');
1560
1876
  }
1877
+ (0, utils_3.assertNotStellar)(vault, 'Vault summary');
1561
1878
  if (!(0, ethers_1.isAddress)(vault)) {
1562
1879
  throw new Error(`Vault parameter is not an address: ${String(vault)}`);
1563
1880
  }
@@ -1582,6 +1899,7 @@ async function getVaultWithdrawals({ vault, chain, options, }) {
1582
1899
  if (!vault) {
1583
1900
  throw new Error('Vault address parameter is undefined.');
1584
1901
  }
1902
+ (0, utils_3.assertNotStellar)(vault, 'Vault withdrawals');
1585
1903
  if (!(0, ethers_1.isAddress)(vault)) {
1586
1904
  throw new Error(`Vault parameter is not an address: ${String(vault)}`);
1587
1905
  }
@@ -1604,10 +1922,78 @@ async function getVaultWithdrawals({ vault, chain, options, }) {
1604
1922
  throw new Error(`#getVaultWithdrawals::${vault}::${chain}:${errorMessage}`);
1605
1923
  }
1606
1924
  }
1925
+ async function getVaultPendingRedemptions({ vault, pastDays, futureDays, options, }) {
1926
+ try {
1927
+ if (!vault)
1928
+ throw new Error('Vault address parameter is undefined.');
1929
+ if (!(0, ethers_1.isAddress)(vault))
1930
+ throw new Error(`Vault parameter is not an address: ${String(vault)}`);
1931
+ if (pastDays !== undefined && (pastDays < 1 || pastDays > 30))
1932
+ throw new Error('pastDays must be between 1 and 30');
1933
+ if (futureDays !== undefined && (futureDays < 1 || futureDays > 30))
1934
+ throw new Error('futureDays must be between 1 and 30');
1935
+ const params = new URLSearchParams();
1936
+ if (pastDays !== undefined)
1937
+ params.set('past_days', pastDays.toString());
1938
+ if (futureDays !== undefined)
1939
+ params.set('future_days', futureDays.toString());
1940
+ const qs = params.toString();
1941
+ const endpoint = `${core_1.WEBSERVER_ENDPOINTS.public.vaults.pendingRedemptions(vault)}${qs ? `?${qs}` : ''}`;
1942
+ const response = await (0, core_1.fetchAugustPublic)(endpoint, {
1943
+ headers: options?.headers,
1944
+ server: 'public',
1945
+ });
1946
+ if (!response.ok) {
1947
+ throw new Error(`Failed to fetch pending redemptions: ${response.statusText}`);
1948
+ }
1949
+ const raw = await response.json();
1950
+ return {
1951
+ vault: {
1952
+ address: raw.vault.address,
1953
+ chainId: raw.vault.chain_id,
1954
+ name: raw.vault.name,
1955
+ symbol: raw.vault.symbol,
1956
+ },
1957
+ asset: {
1958
+ address: raw.asset.address,
1959
+ symbol: raw.asset.symbol,
1960
+ decimals: raw.asset.decimals,
1961
+ },
1962
+ liquidity: {
1963
+ available: raw.liquidity.available,
1964
+ },
1965
+ summary: {
1966
+ totalPending: raw.summary.total_pending,
1967
+ pendingCount: raw.summary.pending_count,
1968
+ pendingToLiquidityRatio: raw.summary.pending_to_liquidity_ratio,
1969
+ isLiquiditySufficient: raw.summary.is_liquidity_sufficient,
1970
+ shortfall: raw.summary.shortfall,
1971
+ nextRedemptionDate: raw.summary.next_redemption_date,
1972
+ isOverdue: raw.summary.is_overdue,
1973
+ },
1974
+ redemptionsByDate: raw.redemptions_by_date.map((item) => ({
1975
+ date: item.date,
1976
+ assets: item.assets,
1977
+ daysUntilDue: item.days_until_due,
1978
+ isOverdue: item.is_overdue,
1979
+ })),
1980
+ };
1981
+ }
1982
+ catch (e) {
1983
+ core_1.Logger.log.error('getVaultPendingRedemptions', e, {
1984
+ vault,
1985
+ pastDays,
1986
+ futureDays,
1987
+ });
1988
+ const errorMessage = e instanceof Error ? e.message : String(e);
1989
+ throw new Error(`#getVaultPendingRedemptions::${vault}:${errorMessage}`);
1990
+ }
1991
+ }
1607
1992
  async function getPreviewRedemption({ vault, sharesAmount, options, }) {
1608
1993
  try {
1609
1994
  if (!vault)
1610
1995
  throw new Error('Vault address parameter is undefined.');
1996
+ (0, utils_3.assertNotStellar)(vault, 'Preview redemption');
1611
1997
  if (!(0, ethers_1.isAddress)(vault)) {
1612
1998
  throw new Error(`Vault parameter is not an address: ${String(vault)}`);
1613
1999
  }
@@ -1650,4 +2036,187 @@ async function getPreviewRedemption({ vault, sharesAmount, options, }) {
1650
2036
  throw new Error(`Failed to preview redemption for ${vault}: ${e instanceof Error ? e.message : 'Unknown error'}`);
1651
2037
  }
1652
2038
  }
2039
+ async function decodeProcessingTransaction(txHash, provider, iface) {
2040
+ const tx = await provider.getTransaction(txHash);
2041
+ if (!tx) {
2042
+ return {
2043
+ functionName: 'unknown',
2044
+ year: 0,
2045
+ month: 0,
2046
+ day: 0,
2047
+ error: 'Transaction not found',
2048
+ };
2049
+ }
2050
+ return (0, call_data_decoder_1.decodeWithdrawalProcessing)(tx.data, iface);
2051
+ }
2052
+ async function getWithdrawalRequestsWithStatus(params) {
2053
+ try {
2054
+ const { vault, receiver, options } = params;
2055
+ if (!vault || !(0, ethers_1.isAddress)(vault)) {
2056
+ throw new Error('Invalid vault address');
2057
+ }
2058
+ const vaultAddress = (0, ethers_1.getAddress)(vault);
2059
+ const provider = (0, core_1.createProvider)(options.rpcUrl);
2060
+ const tokenizedVault = (await (0, core_1.fetchTokenizedVault)(vaultAddress, options?.headers, false, false))?.[0];
2061
+ if (!tokenizedVault) {
2062
+ core_1.Logger.log.warn('getWithdrawalRequestsWithStatus', `Vault not found in backend: ${vaultAddress}`);
2063
+ return [];
2064
+ }
2065
+ const version = (0, core_1.getVaultVersionV2)(tokenizedVault);
2066
+ const isV2 = version === 'evm-2';
2067
+ const vaultAbi = isV2 ? TokenizedVaultV2_1.ABI_TOKENIZED_VAULT_V2 : abis_1.ABI_LENDING_POOL_V2;
2068
+ const vaultContract = (0, core_1.createContract)({
2069
+ address: vaultAddress,
2070
+ abi: vaultAbi,
2071
+ provider,
2072
+ });
2073
+ let lagDuration = 86400;
2074
+ try {
2075
+ const lagValue = await vaultContract.lagDuration?.();
2076
+ if (lagValue !== undefined && lagValue !== null) {
2077
+ lagDuration = Number(lagValue);
2078
+ }
2079
+ }
2080
+ catch (e) {
2081
+ core_1.Logger.log.warn('getWithdrawalRequestsWithStatus', `Failed to fetch lagDuration from vault ${vaultAddress}, using default 1 day — status determinations may be inaccurate: ${e instanceof Error ? e.message : 'Unknown error'}`);
2082
+ }
2083
+ const [withdrawalRequests, processedEvents] = await Promise.all([
2084
+ (0, vaults_1.getSubgraphWithdrawRequests)(vaultAddress, provider),
2085
+ getVaultRedemptionHistory({
2086
+ vault: vaultAddress,
2087
+ wallet: receiver,
2088
+ options,
2089
+ }),
2090
+ ]);
2091
+ if (!withdrawalRequests.length) {
2092
+ return [];
2093
+ }
2094
+ const filteredRequests = receiver
2095
+ ? withdrawalRequests.filter((req) => req.receiverAddr?.toLowerCase() === receiver.toLowerCase())
2096
+ : withdrawalRequests;
2097
+ const iface = new ethers_1.Interface(vaultAbi);
2098
+ const decodedProcessed = await Promise.all((processedEvents || []).map(async (processed) => {
2099
+ if (processed.transactionHash) {
2100
+ try {
2101
+ const decoded = await decodeProcessingTransaction(processed.transactionHash, provider, iface);
2102
+ if (!decoded.error) {
2103
+ return {
2104
+ ...processed,
2105
+ decodedDate: {
2106
+ year: decoded.year,
2107
+ month: decoded.month,
2108
+ day: decoded.day,
2109
+ },
2110
+ };
2111
+ }
2112
+ }
2113
+ catch (e) {
2114
+ core_1.Logger.log.warn('getWithdrawalRequestsWithStatus', `Failed to decode processed transaction ${processed.transactionHash}: ${e instanceof Error ? e.message : 'Unknown error'}`);
2115
+ }
2116
+ }
2117
+ const requestedEpoch = Math.floor(processed.requested.getTime() / 1000);
2118
+ if (requestedEpoch > 0) {
2119
+ const fallbackDate = (0, date_utils_1.computeClaimableDate)(requestedEpoch, lagDuration);
2120
+ return {
2121
+ ...processed,
2122
+ decodedDate: {
2123
+ year: fallbackDate.year,
2124
+ month: fallbackDate.month,
2125
+ day: fallbackDate.day,
2126
+ },
2127
+ };
2128
+ }
2129
+ const processedDate = processed.processed;
2130
+ return {
2131
+ ...processed,
2132
+ decodedDate: {
2133
+ year: processedDate.getUTCFullYear(),
2134
+ month: processedDate.getUTCMonth() + 1,
2135
+ day: processedDate.getUTCDate(),
2136
+ },
2137
+ };
2138
+ }));
2139
+ const processedMap = new Map();
2140
+ for (const processed of decodedProcessed) {
2141
+ if (!processed.decodedDate) {
2142
+ continue;
2143
+ }
2144
+ const dateKey = (0, date_utils_1.formatDateKey)(processed.decodedDate.year, processed.decodedDate.month, processed.decodedDate.day);
2145
+ const key = `${processed.receiver.toLowerCase()}:${dateKey}`;
2146
+ const existing = processedMap.get(key) ?? [];
2147
+ processedMap.set(key, [...existing, processed]);
2148
+ }
2149
+ const chainId = tokenizedVault.chain;
2150
+ const effectiveLookbackBlocks = params.lookbackBlocks ?? (0, core_1.determineBlockCutoff)(chainId);
2151
+ const lookbackSeconds = effectiveLookbackBlocks * (0, core_1.determineSecondsPerBlock)(chainId);
2152
+ const results = [];
2153
+ const now = Math.floor(Date.now() / 1000);
2154
+ const lookbackCutoff = now - lookbackSeconds;
2155
+ for (const req of filteredRequests) {
2156
+ const requestTimestamp = Number(req.timestamp_);
2157
+ const claimableDate = (0, date_utils_1.computeClaimableDate)(requestTimestamp, lagDuration);
2158
+ let status = 'pending';
2159
+ let processedTxHash;
2160
+ let assetsReceived;
2161
+ const dateKey = (0, date_utils_1.formatDateKey)(claimableDate.year, claimableDate.month, claimableDate.day);
2162
+ const lookupKey = `${req.receiverAddr.toLowerCase()}:${dateKey}`;
2163
+ const processedEvents = processedMap.get(lookupKey);
2164
+ const processedEvent = processedEvents && processedEvents.length > 0
2165
+ ? processedEvents.shift()
2166
+ : undefined;
2167
+ if (processedEvent) {
2168
+ status = 'processed';
2169
+ processedTxHash = processedEvent.transactionHash;
2170
+ try {
2171
+ assetsReceived = BigInt(processedEvent.amount.raw);
2172
+ }
2173
+ catch (e) {
2174
+ core_1.Logger.log.warn(`Failed to parse assets as BigInt: ${e}`);
2175
+ }
2176
+ }
2177
+ else if (claimableDate.epoch < lookbackCutoff) {
2178
+ continue;
2179
+ }
2180
+ else if ((0, date_utils_1.isClaimableNow)(claimableDate.epoch, now)) {
2181
+ status = 'ready_to_claim';
2182
+ }
2183
+ results.push({
2184
+ transactionHash: req.transactionHash_,
2185
+ requestTimestamp,
2186
+ shares: (() => {
2187
+ try {
2188
+ return BigInt(req.shares);
2189
+ }
2190
+ catch {
2191
+ const truncated = Math.trunc(Number(req.shares));
2192
+ if (!Number.isFinite(truncated)) {
2193
+ core_1.Logger.log.warn('getWithdrawalRequestsWithStatus', `Cannot parse shares value "${req.shares}" — defaulting to 0`);
2194
+ return BigInt(0);
2195
+ }
2196
+ core_1.Logger.log.info('getWithdrawalRequestsWithStatus', `Truncated decimal shares "${req.shares}" → ${truncated}`);
2197
+ return BigInt(truncated);
2198
+ }
2199
+ })(),
2200
+ receiver: req.receiverAddr,
2201
+ claimableDate: {
2202
+ year: claimableDate.year,
2203
+ month: claimableDate.month,
2204
+ day: claimableDate.day,
2205
+ },
2206
+ claimableEpoch: claimableDate.epoch,
2207
+ status,
2208
+ processedTransactionHash: processedTxHash,
2209
+ assetsReceived,
2210
+ });
2211
+ }
2212
+ return results;
2213
+ }
2214
+ catch (e) {
2215
+ core_1.Logger.log.error('getWithdrawalRequestsWithStatus', e, {
2216
+ vaultAddress: params.vault,
2217
+ hasReceiver: !!params.receiver,
2218
+ });
2219
+ throw new Error(`Failed to get withdrawal requests with status: ${e instanceof Error ? e.message : 'Unknown error'}`);
2220
+ }
2221
+ }
1653
2222
  //# sourceMappingURL=getters.js.map