@augustdigital/sdk 8.24.0 → 8.26.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/solana/idl/vault-idl.d.ts +185 -18
- package/lib/adapters/solana/idl/vault-idl.js +521 -28
- package/lib/adapters/sui/getters.d.ts +7 -1
- package/lib/adapters/sui/getters.js +53 -6
- package/lib/core/analytics/method-taxonomy.js +10 -0
- package/lib/core/analytics/version.d.ts +1 -1
- package/lib/core/analytics/version.js +1 -1
- package/lib/core/constants/core.d.ts +11 -0
- package/lib/core/constants/core.js +54 -0
- package/lib/main.d.ts +28 -11
- package/lib/main.js +25 -3
- package/lib/modules/api/fetcher.d.ts +27 -1
- package/lib/modules/api/fetcher.js +38 -1
- package/lib/modules/api/main.d.ts +288 -14
- package/lib/modules/api/main.js +439 -13
- 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/modules/vaults/write.actions.d.ts +4 -0
- package/lib/modules/vaults/write.actions.js +9 -1
- package/lib/sdk.d.ts +11618 -10864
- package/lib/types/api.d.ts +218 -0
- package/package.json +1 -1
|
@@ -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);
|
|
@@ -501,6 +501,10 @@ export declare function depositNativeViaSwapRouter(signer: Signer | Wallet, opti
|
|
|
501
501
|
* the chain's whitelisted aggregator, fail-closed on router/selector drift)
|
|
502
502
|
* bundled into {@link swapAndDeposit}.
|
|
503
503
|
*
|
|
504
|
+
* An `originCode` is forwarded verbatim to whichever of those three entry points
|
|
505
|
+
* runs, so a partner's origin fee accrues on every path. Omitting it sends the
|
|
506
|
+
* all-zero sentinel, which the router reads as "no origin fee".
|
|
507
|
+
*
|
|
504
508
|
* Side effects: reads tokenized-vault metadata, the vault's reference asset and
|
|
505
509
|
* decimals, and (on the swap path) one Paraswap quote; sends one ERC-20
|
|
506
510
|
* `approve` to the SwapRouter when allowance is short, then the deposit tx.
|
|
@@ -1311,6 +1311,7 @@ async function dispatchViaSwapRouter(args) {
|
|
|
1311
1311
|
vault: args.target,
|
|
1312
1312
|
receiver: sharesReceiver,
|
|
1313
1313
|
amount: amountRaw,
|
|
1314
|
+
originCode: args.originCode,
|
|
1314
1315
|
wait: args.wait,
|
|
1315
1316
|
});
|
|
1316
1317
|
}
|
|
@@ -1323,6 +1324,7 @@ async function dispatchViaSwapRouter(args) {
|
|
|
1323
1324
|
receiver: sharesReceiver,
|
|
1324
1325
|
asset: args.actualDepositAsset,
|
|
1325
1326
|
amount: amountRaw,
|
|
1327
|
+
originCode: args.originCode,
|
|
1326
1328
|
wait: args.wait,
|
|
1327
1329
|
});
|
|
1328
1330
|
}
|
|
@@ -1389,6 +1391,7 @@ async function dispatchViaSwapRouter(args) {
|
|
|
1389
1391
|
payload: quote.payload,
|
|
1390
1392
|
},
|
|
1391
1393
|
],
|
|
1394
|
+
originCode: args.originCode,
|
|
1392
1395
|
wait: args.wait,
|
|
1393
1396
|
});
|
|
1394
1397
|
}
|
|
@@ -1638,6 +1641,10 @@ async function depositNativeViaSwapRouter(signer, options) {
|
|
|
1638
1641
|
* the chain's whitelisted aggregator, fail-closed on router/selector drift)
|
|
1639
1642
|
* bundled into {@link swapAndDeposit}.
|
|
1640
1643
|
*
|
|
1644
|
+
* An `originCode` is forwarded verbatim to whichever of those three entry points
|
|
1645
|
+
* runs, so a partner's origin fee accrues on every path. Omitting it sends the
|
|
1646
|
+
* all-zero sentinel, which the router reads as "no origin fee".
|
|
1647
|
+
*
|
|
1641
1648
|
* Side effects: reads tokenized-vault metadata, the vault's reference asset and
|
|
1642
1649
|
* decimals, and (on the swap path) one Paraswap quote; sends one ERC-20
|
|
1643
1650
|
* `approve` to the SwapRouter when allowance is short, then the deposit tx.
|
|
@@ -1664,7 +1671,7 @@ async function depositNativeViaSwapRouter(signer, options) {
|
|
|
1664
1671
|
* ```
|
|
1665
1672
|
*/
|
|
1666
1673
|
async function swapRouterDeposit(signer, options) {
|
|
1667
|
-
const { chainId, vault, depositAsset, amount, receiver, slippageBps, wait } = options;
|
|
1674
|
+
const { chainId, vault, depositAsset, amount, receiver, slippageBps, originCode, wait, } = options;
|
|
1668
1675
|
if (!(0, core_1.checkAddress)(vault, console, 'contract')) {
|
|
1669
1676
|
throw new core_1.AugustValidationError('INVALID_ADDRESS', `swapRouterDeposit: invalid vault address "${vault}"`);
|
|
1670
1677
|
}
|
|
@@ -1743,6 +1750,7 @@ async function swapRouterDeposit(signer, options) {
|
|
|
1743
1750
|
depositTokenDecimals,
|
|
1744
1751
|
normalizedAmt,
|
|
1745
1752
|
slippageBps,
|
|
1753
|
+
originCode,
|
|
1746
1754
|
wait,
|
|
1747
1755
|
});
|
|
1748
1756
|
}
|