@augustdigital/sdk 9.3.0 → 9.4.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 (56) hide show
  1. package/lib/adapters/evm/getters.js +40 -0
  2. package/lib/adapters/evm/index.d.ts +106 -2
  3. package/lib/adapters/evm/index.js +125 -0
  4. package/lib/adapters/solana/index.d.ts +12 -5
  5. package/lib/adapters/solana/index.js +12 -4
  6. package/lib/adapters/solana/pricing.d.ts +173 -0
  7. package/lib/adapters/solana/pricing.js +223 -0
  8. package/lib/adapters/solana/types.d.ts +45 -0
  9. package/lib/adapters/solana/vault.actions.d.ts +33 -8
  10. package/lib/adapters/solana/vault.actions.js +185 -28
  11. package/lib/adapters/stellar/actions.d.ts +2 -2
  12. package/lib/adapters/stellar/actions.js +2 -2
  13. package/lib/adapters/stellar/getters.d.ts +1 -1
  14. package/lib/adapters/stellar/getters.js +2 -2
  15. package/lib/adapters/stellar/index.d.ts +1 -1
  16. package/lib/adapters/stellar/index.js +1 -1
  17. package/lib/adapters/stellar/types.d.ts +1 -2
  18. package/lib/core/analytics/method-taxonomy.js +7 -0
  19. package/lib/core/analytics/version.d.ts +1 -1
  20. package/lib/core/analytics/version.js +1 -1
  21. package/lib/core/base.class.d.ts +2 -2
  22. package/lib/core/base.class.js +2 -2
  23. package/lib/core/constants/core.d.ts +17 -3
  24. package/lib/core/constants/core.js +17 -3
  25. package/lib/core/constants/vaults.js +4 -0
  26. package/lib/core/fetcher.js +112 -45
  27. package/lib/core/helpers/concurrency.d.ts +37 -0
  28. package/lib/core/helpers/concurrency.js +58 -0
  29. package/lib/core/helpers/core.d.ts +9 -0
  30. package/lib/core/helpers/core.js +47 -0
  31. package/lib/core/helpers/vaults.d.ts +1 -1
  32. package/lib/core/helpers/vaults.js +1 -1
  33. package/lib/core/helpers/web3.js +14 -1
  34. package/lib/core/logger/curator-alert.d.ts +2 -2
  35. package/lib/core/logger/curator-alert.js +2 -2
  36. package/lib/evm/methods/crossChainVaultRegistry.d.ts +2 -3
  37. package/lib/evm/methods/crossChainVaultRegistry.js +2 -3
  38. package/lib/evm/types/crossChain.d.ts +1 -1
  39. package/lib/main.d.ts +7 -5
  40. package/lib/main.js +7 -5
  41. package/lib/modules/vaults/getters.d.ts +10 -3
  42. package/lib/modules/vaults/getters.js +205 -71
  43. package/lib/modules/vaults/main.d.ts +4 -4
  44. package/lib/modules/vaults/main.js +7 -4
  45. package/lib/modules/vaults/read.actions.d.ts +181 -0
  46. package/lib/modules/vaults/read.actions.js +331 -36
  47. package/lib/modules/vaults/types.d.ts +13 -0
  48. package/lib/modules/vaults/utils.js +5 -1
  49. package/lib/modules/vaults/write.actions.d.ts +74 -6
  50. package/lib/modules/vaults/write.actions.js +133 -23
  51. package/lib/sdk.d.ts +9827 -9342
  52. package/lib/services/subgraph/schema.d.ts +1 -1
  53. package/lib/services/subgraph/schema.js +1 -1
  54. package/lib/types/pools.d.ts +1 -1
  55. package/lib/types/vaults.d.ts +4 -4
  56. package/package.json +1 -1
@@ -69,6 +69,7 @@ const types_1 = require("../../types");
69
69
  const core_1 = require("../../core");
70
70
  const ethers_1 = require("ethers");
71
71
  const cache_1 = require("../../core/cache");
72
+ const concurrency_1 = require("../../core/helpers/concurrency");
72
73
  const utils_1 = require("./utils");
73
74
  const subgraph_1 = require("../../services/subgraph");
74
75
  const vaults_1 = require("../../services/subgraph/vaults");
@@ -127,9 +128,13 @@ const errors_1 = require("../../core/errors");
127
128
  */
