@augustdigital/sdk 9.9.1 → 9.10.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.
@@ -10,6 +10,7 @@
10
10
  */
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.mapWithConcurrency = mapWithConcurrency;
13
+ exports.withTimeout = withTimeout;
13
14
  /**
14
15
  * Map over `items` running at most `limit` tasks at a time.
15
16
  *
@@ -55,4 +56,24 @@ async function mapWithConcurrency(items, limit, task) {
55
56
  await Promise.all(Array.from({ length: width }, worker));
56
57
  return results;
57
58
  }
59
+ /**
60
+ * Race a promise against a timeout so a hung call can't block indefinitely. The
61
+ * timer is always cleared, so a fast-resolving promise leaves nothing pending.
62
+ *
63
+ * @param promise - The call to bound. It keeps running after a timeout; only
64
+ * the wait is abandoned.
65
+ * @param ms - Timeout in milliseconds. Values below 0 are treated as 0.
66
+ * @param label - Names the call in the rejection message.
67
+ * @returns What `promise` resolves to.
68
+ * @throws `Error("<label> timed out after <ms>ms")` on timeout, or whatever
69
+ * `promise` rejects with.
70
+ * @internal
71
+ */
72
+ function withTimeout(promise, ms, label) {
73
+ let timer;
74
+ const timeout = new Promise((_resolve, reject) => {
75
+ timer = setTimeout(() => reject(new Error(`${label} timed out after ${ms}ms`)), Math.max(0, ms));
76
+ });
77
+ return Promise.race([promise, timeout]).finally(() => clearTimeout(timer));
78
+ }
58
79
  //# sourceMappingURL=concurrency.js.map
