@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
@@ -195,6 +195,30 @@ function buildRequestAbortSignal(options) {
195
195
  },
196
196
  };
197
197
  }
198
+ /**
199
+ * Build the `AugustTimeoutError` a fetcher throws when its own timeout fired,
200
+ * and record it as a breadcrumb rather than a Sentry issue.
201
+ *
202
+ * Severity rationale: the error is *thrown* to the caller, so whoever owns the
203
+ * request decides whether it is fatal. Logging it at `error` here as well made
204
+ * every timeout a standalone Sentry issue even when the caller swallowed it
205
+ * (`Promise.allSettled` fan-outs in `getVaultAllocations` do exactly that) — a
206
+ * single stalled render produced 20–30 identical issues in the same second and
207
+ * ~40k events a week, none of them separately actionable. As a breadcrumb the
208
+ * timeout still rides along with whatever the caller ultimately reports, with
209
+ * the endpoint and elapsed budget attached.
210
+ *
211
+ * @param tag - Call-site tag (`fetchAugustPublic`, …) used as the breadcrumb label.
212
+ * @param relativeUrl - Endpoint path that timed out; sanitized before use.
213
+ * @param timeoutMs - Timeout budget that elapsed, in milliseconds.
214
+ * @returns The error to throw. Never throws.
215
+ * @internal
216
+ */
217
+ function timeoutErrorFor(tag, relativeUrl, timeoutMs) {
218
+ const timeoutError = new errors_1.AugustTimeoutError((0, sanitize_1.sanitizeString)(`Request timeout after ${timeoutMs / 1000}s: ${relativeUrl}`), timeoutMs);
219
+ logger_1.Logger.log.warn(tag, { relativeUrl, timeoutMs, reason: 'request timeout' });
220
+ return timeoutError;
221
+ }
198
222
  let _overrideDeprecationWarned = false;
