@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.
- package/lib/adapters/evm/getters.js +40 -0
- package/lib/adapters/evm/index.d.ts +106 -2
- package/lib/adapters/evm/index.js +125 -0
- package/lib/adapters/solana/index.d.ts +12 -5
- package/lib/adapters/solana/index.js +12 -4
- package/lib/adapters/solana/pricing.d.ts +173 -0
- package/lib/adapters/solana/pricing.js +223 -0
- package/lib/adapters/solana/types.d.ts +45 -0
- package/lib/adapters/solana/vault.actions.d.ts +33 -8
- package/lib/adapters/solana/vault.actions.js +185 -28
- package/lib/adapters/stellar/actions.d.ts +2 -2
- package/lib/adapters/stellar/actions.js +2 -2
- package/lib/adapters/stellar/getters.d.ts +1 -1
- package/lib/adapters/stellar/getters.js +2 -2
- package/lib/adapters/stellar/index.d.ts +1 -1
- package/lib/adapters/stellar/index.js +1 -1
- package/lib/adapters/stellar/types.d.ts +1 -2
- package/lib/core/analytics/method-taxonomy.js +7 -0
- package/lib/core/analytics/version.d.ts +1 -1
- package/lib/core/analytics/version.js +1 -1
- package/lib/core/base.class.d.ts +2 -2
- package/lib/core/base.class.js +2 -2
- package/lib/core/constants/core.d.ts +17 -3
- package/lib/core/constants/core.js +17 -3
- package/lib/core/constants/vaults.js +4 -0
- package/lib/core/fetcher.js +112 -45
- package/lib/core/helpers/concurrency.d.ts +37 -0
- package/lib/core/helpers/concurrency.js +58 -0
- package/lib/core/helpers/core.d.ts +9 -0
- package/lib/core/helpers/core.js +47 -0
- package/lib/core/helpers/vaults.d.ts +1 -1
- package/lib/core/helpers/vaults.js +1 -1
- package/lib/core/helpers/web3.js +14 -1
- package/lib/core/logger/curator-alert.d.ts +2 -2
- package/lib/core/logger/curator-alert.js +2 -2
- package/lib/evm/methods/crossChainVaultRegistry.d.ts +2 -3
- package/lib/evm/methods/crossChainVaultRegistry.js +2 -3
- package/lib/evm/types/crossChain.d.ts +1 -1
- package/lib/main.d.ts +7 -5
- package/lib/main.js +7 -5
- package/lib/modules/vaults/getters.d.ts +10 -3
- package/lib/modules/vaults/getters.js +205 -71
- package/lib/modules/vaults/main.d.ts +4 -4
- package/lib/modules/vaults/main.js +7 -4
- package/lib/modules/vaults/read.actions.d.ts +181 -0
- package/lib/modules/vaults/read.actions.js +331 -36
- package/lib/modules/vaults/types.d.ts +13 -0
- package/lib/modules/vaults/utils.js +5 -1
- package/lib/modules/vaults/write.actions.d.ts +74 -6
- package/lib/modules/vaults/write.actions.js +133 -23
- package/lib/sdk.d.ts +9827 -9342
- package/lib/services/subgraph/schema.d.ts +1 -1
- package/lib/services/subgraph/schema.js +1 -1
- package/lib/types/pools.d.ts +1 -1
- package/lib/types/vaults.d.ts +4 -4
- package/package.json +1 -1
package/lib/core/fetcher.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
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
|
-
//
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
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;
|
package/lib/core/helpers/core.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
*
|
package/lib/core/helpers/web3.js
CHANGED
|
@@ -735,7 +735,20 @@ const getSymbol = async (provider, address, isVault = true) => {
|
|
|
735
735
|
}
|
|
736
736
|
}
|
|
737
737
|
catch (e) {
|
|
738
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
* @
|
|
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
|
|
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
|
-
*
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
* @
|
|
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
|
|
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
|
|
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
|
|
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
|