@@ -311,6 +311,16 @@ export interface PnlHistoryConsistencyParams {
311
311
  * (subgraph deposits or LayerZero cross-chain deposits).
312
312
  */
313
313
  hasDeposits: boolean;
314
+ /**
315
+ * Whether the indexed deposits explain every share mint to the wallet (see
316
+ * {@link historyCoversMints}). Defaults to `true`.
317
+ */
318
+ mintsMatchHistory?: boolean;
319
+ /**
320
+ * Shares received by peer transfer, priced in raw base units (asset
321
+ * decimals) by {@link transferCostBasis}. Defaults to zero.
322
+ */
323
+ receivedByTransferRaw?: bigint;
314
324
  /** Total withdrawn, in raw base units (asset decimals). */
315
325
  totalWithdrawnRaw: bigint;
316
326
  /** Current on-chain position value, in raw base units (asset decimals). */
@@ -326,9 +336,14 @@ export interface PnlHistoryConsistencyParams {
326
336
  * position as pure profit — a plausible-looking but wrong number.
327
337
  *
328
338
  * This guard rejects exactly that state: a non-zero position with no recorded
329
- * deposits *and* no recorded withdrawals. Any of the following is treated as
330
- * consistent and passes:
339
+ * deposits, no shares received by transfer *and* no recorded withdrawals. It
340
+ * also rejects a non-zero position with no recorded deposits when a share mint
341
+ * to the wallet has no matching deposit (`mintsMatchHistory: false`): the mint
342
+ * proves a deposit the history failed to return, so neither a peer transfer
343
+ * nor a withdrawal makes the cost basis complete. Otherwise, any of the
344
+ * following is treated as consistent and passes:
331
345
  * - deposits are present (the normal, computable case);
346
+ * - shares were received by transfer and priced (see {@link transferCostBasis});
332
347
  * - withdrawals are present (a fully-exited-then-re-entered position is still
333
348
  * computable — the withdrawal records prove history loaded);
334
349
  * - the current position is zero (the wallet never interacted or fully exited,
@@ -338,15 +353,17 @@ export interface PnlHistoryConsistencyParams {
338
353
  * path with no added latency.
339
354
  *
340
355
  * Shares received by a direct token transfer (never deposited, never withdrew)
341
- * reach this guard as deposits: {@link getVaultUserLifetimePnl} prices them
342
- * with {@link transferCostBasis} first. The guard still throws for such a
343
- * wallet when its transfers cannot be read or priced.
356
+ * reach this guard as `receivedByTransferRaw`: {@link getVaultUserLifetimePnl}
357
+ * prices them with {@link transferCostBasis} first. The guard still throws for
358
+ * such a wallet when its transfers cannot be read or priced, or when a share
359
+ * mint to it has no indexed deposit.
344
360
  *
345
361
  * @param params - See {@link PnlHistoryConsistencyParams}.
346
362
  * @returns `void` when the history is consistent.
347
363
  * @throws {@link AugustHistoryUnavailableError} with code `HISTORY_UNAVAILABLE`
348
- * and `context: { vault, wallet }` when a non-zero position has neither
349
- * deposits nor withdrawals recorded. The message carries the
364
+ * and `context: { vault, wallet }` when a non-zero position has no deposits
365
+ * recorded and either a share mint without a matching deposit or neither
366
+ * received shares nor withdrawals. The message carries the
350
367
  * `#getVaultUserLifetimePnl::<vault>::<wallet>` prefix so it groups with the
351
368
  * other errors leaving the getter.
352
369
  * @example
@@ -355,12 +372,14 @@ export interface PnlHistoryConsistencyParams {
355
372
  * vault,
356
373
  * wallet,
357
374
  * hasDeposits: depositsByAsset.size > 0,
375
+ * mintsMatchHistory,
376
+ * receivedByTransferRaw: costBasis.receivedByTransferRaw,
358
377
  * totalWithdrawnRaw,
359
378
  * currentPositionRaw: currentPositionValue.raw,
360
379
  * });
361
380
  * ```
362
381
  */
363
- export declare function assertPnlHistoryConsistent({ vault, wallet, hasDeposits, totalWithdrawnRaw, currentPositionRaw, }: PnlHistoryConsistencyParams): void;
382
+ export declare function assertPnlHistoryConsistent({ vault, wallet, hasDeposits, mintsMatchHistory, receivedByTransferRaw, totalWithdrawnRaw, currentPositionRaw, }: PnlHistoryConsistencyParams): void;
364
383
  /** Inputs the lifetime-PnL price guard inspects. */
365
384
  export interface PnlTokenPriceParams {
366
385
  /** Vault contract address, used for the error message and context. */
@@ -728,7 +747,9 @@ export interface PnlCostBasis {
728
747
  *
729
748
  * A depositor whose history misses a mint ({@link historyCoversMints}) is the
730
749
  * exception: its transfers do not count, so the result matches what the getter
731
- * returned before transfers counted for depositors. On a LayerZero OVault the
750
+ * returned before transfers counted for depositors. A wallet with no deposit
751
+ * still gets a basis here when its history misses a mint, but
752
+ * {@link assertPnlHistoryConsistent} rejects it. On a LayerZero OVault the
732
753
  * caller leaves the hub composer and share OFT out of the transfers (see
733
754
  * {@link selectPeerTransfers}): the composer's deliveries are already counted
734
755
  * as LayerZero deposits, and shares bridged to a spoke chain still count in the
@@ -789,16 +810,18 @@ export declare function pnlCostBasis({ depositedRaw, withdrawnAssetsRaw, hasDepo
789
810
  * shares add to `totalDeposited` (and are reported again as
790
811
  * `receivedByTransfer`), sent shares add to `totalWithdrawn`. This holds
791
812
  * alongside indexed deposits, so a wallet that received shares and also
792
- * deposited is not credited with the received shares as profit. LayerZero
793
- * OVaults count transfers only when history holds no deposit, because their
794
- * composer delivers cross-chain deposits by transfer.
813
+ * deposited is not credited with the received shares as profit. On LayerZero
814
+ * OVaults, transfers from or to the hub composer and share OFT do not count,
815
+ * because the composer delivers cross-chain deposits by transfer and those
816
+ * are already counted as LayerZero deposits.
795
817
  *
796
818
  * Gaps in the indexed history: a share mint with no `Deposit` event counts as
797
819
  * a deposit of the assets in its `ReserveDeposit` event
798
820
  * ({@link selectReserveDeposits}; High Growth ETH emits it for Kelp gain-adapter
799
821
  * deposits), and a withdrawal request the vault logged twice counts once
800
822
  * ({@link countWithdrawalRequestsOnce}). Transfers fold in for a depositor only
801
- * once every mint is explained.
823
+ * once every mint is explained. A wallet with no indexed deposit and a mint
824
+ * that no deposit explains throws `HISTORY_UNAVAILABLE`.
802
825
  *
803
826
  * Tokenized Vault V2 redemptions carry only shares, so a settled one counts at
804
827
  * the assets the vault paid, or at the share ratio on its claim date when the
@@ -813,9 +836,8 @@ export declare function pnlCostBasis({ depositedRaw, withdrawnAssetsRaw, hasDepo
813
836
  * for a Tokenized Vault V2 wallet with redemption requests, a `lagDuration()`
814
837
  * read plus one backend timeseries request. A timeseries window with no usable
815
838
  * ratio (a closed vault whose history stopped earlier) is read again in full,
816
- * so the latest earlier day still prices it. For
817
- * non-LayerZero vaults the transfer query runs in parallel with the history
818
- * read; for LayerZero vaults it runs only when history holds no deposit.
839
+ * so the latest earlier day still prices it. The transfer query runs for
840
+ * every vault, in parallel with the history read.
819
841
  *
820
842
  * @param vault - Vault contract address
821
843
  * @param wallet - User wallet address
@@ -823,7 +845,8 @@ export declare function pnlCostBasis({ depositedRaw, withdrawnAssetsRaw, hasDepo
823
845
  * @returns Lifetime PnL data in both native token and USD
824
846
  * @throws {@link AugustHistoryUnavailableError} (`HISTORY_UNAVAILABLE`) when a
825
847
  * live position has no indexed deposits, withdrawals or priceable share
826
- * transfers.
848
+ * transfers, or has no indexed deposit while a share mint to the wallet has
849
+ * no matching deposit.
827
850
  * @throws {@link AugustPriceUnavailableError} (`PRICE_UNAVAILABLE`) when the
828
851
  * underlying asset has no USD price, or `asset()` cannot be read.
829
852
  */
@@ -2273,9 +2273,14 @@ async function getYieldLastRealizedOn({ vault, options, }) {
2273
2273
  * position as pure profit — a plausible-looking but wrong number.
2274
2274
  *
2275
2275
  * This guard rejects exactly that state: a non-zero position with no recorded
2276
- * deposits *and* no recorded withdrawals. Any of the following is treated as
2277
- * consistent and passes:
2276
+ * deposits, no shares received by transfer *and* no recorded withdrawals. It
2277
+ * also rejects a non-zero position with no recorded deposits when a share mint
2278
+ * to the wallet has no matching deposit (`mintsMatchHistory: false`): the mint
2279
+ * proves a deposit the history failed to return, so neither a peer transfer
2280
+ * nor a withdrawal makes the cost basis complete. Otherwise, any of the
2281
+ * following is treated as consistent and passes:
2278
2282
  * - deposits are present (the normal, computable case);
2283
+ * - shares were received by transfer and priced (see {@link transferCostBasis});
2279
2284
  * - withdrawals are present (a fully-exited-then-re-entered position is still
2280
2285
  * computable — the withdrawal records prove history loaded);
2281
2286
  * - the current position is zero (the wallet never interacted or fully exited,
@@ -2285,15 +2290,17 @@ async function getYieldLastRealizedOn({ vault, options, }) {
2285
2290
  * path with no added latency.
2286
2291
  *
2287
2292
  * Shares received by a direct token transfer (never deposited, never withdrew)
2288
- * reach this guard as deposits: {@link getVaultUserLifetimePnl} prices them
2289
- * with {@link transferCostBasis} first. The guard still throws for such a
2290
- * wallet when its transfers cannot be read or priced.
2293
+ * reach this guard as `receivedByTransferRaw`: {@link getVaultUserLifetimePnl}
2294
+ * prices them with {@link transferCostBasis} first. The guard still throws for
2295
+ * such a wallet when its transfers cannot be read or priced, or when a share
2296
+ * mint to it has no indexed deposit.
2291
2297
  *
2292
2298
  * @param params - See {@link PnlHistoryConsistencyParams}.
2293
2299
  * @returns `void` when the history is consistent.
2294
2300
  * @throws {@link AugustHistoryUnavailableError} with code `HISTORY_UNAVAILABLE`
2295
- * and `context: { vault, wallet }` when a non-zero position has neither
2296
- * deposits nor withdrawals recorded. The message carries the
2301
+ * and `context: { vault, wallet }` when a non-zero position has no deposits
2302
+ * recorded and either a share mint without a matching deposit or neither
2303
+ * received shares nor withdrawals. The message carries the
2297
2304
  * `#getVaultUserLifetimePnl::<vault>::<wallet>` prefix so it groups with the
2298
2305
  * other errors leaving the getter.
2299
2306
  * @example
@@ -2302,16 +2309,23 @@ async function getYieldLastRealizedOn({ vault, options, }) {
2302
2309
  * vault,
2303
2310
  * wallet,
2304
2311
  * hasDeposits: depositsByAsset.size > 0,
2312
+ * mintsMatchHistory,
2313
+ * receivedByTransferRaw: costBasis.receivedByTransferRaw,
2305
2314
  * totalWithdrawnRaw,
2306
2315
  * currentPositionRaw: currentPositionValue.raw,
2307
2316
  * });
2308
2317
  * ```
2309
2318
  */
2310
- function assertPnlHistoryConsistent({ vault, wallet, hasDeposits, totalWithdrawnRaw, currentPositionRaw, }) {
2311
- const positionExists = currentPositionRaw > BigInt(0);
2312
- const noHistory = !hasDeposits && totalWithdrawnRaw === BigInt(0);
2313
- if (positionExists && noHistory) {
2314
- throw new errors_1.AugustHistoryUnavailableError(`#getVaultUserLifetimePnl::${vault}::${wallet}:transaction history unavailable — a live position exists but no deposits or withdrawals were indexed, so lifetime PnL cannot be computed without over-reporting the entire position as profit`, { context: { vault, wallet } });
2319
+ function assertPnlHistoryConsistent({ vault, wallet, hasDeposits, mintsMatchHistory = true, receivedByTransferRaw = BigInt(0), totalWithdrawnRaw, currentPositionRaw, }) {
2320
+ if (currentPositionRaw <= BigInt(0) || hasDeposits)
2321
+ return;
2322
+ const missingDeposit = !mintsMatchHistory;
2323
+ const noHistory = receivedByTransferRaw === BigInt(0) && totalWithdrawnRaw === BigInt(0);
2324
+ if (missingDeposit || noHistory) {
2325
+ const reason = missingDeposit
2326
+ ? 'a share mint has no indexed deposit'
2327
+ : 'no deposits or withdrawals were indexed';
2328
+ throw new errors_1.AugustHistoryUnavailableError(`#getVaultUserLifetimePnl::${vault}::${wallet}:transaction history unavailable — a live position exists but ${reason}, so lifetime PnL cannot be computed without over-reporting the entire position as profit`, { context: { vault, wallet } });
2315
2329
  }
2316
2330
  }
2317
2331
  /**
@@ -2713,7 +2727,9 @@ function settleV2Redemptions({ history, lagDuration, ratios, now, }) {
2713
2727
  *
2714
2728
  * A depositor whose history misses a mint ({@link historyCoversMints}) is the
2715
2729
  * exception: its transfers do not count, so the result matches what the getter
2716
- * returned before transfers counted for depositors. On a LayerZero OVault the
2730
+ * returned before transfers counted for depositors. A wallet with no deposit
2731
+ * still gets a basis here when its history misses a mint, but
2732
+ * {@link assertPnlHistoryConsistent} rejects it. On a LayerZero OVault the
2717
2733
  * caller leaves the hub composer and share OFT out of the transfers (see
2718
2734
  * {@link selectPeerTransfers}): the composer's deliveries are already counted
2719
2735
  * as LayerZero deposits, and shares bridged to a spoke chain still count in the
@@ -2855,16 +2871,18 @@ async function readV2Redemptions(provider, vault, history, headers) {
2855
2871
  * shares add to `totalDeposited` (and are reported again as
2856
2872
  * `receivedByTransfer`), sent shares add to `totalWithdrawn`. This holds
2857
2873
  * alongside indexed deposits, so a wallet that received shares and also
2858
- * deposited is not credited with the received shares as profit. LayerZero
2859
- * OVaults count transfers only when history holds no deposit, because their
2860
- * composer delivers cross-chain deposits by transfer.
2874
+ * deposited is not credited with the received shares as profit. On LayerZero
2875
+ * OVaults, transfers from or to the hub composer and share OFT do not count,
2876
+ * because the composer delivers cross-chain deposits by transfer and those
2877
+ * are already counted as LayerZero deposits.
2861
2878
  *
2862
2879
  * Gaps in the indexed history: a share mint with no `Deposit` event counts as
2863
2880
  * a deposit of the assets in its `ReserveDeposit` event
2864
2881
  * ({@link selectReserveDeposits}; High Growth ETH emits it for Kelp gain-adapter
2865
2882
  * deposits), and a withdrawal request the vault logged twice counts once
2866
2883
  * ({@link countWithdrawalRequestsOnce}). Transfers fold in for a depositor only
2867
- * once every mint is explained.
2884
+ * once every mint is explained. A wallet with no indexed deposit and a mint
2885
+ * that no deposit explains throws `HISTORY_UNAVAILABLE`.
2868
2886
  *
2869
2887
  * Tokenized Vault V2 redemptions carry only shares, so a settled one counts at
2870
2888
  * the assets the vault paid, or at the share ratio on its claim date when the
@@ -2879,9 +2897,8 @@ async function readV2Redemptions(provider, vault, history, headers) {
2879
2897
  * for a Tokenized Vault V2 wallet with redemption requests, a `lagDuration()`
2880
2898
  * read plus one backend timeseries request. A timeseries window with no usable
2881
2899
  * ratio (a closed vault whose history stopped earlier) is read again in full,
2882
- * so the latest earlier day still prices it. For
2883
- * non-LayerZero vaults the transfer query runs in parallel with the history
2884
- * read; for LayerZero vaults it runs only when history holds no deposit.
2900
+ * so the latest earlier day still prices it. The transfer query runs for
2901
+ * every vault, in parallel with the history read.
2885
2902
  *
2886
2903
  * @param vault - Vault contract address
2887
2904
  * @param wallet - User wallet address
@@ -2889,7 +2906,8 @@ async function readV2Redemptions(provider, vault, history, headers) {
2889
2906
  * @returns Lifetime PnL data in both native token and USD
2890
2907
  * @throws {@link AugustHistoryUnavailableError} (`HISTORY_UNAVAILABLE`) when a
2891
2908
  * live position has no indexed deposits, withdrawals or priceable share
2892
- * transfers.
2909
+ * transfers, or has no indexed deposit while a share mint to the wallet has
2910
+ * no matching deposit.
2893
2911
  * @throws {@link AugustPriceUnavailableError} (`PRICE_UNAVAILABLE`) when the
2894
2912
  * underlying asset has no USD price, or `asset()` cannot be read.
2895
2913
  */
@@ -3259,7 +3277,9 @@ async function getVaultUserLifetimePnl({ vault, wallet, options, }) {
3259
3277
  assertPnlHistoryConsistent({
3260
3278
  vault,
3261
3279
  wallet,
3262
- hasDeposits: hasDeposits || costBasis.receivedByTransferRaw > BigInt(0),
3280
+ hasDeposits,
3281
+ mintsMatchHistory,
3282
+ receivedByTransferRaw: costBasis.receivedByTransferRaw,
3263
3283
  totalWithdrawnRaw: costBasis.withdrawnAssetsRaw,
3264
3284
  currentPositionRaw: BigInt(currentPositionValue.raw),
3265
3285
  });
package/lib/sdk.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import type { Abi } from 'abitype';
2
2
  import type { AbiParametersToPrimitiveTypes } from 'abitype';
3
- import type { AnchorProvider } from '@coral-xyz/anchor';
3
+ import { AnchorProvider } from '@coral-xyz/anchor';
4
4
  import type { BaseContract } from 'ethers';
5
5
  import { Commitment } from '@solana/web3.js';
6
+ import { ConfirmOptions } from '@solana/web3.js';
6
7
  import { Connection } from '@solana/web3.js';
7
8
  import type { ContractTransaction } from 'ethers';
8
9
  import type { ContractTransactionResponse } from 'ethers';
@@ -28,9 +29,12 @@ import type { Result } from 'ethers';
28
29
  import type { SendTransactionOptions } from '@solana/wallet-adapter-base';
29
30
  import type * as Sentry from '@sentry/browser';
30
31
  import { Signer } from 'ethers';
32
+ import { Signer as Signer_2 } from '@solana/web3.js';
31
33
  import { Transaction } from '@solana/web3.js';
32
34
  import { TransactionReceipt } from 'ethers';
33
35
  import { TransactionResponse } from 'ethers';
36
+ import { TransactionSignature } from '@solana/web3.js';
37
+ import { VersionedTransaction } from '@solana/web3.js';
34
38
  import { Wallet } from 'ethers';
35
39
  import type { WalletClient } from 'viem';
36
40
  import { web3 } from '@coral-xyz/anchor';
@@ -15201,9 +15205,14 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
15201
15205
  * position as pure profit — a plausible-looking but wrong number.
15202
15206
  *
15203
15207
  * This guard rejects exactly that state: a non-zero position with no recorded
15204
- * deposits *and* no recorded withdrawals. Any of the following is treated as
15205
- * consistent and passes:
15208
+ * deposits, no shares received by transfer *and* no recorded withdrawals. It
15209
+ * also rejects a non-zero position with no recorded deposits when a share mint
15210
+ * to the wallet has no matching deposit (`mintsMatchHistory: false`): the mint
15211
+ * proves a deposit the history failed to return, so neither a peer transfer
15212
+ * nor a withdrawal makes the cost basis complete. Otherwise, any of the
15213
+ * following is treated as consistent and passes:
15206
15214
  * - deposits are present (the normal, computable case);
15215
+ * - shares were received by transfer and priced (see {@link transferCostBasis});
15207
15216
  * - withdrawals are present (a fully-exited-then-re-entered position is still
15208
15217
  * computable — the withdrawal records prove history loaded);
15209
15218
  * - the current position is zero (the wallet never interacted or fully exited,
@@ -15213,15 +15222,17 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
15213
15222
  * path with no added latency.
15214
15223
  *
15215
15224
  * Shares received by a direct token transfer (never deposited, never withdrew)
15216
- * reach this guard as deposits: {@link getVaultUserLifetimePnl} prices them
15217
- * with {@link transferCostBasis} first. The guard still throws for such a
15218
- * wallet when its transfers cannot be read or priced.
15225
+ * reach this guard as `receivedByTransferRaw`: {@link getVaultUserLifetimePnl}
15226
+ * prices them with {@link transferCostBasis} first. The guard still throws for
15227
+ * such a wallet when its transfers cannot be read or priced, or when a share
15228
+ * mint to it has no indexed deposit.
15219
15229
  *
15220
15230
  * @param params - See {@link PnlHistoryConsistencyParams}.
15221
15231
  * @returns `void` when the history is consistent.
15222
15232
  * @throws {@link AugustHistoryUnavailableError} with code `HISTORY_UNAVAILABLE`
15223
- * and `context: { vault, wallet }` when a non-zero position has neither
15224
- * deposits nor withdrawals recorded. The message carries the
15233
+ * and `context: { vault, wallet }` when a non-zero position has no deposits
15234
+ * recorded and either a share mint without a matching deposit or neither
15235
+ * received shares nor withdrawals. The message carries the
15225
15236
  * `#getVaultUserLifetimePnl::<vault>::<wallet>` prefix so it groups with the
15226
15237
  * other errors leaving the getter.
15227
15238
  * @example
@@ -15230,12 +15241,14 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
15230
15241
  * vault,
15231
15242
  * wallet,
15232
15243
  * hasDeposits: depositsByAsset.size > 0,
15244
+ * mintsMatchHistory,
15245
+ * receivedByTransferRaw: costBasis.receivedByTransferRaw,
15233
15246
  * totalWithdrawnRaw,
15234
15247
  * currentPositionRaw: currentPositionValue.raw,
15235
15248
  * });
15236
15249
  * ```
15237
15250
  */
15238
- export declare function assertPnlHistoryConsistent({ vault, wallet, hasDeposits, totalWithdrawnRaw, currentPositionRaw, }: PnlHistoryConsistencyParams): void;
15251
+ export declare function assertPnlHistoryConsistent({ vault, wallet, hasDeposits, mintsMatchHistory, receivedByTransferRaw, totalWithdrawnRaw, currentPositionRaw, }: PnlHistoryConsistencyParams): void;
15239
15252
 
15240
15253
  /**
15241
15254
  * Guard against converting lifetime PnL to USD with a fabricated price.
@@ -15922,7 +15935,7 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
15922
15935
  * ```
15923
15936
  */
15924
15937
  /** Stable error codes attached to SDK errors. */
15925
- export declare type AugustErrorCode = 'AUTH_MISSING_KEY' | 'AUTH_INVALID_KEY' | 'AUTH_FORBIDDEN' | 'AUTH_UNAUTHORIZED' | 'INVALID_URL' | 'INVALID_INPUT' | 'INVALID_CHAIN' | 'INVALID_ADDRESS' | 'ACCOUNT_NOT_FUNDED' | 'NETWORK_ERROR' | 'TIMEOUT' | 'RATE_LIMITED' | 'SERVER_ERROR' | 'HISTORY_UNAVAILABLE' | 'PRICE_UNAVAILABLE' | 'UNKNOWN';
15938
+ export declare type AugustErrorCode = 'AUTH_MISSING_KEY' | 'AUTH_INVALID_KEY' | 'AUTH_FORBIDDEN' | 'AUTH_UNAUTHORIZED' | 'INVALID_URL' | 'INVALID_INPUT' | 'INVALID_CHAIN' | 'INVALID_ADDRESS' | 'ACCOUNT_NOT_FUNDED' | 'NETWORK_ERROR' | 'TIMEOUT' | 'RATE_LIMITED' | 'SERVER_ERROR' | 'TRANSACTION_UNCONFIRMED' | 'HISTORY_UNAVAILABLE' | 'PRICE_UNAVAILABLE' | 'UNKNOWN';
15926
15939
 
15927
15940
  /** Options accepted by every SDK error constructor. */
15928
15941
  export declare interface AugustErrorOptions {
@@ -16863,6 +16876,35 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
16863
16876
  toJSON(): Record<string, unknown>;
16864
16877
  }
16865
16878
 
16879
+ /**
16880
+ * A transaction was sent but its outcome could not be established
16881
+ * (`TRANSACTION_UNCONFIRMED`). It may have landed: check {@link signature}
16882
+ * before resubmitting, or a deposit or redeem can execute twice.
16883
+ * `context.reason` says what was seen (e.g. `expired_not_found`: the blockhash
16884
+ * expired and no lookup found it, so it very likely never landed).
16885
+ *
16886
+ * @example
16887
+ * ```ts
16888
+ * try {
16889
+ * await sdk.solana.vaultDeposit(programId, idl, wallet, amount, undefined, vault);
16890
+ * } catch (err) {
16891
+ * if (err instanceof AugustTransactionError) showPending(err.signature);
16892
+ * else throw err;
16893
+ * }
16894
+ * ```
16895
+ */
16896
+ export declare class AugustTransactionError extends AugustSDKError {
16897
+ /** Signature of the transaction that was sent. */
16898
+ readonly signature: string;
16899
+ /**
16900
+ * @param message - Human-readable description, naming the signature.
16901
+ * @param signature - Signature of the transaction that was sent.
16902
+ * @param options - Standard SDK error options.
16903
+ */
16904
+ constructor(message: string, signature: string, options?: AugustErrorOptions);
16905
+ toJSON(): Record<string, unknown>;
16906
+ }
16907
+
16866
16908
  /** Caller-side input failed validation. */
16867
16909
  export declare class AugustValidationError extends AugustSDKError {
16868
16910
  constructor(code: Extract<AugustErrorCode, 'INVALID_URL' | 'INVALID_INPUT' | 'INVALID_CHAIN' | 'INVALID_ADDRESS' | 'ACCOUNT_NOT_FUNDED'>, message: string, options?: AugustErrorOptions);
@@ -17478,6 +17520,29 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
17478
17520
  */
17479
17521
  export declare function balanceOf(signer: IContractRunner, options: IBalanceOfOptions): Promise<bigint>;
17480
17522
 
17523
+ /**
17524
+ * `AnchorProvider` whose `sendAndConfirm` — what `program.methods…rpc()` calls —
17525
+ * confirms with {@link confirmByBlockhash} instead of Anchor's signature-only
17526
+ * WebSocket wait. Signing and Anchor's error translation are unchanged.
17527
+ */
17528
+ declare class BlockhashConfirmingProvider extends AnchorProvider {
17529
+ /**
17530
+ * Sign, send and confirm a transaction.
17531
+ *
17532
+ * @param tx - Transaction to send. Its blockhash (and fee payer, if unset)
17533
+ * are set here. A `VersionedTransaction` already carries a blockhash this
17534
+ * cannot learn the expiry of, so it takes Anchor's default path.
17535
+ * @param signers - Extra signers besides the wallet.
17536
+ * @param opts - Defaults to the provider's options.
17537
+ * @returns The transaction signature.
17538
+ * @throws See {@link confirmByBlockhash}; also whatever the wallet or
17539
+ * `sendRawTransaction` throws (user rejection, preflight failure).
17540
+ * @remarks **RPC cost.** `getLatestBlockhash` + `sendRawTransaction`, then
17541
+ * the confirmation polls described on {@link confirmByBlockhash}.
17542
+ */
17543
+ sendAndConfirm(tx: Transaction | VersionedTransaction, signers?: Signer_2[], opts?: ConfirmOptions): Promise<TransactionSignature>;
17544
+ }
17545
+
17481
17546
  /**
17482
17547
  * Build an ERC-8021 schema-0 attribution suffix from builder codes.
17483
17548
  *
@@ -20179,16 +20244,18 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
20179
20244
  * shares add to `totalDeposited` (and are reported again as
20180
20245
  * `receivedByTransfer`), sent shares add to `totalWithdrawn`. This holds
20181
20246
  * alongside indexed deposits, so a wallet that received shares and also
20182
- * deposited is not credited with the received shares as profit. LayerZero
20183
- * OVaults count transfers only when history holds no deposit, because their
20184
- * composer delivers cross-chain deposits by transfer.
20247
+ * deposited is not credited with the received shares as profit. On LayerZero
20248
+ * OVaults, transfers from or to the hub composer and share OFT do not count,
20249
+ * because the composer delivers cross-chain deposits by transfer and those
20250
+ * are already counted as LayerZero deposits.
20185
20251
  *
20186
20252
  * Gaps in the indexed history: a share mint with no `Deposit` event counts as
20187
20253
  * a deposit of the assets in its `ReserveDeposit` event
20188
20254
  * ({@link selectReserveDeposits}; High Growth ETH emits it for Kelp gain-adapter
20189
20255
  * deposits), and a withdrawal request the vault logged twice counts once
20190
20256
  * ({@link countWithdrawalRequestsOnce}). Transfers fold in for a depositor only
20191
- * once every mint is explained.
20257
+ * once every mint is explained. A wallet with no indexed deposit and a mint
20258
+ * that no deposit explains throws `HISTORY_UNAVAILABLE`.
20192
20259
  *
20193
20260
  * Tokenized Vault V2 redemptions carry only shares, so a settled one counts at
20194
20261
  * the assets the vault paid, or at the share ratio on its claim date when the
@@ -20203,9 +20270,8 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
20203
20270
  * for a Tokenized Vault V2 wallet with redemption requests, a `lagDuration()`
20204
20271
  * read plus one backend timeseries request. A timeseries window with no usable
20205
20272
  * ratio (a closed vault whose history stopped earlier) is read again in full,
20206
- * so the latest earlier day still prices it. For
20207
- * non-LayerZero vaults the transfer query runs in parallel with the history
20208
- * read; for LayerZero vaults it runs only when history holds no deposit.
20273
+ * so the latest earlier day still prices it. The transfer query runs for
20274
+ * every vault, in parallel with the history read.
20209
20275
  *
20210
20276
  * @param vault - Vault contract address
20211
20277
  * @param wallet - User wallet address
@@ -20213,7 +20279,8 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
20213
20279
  * @returns Lifetime PnL data in both native token and USD
20214
20280
  * @throws {@link AugustHistoryUnavailableError} (`HISTORY_UNAVAILABLE`) when a
20215
20281
  * live position has no indexed deposits, withdrawals or priceable share
20216
- * transfers.
20282
+ * transfers, or has no indexed deposit while a share mint to the wallet has
20283
+ * no matching deposit.
20217
20284
  * @throws {@link AugustPriceUnavailableError} (`PRICE_UNAVAILABLE`) when the
20218
20285
  * underlying asset has no USD price, or `asset()` cannot be read.
20219
20286
  */
@@ -20389,6 +20456,9 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
20389
20456
  * or when the wallet's deposit-mint balance is below `depositAmount`.
20390
20457
  * @throws AugustSDKError when a candidate token account's balance cannot be
20391
20458
  * read, or wrapping any downstream failure (`cause` preserved).
20459
+ * @throws AugustTransactionError (`TRANSACTION_UNCONFIRMED`) when the
20460
+ * transaction was sent but its outcome could not be established; check
20461
+ * `signature` before resubmitting.
20392
20462
  * @remarks **Side effects.** Submits exactly one transaction, signed by the
20393
20463
  * provider's wallet. When the wallet has no share account, that transaction
20394
20464
  * also creates one, and `publicKey` pays its rent — roughly 0.00204 SOL,
@@ -20437,6 +20507,9 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
20437
20507
  * or when the wallet holds fewer shares than `redeemShares`.
20438
20508
  * @throws AugustSDKError when a candidate token account's balance cannot be
20439
20509
  * read, or wrapping any downstream failure (`cause` preserved).
20510
+ * @throws AugustTransactionError (`TRANSACTION_UNCONFIRMED`) when the
20511
+ * transaction was sent but its outcome could not be established; check
20512
+ * `signature` before resubmitting.
20440
20513
  * @remarks **Side effects.** Submits exactly one transaction, signed by the
20441
20514
  * provider's wallet. That transaction also creates the payout account when
20442
20515
  * the wallet has none, and the vault's fee-recipient account when *it* has
@@ -24884,9 +24957,10 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
24884
24957
  }
24885
24958
 
24886
24959
  /**
24887
- * One subaccount record from the admin-only `GET /subaccount` directory
24888
- * endpoint (backend `ISubaccountRead` schema). Nullable fields are optional
24889
- * metadata the operations team may not have filled in.
24960
+ * One subaccount record (backend `ISubaccountRead` schema), as returned by the
24961
+ * admin-only `GET /subaccount` directory, `GET /users/{address}/subaccounts`
24962
+ * and `GET /org/subaccounts`. Nullable fields are optional metadata the
24963
+ * operations team may not have filled in.
24890
24964
  */
24891
24965
  export declare interface IWSSubaccountListItem {
24892
24966
  id: string;
@@ -24908,6 +24982,15 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
24908
24982
  variant: string | null;
24909
24983
  default_fee_rate_in_bips: number | null;
24910
24984
  wallet_role: string | null;
24985
+ /**
24986
+ * Cached USD account value, refreshed out of band by an hourly backend job.
24987
+ * A sort key and placeholder, not an authoritative NAV — read the live value
24988
+ * from the subaccount summary. `null` before the job's first run; absent on
24989
+ * backends that predate the field.
24990
+ */
24991
+ latest_account_value?: number | null;
24992
+ /** Naive-UTC ISO timestamp of `latest_account_value`. */
24993
+ account_value_updated_at?: string | null;
24911
24994
  chains: IWSSubaccountListChain[];
24912
24995
  }
24913
24996
 
@@ -25524,7 +25607,9 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
25524
25607
  *
25525
25608
  * A depositor whose history misses a mint ({@link historyCoversMints}) is the
25526
25609
  * exception: its transfers do not count, so the result matches what the getter
25527
- * returned before transfers counted for depositors. On a LayerZero OVault the
25610
+ * returned before transfers counted for depositors. A wallet with no deposit
25611
+ * still gets a basis here when its history misses a mint, but
25612
+ * {@link assertPnlHistoryConsistent} rejects it. On a LayerZero OVault the
25528
25613
  * caller leaves the hub composer and share OFT out of the transfers (see
25529
25614
  * {@link selectPeerTransfers}): the composer's deliveries are already counted
25530
25615
  * as LayerZero deposits, and shares bridged to a spoke chain still count in the
@@ -25587,6 +25672,16 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
25587
25672
  * (subgraph deposits or LayerZero cross-chain deposits).
25588
25673
  */
25589
25674
  hasDeposits: boolean;
25675
+ /**
25676
+ * Whether the indexed deposits explain every share mint to the wallet (see
25677
+ * {@link historyCoversMints}). Defaults to `true`.
25678
+ */
25679
+ mintsMatchHistory?: boolean;
25680
+ /**
25681
+ * Shares received by peer transfer, priced in raw base units (asset
25682
+ * decimals) by {@link transferCostBasis}. Defaults to zero.
25683
+ */
25684
+ receivedByTransferRaw?: bigint;
25590
25685
  /** Total withdrawn, in raw base units (asset decimals). */
25591
25686
  totalWithdrawnRaw: bigint;
25592
25687
  /** Current on-chain position value, in raw base units (asset decimals). */
@@ -27174,7 +27269,7 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
27174
27269
  getProvider: ({ connection, publicKey, signTransaction, }: {
27175
27270
  publicKey: PublicKey;
27176
27271
  signTransaction: (<T extends Transaction | web3.VersionedTransaction>(transaction: T) => Promise<T>) | undefined;
27177
- } & ISolanaConnectionOptions) => AnchorProvider;
27272
+ } & ISolanaConnectionOptions) => BlockhashConfirmingProvider;
27178
27273
  getReadOnlyProvider: ({ connection }: ISolanaConnectionOptions) => AnchorProvider;
