@augustdigital/sdk 8.25.0 → 9.0.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/sui/getters.d.ts +7 -1
- package/lib/adapters/sui/getters.js +53 -6
- package/lib/core/analytics/app-name.d.ts +27 -0
- package/lib/core/analytics/app-name.js +48 -0
- package/lib/core/analytics/sentry.d.ts +16 -4
- package/lib/core/analytics/sentry.js +23 -8
- package/lib/core/analytics/version.d.ts +1 -1
- package/lib/core/analytics/version.js +1 -1
- package/lib/core/base.class.d.ts +4 -3
- package/lib/core/base.class.js +5 -31
- package/lib/main.d.ts +6 -9
- package/lib/main.js +3 -1
- package/lib/modules/vaults/getters.d.ts +9 -2
- package/lib/modules/vaults/getters.js +9 -3
- package/lib/modules/vaults/main.d.ts +3 -28
- package/lib/modules/vaults/main.js +55 -19
- package/lib/modules/vaults/types.d.ts +52 -0
- package/lib/modules/vaults/utils.d.ts +7 -2
- package/lib/modules/vaults/utils.js +12 -4
- package/lib/sdk.d.ts +92 -42
- package/package.json +1 -1
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import type { IEmberVault, IFetchEmberVaultsOptions } from './types';
|
|
2
2
|
/**
|
|
3
|
-
* Fetch Ember vaults from API
|
|
3
|
+
* Fetch Ember vaults from API.
|
|
4
|
+
*
|
|
5
|
+
* Results are cached for {@link EMBER_CACHE_TTL_MS} (keyed by the full request
|
|
6
|
+
* URL, so different query options cache independently) and the request is
|
|
7
|
+
* aborted after {@link EMBER_FETCH_TIMEOUT_MS}. Failures — including timeouts —
|
|
8
|
+
* are never cached and resolve to `[]`, preserving the long-standing
|
|
9
|
+
* fail-tolerant contract of this getter.
|
|
4
10
|
*/
|
|
5
11
|
export declare function getEmberVaults(options?: IFetchEmberVaultsOptions): Promise<IEmberVault[]>;
|
|
6
12
|
/**
|
|
@@ -4,9 +4,32 @@ exports.getEmberVaults = getEmberVaults;
|
|
|
4
4
|
exports.getEmberTVL = getEmberTVL;
|
|
5
5
|
const constants_1 = require("./constants");
|
|
6
6
|
const core_1 = require("../../core");
|
|
7
|
+
const cache_1 = require("../../core/cache");
|
|
7
8
|
const logger_1 = require("../../core/logger");
|
|
8
9
|
/**
|
|
9
|
-
*
|
|
10
|
+
* Hard ceiling on the Ember (Bluefin) vaults request. The endpoint is a
|
|
11
|
+
* third-party API awaited on the `getVaults` hot path; without a bound, a
|
|
12
|
+
* hung connection stalls every vault-list consumer indefinitely (the fetch
|
|
13
|
+
* options carry no signal and no timeout). Measured latency is 0.24–1.02s,
|
|
14
|
+
* so 5s is ~5× the observed worst case while still failing fast enough for
|
|
15
|
+
* callers racing `getVaults` against their own budgets.
|
|
16
|
+
*/
|
|
17
|
+
const EMBER_FETCH_TIMEOUT_MS = 5_000;
|
|
18
|
+
/**
|
|
19
|
+
* TTL for the cached Ember vaults payload. The set of active Ember vaults
|
|
20
|
+
* changes rarely (the SDK additionally filters it to a hardcoded allowlist),
|
|
21
|
+
* so 5 minutes matches the freshness of the other list-shaped caches without
|
|
22
|
+
* letting a stale payload outlive a delisting for long.
|
|
23
|
+
*/
|
|
24
|
+
const EMBER_CACHE_TTL_MS = 5 * 60 * 1000;
|
|
25
|
+
/**
|
|
26
|
+
* Fetch Ember vaults from API.
|
|
27
|
+
*
|
|
28
|
+
* Results are cached for {@link EMBER_CACHE_TTL_MS} (keyed by the full request
|
|
29
|
+
* URL, so different query options cache independently) and the request is
|
|
30
|
+
* aborted after {@link EMBER_FETCH_TIMEOUT_MS}. Failures — including timeouts —
|
|
31
|
+
* are never cached and resolve to `[]`, preserving the long-standing
|
|
32
|
+
* fail-tolerant contract of this getter.
|
|
10
33
|
*/
|
|
11
34
|
async function getEmberVaults(options) {
|
|
12
35
|
try {
|
|
@@ -19,12 +42,36 @@ async function getEmberVaults(options) {
|
|
|
19
42
|
params.append('status', options.status);
|
|
20
43
|
const queryString = params.toString();
|
|
21
44
|
const url = `${constants_1.EMBER_API_BASE_URL}${queryString ? `?${queryString}` : ''}`;
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
45
|
+
const cacheKey = `ember-vaults-${url}`;
|
|
46
|
+
// The shared LRU is constructed with `allowStale: true`; opt out here so a
|
|
47
|
+
// payload past its TTL is refetched rather than served one last time —
|
|
48
|
+
// keeping the 5-minute bound above an exact contract.
|
|
49
|
+
const cached = cache_1.CACHE.get(cacheKey, { allowStale: false });
|
|
50
|
+
if (cached)
|
|
51
|
+
return cached;
|
|
52
|
+
// AbortController (not AbortSignal.timeout) for browser + older-Node parity.
|
|
53
|
+
// The timer stays armed through the body read: `fetch` resolves as soon as
|
|
54
|
+
// headers arrive, so clearing it there would leave a stalled `json()`
|
|
55
|
+
// unbounded — the exact hang the ceiling exists to prevent.
|
|
56
|
+
const controller = new AbortController();
|
|
57
|
+
const timer = setTimeout(() => controller.abort(), EMBER_FETCH_TIMEOUT_MS);
|
|
58
|
+
let data;
|
|
59
|
+
try {
|
|
60
|
+
const response = await fetch(url, {
|
|
61
|
+
...core_1.DEFAULT_FETCH_OPTIONS,
|
|
62
|
+
signal: controller.signal,
|
|
63
|
+
});
|
|
64
|
+
if (!response.ok) {
|
|
65
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
66
|
+
}
|
|
67
|
+
data = await response.json();
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
clearTimeout(timer);
|
|
25
71
|
}
|
|
26
|
-
const
|
|
27
|
-
|
|
72
|
+
const vaults = Array.isArray(data) ? data : [];
|
|
73
|
+
cache_1.CACHE.set(cacheKey, vaults, { ttl: EMBER_CACHE_TTL_MS });
|
|
74
|
+
return vaults;
|
|
28
75
|
}
|
|
29
76
|
catch (error) {
|
|
30
77
|
logger_1.Logger.log.error('getEmberVaults', error);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate an `appName` slug at SDK boundary points (the `AugustSDK`
|
|
3
|
+
* constructor and the standalone {@link initializeSentry} entry point).
|
|
4
|
+
*
|
|
5
|
+
* Rules (kept intentionally narrow so the value is safe to use as a Sentry
|
|
6
|
+
* tag, an HTTP header value, and a filesystem-safe identifier — this is
|
|
7
|
+
* why we accept slugs only, not display names):
|
|
8
|
+
* - non-empty after trim
|
|
9
|
+
* - 3..64 characters
|
|
10
|
+
* - only `[a-zA-Z0-9._-]`
|
|
11
|
+
* - not shaped like an EVM address (`0x` + 40 hex chars) — an address
|
|
12
|
+
* passes the character rules but is a high-cardinality wallet
|
|
13
|
+
* identifier, not an application name. This also catches callers of
|
|
14
|
+
* `initializeSentry` still passing the pre-v9 positional argument
|
|
15
|
+
* order, where a wallet address occupied the slot `appName` now holds.
|
|
16
|
+
*
|
|
17
|
+
* Throws a descriptive `AugustValidationError` (code `INVALID_INPUT`) that
|
|
18
|
+
* names the failed rule and includes a remediation hint pointing at the
|
|
19
|
+
* docs link.
|
|
20
|
+
*
|
|
21
|
+
* @param value - The candidate app name, as received from the caller.
|
|
22
|
+
* @returns The trimmed, validated slug.
|
|
23
|
+
* @throws AugustValidationError when the value is missing, empty,
|
|
24
|
+
* mis-typed, out of the 3–64 length range, contains disallowed
|
|
25
|
+
* characters, or is shaped like an EVM address.
|
|
26
|
+
*/
|
|
27
|
+
export declare function validateAppName(value: unknown): string;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateAppName = validateAppName;
|
|
4
|
+
const errors_1 = require("../errors");
|
|
5
|
+
/**
|
|
6
|
+
* Validate an `appName` slug at SDK boundary points (the `AugustSDK`
|
|
7
|
+
* constructor and the standalone {@link initializeSentry} entry point).
|
|
8
|
+
*
|
|
9
|
+
* Rules (kept intentionally narrow so the value is safe to use as a Sentry
|
|
10
|
+
* tag, an HTTP header value, and a filesystem-safe identifier — this is
|
|
11
|
+
* why we accept slugs only, not display names):
|
|
12
|
+
* - non-empty after trim
|
|
13
|
+
* - 3..64 characters
|
|
14
|
+
* - only `[a-zA-Z0-9._-]`
|
|
15
|
+
* - not shaped like an EVM address (`0x` + 40 hex chars) — an address
|
|
16
|
+
* passes the character rules but is a high-cardinality wallet
|
|
17
|
+
* identifier, not an application name. This also catches callers of
|
|
18
|
+
* `initializeSentry` still passing the pre-v9 positional argument
|
|
19
|
+
* order, where a wallet address occupied the slot `appName` now holds.
|
|
20
|
+
*
|
|
21
|
+
* Throws a descriptive `AugustValidationError` (code `INVALID_INPUT`) that
|
|
22
|
+
* names the failed rule and includes a remediation hint pointing at the
|
|
23
|
+
* docs link.
|
|
24
|
+
*
|
|
25
|
+
* @param value - The candidate app name, as received from the caller.
|
|
26
|
+
* @returns The trimmed, validated slug.
|
|
27
|
+
* @throws AugustValidationError when the value is missing, empty,
|
|
28
|
+
* mis-typed, out of the 3–64 length range, contains disallowed
|
|
29
|
+
* characters, or is shaped like an EVM address.
|
|
30
|
+
*/
|
|
31
|
+
function validateAppName(value) {
|
|
32
|
+
const docsHint = 'See https://docs.augustdigital.io/developers/typescript-sdk#app-name';
|
|
33
|
+
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
34
|
+
throw new errors_1.AugustValidationError('INVALID_INPUT', `August SDK: \`appName\` is required. Pass a stable kebab-case slug identifying your application (e.g. "acme-trader"). ${docsHint}`);
|
|
35
|
+
}
|
|
36
|
+
const trimmed = value.trim();
|
|
37
|
+
if (trimmed.length < 3 || trimmed.length > 64) {
|
|
38
|
+
throw new errors_1.AugustValidationError('INVALID_INPUT', `August SDK: \`appName\` must be 3-64 characters (got ${trimmed.length}). ${docsHint}`);
|
|
39
|
+
}
|
|
40
|
+
if (!/^[a-zA-Z0-9._-]+$/.test(trimmed)) {
|
|
41
|
+
throw new errors_1.AugustValidationError('INVALID_INPUT', `August SDK: \`appName\` may only contain letters, digits, '.', '_' and '-' (got "${trimmed}"). Use a slug like "acme-trader", not a display name. ${docsHint}`);
|
|
42
|
+
}
|
|
43
|
+
if (/^0x[0-9a-fA-F]{40}$/.test(trimmed)) {
|
|
44
|
+
throw new errors_1.AugustValidationError('INVALID_INPUT', `August SDK: \`appName\` looks like a wallet address ("${trimmed}"). Pass an application slug like "acme-trader" — if you are calling initializeSentry directly, note that since v9 the argument order is (config, environment, appName, walletAddress?, apiKey?). ${docsHint}`);
|
|
45
|
+
}
|
|
46
|
+
return trimmed;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=app-name.js.map
|
|
@@ -12,16 +12,28 @@ export declare function resetErrorDedupe(): void;
|
|
|
12
12
|
* Initialize Sentry with SDK-specific configuration. Idempotent: re-calls
|
|
13
13
|
* only refresh user identity and the cached API-key hash.
|
|
14
14
|
*
|
|
15
|
+
* Breaking change in v9: `appName` moved from the optional fifth parameter
|
|
16
|
+
* to the required third parameter, so every telemetry stream carries an
|
|
17
|
+
* application identity (the `AugustSDK` constructor has required it since
|
|
18
|
+
* v5). Callers on the old positional order get a synchronous validation
|
|
19
|
+
* error rather than silently anonymous events.
|
|
20
|
+
*
|
|
15
21
|
* @param config - Analytics configuration. Pass `tracesSampleRate` to
|
|
16
22
|
* override the default of `0.1`.
|
|
17
23
|
* @param environment - Current environment (DEV or PROD).
|
|
24
|
+
* @param appName - App-name slug, required. Set as the global `app.name`
|
|
25
|
+
* tag on every event and used to derive `partner.id`. Identifier-shaped:
|
|
26
|
+
* 3–64 chars, `[a-zA-Z0-9._-]` only, and not an EVM address — the same
|
|
27
|
+
* rules the `AugustSDK` constructor enforces.
|
|
18
28
|
* @param walletAddress - Optional wallet address for user identification.
|
|
19
29
|
* @param apiKey - Optional API key (hashed for identification).
|
|
20
|
-
* @
|
|
21
|
-
*
|
|
22
|
-
*
|
|
30
|
+
* @throws AugustValidationError (code `INVALID_INPUT`) when `appName` is
|
|
31
|
+
* missing, empty, mis-typed, out of the allowed length range, contains
|
|
32
|
+
* disallowed characters, or is shaped like an EVM address. Thrown before
|
|
33
|
+
* any analytics state mutates, even when analytics would be disabled by
|
|
34
|
+
* config or environment gates.
|
|
23
35
|
*/
|
|
24
|
-
export declare function initializeSentry(config: IAnalyticsConfig, environment: IEnv,
|
|
36
|
+
export declare function initializeSentry(config: IAnalyticsConfig, environment: IEnv, appName: string, walletAddress?: string, apiKey?: string): void;
|
|
25
37
|
/**
|
|
26
38
|
* Update the current user identity in Sentry.
|
|
27
39
|
* Called when wallet address changes.
|
|
@@ -9,6 +9,7 @@ exports.getSentry = getSentry;
|
|
|
9
9
|
exports.resetAnalytics = resetAnalytics;
|
|
10
10
|
exports.captureSdkException = captureSdkException;
|
|
11
11
|
const logger_1 = require("../logger");
|
|
12
|
+
const app_name_1 = require("./app-name");
|
|
12
13
|
const constants_1 = require("./constants");
|
|
13
14
|
const env_1 = require("./env");
|
|
14
15
|
const sentry_runtime_1 = require("./sentry-runtime");
|
|
@@ -305,16 +306,32 @@ function createSentrySink() {
|
|
|
305
306
|
* Initialize Sentry with SDK-specific configuration. Idempotent: re-calls
|
|
306
307
|
* only refresh user identity and the cached API-key hash.
|
|
307
308
|
*
|
|
309
|
+
* Breaking change in v9: `appName` moved from the optional fifth parameter
|
|
310
|
+
* to the required third parameter, so every telemetry stream carries an
|
|
311
|
+
* application identity (the `AugustSDK` constructor has required it since
|
|
312
|
+
* v5). Callers on the old positional order get a synchronous validation
|
|
313
|
+
* error rather than silently anonymous events.
|
|
314
|
+
*
|
|
308
315
|
* @param config - Analytics configuration. Pass `tracesSampleRate` to
|
|
309
316
|
* override the default of `0.1`.
|
|
310
317
|
* @param environment - Current environment (DEV or PROD).
|
|
318
|
+
* @param appName - App-name slug, required. Set as the global `app.name`
|
|
319
|
+
* tag on every event and used to derive `partner.id`. Identifier-shaped:
|
|
320
|
+
* 3–64 chars, `[a-zA-Z0-9._-]` only, and not an EVM address — the same
|
|
321
|
+
* rules the `AugustSDK` constructor enforces.
|
|
311
322
|
* @param walletAddress - Optional wallet address for user identification.
|
|
312
323
|
* @param apiKey - Optional API key (hashed for identification).
|
|
313
|
-
* @
|
|
314
|
-
*
|
|
315
|
-
*
|
|
324
|
+
* @throws AugustValidationError (code `INVALID_INPUT`) when `appName` is
|
|
325
|
+
* missing, empty, mis-typed, out of the allowed length range, contains
|
|
326
|
+
* disallowed characters, or is shaped like an EVM address. Thrown before
|
|
327
|
+
* any analytics state mutates, even when analytics would be disabled by
|
|
328
|
+
* config or environment gates.
|
|
316
329
|
*/
|
|
317
|
-
function initializeSentry(config, environment, walletAddress, apiKey
|
|
330
|
+
function initializeSentry(config, environment, appName, walletAddress, apiKey) {
|
|
331
|
+
// Enforce the identity contract before anything else — including the
|
|
332
|
+
// idempotency short-circuit and the disable gates — so a bad appName is
|
|
333
|
+
// equally loud on every call path and in every environment.
|
|
334
|
+
const validatedAppName = (0, app_name_1.validateAppName)(appName);
|
|
318
335
|
// SDK construction runs this multiple times (base + adapter constructors).
|
|
319
336
|
// Short-circuit so the disable-reason logs only once per process.
|
|
320
337
|
if (isInitialized) {
|
|
@@ -473,11 +490,9 @@ function initializeSentry(config, environment, walletAddress, apiKey, appName) {
|
|
|
473
490
|
safeSetTag('sdk.runtime', (0, sentry_runtime_1.getSentryRuntime)());
|
|
474
491
|
// `app.name` is the dimension we filter on in Sentry to attribute
|
|
475
492
|
// events to a specific consuming application — see SDK quickstart docs.
|
|
476
|
-
|
|
477
|
-
safeSetTag('app.name', appName);
|
|
478
|
-
}
|
|
493
|
+
safeSetTag('app.name', validatedAppName);
|
|
479
494
|
// `unverified:` prefix until the backend API-key → partner-id endpoint exists.
|
|
480
|
-
safeSetTag('partner.id',
|
|
495
|
+
safeSetTag('partner.id', `unverified:${validatedAppName}`);
|
|
481
496
|
safeSetTag('partner.tier', 'unverified');
|
|
482
497
|
// Bridge the SDK's structured logger into Sentry now that the SDK is live.
|
|
483
498
|
// Without this, Logger.log.error/warn are no-ops in production (no
|
package/lib/core/base.class.d.ts
CHANGED
|
@@ -25,7 +25,8 @@ export interface IAugustBase {
|
|
|
25
25
|
* 3–64 characters, `[a-zA-Z0-9._-]` only. Use a slug ("acme-trader"),
|
|
26
26
|
* not a display name ("Acme Trader").
|
|
27
27
|
*
|
|
28
|
-
* @throws
|
|
28
|
+
* @throws AugustValidationError synchronously from the constructor if
|
|
29
|
+
* missing, empty, or malformed.
|
|
29
30
|
*
|
|
30
31
|
* @example
|
|
31
32
|
* ```typescript
|
|
@@ -120,8 +121,8 @@ export declare class AugustBase {
|
|
|
120
121
|
* Initialize base SDK with provider configuration and API keys.
|
|
121
122
|
* Sets up the first provider as the active network by default.
|
|
122
123
|
*
|
|
123
|
-
* @throws
|
|
124
|
-
* length range — see {@link IAugustBase.appName}.
|
|
124
|
+
* @throws AugustValidationError if `appName` is missing, malformed, or
|
|
125
|
+
* out of the allowed length range — see {@link IAugustBase.appName}.
|
|
125
126
|
*/
|
|
126
127
|
constructor({ appName, providers, keys, monitoring, analytics, versionCheck, timeoutMs, publicApiBaseUrl, attribution, }: IAugustBase);
|
|
127
128
|
/**
|
package/lib/core/base.class.js
CHANGED
|
@@ -4,36 +4,10 @@ exports.AugustBase = void 0;
|
|
|
4
4
|
const auth_1 = require("./auth");
|
|
5
5
|
const logger_1 = require("./logger");
|
|
6
6
|
const analytics_1 = require("./analytics");
|
|
7
|
+
const app_name_1 = require("./analytics/app-name");
|
|
7
8
|
const version_check_1 = require("./version-check");
|
|
8
9
|
const fetcher_1 = require("./fetcher");
|
|
9
10
|
const attribution_1 = require("./attribution");
|
|
10
|
-
/**
|
|
11
|
-
* Validate an appName at SDK construction time.
|
|
12
|
-
*
|
|
13
|
-
* Rules (kept intentionally narrow so the value is safe to use as a Sentry
|
|
14
|
-
* tag, an HTTP header value, and a filesystem-safe identifier — this is
|
|
15
|
-
* why we accept slugs only, not display names):
|
|
16
|
-
* - non-empty after trim
|
|
17
|
-
* - 3..64 characters
|
|
18
|
-
* - only `[a-zA-Z0-9._-]`
|
|
19
|
-
*
|
|
20
|
-
* Throws a descriptive Error that names the failed rule and includes a
|
|
21
|
-
* remediation hint pointing at the docs link.
|
|
22
|
-
*/
|
|
23
|
-
function validateAppName(value) {
|
|
24
|
-
const docsHint = 'See https://docs.augustdigital.io/developers/typescript-sdk#app-name';
|
|
25
|
-
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
26
|
-
throw new Error(`August SDK: \`appName\` is required. Pass a stable kebab-case slug identifying your application (e.g. "acme-trader"). ${docsHint}`);
|
|
27
|
-
}
|
|
28
|
-
const trimmed = value.trim();
|
|
29
|
-
if (trimmed.length < 3 || trimmed.length > 64) {
|
|
30
|
-
throw new Error(`August SDK: \`appName\` must be 3-64 characters (got ${trimmed.length}). ${docsHint}`);
|
|
31
|
-
}
|
|
32
|
-
if (!/^[a-zA-Z0-9._-]+$/.test(trimmed)) {
|
|
33
|
-
throw new Error(`August SDK: \`appName\` may only contain letters, digits, '.', '_' and '-' (got "${trimmed}"). Use a slug like "acme-trader", not a display name. ${docsHint}`);
|
|
34
|
-
}
|
|
35
|
-
return trimmed;
|
|
36
|
-
}
|
|
37
11
|
/**
|
|
38
12
|
* Base class providing core SDK functionality including provider management,
|
|
39
13
|
* network switching, and authentication state.
|
|
@@ -53,13 +27,13 @@ class AugustBase {
|
|
|
53
27
|
* Initialize base SDK with provider configuration and API keys.
|
|
54
28
|
* Sets up the first provider as the active network by default.
|
|
55
29
|
*
|
|
56
|
-
* @throws
|
|
57
|
-
* length range — see {@link IAugustBase.appName}.
|
|
30
|
+
* @throws AugustValidationError if `appName` is missing, malformed, or
|
|
31
|
+
* out of the allowed length range — see {@link IAugustBase.appName}.
|
|
58
32
|
*/
|
|
59
33
|
constructor({ appName, providers = {}, keys, monitoring, analytics, versionCheck, timeoutMs, publicApiBaseUrl, attribution, }) {
|
|
60
34
|
// Validate first so the failure mode is a clear, actionable error before
|
|
61
35
|
// any provider / analytics side effects run.
|
|
62
|
-
this.appName = validateAppName(appName);
|
|
36
|
+
this.appName = (0, app_name_1.validateAppName)(appName);
|
|
63
37
|
// TODO: change this to false later when august key is required
|
|
64
38
|
this.authorized = true;
|
|
65
39
|
this.providers = providers;
|
|
@@ -82,7 +56,7 @@ class AugustBase {
|
|
|
82
56
|
logger_1.Logger.setDevMode(environment === 'DEV');
|
|
83
57
|
// Initialize analytics (pass API key for hashed identification + the
|
|
84
58
|
// appName so events can be filtered by consuming application).
|
|
85
|
-
(0, analytics_1.initializeSentry)(analytics ?? { enabled: true }, environment, monitoring?.['x-user-id'], keys?.august
|
|
59
|
+
(0, analytics_1.initializeSentry)(analytics ?? { enabled: true }, environment, this.appName, monitoring?.['x-user-id'], keys?.august);
|
|
86
60
|
// Best-effort version nudge — fire-and-forget, never blocks init, no
|
|
87
61
|
// network call in production. See `core/version-check.ts` for details.
|
|
88
62
|
(0, version_check_1.runVersionCheck)(versionCheck);
|
package/lib/main.d.ts
CHANGED
|
@@ -7,9 +7,9 @@ import SolanaAdapter from './adapters/solana';
|
|
|
7
7
|
import SuiAdapter from './adapters/sui';
|
|
8
8
|
import StellarAdapter from './adapters/stellar';
|
|
9
9
|
import EVMAdapter from './adapters/evm';
|
|
10
|
-
import type { IAddress, IChainId, IVaultHistoricalParams
|
|
10
|
+
import type { IAddress, IChainId, IVaultHistoricalParams } from './types';
|
|
11
11
|
import { AugustBase, type IAugustBase } from './core';
|
|
12
|
-
import { AugustVaults, type IVaultBaseOptions, type IVaultCustomOptions } from './modules/vaults';
|
|
12
|
+
import { AugustVaults, type IGetVaultsOptions, type IVaultBaseOptions, type IVaultCustomOptions } from './modules/vaults';
|
|
13
13
|
import type { Signer, Wallet } from 'ethers';
|
|
14
14
|
import type { IContractWriteOptions } from './modules/vaults/write.actions';
|
|
15
15
|
import { AugustSubAccounts } from './modules/sub-accounts';
|
|
@@ -77,15 +77,12 @@ export declare class AugustSDK extends AugustBase {
|
|
|
77
77
|
/**
|
|
78
78
|
* Fetch all available vaults across configured networks.
|
|
79
79
|
* Optionally filter by chain IDs and include loan/allocation data.
|
|
80
|
-
* @param options - Configuration for filtering and enriching vault data
|
|
80
|
+
* @param options - Configuration for filtering and enriching vault data —
|
|
81
|
+
* see {@link IGetVaultsOptions} for the full surface (`includeClosed`
|
|
82
|
+
* portfolio mode, `maxRetries`/`baseDelay` retry tuning)
|
|
81
83
|
* @returns Array of vault objects with metadata and optional position data
|
|
82
84
|
*/
|
|
83
|
-
getVaults(options?:
|
|
84
|
-
chainIds?: number[];
|
|
85
|
-
headers?: IWSMonitorHeaders;
|
|
86
|
-
loadSubaccounts?: boolean;
|
|
87
|
-
loadSnapshots?: boolean;
|
|
88
|
-
} & IVaultCustomOptions): Promise<import("./types").IVault[]>;
|
|
85
|
+
getVaults(options?: IGetVaultsOptions): Promise<import("./types").IVault[]>;
|
|
89
86
|
getTotalDeposited(options?: {
|
|
90
87
|
loadSubaccounts?: boolean;
|
|
91
88
|
loadSnapshots?: boolean;
|
package/lib/main.js
CHANGED
|
@@ -207,7 +207,9 @@ class AugustSDK extends core_1.AugustBase {
|
|
|
207
207
|
/**
|
|
208
208
|
* Fetch all available vaults across configured networks.
|
|
209
209
|
* Optionally filter by chain IDs and include loan/allocation data.
|
|
210
|
-
* @param options - Configuration for filtering and enriching vault data
|
|
210
|
+
* @param options - Configuration for filtering and enriching vault data —
|
|
211
|
+
* see {@link IGetVaultsOptions} for the full surface (`includeClosed`
|
|
212
|
+
* portfolio mode, `maxRetries`/`baseDelay` retry tuning)
|
|
211
213
|
* @returns Array of vault objects with metadata and optional position data
|
|
212
214
|
*/
|
|
213
215
|
async getVaults(options) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type IAddress, type IHistoricalTimeseriesResponse, type INormalizedNumber, type ISubgraphWithdrawProccessed, type IVault, type IVaultAllocations, type IVaultAnnualizedApy, type IVaultAvailableRedemption, type IVaultLoan, type IVaultPosition, type IVaultRedemptionHistoryItem, type IVaultSummary, type IVaultWithdrawals, type IVaultPendingRedemptions, type IActiveStakingPosition, type IVaultHistoricalParams, type IVaultUserLifetimePnl, type IVaultBorrowerHealthFactor, type IVaultPnl, type VaultAddress } from '../../types';
|
|
1
|
+
import { type IAddress, type IHistoricalTimeseriesResponse, type INormalizedNumber, type ITokenizedVault, type ISubgraphWithdrawProccessed, type IVault, type IVaultAllocations, type IVaultAnnualizedApy, type IVaultAvailableRedemption, type IVaultLoan, type IVaultPosition, type IVaultRedemptionHistoryItem, type IVaultSummary, type IVaultWithdrawals, type IVaultPendingRedemptions, type IActiveStakingPosition, type IVaultHistoricalParams, type IVaultUserLifetimePnl, type IVaultBorrowerHealthFactor, type IVaultPnl, type VaultAddress } from '../../types';
|
|
2
2
|
import type { IVaultBaseOptions } from './types';
|
|
3
3
|
/**
|
|
4
4
|
* Vault Data Getters
|
|
@@ -23,15 +23,22 @@ import type { IVaultBaseOptions } from './types';
|
|
|
23
23
|
* @param loans - Include active loan data
|
|
24
24
|
* @param allocations - Include DeFi/CeFi allocation breakdowns
|
|
25
25
|
* @param options - RPC and service configuration
|
|
26
|
+
* @param tokenizedVault - Optional pre-fetched backend row for `vault`. When a
|
|
27
|
+
* caller already holds the row (e.g. `getVaults` fetched the whole list one
|
|
28
|
+
* call earlier), passing it skips this function's own
|
|
29
|
+
* `GET /tokenized_vault/{address}` — a pure de-duplication of backend
|
|
30
|
+
* traffic. The row must have been fetched with the same
|
|
31
|
+
* `loadSubaccounts`/`loadSnapshots` flags the caller passes here.
|
|
26
32
|
* @returns Complete vault object with optional enrichments
|
|
27
33
|
*/
|
|
28
|
-
export declare function getVault({ vault, loans, allocations, options, loadSubaccounts, loadSnapshots, }: {
|
|
34
|
+
export declare function getVault({ vault, loans, allocations, options, loadSubaccounts, loadSnapshots, tokenizedVault: prefetchedRow, }: {
|
|
29
35
|
vault: IAddress;
|
|
30
36
|
loans?: boolean;
|
|
31
37
|
allocations?: boolean;
|
|
32
38
|
options: IVaultBaseOptions;
|
|
33
39
|
loadSubaccounts?: boolean;
|
|
34
40
|
loadSnapshots?: boolean;
|
|
41
|
+
tokenizedVault?: ITokenizedVault;
|
|
35
42
|
}): Promise<IVault>;
|
|
36
43
|
/**
|
|
37
44
|
* Vault Loans
|
|
@@ -112,13 +112,19 @@ const errors_1 = require("../../core/errors");
|
|
|
112
112
|
* @param loans - Include active loan data
|
|
113
113
|
* @param allocations - Include DeFi/CeFi allocation breakdowns
|
|
114
114
|
* @param options - RPC and service configuration
|
|
115
|
+
* @param tokenizedVault - Optional pre-fetched backend row for `vault`. When a
|
|
116
|
+
* caller already holds the row (e.g. `getVaults` fetched the whole list one
|
|
117
|
+
* call earlier), passing it skips this function's own
|
|
118
|
+
* `GET /tokenized_vault/{address}` — a pure de-duplication of backend
|
|
119
|
+
* traffic. The row must have been fetched with the same
|
|
120
|
+
* `loadSubaccounts`/`loadSnapshots` flags the caller passes here.
|
|
115
121
|
* @returns Complete vault object with optional enrichments
|
|
116
122
|
*/
|
|
117
|
-
async function getVault({ vault, loans = false, allocations = false, options, loadSubaccounts, loadSnapshots, }) {
|
|
123
|
+
async function getVault({ vault, loans = false, allocations = false, options, loadSubaccounts, loadSnapshots, tokenizedVault: prefetchedRow, }) {
|
|
118
124
|
let returnedVault;
|
|
119
125
|
try {
|
|
120
|
-
const
|
|
121
|
-
|
|
126
|
+
const tokenizedVault = prefetchedRow ??
|
|
127
|
+
(await (0, core_1.fetchTokenizedVault)(vault, undefined, loadSubaccounts, loadSnapshots))?.[0];
|
|
122
128
|
const vaultVersion = (0, core_1.getVaultVersionV2)(tokenizedVault);
|
|
123
129
|
switch (vaultVersion) {
|
|
124
130
|
case 'sol-0': {
|
|
@@ -13,8 +13,8 @@ import { AugustBase, type IAugustBase } from '../../core';
|
|
|
13
13
|
import SuiAdapter from '../../adapters/sui';
|
|
14
14
|
import { type IContractWriteOptions, type INativeDepositOptions } from './write.actions';
|
|
15
15
|
import type { Signer, Wallet } from 'ethers';
|
|
16
|
-
import type { IVaultBaseOptions, IVaultCustomOptions } from './types';
|
|
17
|
-
export type { IVaultBaseOptions, IVaultCustomOptions } from './types';
|
|
16
|
+
import type { IGetVaultsOptions, IVaultBaseOptions, IVaultCustomOptions } from './types';
|
|
17
|
+
export type { IGetVaultsOptions, IVaultBaseOptions, IVaultCustomOptions, } from './types';
|
|
18
18
|
/**
|
|
19
19
|
* Vault operations class handling multi-chain vault queries and user positions.
|
|
20
20
|
* Supports both EVM and Solana vaults with unified interface.
|
|
@@ -64,32 +64,7 @@ export declare class AugustVaults extends AugustBase {
|
|
|
64
64
|
* @param options Filtering and enrichment configuration
|
|
65
65
|
* @returns Array of vault objects with optional loans/allocations/positions
|
|
66
66
|
*/
|
|
67
|
-
getVaults(options?:
|
|
68
|
-
chainIds?: number[];
|
|
69
|
-
loadSubaccounts?: boolean;
|
|
70
|
-
loadSnapshots?: boolean;
|
|
71
|
-
/**
|
|
72
|
-
* Portfolio mode: include closed vaults in the result.
|
|
73
|
-
*
|
|
74
|
-
* By default (`false`) closed vaults are excluded, so marketplace /
|
|
75
|
-
* discovery callers never receive a `status: 'closed'` vault. When set,
|
|
76
|
-
* closed vaults are returned regardless of `is_visible` (closed +
|
|
77
|
-
* invisible vaults bucket as closed), so a consumer joining user
|
|
78
|
-
* positions can render a position held in a closed vault on the
|
|
79
|
-
* portfolio page.
|
|
80
|
-
*
|
|
81
|
-
* In this mode, loans/allocations enrichment is also skipped for closed
|
|
82
|
-
* vaults: they have none, and the per-vault enrichment
|
|
83
|
-
* (`getVault` → `getVaultAllocations`) otherwise re-throws when a closed
|
|
84
|
-
* vault has no live strategy/debank data or no subaccounts, which would
|
|
85
|
-
* land the vault in the `failed` bucket and silently drop it before it
|
|
86
|
-
* reaches the filter. Skipping enrichment lets the vault survive on its
|
|
87
|
-
* backend metadata + base on-chain read.
|
|
88
|
-
*
|
|
89
|
-
* @default false
|
|
90
|
-
*/
|
|
91
|
-
includeClosed?: boolean;
|
|
92
|
-
} & IVaultCustomOptions): Promise<import("../../types").IVault[]>;
|
|
67
|
+
getVaults(options?: IGetVaultsOptions): Promise<import("../../types").IVault[]>;
|
|
93
68
|
/**
|
|
94
69
|
* Calculate total deposited across all tokenized vaults by summing latest_reported_tvl.
|
|
95
70
|
* Uses the /tokenized_vault endpoint which returns latest_reported_tvl in USD.
|
|
@@ -53,6 +53,7 @@ __exportStar(require("./getters"), exports);
|
|
|
53
53
|
* AugustVaults class
|
|
54
54
|
*/
|
|
55
55
|
const fetcher_1 = require("./fetcher");
|
|
56
|
+
const web3_1 = require("../../core/constants/web3");
|
|
56
57
|
const ethers_1 = require("ethers");
|
|
57
58
|
const getters_1 = require("./getters");
|
|
58
59
|
const vaults_1 = require("../../services/subgraph/vaults");
|
|
@@ -152,22 +153,54 @@ class AugustVaults extends core_1.AugustBase {
|
|
|
152
153
|
const vaultsPerChainId = options?.chainIds
|
|
153
154
|
? vaultsPerAvailableProviders.filter((v) => options.chainIds.includes(v.chain))
|
|
154
155
|
: vaultsPerAvailableProviders;
|
|
155
|
-
//
|
|
156
|
-
|
|
157
|
-
|
|
156
|
+
// Skip vaults the post-enrichment filter (filterVaultsIntelligently +
|
|
157
|
+
// the includeClosed gate below) is guaranteed to drop, BEFORE paying
|
|
158
|
+
// their per-vault enrichment. `status` / `is_visible` land on the
|
|
159
|
+
// enriched vault verbatim from this backend row, so filtering on the row
|
|
160
|
+
// is exactly equivalent to filtering on the enriched result — it just
|
|
161
|
+
// saves the on-chain reads (and their retry backoff) for vaults that can
|
|
162
|
+
// never appear in the output. The post-filter below is kept unchanged as
|
|
163
|
+
// the authority on the final shape.
|
|
164
|
+
const enrichableVaults = vaultsPerChainId.filter((v) => {
|
|
165
|
+
const status = v?.status || 'unknown';
|
|
166
|
+
if (status === 'closed')
|
|
167
|
+
return !!options?.includeClosed;
|
|
168
|
+
if (status === 'active')
|
|
169
|
+
return true;
|
|
170
|
+
// Mirrors filterVaultsIntelligently: an unknown-status vault survives
|
|
171
|
+
// only through the invisible bucket; a visible one lands in `failed`.
|
|
172
|
+
return !(v?.is_visible ?? true);
|
|
158
173
|
});
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
174
|
+
// The backend row for each vault about to be enriched. getVault re-uses
|
|
175
|
+
// it instead of re-fetching `GET /tokenized_vault/{address}` per vault —
|
|
176
|
+
// the row came from the same list response (same load flags), so this is
|
|
177
|
+
// a pure de-duplication of backend traffic, not a freshness change.
|
|
178
|
+
const vaultRowsByAddress = new Map(enrichableVaults.map((row) => [String(row.address).toLowerCase(), row]));
|
|
179
|
+
// Ember (Sui) vaults come from a third-party API and are appended to the
|
|
180
|
+
// non-wallet result. When the caller scopes the query with `chainIds` and
|
|
181
|
+
// that scope excludes Sui, skip the fetch entirely — previously it was
|
|
182
|
+
// awaited unconditionally, so a slow Bluefin endpoint stalled even
|
|
183
|
+
// EVM-only and Solana/Stellar-only queries.
|
|
184
|
+
const includeSuiVaults = !options?.chainIds || options.chainIds.includes(web3_1.SUI_CHAIN_ID);
|
|
185
|
+
let transformedVaults = [];
|
|
186
|
+
if (includeSuiVaults) {
|
|
187
|
+
// Fetch and transform (filter for active status)
|
|
188
|
+
const emberVaults = await this.suiService.getEmberVaults({
|
|
189
|
+
status: 'active',
|
|
190
|
+
});
|
|
191
|
+
const activeEmberVaults = Array.isArray(emberVaults)
|
|
192
|
+
? emberVaults.filter((v) => v?.status === 'active')
|
|
193
|
+
: [];
|
|
194
|
+
const whitelistedEmberVaults = activeEmberVaults.filter((v) => {
|
|
195
|
+
if (!v?.address)
|
|
196
|
+
return false;
|
|
197
|
+
const normalizedAddress = v.address.toLowerCase().trim();
|
|
198
|
+
return constants_1.ALLOWED_SUI_VAULT_ADDRESSES.includes(normalizedAddress);
|
|
199
|
+
});
|
|
200
|
+
transformedVaults = this.suiService.transformEmberVaultsToIVaults(whitelistedEmberVaults);
|
|
201
|
+
}
|
|
169
202
|
// Use comprehensive vault fetching for maximum coverage
|
|
170
|
-
const vaultFetchResult = await (0, fetcher_1.fetchVaultsComprehensive)(
|
|
203
|
+
const vaultFetchResult = await (0, fetcher_1.fetchVaultsComprehensive)(enrichableVaults, async (vault) => {
|
|
171
204
|
// Handle fallback RPC if provided
|
|
172
205
|
const rpcUrl = vault.fallbackRpc || this.providers?.[vault.chain];
|
|
173
206
|
// Closed vaults have no live loans/allocations. In portfolio mode,
|
|
@@ -188,6 +221,9 @@ class AugustVaults extends core_1.AugustBase {
|
|
|
188
221
|
vault: vault.address,
|
|
189
222
|
loans: shouldFetchLoans,
|
|
190
223
|
allocations: shouldFetchAllocations,
|
|
224
|
+
// Re-use the backend row from the list response instead of letting
|
|
225
|
+
// getVault re-fetch it per vault (an N+1 against the backend).
|
|
226
|
+
tokenizedVault: vaultRowsByAddress.get(String(vault.address).toLowerCase()),
|
|
191
227
|
options: {
|
|
192
228
|
rpcUrl,
|
|
193
229
|
solanaService: this.solanaService,
|
|
@@ -204,8 +240,8 @@ class AugustVaults extends core_1.AugustBase {
|
|
|
204
240
|
});
|
|
205
241
|
return v;
|
|
206
242
|
}, {
|
|
207
|
-
maxRetries: 5,
|
|
208
|
-
baseDelay: 2000,
|
|
243
|
+
maxRetries: options?.maxRetries ?? 5,
|
|
244
|
+
baseDelay: options?.baseDelay ?? 2000,
|
|
209
245
|
batchSize: 15,
|
|
210
246
|
parallelLimit: 8,
|
|
211
247
|
includeClosed: true,
|
|
@@ -257,8 +293,8 @@ class AugustVaults extends core_1.AugustBase {
|
|
|
257
293
|
...(options?.includeClosed ? filteredResults.closed : []),
|
|
258
294
|
...filteredResults.invisible,
|
|
259
295
|
];
|
|
260
|
-
if ((options
|
|
261
|
-
(options
|
|
296
|
+
if ((options?.wallet && (0, ethers_1.isAddress)(options.wallet)) ||
|
|
297
|
+
(options?.solanaWallet &&
|
|
262
298
|
utils_1.SolanaUtils.isSolanaAddress(options.solanaWallet))) {
|
|
263
299
|
// Batch the per-vault balanceOf/lagDuration reads (Multicall3, grouped
|
|
264
300
|
// by chain) before fanning out — vaults the batch couldn't serve fall
|
|
@@ -294,7 +330,7 @@ class AugustVaults extends core_1.AugustBase {
|
|
|
294
330
|
position: positions?.find((pos) => pos.vault?.toLowerCase() === r.address?.toLowerCase()) || null,
|
|
295
331
|
}));
|
|
296
332
|
}
|
|
297
|
-
if (options
|
|
333
|
+
if (options?.wallet && !(0, ethers_1.isAddress)(options.wallet)) {
|
|
298
334
|
core_1.Logger.log.warn('getVaults:invalid_wallet', options.wallet);
|
|
299
335
|
}
|
|
300
336
|
// console.log(`#getVaults:`, filteredResponses);
|
|
@@ -69,3 +69,55 @@ export interface IVaultCustomOptions {
|
|
|
69
69
|
solanaWallet?: string;
|
|
70
70
|
stellarWallet?: string;
|
|
71
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Options accepted by `getVaults` — on both the `AugustSDK` facade and the
|
|
74
|
+
* underlying `AugustVaults` module. Defined once so the two signatures cannot
|
|
75
|
+
* drift (the facade previously declared a narrower inline type that rejected
|
|
76
|
+
* documented options like `includeClosed` at compile time).
|
|
77
|
+
*/
|
|
78
|
+
export interface IGetVaultsOptions extends IVaultCustomOptions {
|
|
79
|
+
chainIds?: number[];
|
|
80
|
+
headers?: IWSMonitorHeaders;
|
|
81
|
+
loadSubaccounts?: boolean;
|
|
82
|
+
loadSnapshots?: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Portfolio mode: include closed vaults in the result.
|
|
85
|
+
*
|
|
86
|
+
* By default (`false`) closed vaults are excluded, so marketplace /
|
|
87
|
+
* discovery callers never receive a `status: 'closed'` vault. When set,
|
|
88
|
+
* closed vaults are returned regardless of `is_visible` (closed +
|
|
89
|
+
* invisible vaults bucket as closed), so a consumer joining user
|
|
90
|
+
* positions can render a position held in a closed vault on the
|
|
91
|
+
* portfolio page.
|
|
92
|
+
*
|
|
93
|
+
* In this mode, loans/allocations enrichment is also skipped for closed
|
|
94
|
+
* vaults: they have none, and the per-vault enrichment
|
|
95
|
+
* (`getVault` → `getVaultAllocations`) otherwise re-throws when a closed
|
|
96
|
+
* vault has no live strategy/debank data or no subaccounts, which would
|
|
97
|
+
* land the vault in the `failed` bucket and silently drop it before it
|
|
98
|
+
* reaches the filter. Skipping enrichment lets the vault survive on its
|
|
99
|
+
* backend metadata + base on-chain read.
|
|
100
|
+
*
|
|
101
|
+
* @default false
|
|
102
|
+
*/
|
|
103
|
+
includeClosed?: boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Maximum primary-fetch attempts per vault before the fallback
|
|
106
|
+
* strategies (fallback RPCs, minimal fetch, extended retry) run.
|
|
107
|
+
* Attempt `n` waits `baseDelay * 2^(n-1)` ms before retrying, so the
|
|
108
|
+
* default (5 attempts, 2000 ms base) can spend up to 30s of backoff on
|
|
109
|
+
* a single persistently-failing vault. Callers racing this method
|
|
110
|
+
* against their own timeout should lower it (e.g. `2`) so one flaky
|
|
111
|
+
* vault cannot exhaust the whole budget.
|
|
112
|
+
*
|
|
113
|
+
* @default 5
|
|
114
|
+
*/
|
|
115
|
+
maxRetries?: number;
|
|
116
|
+
/**
|
|
117
|
+
* Base backoff delay in **milliseconds** for the per-vault retry
|
|
118
|
+
* schedule (see `maxRetries`).
|
|
119
|
+
*
|
|
120
|
+
* @default 2000
|
|
121
|
+
*/
|
|
122
|
+
baseDelay?: number;
|
|
123
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { IAddress, IContractRunner, INormalizedNumber, IPoolFunctions, ITokenizedVault, IVault, IVaultFreshness } from '../../types';
|
|
1
|
+
import type { IAddress, IContractRunner, INormalizedNumber, IPoolFunctions, ITokenizedVault, IVault, IVaultFreshness, IVaultVersion } from '../../types';
|
|
2
2
|
import { ethers } from 'ethers';
|
|
3
3
|
import type { WalletClient } from 'viem';
|
|
4
4
|
/**
|
|
@@ -50,9 +50,14 @@ export declare function getVaultRewards(tokenizedVault: ITokenizedVault): {
|
|
|
50
50
|
* @param provider - The provider
|
|
51
51
|
* @param vaultAddress - The vault address
|
|
52
52
|
* @param totalAssets - The total assets of the vault
|
|
53
|
+
* @param knownVersion - Optional pre-resolved vault version. Callers that
|
|
54
|
+
* already hold the backend row (e.g. `buildFormattedVault`) pass it so this
|
|
55
|
+
* function doesn't re-fetch `GET /tokenized_vault/{address}` — and with the
|
|
56
|
+
* API's default load flags at that, a heavier payload on a different cache
|
|
57
|
+
* key than the caller's own fetch — just to dispatch on the version.
|
|
53
58
|
* @returns The idle assets
|
|
54
59
|
*/
|
|
55
|
-
export declare function getIdleAssets(provider: IContractRunner, vaultAddress: IAddress, underlying: IAddress, totalAssets: INormalizedNumber): Promise<bigint>;
|
|
60
|
+
export declare function getIdleAssets(provider: IContractRunner, vaultAddress: IAddress, underlying: IAddress, totalAssets: INormalizedNumber, knownVersion?: IVaultVersion): Promise<bigint>;
|
|
56
61
|
export declare function getYieldLastRealizedOn(provider: IContractRunner, vaultAddress: IAddress): Promise<number>;
|
|
57
62
|
/**
|
|
58
63
|
* Format APY data from backend tokenized vault into the unified IVaultApy shape.
|
|
@@ -133,11 +133,16 @@ function getVaultRewards(tokenizedVault) {
|
|
|
133
133
|
* @param provider - The provider
|
|
134
134
|
* @param vaultAddress - The vault address
|
|
135
135
|
* @param totalAssets - The total assets of the vault
|
|
136
|
+
* @param knownVersion - Optional pre-resolved vault version. Callers that
|
|
137
|
+
* already hold the backend row (e.g. `buildFormattedVault`) pass it so this
|
|
138
|
+
* function doesn't re-fetch `GET /tokenized_vault/{address}` — and with the
|
|
139
|
+
* API's default load flags at that, a heavier payload on a different cache
|
|
140
|
+
* key than the caller's own fetch — just to dispatch on the version.
|
|
136
141
|
* @returns The idle assets
|
|
137
142
|
*/
|
|
138
|
-
async function getIdleAssets(provider, vaultAddress, underlying, totalAssets) {
|
|
139
|
-
const
|
|
140
|
-
|
|
143
|
+
async function getIdleAssets(provider, vaultAddress, underlying, totalAssets, knownVersion) {
|
|
144
|
+
const version = knownVersion ??
|
|
145
|
+
(0, vaults_1.getVaultVersionV2)((await (0, core_1.fetchTokenizedVault)(vaultAddress))?.[0]);
|
|
141
146
|
let idleAssets;
|
|
142
147
|
switch (version) {
|
|
143
148
|
case 'evm-0': {
|
|
@@ -522,7 +527,10 @@ async function buildFormattedVault(provider, tokenizedVault, contractCalls) {
|
|
|
522
527
|
isDepositPaused: (0, vaults_1.isBadVault)(tokenizedVault.address),
|
|
523
528
|
decimals: contractCalls.decimals,
|
|
524
529
|
isWithdrawalPaused: contractCalls.withdrawalsPaused,
|
|
525
|
-
idleAssets: (0, core_1.toNormalizedBn)(await getIdleAssets(provider, tokenizedVault.address, contractCalls.asset, contractCalls.totalAssets
|
|
530
|
+
idleAssets: (0, core_1.toNormalizedBn)(await getIdleAssets(provider, tokenizedVault.address, contractCalls.asset, contractCalls.totalAssets,
|
|
531
|
+
// The row is already in hand — don't let getIdleAssets re-fetch it
|
|
532
|
+
// just to resolve the version.
|
|
533
|
+
(0, vaults_1.getVaultVersionV2)(tokenizedVault)), Number(contractCalls.decimals)),
|
|
526
534
|
};
|
|
527
535
|
// Version specific logic
|
|
528
536
|
const version = (0, vaults_1.getVaultVersionV2)(tokenizedVault);
|
package/lib/sdk.d.ts
CHANGED
|
@@ -15822,8 +15822,8 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
15822
15822
|
* Initialize base SDK with provider configuration and API keys.
|
|
15823
15823
|
* Sets up the first provider as the active network by default.
|
|
15824
15824
|
*
|
|
15825
|
-
* @throws
|
|
15826
|
-
* length range — see {@link IAugustBase.appName}.
|
|
15825
|
+
* @throws AugustValidationError if `appName` is missing, malformed, or
|
|
15826
|
+
* out of the allowed length range — see {@link IAugustBase.appName}.
|
|
15827
15827
|
*/
|
|
15828
15828
|
constructor({ appName, providers, keys, monitoring, analytics, versionCheck, timeoutMs, publicApiBaseUrl, attribution, }: IAugustBase);
|
|
15829
15829
|
/**
|
|
@@ -15998,15 +15998,12 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
15998
15998
|
/**
|
|
15999
15999
|
* Fetch all available vaults across configured networks.
|
|
16000
16000
|
* Optionally filter by chain IDs and include loan/allocation data.
|
|
16001
|
-
* @param options - Configuration for filtering and enriching vault data
|
|
16001
|
+
* @param options - Configuration for filtering and enriching vault data —
|
|
16002
|
+
* see {@link IGetVaultsOptions} for the full surface (`includeClosed`
|
|
16003
|
+
* portfolio mode, `maxRetries`/`baseDelay` retry tuning)
|
|
16002
16004
|
* @returns Array of vault objects with metadata and optional position data
|
|
16003
16005
|
*/
|
|
16004
|
-
getVaults(options?:
|
|
16005
|
-
chainIds?: number[];
|
|
16006
|
-
headers?: IWSMonitorHeaders;
|
|
16007
|
-
loadSubaccounts?: boolean;
|
|
16008
|
-
loadSnapshots?: boolean;
|
|
16009
|
-
} & IVaultCustomOptions): Promise<IVault[]>;
|
|
16006
|
+
getVaults(options?: IGetVaultsOptions): Promise<IVault[]>;
|
|
16010
16007
|
getTotalDeposited(options?: {
|
|
16011
16008
|
loadSubaccounts?: boolean;
|
|
16012
16009
|
loadSnapshots?: boolean;
|
|
@@ -16793,32 +16790,7 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
16793
16790
|
* @param options Filtering and enrichment configuration
|
|
16794
16791
|
* @returns Array of vault objects with optional loans/allocations/positions
|
|
16795
16792
|
*/
|
|
16796
|
-
getVaults(options?:
|
|
16797
|
-
chainIds?: number[];
|
|
16798
|
-
loadSubaccounts?: boolean;
|
|
16799
|
-
loadSnapshots?: boolean;
|
|
16800
|
-
/**
|
|
16801
|
-
* Portfolio mode: include closed vaults in the result.
|
|
16802
|
-
*
|
|
16803
|
-
* By default (`false`) closed vaults are excluded, so marketplace /
|
|
16804
|
-
* discovery callers never receive a `status: 'closed'` vault. When set,
|
|
16805
|
-
* closed vaults are returned regardless of `is_visible` (closed +
|
|
16806
|
-
* invisible vaults bucket as closed), so a consumer joining user
|
|
16807
|
-
* positions can render a position held in a closed vault on the
|
|
16808
|
-
* portfolio page.
|
|
16809
|
-
*
|
|
16810
|
-
* In this mode, loans/allocations enrichment is also skipped for closed
|
|
16811
|
-
* vaults: they have none, and the per-vault enrichment
|
|
16812
|
-
* (`getVault` → `getVaultAllocations`) otherwise re-throws when a closed
|
|
16813
|
-
* vault has no live strategy/debank data or no subaccounts, which would
|
|
16814
|
-
* land the vault in the `failed` bucket and silently drop it before it
|
|
16815
|
-
* reaches the filter. Skipping enrichment lets the vault survive on its
|
|
16816
|
-
* backend metadata + base on-chain read.
|
|
16817
|
-
*
|
|
16818
|
-
* @default false
|
|
16819
|
-
*/
|
|
16820
|
-
includeClosed?: boolean;
|
|
16821
|
-
} & IVaultCustomOptions): Promise<IVault[]>;
|
|
16793
|
+
getVaults(options?: IGetVaultsOptions): Promise<IVault[]>;
|
|
16822
16794
|
/**
|
|
16823
16795
|
* Calculate total deposited across all tokenized vaults by summing latest_reported_tvl.
|
|
16824
16796
|
* Uses the /tokenized_vault endpoint which returns latest_reported_tvl in USD.
|
|
@@ -18830,9 +18802,14 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
18830
18802
|
* @param provider - The provider
|
|
18831
18803
|
* @param vaultAddress - The vault address
|
|
18832
18804
|
* @param totalAssets - The total assets of the vault
|
|
18805
|
+
* @param knownVersion - Optional pre-resolved vault version. Callers that
|
|
18806
|
+
* already hold the backend row (e.g. `buildFormattedVault`) pass it so this
|
|
18807
|
+
* function doesn't re-fetch `GET /tokenized_vault/{address}` — and with the
|
|
18808
|
+
* API's default load flags at that, a heavier payload on a different cache
|
|
18809
|
+
* key than the caller's own fetch — just to dispatch on the version.
|
|
18833
18810
|
* @returns The idle assets
|
|
18834
18811
|
*/
|
|
18835
|
-
export declare function getIdleAssets(provider: IContractRunner, vaultAddress: IAddress, underlying: IAddress, totalAssets: INormalizedNumber): Promise<bigint>;
|
|
18812
|
+
export declare function getIdleAssets(provider: IContractRunner, vaultAddress: IAddress, underlying: IAddress, totalAssets: INormalizedNumber, knownVersion?: IVaultVersion): Promise<bigint>;
|
|
18836
18813
|
|
|
18837
18814
|
/**
|
|
18838
18815
|
* Create or reuse a cached Infura provider for the specified chain.
|
|
@@ -19348,15 +19325,22 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
19348
19325
|
* @param loans - Include active loan data
|
|
19349
19326
|
* @param allocations - Include DeFi/CeFi allocation breakdowns
|
|
19350
19327
|
* @param options - RPC and service configuration
|
|
19328
|
+
* @param tokenizedVault - Optional pre-fetched backend row for `vault`. When a
|
|
19329
|
+
* caller already holds the row (e.g. `getVaults` fetched the whole list one
|
|
19330
|
+
* call earlier), passing it skips this function's own
|
|
19331
|
+
* `GET /tokenized_vault/{address}` — a pure de-duplication of backend
|
|
19332
|
+
* traffic. The row must have been fetched with the same
|
|
19333
|
+
* `loadSubaccounts`/`loadSnapshots` flags the caller passes here.
|
|
19351
19334
|
* @returns Complete vault object with optional enrichments
|
|
19352
19335
|
*/
|
|
19353
|
-
export declare function getVault({ vault, loans, allocations, options, loadSubaccounts, loadSnapshots, }: {
|
|
19336
|
+
export declare function getVault({ vault, loans, allocations, options, loadSubaccounts, loadSnapshots, tokenizedVault: prefetchedRow, }: {
|
|
19354
19337
|
vault: IAddress;
|
|
19355
19338
|
loans?: boolean;
|
|
19356
19339
|
allocations?: boolean;
|
|
19357
19340
|
options: IVaultBaseOptions;
|
|
19358
19341
|
loadSubaccounts?: boolean;
|
|
19359
19342
|
loadSnapshots?: boolean;
|
|
19343
|
+
tokenizedVault?: ITokenizedVault;
|
|
19360
19344
|
}): Promise<IVault>;
|
|
19361
19345
|
|
|
19362
19346
|
/**
|
|
@@ -19976,7 +19960,8 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
19976
19960
|
* 3–64 characters, `[a-zA-Z0-9._-]` only. Use a slug ("acme-trader"),
|
|
19977
19961
|
* not a display name ("Acme Trader").
|
|
19978
19962
|
*
|
|
19979
|
-
* @throws
|
|
19963
|
+
* @throws AugustValidationError synchronously from the constructor if
|
|
19964
|
+
* missing, empty, or malformed.
|
|
19980
19965
|
*
|
|
19981
19966
|
* @example
|
|
19982
19967
|
* ```typescript
|
|
@@ -20756,6 +20741,59 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
20756
20741
|
status?: string;
|
|
20757
20742
|
}
|
|
20758
20743
|
|
|
20744
|
+
/**
|
|
20745
|
+
* Options accepted by `getVaults` — on both the `AugustSDK` facade and the
|
|
20746
|
+
* underlying `AugustVaults` module. Defined once so the two signatures cannot
|
|
20747
|
+
* drift (the facade previously declared a narrower inline type that rejected
|
|
20748
|
+
* documented options like `includeClosed` at compile time).
|
|
20749
|
+
*/
|
|
20750
|
+
export declare interface IGetVaultsOptions extends IVaultCustomOptions {
|
|
20751
|
+
chainIds?: number[];
|
|
20752
|
+
headers?: IWSMonitorHeaders;
|
|
20753
|
+
loadSubaccounts?: boolean;
|
|
20754
|
+
loadSnapshots?: boolean;
|
|
20755
|
+
/**
|
|
20756
|
+
* Portfolio mode: include closed vaults in the result.
|
|
20757
|
+
*
|
|
20758
|
+
* By default (`false`) closed vaults are excluded, so marketplace /
|
|
20759
|
+
* discovery callers never receive a `status: 'closed'` vault. When set,
|
|
20760
|
+
* closed vaults are returned regardless of `is_visible` (closed +
|
|
20761
|
+
* invisible vaults bucket as closed), so a consumer joining user
|
|
20762
|
+
* positions can render a position held in a closed vault on the
|
|
20763
|
+
* portfolio page.
|
|
20764
|
+
*
|
|
20765
|
+
* In this mode, loans/allocations enrichment is also skipped for closed
|
|
20766
|
+
* vaults: they have none, and the per-vault enrichment
|
|
20767
|
+
* (`getVault` → `getVaultAllocations`) otherwise re-throws when a closed
|
|
20768
|
+
* vault has no live strategy/debank data or no subaccounts, which would
|
|
20769
|
+
* land the vault in the `failed` bucket and silently drop it before it
|
|
20770
|
+
* reaches the filter. Skipping enrichment lets the vault survive on its
|
|
20771
|
+
* backend metadata + base on-chain read.
|
|
20772
|
+
*
|
|
20773
|
+
* @default false
|
|
20774
|
+
*/
|
|
20775
|
+
includeClosed?: boolean;
|
|
20776
|
+
/**
|
|
20777
|
+
* Maximum primary-fetch attempts per vault before the fallback
|
|
20778
|
+
* strategies (fallback RPCs, minimal fetch, extended retry) run.
|
|
20779
|
+
* Attempt `n` waits `baseDelay * 2^(n-1)` ms before retrying, so the
|
|
20780
|
+
* default (5 attempts, 2000 ms base) can spend up to 30s of backoff on
|
|
20781
|
+
* a single persistently-failing vault. Callers racing this method
|
|
20782
|
+
* against their own timeout should lower it (e.g. `2`) so one flaky
|
|
20783
|
+
* vault cannot exhaust the whole budget.
|
|
20784
|
+
*
|
|
20785
|
+
* @default 5
|
|
20786
|
+
*/
|
|
20787
|
+
maxRetries?: number;
|
|
20788
|
+
/**
|
|
20789
|
+
* Base backoff delay in **milliseconds** for the per-vault retry
|
|
20790
|
+
* schedule (see `maxRetries`).
|
|
20791
|
+
*
|
|
20792
|
+
* @default 2000
|
|
20793
|
+
*/
|
|
20794
|
+
baseDelay?: number;
|
|
20795
|
+
}
|
|
20796
|
+
|
|
20759
20797
|
/**
|
|
20760
20798
|
* Table of Contents
|
|
20761
20799
|
* 1) Subaccounts
|
|
@@ -20946,16 +20984,28 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
20946
20984
|
* Initialize Sentry with SDK-specific configuration. Idempotent: re-calls
|
|
20947
20985
|
* only refresh user identity and the cached API-key hash.
|
|
20948
20986
|
*
|
|
20987
|
+
* Breaking change in v9: `appName` moved from the optional fifth parameter
|
|
20988
|
+
* to the required third parameter, so every telemetry stream carries an
|
|
20989
|
+
* application identity (the `AugustSDK` constructor has required it since
|
|
20990
|
+
* v5). Callers on the old positional order get a synchronous validation
|
|
20991
|
+
* error rather than silently anonymous events.
|
|
20992
|
+
*
|
|
20949
20993
|
* @param config - Analytics configuration. Pass `tracesSampleRate` to
|
|
20950
20994
|
* override the default of `0.1`.
|
|
20951
20995
|
* @param environment - Current environment (DEV or PROD).
|
|
20996
|
+
* @param appName - App-name slug, required. Set as the global `app.name`
|
|
20997
|
+
* tag on every event and used to derive `partner.id`. Identifier-shaped:
|
|
20998
|
+
* 3–64 chars, `[a-zA-Z0-9._-]` only, and not an EVM address — the same
|
|
20999
|
+
* rules the `AugustSDK` constructor enforces.
|
|
20952
21000
|
* @param walletAddress - Optional wallet address for user identification.
|
|
20953
21001
|
* @param apiKey - Optional API key (hashed for identification).
|
|
20954
|
-
* @
|
|
20955
|
-
*
|
|
20956
|
-
*
|
|
21002
|
+
* @throws AugustValidationError (code `INVALID_INPUT`) when `appName` is
|
|
21003
|
+
* missing, empty, mis-typed, out of the allowed length range, contains
|
|
21004
|
+
* disallowed characters, or is shaped like an EVM address. Thrown before
|
|
21005
|
+
* any analytics state mutates, even when analytics would be disabled by
|
|
21006
|
+
* config or environment gates.
|
|
20957
21007
|
*/
|
|
20958
|
-
export declare function initializeSentry(config: IAnalyticsConfig, environment: IEnv,
|
|
21008
|
+
export declare function initializeSentry(config: IAnalyticsConfig, environment: IEnv, appName: string, walletAddress?: string, apiKey?: string): void;
|
|
20959
21009
|
|
|
20960
21010
|
export declare type INormalizedNumber = {
|
|
20961
21011
|
normalized: string;
|