128
129
  async function getVault({ vault, loans = false, allocations = false, options, loadSubaccounts, loadSnapshots, tokenizedVault: prefetchedRow, }) {
129
130
  let returnedVault;
131
+ // Hoisted out of the try so the allocations enrichment below can reuse the
132
+ // row instead of re-fetching it.
133
+ let tokenizedVault;
130
134
  try {
131
- const tokenizedVault = prefetchedRow ??
132
- (await (0, core_1.fetchTokenizedVault)(vault, undefined, loadSubaccounts, loadSnapshots))?.[0];
135
+ tokenizedVault =
136
+ prefetchedRow ??
137
+ (await (0, core_1.fetchTokenizedVault)(vault, options?.headers, loadSubaccounts, loadSnapshots))?.[0];
133
138
  const vaultVersion = (0, core_1.getVaultVersionV2)(tokenizedVault);
134
139
  switch (vaultVersion) {
135
140
  case 'sol-0': {
@@ -175,12 +180,24 @@ async function getVault({ vault, loans = false, allocations = false, options, lo
175
180
  core_1.Logger.log.warn('getVault', 'Loans/allocations enrichment is not supported for this vault — skipping', { vault, version: returnedVault.version });
176
181
  }
177
182
  if (!(0, core_1.isBadVault)(vault) && (readLoans || readAllocations)) {
183
+ // `getVaultAllocations` reads `.subaccounts`/`.eoa_operators` off the row to
184
+ // discover borrowers, so the row is withheld unless it can carry them and
185
+ // the getter fetches a full one itself. Both guards matter: `loadSubaccounts:
186
+ // false` can answer with the keys present but empty, and a row threaded in
187
+ // from `getVaults` comes from the list endpoint rather than this one. Getting
188
+ // either wrong resolves zero borrowers with no error — the silent-empty
189
+ // failure this de-duplication exists to avoid.
190
+ const allocationsRow = loadSubaccounts !== false &&
191
+ tokenizedVault?.subaccounts &&
192
+ tokenizedVault?.eoa_operators
193
+ ? tokenizedVault
194
+ : undefined;
178
195
  const [loansResult, allocationsResult] = await Promise.allSettled([
179
196
  readLoans
180
197
  ? getVaultLoans(returnedVault, options)
181
198
  : Promise.resolve(undefined),
182
199
  readAllocations
183
- ? getVaultAllocations(vault, options)
200
+ ? getVaultAllocations(vault, options, allocationsRow)
184
201
  : Promise.resolve(undefined),
185
202
  ]);
186
203
  if (readLoans) {
@@ -401,6 +418,125 @@ async function getVaultSubaccountLoans(vault, options) {
401
418
  * the backend distinguish the two cases with a status of its own.
402
419
  */
403
420
  const EXPECTED_SUBACCOUNT_FETCH_STATUSES = new Set([204, 400, 404]);
421
+ /**
422
+ * How long a per-borrower CeFi/OTC enrichment result stays cached, in ms.
423
+ *
424
+ * `getVaultAllocations` asks for the same borrowers on every call, and a vault
425
+ * page re-renders far more often than a CeFi balance changes. Without a cache
426
+ * each render re-issued one request per borrower — together, the two endpoints
427
+ * accounted for ~15.7k of the weekly `AugustTimeoutError` events in production.
428
+ *
429
+ * A `null` answer ("this borrower has no CeFi/OTC record") is cached alongside
430
+ * real data: it is the common case and just as worth remembering as a hit.
431
+ * Failures are NOT cached — they leave the key absent so the next call retries.
432
+ *
433
+ * 60s keeps a burst of renders on a single request while staying well inside
434
+ * the freshness any allocation view needs. Entries live in the shared process
435
+ * `CACHE`, so `CACHE.clear()` drops them along with everything else.
436
+ */
437
+ const SUBACCOUNT_ENRICHMENT_TTL_MS = 1000 * 60;
438
+ /** Shared-cache key for a borrower's CeFi positions. */
439
+ const cefiCacheKey = (borrower) => `subaccount-cefi-${borrower}`;
440
+ /** Shared-cache key for a borrower's OTC positions. */
441
+ const otcCacheKey = (borrower) => `subaccount-otc-${borrower}`;
442
+ /**
443
+ * Maximum simultaneous subaccount enrichment requests.
444
+ *
445
+ * Each borrower costs 2 requests (CeFi + OTC), so a window of 5 means at most
446
+ * 5 open connections to the August API from one `getVaultAllocations` call.
447
+ * Worst-case RPC/HTTP volume for a 40-borrower vault: 80 requests, 5 at a time,
448
+ * versus 80 sequential before — and versus 80 simultaneous had this been a bare
449
+ * `Promise.all`.
450
+ */
451
+ const SUBACCOUNT_FETCH_CONCURRENCY = 5;
452
+ /**
453
+ * Fetch one borrower's CeFi positions, memoized for
454
+ * {@link SUBACCOUNT_ENRICHMENT_TTL_MS}.
455
+ *
456
+ * @param borrower - Subaccount/borrower address.
457
+ * @param options - Vault options carrying `augustKey` and monitoring headers.
458
+ * @param vault - Vault address, for log context only.
459
+ * @returns The borrower's CeFi positions, or `null` when the backend has no
460
+ * record (or the fetch failed — this is best-effort enrichment and never
461
+ * throws).
462
+ */
463
+ async function fetchSubaccountCefi(borrower, options, vault) {
464
+ const key = cefiCacheKey(borrower);
465
+ // `has` rather than a truthiness check: `null` is a cached answer ("no
466
+ // record for this borrower"), not a miss.
467
+ if (cache_1.CACHE.has(key))
468
+ return cache_1.CACHE.get(key);
469
+ try {
470
+ const cefiResponse = await (0, core_1.fetchAugustWithKey)(options.augustKey, core_1.WEBSERVER_ENDPOINTS.subaccount.cefi(borrower), { headers: options?.headers });
471
+ if (cefiResponse.status === 200) {
472
+ const cefiRes = (await cefiResponse.json());
473
+ cache_1.CACHE.set(key, cefiRes, { ttl: SUBACCOUNT_ENRICHMENT_TTL_MS });
474
+ return cefiRes;
475
+ }
476
+ // 404 means "this subaccount has no CeFi position", which is the common
477
+ // case for most borrowers — a breadcrumb, not an exception.
478
+ logSubaccountFetchFailure('getVaultAllocations:cefi', cefiResponse.status, cefiResponse.statusText, { vault, borrower });
479
+ if (EXPECTED_SUBACCOUNT_FETCH_STATUSES.has(cefiResponse.status)) {
480
+ // A known "no record" answer is a stable fact about this borrower; cache
481
+ // it so the next render does not re-ask.
482
+ cache_1.CACHE.set(key, null, { ttl: SUBACCOUNT_ENRICHMENT_TTL_MS });
483
+ }
484
+ return null;
485
+ }
486
+ catch (e) {
487
+ const status = httpStatusFromError(e);
488
+ logSubaccountFetchFailure('getVaultAllocations:cefi', status, e, {
489
+ vault,
490
+ borrower,
491
+ });
492
+ if (status !== undefined &&
493
+ EXPECTED_SUBACCOUNT_FETCH_STATUSES.has(status)) {
494
+ cache_1.CACHE.set(key, null, { ttl: SUBACCOUNT_ENRICHMENT_TTL_MS });
495
+ }
496
+ return null;
497
+ }
498
+ }
499
+ /**
500
+ * Fetch one borrower's OTC positions, memoized for
501
+ * {@link SUBACCOUNT_ENRICHMENT_TTL_MS}. Mirrors {@link fetchSubaccountCefi}.
502
+ *
503
+ * @param borrower - Subaccount/borrower address.
504
+ * @param options - Vault options carrying `augustKey` and monitoring headers.
505
+ * @param vault - Vault address, for log context only.
506
+ * @returns The borrower's OTC position, or `null` when absent or unfetchable.
507
+ */
508
+ async function fetchSubaccountOtc(borrower, options, vault) {
509
+ const key = otcCacheKey(borrower);
510
+ if (cache_1.CACHE.has(key))
511
+ return cache_1.CACHE.get(key);
512
+ try {
513
+ const otcResponse = await (0, core_1.fetchAugustWithKey)(options.augustKey, core_1.WEBSERVER_ENDPOINTS.subaccount.otc_positions(borrower), { headers: options?.headers });
514
+ if (otcResponse.status === 200) {
515
+ const otcRes = (await otcResponse.json());
516
+ cache_1.CACHE.set(key, otcRes, { ttl: SUBACCOUNT_ENRICHMENT_TTL_MS });
517
+ return otcRes;
518
+ }
519
+ // 404 means "this subaccount has no OTC positions" — expected for nearly
520
+ // every borrower. See logSubaccountFetchFailure.
521
+ logSubaccountFetchFailure('getVaultAllocations:otc', otcResponse.status, otcResponse.statusText, { vault, borrower });
522
+ if (EXPECTED_SUBACCOUNT_FETCH_STATUSES.has(otcResponse.status)) {
523
+ cache_1.CACHE.set(key, null, { ttl: SUBACCOUNT_ENRICHMENT_TTL_MS });
524
+ }
525
+ return null;
526
+ }
527
+ catch (e) {
528
+ const status = httpStatusFromError(e);
529
+ logSubaccountFetchFailure('getVaultAllocations:otc', status, e, {
530
+ vault,
531
+ borrower,
532
+ });
533
+ if (status !== undefined &&
534
+ EXPECTED_SUBACCOUNT_FETCH_STATUSES.has(status)) {
535
+ cache_1.CACHE.set(key, null, { ttl: SUBACCOUNT_ENRICHMENT_TTL_MS });
536
+ }
537
+ return null;
538
+ }
539
+ }
404
540
  /**
405
541
  * Log a per-subaccount enrichment fetch failure at the right severity.
406
542
  *
@@ -458,9 +594,16 @@ function httpStatusFromError(error) {
458
594
  *
459
595
  * @param vault - Vault address
460
596
  * @param options - RPC configuration
597
+ * @param tokenizedVault - Optional pre-fetched backend row for `vault`. When a
598
+ * caller already holds the row (e.g. `getVault` fetched it one call earlier),
599
+ * passing it skips this function's own `GET /tokenized_vault/{address}` — a
600
+ * pure de-duplication of backend traffic. The row must carry the subaccount
601
+ * data this function reads (`.subaccounts`, `.eoa_operators`), so it must not
602
+ * have been fetched with `loadSubaccounts: false`; a row fetched that way
603
+ * would silently resolve zero borrowers.
461
604
  * @returns Detailed allocation data with exposure categorization
462
605
  */
463
- async function getVaultAllocations(vault, options) {
606
+ async function getVaultAllocations(vault, options, tokenizedVault) {
464
607
  // to be used on upshift UI
465
608
  const protocolExposure = [];
466
609
  const tokenExposure = [];
@@ -500,18 +643,19 @@ async function getVaultAllocations(vault, options) {
500
643
  };
501
644
  // Determine wallets to fetch allocation responses from
502
645
  let uniqueBorrowers = [];
503
- const tokenizedVault = (await (0, core_1.fetchTokenizedVault)(vault, options?.headers))?.[0];
646
+ const vaultRow = tokenizedVault ??
647
+ (await (0, core_1.fetchTokenizedVault)(vault, options?.headers))?.[0];
504
648
  // fetch all vault unique subaccounts/loan borrowers
505
649
  try {
506
- const vaultVersion = (0, core_1.getVaultVersionV2)(tokenizedVault);
650
+ const vaultVersion = (0, core_1.getVaultVersionV2)(vaultRow);
507
651
  if (vaultVersion === 'evm-0') {
508
652
  const loans = await getVaultLoans(vault, options);
509
653
  uniqueBorrowers = [...new Set(loans.map((l) => l.borrower))];
510
654
  }
511
655
  else {
512
- const eoa_operators = tokenizedVault.eoa_operators.map((s) => s.address);
656
+ const eoa_operators = vaultRow.eoa_operators.map((s) => s.address);
513
657
  uniqueBorrowers = [
514
- ...tokenizedVault.subaccounts.map((s) => s.address),
658
+ ...vaultRow.subaccounts.map((s) => s.address),
515
659
  ...eoa_operators,
516
660
  ];
517
661
  }
@@ -583,76 +727,66 @@ async function getVaultAllocations(vault, options) {
583
727
  }
584
728
  }
585
729
  // Fetch portfolio data for non-EVM borrowers (EVM handled by fetchVaultDebankResponse above).
586
- // CeFi and OTC fetches below run for ALL borrowers regardless of chain type.
730
+ // Sequential by design: this branch only runs for non-EVM borrowers (a
731
+ // handful per vault) and each parser call mutates the shared accumulators
732
+ // below, which are not safe to interleave.
587
733
  for (const borrower of uniqueBorrowers) {
588
734
  const chainType = (0, core_1.getAddressChainType)(borrower);
589
- if (chainType !== 'evm') {
590
- const fetcher = borrowerPortfolioFetchers[chainType];
591
- if (fetcher) {
592
- try {
593
- const debankRes = await fetcher(borrower);
594
- if (debankRes) {
595
- (0, debank_1.parseVaultLevelDebank)(debankRes, protocolExposure, tokenExposure, borrower, exposurePerCategory, netValue);
596
- unfilteredTokens = debankRes?.subaccount?.tokens;
597
- defiPerBorrower[borrower] = (0, debank_1.parseLoanLevelDebank)(debankRes);
598
- }
599
- else {
600
- debankErr = true;
601
- }
602
- }
603
- catch (error) {
604
- core_1.Logger.log.error(`getVaultAllocations:${chainType}`, error, {
605
- vault,
606
- borrower,
607
- });
608
- debankErr = true;
609
- }
610
- }
611
- else {
612
- // Not an error: portfolio providers simply have no coverage for this
613
- // chain type yet (Stellar, Sui). Reporting it as an exception filled
614
- // Sentry with a known, permanent gap, and setting `debankErr` made
615
- // every Stellar vault throw `failure to fetch debank response`
616
- // instead of returning the CeFi/OTC/loan allocations it did resolve.
617
- core_1.Logger.log.warn(`getVaultAllocations:no_fetcher`, {
618
- vault,
619
- borrower,
620
- chainType,
621
- reason: `No portfolio fetcher for chain type: ${chainType}`,
622
- });
623
- }
735
+ if (chainType === 'evm')
736
+ continue;
737
+ const fetcher = borrowerPortfolioFetchers[chainType];
738
+ if (!fetcher) {
739
+ // Not an error: portfolio providers simply have no coverage for this
740
+ // chain type yet (Stellar, Sui). Reporting it as an exception filled
741
+ // Sentry with a known, permanent gap, and setting `debankErr` made
742
+ // every Stellar vault throw `failure to fetch debank response`
743
+ // instead of returning the CeFi/OTC/loan allocations it did resolve.
744
+ core_1.Logger.log.warn(`getVaultAllocations:no_fetcher`, {
745
+ vault,
746
+ borrower,
747
+ chainType,
748
+ reason: `No portfolio fetcher for chain type: ${chainType}`,
749
+ });
750
+ continue;
624
751
  }
625
- // fetch cefi_positions
626
752
  try {
627
- const cefiResponse = await (0, core_1.fetchAugustWithKey)(options.augustKey, core_1.WEBSERVER_ENDPOINTS.subaccount.cefi(borrower), { headers: options?.headers });
628
- if (cefiResponse.status !== 200) {
629
- // 404 means "this subaccount has no CeFi position", which is the
630
- // common case for most borrowers — a breadcrumb, not an exception.
631
- logSubaccountFetchFailure('getVaultAllocations:cefi', cefiResponse.status, cefiResponse.statusText, { vault, borrower });
753
+ const debankRes = await fetcher(borrower);
754
+ if (debankRes) {
755
+ (0, debank_1.parseVaultLevelDebank)(debankRes, protocolExposure, tokenExposure, borrower, exposurePerCategory, netValue);
756
+ unfilteredTokens = debankRes?.subaccount?.tokens;
757
+ defiPerBorrower[borrower] = (0, debank_1.parseLoanLevelDebank)(debankRes);
632
758
  }
633
- if (cefiResponse.status === 200) {
634
- const cefiRes = (await cefiResponse.json());
635
- cefiExposure = [...cefiExposure, ...cefiRes];
759
+ else {
760
+ debankErr = true;
636
761
  }
637
762
  }
638
- catch (e) {
639
- logSubaccountFetchFailure('getVaultAllocations:cefi', httpStatusFromError(e), e, { vault, borrower });
763
+ catch (error) {
764
+ core_1.Logger.log.error(`getVaultAllocations:${chainType}`, error, {
765
+ vault,
766
+ borrower,
767
+ });
768
+ debankErr = true;
640
769
  }
641
- // fetch otc_positions
642
- try {
643
- const otcResponse = await (0, core_1.fetchAugustWithKey)(options.augustKey, core_1.WEBSERVER_ENDPOINTS.subaccount.otc_positions(borrower), { headers: options?.headers });
644
- if (otcResponse.status !== 200) {
645
- // 404 means "this subaccount has no OTC positions" — expected for
646
- // nearly every borrower. See logSubaccountFetchFailure.
647
- logSubaccountFetchFailure('getVaultAllocations:otc', otcResponse.status, otcResponse.statusText, { vault, borrower });
648
- }
649
- if (otcResponse.status === 200) {
650
- const otcRes = (await otcResponse.json());
651
- otcPositions[borrower] = otcRes;
652
- }
770
+ }
771
+ // CeFi and OTC enrichment runs for ALL borrowers regardless of chain type.
772
+ // Previously sequential — one borrower's slow (or timing-out) request
773
+ // delayed every borrower behind it, so a vault with N borrowers serialised
774
+ // 2N requests. Now cached per borrower and run through a bounded window:
775
+ // fewer requests, and the ones that remain overlap without stampeding the
776
+ // API. Both fetchers swallow their own failures, so no result is rejected.
777
+ const subaccountPositions = await (0, concurrency_1.mapWithConcurrency)(uniqueBorrowers, SUBACCOUNT_FETCH_CONCURRENCY, async (borrower) => ({
778
+ borrower,
779
+ cefi: await fetchSubaccountCefi(borrower, options, vault),
780
+ otc: await fetchSubaccountOtc(borrower, options, vault),
781
+ }));
782
+ // Fold sequentially so the accumulated order stays deterministic and
783
+ // independent of which request finished first.
784
+ for (const { borrower, cefi, otc } of subaccountPositions) {
785
+ if (cefi) {
786
+ cefiExposure = [...cefiExposure, ...cefi];
653
787
  }
654
- catch (e) {
655
- logSubaccountFetchFailure('getVaultAllocations:otc', httpStatusFromError(e), e, { vault, borrower });
788
+ if (otc) {
789
+ otcPositions[borrower] = otc;
656
790
  }
657
791
  }
658
792
  }
@@ -2106,7 +2240,7 @@ async function getYieldLastRealizedOn({ vault, options, }) {
2106
2240
  }
2107
2241
  }
2108
2242
  /**
2109
- * Guard against the 2026-07-09 lifetime-PnL over-inflation failure mode.
2243
+ * Guard against lifetime-PnL over-inflation when the deposit history fails to load.
2110
2244
  *
2111
2245
  * Lifetime PnL is `currentPosition + totalWithdrawn - totalDeposited`. When the
2112
2246
  * deposit/withdrawal history fails to load it collapses to empty, so both
@@ -2714,7 +2848,7 @@ async function getVaultHistoricalTimeseries({ vault, nDays, options, }) {
2714
2848
  * Supported Vaults: cUSDO, tETH, wstETH, rsETH
2715
2849
  *
2716
2850
  * @deprecated The `hgETH30dLiquidAPY` and `hgETH7dLiquidAPY` response fields are deprecated.
2717
- * These fields will be removed on 2026-01-01.
2851
+ * These fields will be removed in the next major release.
2718
2852
  * Use `liquidAPY30Day` and `liquidAPY7Day` fields instead.
2719
2853
  *
2720
2854
  * @param vault - Vault contract address
@@ -55,8 +55,8 @@ export declare class AugustVaults extends AugustBase {
55
55
  * `balanceOf`/`lagDuration` reads are aggregated into chunked Multicall3
56
56
  * `aggregate3` batches per chain (10 calls per chunk) on chains where the
57
57
  * canonical Multicall3 deployment is verified; other chains (e.g. Citrea
58
- * 4114) keep one `eth_call` per read. Measured with
59
- * `benchmarks/request-counter.js` on a cold cache for a wallet with 62
58
+ * 4114) keep one `eth_call` per read. Measured on a
59
+ * cold cache for a wallet with 62
60
60
  * vaults across Ethereum + Avalanche: 83 RPC HTTP requests before batching,
61
61
  * 54 after (~35% fewer; 124 per-vault `eth_call`s collapse into ~13
62
62
  * `aggregate3` calls — the remaining requests are the per-vault cached
@@ -217,7 +217,7 @@ export declare class AugustVaults extends AugustBase {
217
217
  * Multicall3 `aggregate3` batches per chain (10 calls per chunk) on chains
218
218
  * where the canonical deployment is verified; unverified chains (e.g.
219
219
  * Citrea 4114) and non-EVM vaults keep one `eth_call` per read. Measured
220
- * with `benchmarks/request-counter.js` on a cold cache for a wallet with 62
220
+ * on a cold cache for a wallet with 62
221
221
  * vaults across Ethereum + Avalanche: 83 RPC HTTP requests before batching,
222
222
  * 54 after (~35% fewer). A vault whose batched read fails (e.g. paused)
223
223
  * falls back to its own per-vault reads — never to a zeroed balance.
@@ -469,7 +469,7 @@ export declare class AugustVaults extends AugustBase {
469
469
  * Supported Vaults: cUSDO, tETH, wstETH, rsETH
470
470
  *
471
471
  * @deprecated The `hgETH30dLiquidAPY` and `hgETH7dLiquidAPY` response fields are deprecated.
472
- * These fields will be removed on 2026-01-01.
472
+ * These fields will be removed in the next major release.
473
473
  * Use `liquidAPY30Day` and `liquidAPY7Day` fields instead.
474
474
  *
475
475
  * @param vault Vault address
@@ -127,8 +127,8 @@ class AugustVaults extends core_1.AugustBase {
127
127
  * `balanceOf`/`lagDuration` reads are aggregated into chunked Multicall3
128
128
  * `aggregate3` batches per chain (10 calls per chunk) on chains where the
129
129
  * canonical Multicall3 deployment is verified; other chains (e.g. Citrea
130
- * 4114) keep one `eth_call` per read. Measured with
131
- * `benchmarks/request-counter.js` on a cold cache for a wallet with 62
130
+ * 4114) keep one `eth_call` per read. Measured on a
131
+ * cold cache for a wallet with 62
132
132
  * vaults across Ethereum + Avalanche: 83 RPC HTTP requests before batching,
133
133
  * 54 after (~35% fewer; 124 per-vault `eth_call`s collapse into ~13
134
134
  * `aggregate3` calls — the remaining requests are the per-vault cached
@@ -392,6 +392,9 @@ class AugustVaults extends core_1.AugustBase {
392
392
  augustKey: this.keys?.august,
393
393
  subgraphKey: this.keys?.graph,
394
394
  headers: this.headers,
395
+ // Rebuilding these options previously dropped this, making the flag
396
+ // unreachable on the per-address path.
397
+ includeClosed: options?.includeClosed,
395
398
  },
396
399
  loadSubaccounts,
397
400
  loadSnapshots,
@@ -675,7 +678,7 @@ class AugustVaults extends core_1.AugustBase {
675
678
  * Multicall3 `aggregate3` batches per chain (10 calls per chunk) on chains
676
679
  * where the canonical deployment is verified; unverified chains (e.g.
677
680
  * Citrea 4114) and non-EVM vaults keep one `eth_call` per read. Measured
678
- * with `benchmarks/request-counter.js` on a cold cache for a wallet with 62
681
+ * on a cold cache for a wallet with 62
679
682
  * vaults across Ethereum + Avalanche: 83 RPC HTTP requests before batching,
680
683
  * 54 after (~35% fewer). A vault whose batched read fails (e.g. paused)
681
684
  * falls back to its own per-vault reads — never to a zeroed balance.
@@ -1386,7 +1389,7 @@ class AugustVaults extends core_1.AugustBase {
1386
1389
  * Supported Vaults: cUSDO, tETH, wstETH, rsETH
1387
1390
  *
1388
1391
  * @deprecated The `hgETH30dLiquidAPY` and `hgETH7dLiquidAPY` response fields are deprecated.
1389
- * These fields will be removed on 2026-01-01.
1392
+ * These fields will be removed in the next major release.
1390
1393
  * Use `liquidAPY30Day` and `liquidAPY7Day` fields instead.
1391
1394
  *
1392
1395
  * @param vault Vault address
@@ -223,3 +223,184 @@ export declare function balanceOf(signer: IContractRunner, options: IBalanceOfOp
223
223
  * ```
224
224
  */
225
225
  export declare function maxDeposit(signer: IContractRunner, options: IMaxDepositOptions): Promise<bigint>;
226
+ /** Options for {@link getIdleLiquidity}. */
227
+ export type IGetIdleLiquidityOptions = {
228
+ /** EVM-2 (Tokenized Vault V2) vault contract address. */
229
+ vault: IAddress;
230
+ };
231
+ /**
232
+ * Read an EVM-2 vault's idle (uncommitted) liquidity — the balance available
233
+ * to satisfy an instant redemption without a synchronous recall from the
234
+ * settlement module, computed as `getTotalAssets() - externalAssets()`.
235
+ *
236
+ * EVM-2 only. Two on-chain reads with no caching — call it immediately
237
+ * before sizing an instant redemption rather than reusing a stale value, and
238
+ * size the redemption against the result rather than against total assets.
239
+ *
240
+ * @returns Idle liquidity, in the vault's reference-asset raw units.
241
+ * @throws AugustValidationError on invalid vault address or a non-EVM-2 vault.
242
+ * @throws AugustSDKError when either underlying contract read fails.
243
+ *
244
+ * @worstCaseRpcCalls 3 — vault-version lookup, `getTotalAssets`, `externalAssets`.
245
+ *
246
+ * @example
247
+ * ```ts
248
+ * const idle = await augustSdk.evm.getIdleLiquidity({ vault: vaultAddress });
249
+ * if (redeemAmount > idle) {
250
+ * // fall back to a queued withdrawal instead of an instant one
251
+ * }
252
+ * ```
253
+ */
254
+ export declare function getIdleLiquidity(signer: IContractRunner, options: IGetIdleLiquidityOptions): Promise<bigint>;
255
+ /** Options for {@link lagDuration}. */
256
+ export type ILagDurationOptions = {
257
+ /** EVM-2 (Tokenized Vault V2) vault contract address. */
258
+ vault: IAddress;
259
+ };
260
+ /**
261
+ * Read an EVM-2 vault's queued-withdrawal lag — the delay, in seconds,
262
+ * between `requestRedeem` and the withdrawal epoch becoming claimable.
263
+ *
264
+ * EVM-2 only. This value is per-vault (259,200s / 3 days on sentUSD, but
265
+ * shorter on other deployments) and can change after launch — read it live
266
+ * rather than hardcoding it.
267
+ *
268
+ * @returns Lag duration, in seconds.
269
+ * @throws AugustValidationError on invalid vault address or a non-EVM-2 vault.
270
+ * @throws AugustSDKError when the underlying contract read fails.
271
+ *
272
+ * @worstCaseRpcCalls 2 — vault-version lookup, `lagDuration`.
273
+ *
274
+ * @example
275
+ * ```ts
276
+ * const seconds = await augustSdk.evm.lagDuration({ vault: vaultAddress });
277
+ * ```
278
+ */
279
+ export declare function lagDuration(signer: IContractRunner, options: ILagDurationOptions): Promise<bigint>;
280
+ /** Options for {@link getWithdrawalEpoch}. */
281
+ export type IGetWithdrawalEpochOptions = {
282
+ /** EVM-2 (Tokenized Vault V2) vault contract address. */
283
+ vault: IAddress;
284
+ };
285
+ /** An EVM-2 vault's current withdrawal epoch, as read from `getWithdrawalEpoch()`. */
286
+ export type IWithdrawalEpoch = {
287
+ year: bigint;
288
+ month: bigint;
289
+ day: bigint;
290
+ /** Unix timestamp at which the current epoch's queued withdrawals become claimable. */
291
+ claimableEpoch: bigint;
292
+ };
293
+ /**
294
+ * Read an EVM-2 vault's current withdrawal epoch.
295
+ *
296
+ * The on-chain return order is `(year, month, day, claimableEpoch)` —
297
+ * `claimableEpoch` last, not first. This is the opposite order from what
298
+ * `requestRedeem` returns (`(claimableEpoch, year, month, day)`, epoch
299
+ * first); treat that call's return value, not this one, as the source of
300
+ * truth for a specific withdrawal's claim date.
301
+ *
302
+ * @returns The vault's current withdrawal epoch, by named field.
303
+ * @throws AugustValidationError on invalid vault address or a non-EVM-2 vault.
304
+ * @throws AugustSDKError when the underlying contract read fails.
305
+ *
306
+ * @worstCaseRpcCalls 2 — vault-version lookup, `getWithdrawalEpoch`.
307
+ *
308
+ * @example
309
+ * ```ts
310
+ * const { year, month, day, claimableEpoch } = await augustSdk.evm.getWithdrawalEpoch({
311
+ * vault: vaultAddress,
312
+ * });
313
+ * ```
314
+ */
315
+ export declare function getWithdrawalEpoch(signer: IContractRunner, options: IGetWithdrawalEpochOptions): Promise<IWithdrawalEpoch>;
316
+ /** Options shared by the EVM-2 queued-withdrawal-date reads. */
317
+ type IWithdrawalDateOptions = {
318
+ /** EVM-2 (Tokenized Vault V2) vault contract address. */
319
+ vault: IAddress;
320
+ /** Withdrawal-epoch year, as returned by `requestRedeem`/`getWithdrawalEpoch`. */
321
+ year: string | bigint | number;
322
+ /** Withdrawal-epoch month, same source as `year`. */
323
+ month: string | bigint | number;
324
+ /** Withdrawal-epoch day, same source as `year`. */
325
+ day: string | bigint | number;
326
+ };
327
+ /** Options for {@link getBurnableAmountByReceiver}. */
328
+ export type IGetBurnableAmountByReceiverOptions = IWithdrawalDateOptions & {
329
+ /** Address whose claimable amount for this date is being queried. */
330
+ receiver: IAddress;
331
+ };
332
+ /**
333
+ * Read how much of a withdrawal-epoch date's queue a given receiver can
334
+ * currently claim via `claim`, before sending the claim transaction.
335
+ *
336
+ * EVM-2 only.
337
+ *
338
+ * @returns The claimable amount, in share-token raw units.
339
+ * @throws AugustValidationError on invalid address input or a non-EVM-2 vault.
340
+ * @throws AugustSDKError when the underlying contract read fails.
341
+ *
342
+ * @worstCaseRpcCalls 2 — vault-version lookup, `getBurnableAmountByReceiver`.
343
+ *
344
+ * @example
345
+ * ```ts
346
+ * const claimable = await augustSdk.evm.getBurnableAmountByReceiver({
347
+ * vault: vaultAddress,
348
+ * receiver: walletAddress,
349
+ * year, month, day,
350
+ * });
351
+ * ```
352
+ */
353
+ export declare function getBurnableAmountByReceiver(signer: IContractRunner, options: IGetBurnableAmountByReceiverOptions): Promise<bigint>;
354
+ /** Options for {@link getRequirementByDate}. */
355
+ export type IGetRequirementByDateOptions = IWithdrawalDateOptions;
356
+ /**
357
+ * Read the total shares required to settle a withdrawal-epoch date's entire
358
+ * queue.
359
+ *
360
+ * EVM-2 only.
361
+ *
362
+ * @returns Required shares, in share-token raw units.
363
+ * @throws AugustValidationError on invalid vault address or a non-EVM-2 vault.
364
+ * @throws AugustSDKError when the underlying contract read fails.
365
+ *
366
+ * @worstCaseRpcCalls 2 — vault-version lookup, `getRequirementByDate`.
367
+ *
368
+ * @example
369
+ * ```ts
370
+ * const shares = await augustSdk.evm.getRequirementByDate({
371
+ * vault: vaultAddress,
372
+ * year, month, day,
373
+ * });
374
+ * ```
375
+ */
376
+ export declare function getRequirementByDate(signer: IContractRunner, options: IGetRequirementByDateOptions): Promise<bigint>;
377
+ /** Options for {@link getScheduledTransactionsByDate}. */
378
+ export type IGetScheduledTransactionsByDateOptions = IWithdrawalDateOptions;
379
+ /** Scheduled queued-withdrawal volume for a withdrawal-epoch date. */
380
+ export type IScheduledTransactionsByDate = {
381
+ totalTransactions: bigint;
382
+ /** Unix timestamp this date's queue is scheduled to execute. */
383
+ executionEpoch: bigint;
384
+ };
385
+ /**
386
+ * Read the scheduled queued-withdrawal volume for a withdrawal-epoch date.
387
+ *
388
+ * EVM-2 only.
389
+ *
390
+ * @returns Total scheduled transactions and their execution epoch.
391
+ * @throws AugustValidationError on invalid vault address or a non-EVM-2 vault.
392
+ * @throws AugustSDKError when the underlying contract read fails.
393
+ *
394
+ * @worstCaseRpcCalls 2 — vault-version lookup, `getScheduledTransactionsByDate`.
395
+ *
396
+ * @example
397
+ * ```ts
398
+ * const { totalTransactions, executionEpoch } =
399
+ * await augustSdk.evm.getScheduledTransactionsByDate({
400
+ * vault: vaultAddress,
401
+ * year, month, day,
402
+ * });
403
+ * ```
404
+ */
405
+ export declare function getScheduledTransactionsByDate(signer: IContractRunner, options: IGetScheduledTransactionsByDateOptions): Promise<IScheduledTransactionsByDate>;
406
+ export {};