27179
27274
  deriveShareMintPda: (vaultProgramId: PublicKey | string) => web3.PublicKey;
27180
27275
  deriveVaultStatePda: (vaultProgramId: PublicKey | string) => web3.PublicKey;
@@ -9,9 +9,10 @@ export interface IWSSubaccountListChain {
9
9
  name: string;
10
10
  }
11
11
  /**
12
- * One subaccount record from the admin-only `GET /subaccount` directory
13
- * endpoint (backend `ISubaccountRead` schema). Nullable fields are optional
14
- * metadata the operations team may not have filled in.
12
+ * One subaccount record (backend `ISubaccountRead` schema), as returned by the
13
+ * admin-only `GET /subaccount` directory, `GET /users/{address}/subaccounts`
14
+ * and `GET /org/subaccounts`. Nullable fields are optional metadata the
15
+ * operations team may not have filled in.
15
16
  */
16
17
  export interface IWSSubaccountListItem {
17
18
  id: string;
@@ -33,6 +34,15 @@ export interface IWSSubaccountListItem {
33
34
  variant: string | null;
34
35
  default_fee_rate_in_bips: number | null;
35
36
  wallet_role: string | null;
37
+ /**
38
+ * Cached USD account value, refreshed out of band by an hourly backend job.
39
+ * A sort key and placeholder, not an authoritative NAV — read the live value
40
+ * from the subaccount summary. `null` before the job's first run; absent on
41
+ * backends that predate the field.
42
+ */
43
+ latest_account_value?: number | null;
44
+ /** Naive-UTC ISO timestamp of `latest_account_value`. */
45
+ account_value_updated_at?: string | null;
36
46
  chains: IWSSubaccountListChain[];
37
47
  }
38
48
  export interface IWSSubAccountHealthFactor {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@augustdigital/sdk",
3
- "version": "9.9.1",
3
+ "version": "9.10.1",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/sdk.d.ts",
6
6
  "keywords": [