@augustdigital/sdk 9.12.0 → 9.13.1
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/core/analytics/version.d.ts +1 -1
- package/lib/core/analytics/version.js +1 -1
- package/lib/modules/vaults/getters.d.ts +13 -1
- package/lib/modules/vaults/getters.js +37 -48
- package/lib/modules/vaults/utils.d.ts +8 -0
- package/lib/modules/vaults/utils.js +19 -0
- package/lib/sdk.d.ts +30 -1
- package/lib/types/vaults.d.ts +8 -0
- package/package.json +1 -1
|
@@ -860,9 +860,21 @@ export declare function getVaultUserLifetimePnl({ vault, wallet, options, }: {
|
|
|
860
860
|
* Calculate PnL for a vault (vault-level, not user-specific).
|
|
861
861
|
* Returns the vault's overall profit and loss across all users.
|
|
862
862
|
*
|
|
863
|
+
* Sums, over the vault's whole history, each day's change in assets per share
|
|
864
|
+
* times that day's total shares, then prices the result at the receipt
|
|
865
|
+
* token's current USD price. The daily history comes from
|
|
866
|
+
* `GET /tokenized_vault/{vault}/historical-timeseries`, the replacement for the
|
|
867
|
+
* deprecated `load_snapshots` flag on the vault read.
|
|
868
|
+
*
|
|
869
|
+
* Network: one backend vault read, one timeseries read and one price read.
|
|
870
|
+
*
|
|
863
871
|
* @param vault - Vault contract address
|
|
864
872
|
* @param options - RPC configuration and service options
|
|
865
|
-
* @returns Vault PnL in
|
|
873
|
+
* @returns Vault PnL in the deposit asset (`totalPnl`) and in USD (`pnlUsd`).
|
|
874
|
+
* Both are zero for a vault with no recorded history. `pnlUsd` is also zero
|
|
875
|
+
* when the receipt token price cannot be fetched.
|
|
876
|
+
* @throws Error when `vault` is missing, is a Stellar vault, is not an
|
|
877
|
+
* address, or the vault or its history cannot be read.
|
|
866
878
|
*/
|
|
867
879
|
export declare function getVaultPnl({ vault, options, }: {
|
|
868
880
|
vault: IAddress;
|
|
@@ -3445,9 +3445,21 @@ async function getVaultUserLifetimePnl({ vault, wallet, options, }) {
|
|
|
3445
3445
|
* Calculate PnL for a vault (vault-level, not user-specific).
|
|
3446
3446
|
* Returns the vault's overall profit and loss across all users.
|
|
3447
3447
|
*
|
|
3448
|
+
* Sums, over the vault's whole history, each day's change in assets per share
|
|
3449
|
+
* times that day's total shares, then prices the result at the receipt
|
|
3450
|
+
* token's current USD price. The daily history comes from
|
|
3451
|
+
* `GET /tokenized_vault/{vault}/historical-timeseries`, the replacement for the
|
|
3452
|
+
* deprecated `load_snapshots` flag on the vault read.
|
|
3453
|
+
*
|
|
3454
|
+
* Network: one backend vault read, one timeseries read and one price read.
|
|
3455
|
+
*
|
|
3448
3456
|
* @param vault - Vault contract address
|
|
3449
3457
|
* @param options - RPC configuration and service options
|
|
3450
|
-
* @returns Vault PnL in
|
|
3458
|
+
* @returns Vault PnL in the deposit asset (`totalPnl`) and in USD (`pnlUsd`).
|
|
3459
|
+
* Both are zero for a vault with no recorded history. `pnlUsd` is also zero
|
|
3460
|
+
* when the receipt token price cannot be fetched.
|
|
3461
|
+
* @throws Error when `vault` is missing, is a Stellar vault, is not an
|
|
3462
|
+
* address, or the vault or its history cannot be read.
|
|
3451
3463
|
*/
|
|
3452
3464
|
async function getVaultPnl({ vault, options, }) {
|
|
3453
3465
|
try {
|
|
@@ -3456,60 +3468,33 @@ async function getVaultPnl({ vault, options, }) {
|
|
|
3456
3468
|
(0, utils_3.assertNotStellar)(vault, 'Vault PnL');
|
|
3457
3469
|
if (!(0, ethers_1.isAddress)(vault))
|
|
3458
3470
|
throw new Error(`Vault input parameter is not an address: ${String(vault)}`);
|
|
3459
|
-
//
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3471
|
+
// The vault row only supplies decimals, chain and receipt token, so skip
|
|
3472
|
+
// its subaccounts and snapshots. 3650 days reads the full history, as
|
|
3473
|
+
// `fetchShareRatios` does.
|
|
3474
|
+
const [vaultData, { data: history }] = await Promise.all([
|
|
3475
|
+
getVault({
|
|
3476
|
+
vault,
|
|
3477
|
+
loans: false,
|
|
3478
|
+
allocations: false,
|
|
3479
|
+
options,
|
|
3480
|
+
loadSubaccounts: false,
|
|
3481
|
+
loadSnapshots: false,
|
|
3482
|
+
}),
|
|
3483
|
+
(0, core_1.fetchVaultHistoricalTimeseries)(vault, 3650, options?.headers),
|
|
3484
|
+
]);
|
|
3466
3485
|
if (!vaultData) {
|
|
3467
3486
|
throw new Error(`Vault ${vault} not found`);
|
|
3468
3487
|
}
|
|
3469
|
-
// Check if vault has daily_pnl_per_share and historical_snapshots
|
|
3470
|
-
if (!vaultData.dailyPnlPerShare ||
|
|
3471
|
-
!Array.isArray(vaultData.dailyPnlPerShare) ||
|
|
3472
|
-
vaultData.dailyPnlPerShare.length === 0) {
|
|
3473
|
-
return {
|
|
3474
|
-
totalPnl: (0, core_1.toNormalizedBn)(0, vaultData.decimals),
|
|
3475
|
-
pnlUsd: 0,
|
|
3476
|
-
};
|
|
3477
|
-
}
|
|
3478
|
-
if (!vaultData.historical_snapshots ||
|
|
3479
|
-
!Array.isArray(vaultData.historical_snapshots) ||
|
|
3480
|
-
vaultData.historical_snapshots.length === 0) {
|
|
3481
|
-
return {
|
|
3482
|
-
totalPnl: (0, core_1.toNormalizedBn)(0, vaultData.decimals),
|
|
3483
|
-
pnlUsd: 0,
|
|
3484
|
-
};
|
|
3485
|
-
}
|
|
3486
3488
|
const decimals = vaultData.decimals;
|
|
3487
|
-
//
|
|
3488
|
-
|
|
3489
|
-
// Create a map of historical_snapshots by date (YYYY-MM-DD) for quick lookup
|
|
3490
|
-
const snapshotsByDate = new Map();
|
|
3491
|
-
vaultData.historical_snapshots.forEach((snapshot) => {
|
|
3492
|
-
const snapshotDate = new Date(snapshot.snapshot_datetime);
|
|
3493
|
-
const dateKey = snapshotDate.toISOString().split('T')[0]; // YYYY-MM-DD
|
|
3494
|
-
snapshotsByDate.set(dateKey, snapshot);
|
|
3495
|
-
});
|
|
3496
|
-
// Calculate PnL for each day using historical_snapshots
|
|
3489
|
+
// `daily_pnl` is the day's change in assets per share. It is zero on the
|
|
3490
|
+
// first day and on forward-filled (`missing`) days, so those add nothing.
|
|
3497
3491
|
let totalPnlRaw = BigInt(0);
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
const dailyPnlPerShare = dayData.value;
|
|
3501
|
-
// Get date key (YYYY-MM-DD) from timestamp
|
|
3502
|
-
const dayDate = new Date(dayTimestamp);
|
|
3503
|
-
const dateKey = dayDate.toISOString().split('T')[0];
|
|
3504
|
-
// Find matching snapshot for this date
|
|
3505
|
-
const snapshot = snapshotsByDate.get(dateKey);
|
|
3506
|
-
if (!snapshot?.total_shares) {
|
|
3507
|
-
core_1.Logger.log.warn('getVaultPnl:snapshotNotFound', `No snapshot found for date ${dateKey}`);
|
|
3492
|
+
Object.values(history ?? {}).forEach((day) => {
|
|
3493
|
+
if (!day.daily_pnl || !day.total_shares)
|
|
3508
3494
|
return;
|
|
3509
|
-
}
|
|
3510
3495
|
// Convert normalized numbers to BigInt using toNormalizedBn's normalized string
|
|
3511
|
-
const dailyPnlNorm = (0, core_1.toNormalizedBn)(
|
|
3512
|
-
const totalSharesNorm = (0, core_1.toNormalizedBn)(
|
|
3496
|
+
const dailyPnlNorm = (0, core_1.toNormalizedBn)(day.daily_pnl, decimals);
|
|
3497
|
+
const totalSharesNorm = (0, core_1.toNormalizedBn)(day.total_shares, decimals);
|
|
3513
3498
|
// Convert normalized strings to BigInt (split, pad fraction, combine) - all inline
|
|
3514
3499
|
const [dailyWhole = '0', dailyFrac = ''] = dailyPnlNorm.normalized.split('.');
|
|
3515
3500
|
const dailyPnlPerShareScaled = BigInt(dailyWhole + (dailyFrac || '').padEnd(decimals, '0').slice(0, decimals));
|
|
@@ -3520,6 +3505,10 @@ async function getVaultPnl({ vault, options, }) {
|
|
|
3520
3505
|
const dayPnlRaw = (dailyPnlPerShareScaled * totalSharesScaled) / BigInt(10 ** decimals);
|
|
3521
3506
|
totalPnlRaw += dayPnlRaw;
|
|
3522
3507
|
});
|
|
3508
|
+
// No history (or no PnL in it) prices to zero, so skip the price read.
|
|
3509
|
+
if (totalPnlRaw === BigInt(0)) {
|
|
3510
|
+
return { totalPnl: (0, core_1.toNormalizedBn)(0, decimals), pnlUsd: 0 };
|
|
3511
|
+
}
|
|
3523
3512
|
// Convert totalPnlRaw (BigInt) to normalized number using toNormalizedBn
|
|
3524
3513
|
const totalPnl = (0, core_1.toNormalizedBn)(totalPnlRaw, decimals);
|
|
3525
3514
|
const totalPnlNormalized = Number(totalPnl.normalized);
|
|
@@ -82,6 +82,14 @@ export declare function formatVaultApy(tokenizedVault: ITokenizedVault): IVault[
|
|
|
82
82
|
* the trailing `Z` is preserved.
|
|
83
83
|
*/
|
|
84
84
|
export declare function mapVaultFreshness(tokenizedVault: ITokenizedVault | undefined | null): IVaultFreshness | null;
|
|
85
|
+
/**
|
|
86
|
+
* Map a wrapper vault's link to the vault it wraps.
|
|
87
|
+
*
|
|
88
|
+
* @param tokenizedVault - Backend tokenized-vault payload.
|
|
89
|
+
* @returns The underlying vault address (casing preserved) and chain id, both
|
|
90
|
+
* null for a non-wrapper vault. A chain id without an address is dropped.
|
|
91
|
+
*/
|
|
92
|
+
export declare function mapUnderlyingVault(tokenizedVault: ITokenizedVault | undefined | null): Pick<IVault, 'underlyingVaultAddress' | 'underlyingChainId'>;
|
|
85
93
|
/**
|
|
86
94
|
* Map strategists from backend subaccounts or hardcoded list.
|
|
87
95
|
* Shared across all chain adapters.
|
|
@@ -7,6 +7,7 @@ exports.getIdleAssets = getIdleAssets;
|
|
|
7
7
|
exports.getYieldLastRealizedOn = getYieldLastRealizedOn;
|
|
8
8
|
exports.formatVaultApy = formatVaultApy;
|
|
9
9
|
exports.mapVaultFreshness = mapVaultFreshness;
|
|
10
|
+
exports.mapUnderlyingVault = mapUnderlyingVault;
|
|
10
11
|
exports.mapStrategists = mapStrategists;
|
|
11
12
|
exports.mapComposabilityIntegrations = mapComposabilityIntegrations;
|
|
12
13
|
exports.backendTvlToNormalizedBn = backendTvlToNormalizedBn;
|
|
@@ -268,6 +269,22 @@ function mapVaultFreshness(tokenizedVault) {
|
|
|
268
269
|
cachedAt: freshness.cached_at ?? null,
|
|
269
270
|
};
|
|
270
271
|
}
|
|
272
|
+
/**
|
|
273
|
+
* Map a wrapper vault's link to the vault it wraps.
|
|
274
|
+
*
|
|
275
|
+
* @param tokenizedVault - Backend tokenized-vault payload.
|
|
276
|
+
* @returns The underlying vault address (casing preserved) and chain id, both
|
|
277
|
+
* null for a non-wrapper vault. A chain id without an address is dropped.
|
|
278
|
+
*/
|
|
279
|
+
function mapUnderlyingVault(tokenizedVault) {
|
|
280
|
+
const address = tokenizedVault?.underlying_vault_address;
|
|
281
|
+
if (!address)
|
|
282
|
+
return { underlyingVaultAddress: null, underlyingChainId: null };
|
|
283
|
+
return {
|
|
284
|
+
underlyingVaultAddress: address,
|
|
285
|
+
underlyingChainId: tokenizedVault?.underlying_chain ?? null,
|
|
286
|
+
};
|
|
287
|
+
}
|
|
271
288
|
/**
|
|
272
289
|
* Map strategists from backend subaccounts or hardcoded list.
|
|
273
290
|
* Shared across all chain adapters.
|
|
@@ -437,6 +454,7 @@ function buildBackendVault(tokenizedVault, overrides) {
|
|
|
437
454
|
dailyPnlPerShare: mapDailyPnlPerShare(tokenizedVault.daily_pnl_per_share),
|
|
438
455
|
enabled_historical_price_horizons: tokenizedVault.enabled_historical_price_horizons || [],
|
|
439
456
|
latest_reported_tvl: tokenizedVault.latest_reported_tvl,
|
|
457
|
+
...mapUnderlyingVault(tokenizedVault),
|
|
440
458
|
defaultApyHorizon: tokenizedVault.default_apy_horizon,
|
|
441
459
|
...(tokenizedVault.instant_redeem_config
|
|
442
460
|
? {
|
|
@@ -659,6 +677,7 @@ async function buildFormattedVault(provider, tokenizedVault, contractCalls) {
|
|
|
659
677
|
enabled_historical_price_horizons: tokenizedVault?.enabled_historical_price_horizons,
|
|
660
678
|
defaultApyHorizon: tokenizedVault?.default_apy_horizon ?? null,
|
|
661
679
|
latest_reported_tvl: tokenizedVault?.latest_reported_tvl,
|
|
680
|
+
...mapUnderlyingVault(tokenizedVault),
|
|
662
681
|
cachedAt: tokenizedVault?.cached_at ?? null,
|
|
663
682
|
freshness: mapVaultFreshness(tokenizedVault),
|
|
664
683
|
showCapFilled: tokenizedVault?.show_cap_filled ?? null,
|
package/lib/sdk.d.ts
CHANGED
|
@@ -20178,9 +20178,21 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
20178
20178
|
* Calculate PnL for a vault (vault-level, not user-specific).
|
|
20179
20179
|
* Returns the vault's overall profit and loss across all users.
|
|
20180
20180
|
*
|
|
20181
|
+
* Sums, over the vault's whole history, each day's change in assets per share
|
|
20182
|
+
* times that day's total shares, then prices the result at the receipt
|
|
20183
|
+
* token's current USD price. The daily history comes from
|
|
20184
|
+
* `GET /tokenized_vault/{vault}/historical-timeseries`, the replacement for the
|
|
20185
|
+
* deprecated `load_snapshots` flag on the vault read.
|
|
20186
|
+
*
|
|
20187
|
+
* Network: one backend vault read, one timeseries read and one price read.
|
|
20188
|
+
*
|
|
20181
20189
|
* @param vault - Vault contract address
|
|
20182
20190
|
* @param options - RPC configuration and service options
|
|
20183
|
-
* @returns Vault PnL in
|
|
20191
|
+
* @returns Vault PnL in the deposit asset (`totalPnl`) and in USD (`pnlUsd`).
|
|
20192
|
+
* Both are zero for a vault with no recorded history. `pnlUsd` is also zero
|
|
20193
|
+
* when the receipt token price cannot be fetched.
|
|
20194
|
+
* @throws Error when `vault` is missing, is a Stellar vault, is not an
|
|
20195
|
+
* address, or the vault or its history cannot be read.
|
|
20184
20196
|
*/
|
|
20185
20197
|
export declare function getVaultPnl({ vault, options, }: {
|
|
20186
20198
|
vault: IAddress;
|
|
@@ -24276,6 +24288,14 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
24276
24288
|
enabled_historical_price_horizons?: number[];
|
|
24277
24289
|
defaultApyHorizon?: 7 | 30 | null;
|
|
24278
24290
|
latest_reported_tvl?: number | null;
|
|
24291
|
+
/**
|
|
24292
|
+
* Wrapper vaults only: the vault this one wraps, which holds the assets. A
|
|
24293
|
+
* wrapper's own on-chain `totalAssets` reads 0, so its TVL is the underlying
|
|
24294
|
+
* vault's. Null on a non-wrapper vault. Address casing is preserved verbatim.
|
|
24295
|
+
*/
|
|
24296
|
+
underlyingVaultAddress?: VaultAddress | null;
|
|
24297
|
+
/** Chain id of {@link IVault.underlyingVaultAddress}; null on a non-wrapper vault. */
|
|
24298
|
+
underlyingChainId?: number | null;
|
|
24279
24299
|
cachedAt?: string | null;
|
|
24280
24300
|
/**
|
|
24281
24301
|
* Provenance timestamps for the vault's server-side data — when its APY was last
|
|
@@ -25621,6 +25641,15 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
25621
25641
|
website_url: string;
|
|
25622
25642
|
}[];
|
|
25623
25643
|
|
|
25644
|
+
/**
|
|
25645
|
+
* Map a wrapper vault's link to the vault it wraps.
|
|
25646
|
+
*
|
|
25647
|
+
* @param tokenizedVault - Backend tokenized-vault payload.
|
|
25648
|
+
* @returns The underlying vault address (casing preserved) and chain id, both
|
|
25649
|
+
* null for a non-wrapper vault. A chain id without an address is dropped.
|
|
25650
|
+
*/
|
|
25651
|
+
export declare function mapUnderlyingVault(tokenizedVault: ITokenizedVault | undefined | null): Pick<IVault, 'underlyingVaultAddress' | 'underlyingChainId'>;
|
|
25652
|
+
|
|
25624
25653
|
/**
|
|
25625
25654
|
* Map the backend `freshness` object onto the camelCased {@link IVaultFreshness}
|
|
25626
25655
|
* shape carried on `IVault`. Shared across all chain adapters (EVM, Solana,
|
package/lib/types/vaults.d.ts
CHANGED
|
@@ -383,6 +383,14 @@ export interface IVault {
|
|
|
383
383
|
enabled_historical_price_horizons?: number[];
|
|
384
384
|
defaultApyHorizon?: 7 | 30 | null;
|
|
385
385
|
latest_reported_tvl?: number | null;
|
|
386
|
+
/**
|
|
387
|
+
* Wrapper vaults only: the vault this one wraps, which holds the assets. A
|
|
388
|
+
* wrapper's own on-chain `totalAssets` reads 0, so its TVL is the underlying
|
|
389
|
+
* vault's. Null on a non-wrapper vault. Address casing is preserved verbatim.
|
|
390
|
+
*/
|
|
391
|
+
underlyingVaultAddress?: VaultAddress | null;
|
|
392
|
+
/** Chain id of {@link IVault.underlyingVaultAddress}; null on a non-wrapper vault. */
|
|
393
|
+
underlyingChainId?: number | null;
|
|
386
394
|
cachedAt?: string | null;
|
|
387
395
|
/**
|
|
388
396
|
* Provenance timestamps for the vault's server-side data — when its APY was last
|