199
223
  function warnOverrideDeprecation(callerTag) {
200
224
  if (_overrideDeprecationWarned)
@@ -250,6 +274,46 @@ const PRICE_ERROR_CACHE = new lru_cache_1.LRUCache({
250
274
  * In-flight price requests to prevent duplicate simultaneous API calls.
251
275
  */
252
276
  const PRICE_REQUESTS = new Map();
277
+ /**
278
+ * In-flight `/tokenized_vault` requests, keyed by the same cache key the
279
+ * response is stored under.
280
+ *
281
+ * The response cache alone only de-duplicates *sequential* calls: a cold
282
+ * process (a fresh serverless container, a hard page load) fans out N
283
+ * concurrent `getVault` calls for the same vault before any of them has
284
+ * populated the cache, so all N hit the backend. Under load that self-inflicted
285
+ * stampede is what pushed `/tokenized_vault/{address}` past its timeout — the
286
+ * single largest source of `AugustTimeoutError` in production.
287
+ *
288
+ * Joining concurrent callers onto one promise collapses that fan-out to a
289
+ * single request. Entries are removed as soon as the request settles, so a
290
+ * failure is never cached — the next caller retries.
291
+ */
292
+ const TOKENIZED_VAULT_REQUESTS = new Map();
293
+ /**
294
+ * Run `factory` at most once per `key` while it is in flight, joining any
295
+ * concurrent caller onto the same promise.
296
+ *
297
+ * This is a de-duplication primitive, not a cache: the entry lives only for the
298
+ * duration of the request and is cleared on both success and failure, so errors
299
+ * are never shared beyond the callers that were already waiting.
300
+ *
301
+ * @param registry - Map holding the in-flight promises for this resource type.
302
+ * @param key - Identity of the request; callers sharing a key share a result.
303
+ * @param factory - Produces the promise to run when no request is in flight.
304
+ * @returns The shared promise for `key`.
305
+ * @internal
306
+ */
307
+ function dedupeInFlight(registry, key, factory) {
308
+ const existing = registry.get(key);
309
+ if (existing)
310
+ return existing;
311
+ const request = factory().finally(() => {
312
+ registry.delete(key);
313
+ });
314
+ registry.set(key, request);
315
+ return request;
316
+ }
253
317
  /**
254
318
  * Build an August backend URL, rejecting unknown server keys and any
255
319
  * `relativeUrl` that would escape the configured origin.
@@ -347,9 +411,7 @@ async function fetchAugustWithKey(apiKey, relativeUrl, options) {
347
411
  if (!timedOut()) {
348
412
  throw err;
349
413
  }
350
- const timeoutError = new errors_1.AugustTimeoutError((0, sanitize_1.sanitizeString)(`Request timeout after ${effectiveTimeoutMs / 1000}s: ${relativeUrl}`), effectiveTimeoutMs);
351
- logger_1.Logger.log.error('fetchAugustWithKey', timeoutError, { relativeUrl });
352
- throw timeoutError;
414
+ throw timeoutErrorFor('fetchAugustWithKey', relativeUrl, effectiveTimeoutMs);
353
415
  }
354
416
  throw err;
355
417
  }
@@ -402,9 +464,7 @@ async function fetchAugustPublic(relativeUrl, options) {
402
464
  if (!timedOut()) {
403
465
  throw err;
404
466
  }
405
- const timeoutError = new errors_1.AugustTimeoutError((0, sanitize_1.sanitizeString)(`Request timeout after ${effectiveTimeoutMs / 1000}s: ${relativeUrl}`), effectiveTimeoutMs);
406
- logger_1.Logger.log.error('fetchAugustPublic', timeoutError, { relativeUrl });
407
- throw timeoutError;
467
+ throw timeoutErrorFor('fetchAugustPublic', relativeUrl, effectiveTimeoutMs);
408
468
  }
409
469
  throw err;
410
470
  }
@@ -460,9 +520,7 @@ async function fetchAugustWithBearer(bearerToken, relativeUrl, options) {
460
520
  if (!timedOut()) {
461
521
  throw err;
462
522
  }
463
- const timeoutError = new errors_1.AugustTimeoutError((0, sanitize_1.sanitizeString)(`Request timeout after ${effectiveTimeoutMs / 1000}s: ${relativeUrl}`), effectiveTimeoutMs);
464
- logger_1.Logger.log.error('fetchAugustWithBearer', timeoutError, { relativeUrl });
465
- throw timeoutError;
523
+ throw timeoutErrorFor('fetchAugustWithBearer', relativeUrl, effectiveTimeoutMs);
466
524
  }
467
525
  throw err;
468
526
  }
@@ -535,24 +593,29 @@ async function fetchTokenizedVault(pool, headers, loadSubaccounts, loadSnapshots
535
593
  tokenizedVault = cachedResponse;
536
594
  }
537
595
  if (!tokenizedVault) {
538
- // Build endpoint URL with optional query parameters
539
- let endpoint = core_2.WEBSERVER_ENDPOINTS.public.tokenizedVault.byVaultAddress(pool);
540
- const params = new URLSearchParams();
541
- if (loadSubaccounts === false) {
542
- params.set('load_subaccounts', 'false');
543
- }
544
- if (loadSnapshots === false) {
545
- params.set('load_snapshots', 'false');
546
- }
547
- const queryString = params.toString();
548
- if (queryString) {
549
- endpoint += `?${queryString}`;
550
- }
551
- const tokenizedVaultsResponse = await fetchAugustPublic(endpoint, {
552
- headers: headers,
596
+ // Concurrent callers for the same vault share one request; see
597
+ // TOKENIZED_VAULT_REQUESTS.
598
+ tokenizedVault = await dedupeInFlight(TOKENIZED_VAULT_REQUESTS, key, async () => {
599
+ // Build endpoint URL with optional query parameters
600
+ let endpoint = core_2.WEBSERVER_ENDPOINTS.public.tokenizedVault.byVaultAddress(pool);
601
+ const params = new URLSearchParams();
602
+ if (loadSubaccounts === false) {
603
+ params.set('load_subaccounts', 'false');
604
+ }
605
+ if (loadSnapshots === false) {
606
+ params.set('load_snapshots', 'false');
607
+ }
608
+ const queryString = params.toString();
609
+ if (queryString) {
610
+ endpoint += `?${queryString}`;
611
+ }
612
+ const tokenizedVaultsResponse = await fetchAugustPublic(endpoint, {
613
+ headers: headers,
614
+ });
615
+ const parsed = (await tokenizedVaultsResponse.json());
616
+ cache_1.CACHE.set(key, parsed, { ttl: 1000 * 60 * 10 }); // Cache for 10 minutes
617
+ return parsed;
553
618
  });
554
- tokenizedVault = (await tokenizedVaultsResponse.json());
555
- cache_1.CACHE.set(key, tokenizedVault, { ttl: 1000 * 60 * 10 }); // Cache for 10 minutes
556
619
  }
557
620
  // Filter by specific vault if address provided
558
621
  if (pool &&
@@ -585,26 +648,30 @@ async function fetchTokenizedVaults(pool, headers, loadSubaccounts, loadSnapshot
585
648
  tokenizedVaults = cachedResponse;
586
649
  }
587
650
  if (!tokenizedVaults) {
588
- // Build endpoint URL with optional query parameters
589
- let endpoint = core_2.WEBSERVER_ENDPOINTS.public.tokenizedVault.list;
590
- const params = new URLSearchParams();
591
- if (loadSubaccounts === false) {
592
- params.set('load_subaccounts', 'false');
593
- }
594
- if (loadSnapshots === false) {
595
- params.set('load_snapshots', 'false');
596
- }
597
- const queryString = params.toString();
598
- if (queryString) {
599
- endpoint += `?${queryString}`;
600
- }
601
- const tokenizedVaultsResponse = await fetchAugustPublic(endpoint, {
602
- headers: headers,
651
+ // The vault list is requested by every vault page at once on a cold
652
+ // process; join concurrent callers onto one request.
653
+ tokenizedVaults = await dedupeInFlight(TOKENIZED_VAULT_REQUESTS, key, async () => {
654
+ // Build endpoint URL with optional query parameters
655
+ let endpoint = core_2.WEBSERVER_ENDPOINTS.public.tokenizedVault.list;
656
+ const params = new URLSearchParams();
657
+ if (loadSubaccounts === false) {
658
+ params.set('load_subaccounts', 'false');
659
+ }
660
+ if (loadSnapshots === false) {
661
+ params.set('load_snapshots', 'false');
662
+ }
663
+ const queryString = params.toString();
664
+ if (queryString) {
665
+ endpoint += `?${queryString}`;
666
+ }
667
+ const tokenizedVaultsResponse = await fetchAugustPublic(endpoint, {
668
+ headers: headers,
669
+ });
670
+ const parsed = (await tokenizedVaultsResponse.json());
671
+ const ttl = 1000 * 60 * 15; // 15 minute cache
672
+ cache_1.CACHE.set(key, parsed, { ttl });
673
+ return parsed;
603
674
  });
604
- tokenizedVaults =
605
- (await tokenizedVaultsResponse.json());
606
- const ttl = 1000 * 60 * 15; // 15 minute cache
607
- cache_1.CACHE.set(key, tokenizedVaults, { ttl });
608
675
  }
609
676
  // Filter by specific vault if address provided
610
677
  if (pool &&
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Concurrency helpers.
3
+ *
4
+ * Internal only — deliberately not re-exported from `core/index.ts`, so it is
5
+ * not part of the published API surface.
6
+ *
7
+ * Leaf module: depends on nothing inside the SDK, so it is safe to import from
8
+ * any layer without forming a cycle (see CLAUDE.md §9).
9
+ */
10
+ /**
11
+ * Map over `items` running at most `limit` tasks at a time.
12
+ *
13
+ * Exists because `Promise.all` over a caller-sized array is unbounded: a vault
14
+ * with 40 borrowers opens 40 simultaneous connections to the same backend,
15
+ * which is how a slow endpoint turns into a timeout storm rather than a slow
16
+ * response. A small fixed window keeps latency close to the parallel case while
17
+ * bounding the load the SDK can put on one origin.
18
+ *
19
+ * Results preserve input order regardless of completion order. A rejected task
20
+ * rejects the returned promise (like `Promise.all`); callers that need
21
+ * per-item error isolation should catch inside `task`.
22
+ *
23
+ * @param items - Inputs to process. An empty array resolves to `[]` immediately.
24
+ * @param limit - Maximum tasks in flight. Values below 1 are treated as 1.
25
+ * @param task - Receives an item and its index; returns the value for that slot.
26
+ * @returns Results in the same order as `items`.
27
+ * @throws Whatever `task` rejects with, on the first rejection.
28
+ * @example
29
+ * ```ts
30
+ * // At most 5 concurrent requests, regardless of borrower count.
31
+ * const positions = await mapWithConcurrency(borrowers, 5, (b) =>
32
+ * fetchPosition(b).catch(() => null),
33
+ * );
34
+ * ```
35
+ * @internal
36
+ */
37
+ export declare function mapWithConcurrency<TIn, TOut>(items: readonly TIn[], limit: number, task: (item: TIn, index: number) => Promise<TOut>): Promise<TOut[]>;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ /**
3
+ * Concurrency helpers.
4
+ *
5
+ * Internal only — deliberately not re-exported from `core/index.ts`, so it is
6
+ * not part of the published API surface.
7
+ *
8
+ * Leaf module: depends on nothing inside the SDK, so it is safe to import from
9
+ * any layer without forming a cycle (see CLAUDE.md §9).
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.mapWithConcurrency = mapWithConcurrency;
13
+ /**
14
+ * Map over `items` running at most `limit` tasks at a time.
15
+ *
16
+ * Exists because `Promise.all` over a caller-sized array is unbounded: a vault
17
+ * with 40 borrowers opens 40 simultaneous connections to the same backend,
18
+ * which is how a slow endpoint turns into a timeout storm rather than a slow
19
+ * response. A small fixed window keeps latency close to the parallel case while
20
+ * bounding the load the SDK can put on one origin.
21
+ *
22
+ * Results preserve input order regardless of completion order. A rejected task
23
+ * rejects the returned promise (like `Promise.all`); callers that need
24
+ * per-item error isolation should catch inside `task`.
25
+ *
26
+ * @param items - Inputs to process. An empty array resolves to `[]` immediately.
27
+ * @param limit - Maximum tasks in flight. Values below 1 are treated as 1.
28
+ * @param task - Receives an item and its index; returns the value for that slot.
29
+ * @returns Results in the same order as `items`.
30
+ * @throws Whatever `task` rejects with, on the first rejection.
31
+ * @example
32
+ * ```ts
33
+ * // At most 5 concurrent requests, regardless of borrower count.
34
+ * const positions = await mapWithConcurrency(borrowers, 5, (b) =>
35
+ * fetchPosition(b).catch(() => null),
36
+ * );
37
+ * ```
38
+ * @internal
39
+ */
40
+ async function mapWithConcurrency(items, limit, task) {
41
+ if (items.length === 0)
42
+ return [];
43
+ const width = Math.max(1, Math.min(Math.floor(limit), items.length));
44
+ const results = new Array(items.length);
45
+ // Shared cursor: each worker repeatedly claims the next unclaimed index, so
46
+ // a slow item never blocks the workers behind it (as a fixed chunked split
47
+ // would).
48
+ let cursor = 0;
49
+ const worker = async () => {
50
+ while (cursor < items.length) {
51
+ const index = cursor++;
52
+ results[index] = await task(items[index], index);
53
+ }
54
+ };
55
+ await Promise.all(Array.from({ length: width }, worker));
56
+ return results;
57
+ }
58
+ //# sourceMappingURL=concurrency.js.map
@@ -66,3 +66,12 @@ export declare function calculateWeights<T extends Record<string, unknown>>(data
66
66
  * @returns Weighted average
67
67
  */
68
68
  export declare function calculateWeightedAverage<T extends Record<string, unknown>>(data?: T[], valueProperty?: string, weightProperty?: string): number;
69
+ /**
70
+ * Coerce a caller-supplied integer (`string | bigint | number`) to a `bigint`,
71
+ * rejecting anything that is not a non-negative safe integer. `label` names the
72
+ * calling method and `noun` the field being validated, so bad input surfaces as
73
+ * `AugustValidationError('INVALID_INPUT')` at the SDK boundary instead of a
74
+ * `BigInt()` SyntaxError wrapped as `UNKNOWN`.
75
+ * @internal
76
+ */
77
+ export declare function toRawBigInt(value: string | bigint | number, label: string, noun?: string): bigint;
@@ -15,8 +15,10 @@ exports.prepareDateForDb = prepareDateForDb;
15
15
  exports.orderObjArrByDate = orderObjArrByDate;
16
16
  exports.calculateWeights = calculateWeights;
17
17
  exports.calculateWeightedAverage = calculateWeightedAverage;
18
+ exports.toRawBigInt = toRawBigInt;
18
19
  const web3_1 = require("../constants/web3");
19
20
  const ethers_1 = require("ethers");
21
+ const errors_1 = require("../errors");
20
22
  /**
21
23
  * Table of Contents
22
24
  * - Formatters
@@ -282,4 +284,49 @@ function calculateWeightedAverage(data, valueProperty, weightProperty) {
282
284
  const weightedAverage = weightedData.reduce((acc, item) => acc + item[valueProperty] * item.weight, 0);
283
285
  return weightedAverage;
284
286
  }
287
+ /**
288
+ * Coerce a caller-supplied integer (`string | bigint | number`) to a `bigint`,
289
+ * rejecting anything that is not a non-negative safe integer. `label` names the
290
+ * calling method and `noun` the field being validated, so bad input surfaces as
291
+ * `AugustValidationError('INVALID_INPUT')` at the SDK boundary instead of a
292
+ * `BigInt()` SyntaxError wrapped as `UNKNOWN`.
293
+ * @internal
294
+ */
295
+ function toRawBigInt(value, label, noun = 'amount') {
296
+ if (typeof value === 'bigint')
297
+ return value;
298
+ if (typeof value === 'number') {
299
+ if (!Number.isFinite(value)) {
300
+ throw new errors_1.AugustValidationError('INVALID_INPUT', `${label}: ${noun} must be finite, got ${value}`);
301
+ }
302
+ if (value < 0) {
303
+ throw new errors_1.AugustValidationError('INVALID_INPUT', `${label}: ${noun} must be non-negative, got ${value}`);
304
+ }
305
+ if (!Number.isInteger(value)) {
306
+ throw new errors_1.AugustValidationError('INVALID_INPUT', `${label}: ${noun} must be an integer, got ${value}`);
307
+ }
308
+ if (!Number.isSafeInteger(value)) {
309
+ throw new errors_1.AugustValidationError('INVALID_INPUT', `${label}: ${noun} ${value} exceeds Number.MAX_SAFE_INTEGER; pass a string or bigint to preserve precision`);
310
+ }
311
+ return BigInt(value);
312
+ }
313
+ if (typeof value === 'string') {
314
+ if (value.trim() === '') {
315
+ throw new errors_1.AugustValidationError('INVALID_INPUT', `${label}: ${noun} string must not be empty`);
316
+ }
317
+ try {
318
+ const parsed = BigInt(value);
319
+ if (parsed < 0n) {
320
+ throw new errors_1.AugustValidationError('INVALID_INPUT', `${label}: ${noun} must be non-negative, got ${value}`);
321
+ }
322
+ return parsed;
323
+ }
324
+ catch (e) {
325
+ if (e instanceof errors_1.AugustValidationError)
326
+ throw e;
327
+ throw new errors_1.AugustValidationError('INVALID_INPUT', `${label}: ${noun} "${value}" is not a valid integer`);
328
+ }
329
+ }
330
+ throw new errors_1.AugustValidationError('INVALID_INPUT', `${label}: ${noun} must be a string, bigint, or number`);
331
+ }
285
332
  //# sourceMappingURL=core.js.map
@@ -49,7 +49,7 @@ export declare const getDefaultSubgraphUrl: (_network: string, _symbol: string)
49
49
  /**
50
50
  * Resolve whether a single fee (management or performance) is currently waived.
51
51
  *
52
- * Backend-driven, per AUGUST-5584. This centralizes logic that previously lived —
52
+ * Backend-driven. This centralizes logic that previously lived —
53
53
  * and diverged — across two upshift-app components. The resolution is deliberately
54
54
  * split between the backend and the SDK:
55
55
  *
@@ -183,7 +183,7 @@ exports.getDefaultSubgraphUrl = getDefaultSubgraphUrl;
183
183
  /**
184
184
  * Resolve whether a single fee (management or performance) is currently waived.
185
185
  *
186
- * Backend-driven, per AUGUST-5584. This centralizes logic that previously lived —
186
+ * Backend-driven. This centralizes logic that previously lived —
187
187
  * and diverged — across two upshift-app components. The resolution is deliberately
188
188
  * split between the backend and the SDK:
189
189
  *
@@ -735,7 +735,20 @@ const getSymbol = async (provider, address, isVault = true) => {
735
735
  }
736
736
  }
737
737
  catch (e) {
738
- logger_1.Logger.log.error('getSymbol', `${address}::${e}`);
738
+ // Recovered failure, not an incident: the caller gets `undefined` and
739
+ // renders without a symbol. Logging it at `error` made every transient
740
+ // RPC hiccup ("socket hang up", connection reset) a standalone Sentry
741
+ // issue — ~24k events across one grouping, none actionable — and the
742
+ // interpolated `${address}::${e}` message put the token address in the
743
+ // issue title, so each address produced its own group.
744
+ //
745
+ // As a warning it becomes a breadcrumb on whatever the caller ultimately
746
+ // reports, with the address and reason as structured fields.
747
+ logger_1.Logger.log.warn('getSymbol', {
748
+ address,
749
+ isVault,
750
+ reason: e instanceof Error ? e.message : String(e),
751
+ });
739
752
  return undefined;
740
753
  }
741
754
  finally {
@@ -182,7 +182,7 @@ export declare function areCuratorAlertsEnabled(): boolean;
182
182
  * request/queue path — so a curator whose users' redemptions are failing has
183
183
  * no signal at all today: the failure surfaces to the user, and to August's
184
184
  * internal Sentry, and stops there. Emitting from the SDK rather than from a
185
- * single frontend means any integration can report one (AUGUST-7162) — subject
185
+ * single frontend means any integration can report one — subject
186
186
  * to the CORS caveat on {@link DEFAULT_CURATOR_ALERT_ENDPOINT}.
187
187
  *
188
188
  * **Trust model.** The endpoint is public by construction — it ships in this
@@ -210,7 +210,7 @@ export declare function areCuratorAlertsEnabled(): boolean;
210
210
  * process; `sharesRaw` is relayed unscaled, and the receiving service scales
211
211
  * it for display with the decimals it holds for that vault — which for an
212
212
  * offset vault are the asset's, not the share token's, so the figure a curator
213
- * sees is a magnitude rather than an exact amount (see AUGUST-6381).
213
+ * sees is a magnitude rather than an exact amount.
214
214
  * @internal
215
215
  */
216
216
  export declare function reportRedeemFailure(event: IRedeemFailureEvent): void;
@@ -176,7 +176,7 @@ function errorSignature(error) {
176
176
  * request/queue path — so a curator whose users' redemptions are failing has
177
177
  * no signal at all today: the failure surfaces to the user, and to August's
178
178
  * internal Sentry, and stops there. Emitting from the SDK rather than from a
179
- * single frontend means any integration can report one (AUGUST-7162) — subject
179
+ * single frontend means any integration can report one — subject
180
180
  * to the CORS caveat on {@link DEFAULT_CURATOR_ALERT_ENDPOINT}.
181
181
  *
182
182
  * **Trust model.** The endpoint is public by construction — it ships in this
@@ -204,7 +204,7 @@ function errorSignature(error) {
204
204
  * process; `sharesRaw` is relayed unscaled, and the receiving service scales
205
205
  * it for display with the decimals it holds for that vault — which for an
206
206
  * offset vault are the asset's, not the share token's, so the figure a curator
207
- * sees is a magnitude rather than an exact amount (see AUGUST-6381).
207
+ * sees is a magnitude rather than an exact amount.
208
208
  * @internal
209
209
  */
210
210
  function reportRedeemFailure(event) {
@@ -77,13 +77,12 @@ export declare function getOVaultChains(vault: IAddress): {
77
77
  * The deposit UI must not offer a spoke share destination for these vaults.
78
78
  *
79
79
  * @param vault - Vault contract address.
80
- * @returns `true` for vaults whose shares cannot leave the hub chain
81
- * (AUGUST-6300).
80
+ * @returns `true` for vaults whose shares cannot leave the hub chain.
82
81
  */
83
82
  export declare function isHubOnlyReceipt(vault: IAddress): boolean;
84
83
  /**
85
84
  * Chains a user can receive the underlying asset on when withdrawing.
86
- * Hub-only-receipt vaults redeem to the hub chain only (AUGUST-6300); all
85
+ * Hub-only-receipt vaults redeem to the hub chain only; all
87
86
  * other OVault vaults can redeem to the hub or any spoke.
88
87
  *
89
88
  * @param vault - Vault contract address.
@@ -214,15 +214,14 @@ function getOVaultChains(vault) {
214
214
  * The deposit UI must not offer a spoke share destination for these vaults.
215
215
  *
216
216
  * @param vault - Vault contract address.
217
- * @returns `true` for vaults whose shares cannot leave the hub chain
218
- * (AUGUST-6300).
217
+ * @returns `true` for vaults whose shares cannot leave the hub chain.
219
218
  */
220
219
  function isHubOnlyReceipt(vault) {
221
220
  return getCrossChainVaultConfig(vault)?.hubOnlyReceipt === true;
222
221
  }
223
222
  /**
224
223
  * Chains a user can receive the underlying asset on when withdrawing.
225
- * Hub-only-receipt vaults redeem to the hub chain only (AUGUST-6300); all
224
+ * Hub-only-receipt vaults redeem to the hub chain only; all
226
225
  * other OVault vaults can redeem to the hub or any spoke.
227
226
  *
228
227
  * @param vault - Vault contract address.
@@ -89,7 +89,7 @@ export interface ICrossChainVaultConfig {
89
89
  /**
90
90
  * When `true`, the vault's receipt token cannot leave the hub chain: there
91
91
  * is no OFT/bridge for it, so minting shares on a spoke would strand the
92
- * user (AUGUST-6300). Withdraw UIs must offer the hub chain only. Defaults
92
+ * user. Withdraw UIs must offer the hub chain only. Defaults
93
93
  * to `false` when omitted. Drives `getWithdrawDestinationChains`.
94
94
  */
95
95
  hubOnlyReceipt?: boolean;
package/lib/main.d.ts CHANGED
@@ -88,10 +88,12 @@ export declare class AugustSDK extends AugustBase {
88
88
  loadSnapshots?: boolean;
89
89
  }): Promise<number>;
90
90
  /**
91
- * Fetch all available vaults across configured networks.
92
- * Optionally filter by chain IDs and include loan/allocation data.
93
- * @param options - Configuration for filtering and enriching vault data
94
- * @returns Array of vault objects with metadata and optional position data
91
+ * Deposit into a vault with an explicit signer. When `depositAsset` differs
92
+ * from the vault's underlying asset the deposit is routed through the
93
+ * matching adapter (native wrapper, swap router, or permit path).
94
+ * @param signer - ethers Signer or Wallet that sends the transaction
95
+ * @param options - Vault address (`target`), depositor `wallet`, `amount`, and optional `depositAsset`, `wait`, `receiver`, `slippageBps`
96
+ * @returns Deposit transaction hash
95
97
  */
96
98
  vaultDeposit(signer: Signer | Wallet, options: IContractWriteOptions): Promise<string>;
97
99
  /**
@@ -451,7 +453,7 @@ export declare class AugustSDK extends AugustBase {
451
453
  * Supported Vaults: cUSDO, tETH, wstETH, rsETH
452
454
  *
453
455
  * @deprecated The `hgETH30dLiquidAPY` and `hgETH7dLiquidAPY` response fields are deprecated.
454
- * These fields will be removed on 2026-01-01.
456
+ * These fields will be removed in the next major release.
455
457
  * Use `liquidAPY30Day` and `liquidAPY7Day` fields instead.
456
458
  *
457
459
  * @param props - Vault address
package/lib/main.js CHANGED
@@ -219,10 +219,12 @@ class AugustSDK extends core_1.AugustBase {
219
219
  return await this.vaults.getTotalDeposited(options);
220
220
  }
221
221
  /**
222
- * Fetch all available vaults across configured networks.
223
- * Optionally filter by chain IDs and include loan/allocation data.
224
- * @param options - Configuration for filtering and enriching vault data
225
- * @returns Array of vault objects with metadata and optional position data
222
+ * Deposit into a vault with an explicit signer. When `depositAsset` differs
223
+ * from the vault's underlying asset the deposit is routed through the
224
+ * matching adapter (native wrapper, swap router, or permit path).
225
+ * @param signer - ethers Signer or Wallet that sends the transaction
226
+ * @param options - Vault address (`target`), depositor `wallet`, `amount`, and optional `depositAsset`, `wait`, `receiver`, `slippageBps`
227
+ * @returns Deposit transaction hash
226
228
  */
227
229
  async vaultDeposit(signer, options) {
228
230
  return await this.vaults.vaultDeposit(signer, options);
@@ -524,7 +526,7 @@ class AugustSDK extends core_1.AugustBase {
524
526
  * Supported Vaults: cUSDO, tETH, wstETH, rsETH
525
527
  *
526
528
  * @deprecated The `hgETH30dLiquidAPY` and `hgETH7dLiquidAPY` response fields are deprecated.
527
- * These fields will be removed on 2026-01-01.
529
+ * These fields will be removed in the next major release.
528
530
  * Use `liquidAPY30Day` and `liquidAPY7Day` fields instead.
529
531
  *
530
532
  * @param props - Vault address
@@ -70,9 +70,16 @@ export declare function getVaultSubaccountLoans(vault: VaultAddress | IVault, op
70
70
  *
71
71
  * @param vault - Vault address
72
72
  * @param options - RPC configuration
73
+ * @param tokenizedVault - Optional pre-fetched backend row for `vault`. When a
74
+ * caller already holds the row (e.g. `getVault` fetched it one call earlier),
75
+ * passing it skips this function's own `GET /tokenized_vault/{address}` — a
76
+ * pure de-duplication of backend traffic. The row must carry the subaccount
77
+ * data this function reads (`.subaccounts`, `.eoa_operators`), so it must not
78
+ * have been fetched with `loadSubaccounts: false`; a row fetched that way
79
+ * would silently resolve zero borrowers.
73
80
  * @returns Detailed allocation data with exposure categorization
74
81
  */
75
- export declare function getVaultAllocations(vault: IAddress, options: IVaultBaseOptions): Promise<IVaultAllocations>;
82
+ export declare function getVaultAllocations(vault: IAddress, options: IVaultBaseOptions, tokenizedVault?: ITokenizedVault): Promise<IVaultAllocations>;
76
83
  export declare function getVaultAvailableRedemptions({ vault, wallet, options, prefetchedReads, }: {
77
84
  vault: IAddress;
78
85
  wallet?: IAddress;
@@ -310,7 +317,7 @@ export interface PnlHistoryConsistencyParams {
310
317
  currentPositionRaw: bigint;
311
318
  }
312
319
  /**
313
- * Guard against the 2026-07-09 lifetime-PnL over-inflation failure mode.
320
+ * Guard against lifetime-PnL over-inflation when the deposit history fails to load.
314
321
  *
315
322
  * Lifetime PnL is `currentPosition + totalWithdrawn - totalDeposited`. When the
316
323
  * deposit/withdrawal history fails to load it collapses to empty, so both
@@ -435,7 +442,7 @@ export declare function getVaultHistoricalTimeseries({ vault, nDays, options, }:
435
442
  * Supported Vaults: cUSDO, tETH, wstETH, rsETH
436
443
  *
437
444
  * @deprecated The `hgETH30dLiquidAPY` and `hgETH7dLiquidAPY` response fields are deprecated.
438
- * These fields will be removed on 2026-01-01.
445
+ * These fields will be removed in the next major release.
439
446
  * Use `liquidAPY30Day` and `liquidAPY7Day` fields instead.
440
447
  *
441
448
  * @param vault - Vault contract address