@augustdigital/sdk 9.3.0 → 9.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/lib/adapters/evm/getters.js +40 -0
  2. package/lib/adapters/evm/index.d.ts +106 -2
  3. package/lib/adapters/evm/index.js +125 -0
  4. package/lib/adapters/solana/index.d.ts +12 -5
  5. package/lib/adapters/solana/index.js +12 -4
  6. package/lib/adapters/solana/pricing.d.ts +173 -0
  7. package/lib/adapters/solana/pricing.js +223 -0
  8. package/lib/adapters/solana/types.d.ts +45 -0
  9. package/lib/adapters/solana/vault.actions.d.ts +33 -8
  10. package/lib/adapters/solana/vault.actions.js +185 -28
  11. package/lib/adapters/stellar/actions.d.ts +2 -2
  12. package/lib/adapters/stellar/actions.js +2 -2
  13. package/lib/adapters/stellar/getters.d.ts +1 -1
  14. package/lib/adapters/stellar/getters.js +2 -2
  15. package/lib/adapters/stellar/index.d.ts +1 -1
  16. package/lib/adapters/stellar/index.js +1 -1
  17. package/lib/adapters/stellar/types.d.ts +1 -2
  18. package/lib/core/analytics/method-taxonomy.js +7 -0
  19. package/lib/core/analytics/version.d.ts +1 -1
  20. package/lib/core/analytics/version.js +1 -1
  21. package/lib/core/base.class.d.ts +2 -2
  22. package/lib/core/base.class.js +2 -2
  23. package/lib/core/constants/core.d.ts +17 -3
  24. package/lib/core/constants/core.js +17 -3
  25. package/lib/core/constants/vaults.js +4 -0
  26. package/lib/core/fetcher.js +112 -45
  27. package/lib/core/helpers/concurrency.d.ts +37 -0
  28. package/lib/core/helpers/concurrency.js +58 -0
  29. package/lib/core/helpers/core.d.ts +9 -0
  30. package/lib/core/helpers/core.js +47 -0
  31. package/lib/core/helpers/vaults.d.ts +1 -1
  32. package/lib/core/helpers/vaults.js +1 -1
  33. package/lib/core/helpers/web3.js +14 -1
  34. package/lib/core/logger/curator-alert.d.ts +2 -2
  35. package/lib/core/logger/curator-alert.js +2 -2
  36. package/lib/evm/methods/crossChainVaultRegistry.d.ts +2 -3
  37. package/lib/evm/methods/crossChainVaultRegistry.js +2 -3
  38. package/lib/evm/types/crossChain.d.ts +1 -1
  39. package/lib/main.d.ts +7 -5
  40. package/lib/main.js +7 -5
  41. package/lib/modules/vaults/getters.d.ts +10 -3
  42. package/lib/modules/vaults/getters.js +205 -71
  43. package/lib/modules/vaults/main.d.ts +4 -4
  44. package/lib/modules/vaults/main.js +7 -4
  45. package/lib/modules/vaults/read.actions.d.ts +181 -0
  46. package/lib/modules/vaults/read.actions.js +331 -36
  47. package/lib/modules/vaults/types.d.ts +13 -0
  48. package/lib/modules/vaults/utils.js +5 -1
  49. package/lib/modules/vaults/write.actions.d.ts +74 -6
  50. package/lib/modules/vaults/write.actions.js +133 -23
  51. package/lib/sdk.d.ts +9827 -9342
  52. package/lib/services/subgraph/schema.d.ts +1 -1
  53. package/lib/services/subgraph/schema.js +1 -1
  54. package/lib/types/pools.d.ts +1 -1
  55. package/lib/types/vaults.d.ts +4 -4
  56. package/package.json +1 -1
@@ -1,12 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.describeSolanaError = describeSolanaError;
4
+ exports.slippageHint = slippageHint;
4
5
  exports.handleSolanaDeposit = handleSolanaDeposit;
5
6
  exports.handleSolanaRedeem = handleSolanaRedeem;
6
7
  const anchor_1 = require("@coral-xyz/anchor");
7
8
  const web3_js_1 = require("@solana/web3.js");
8
9
  const spl_token_1 = require("@solana/spl-token");
9
10
  const constants_1 = require("./constants");
11
+ const pricing_1 = require("./pricing");
10
12
  const utils_1 = require("./utils");
11
13
  const core_1 = require("../../core");
12
14
  /**
@@ -49,6 +51,113 @@ function describeSolanaError(e) {
49
51
  ? str
50
52
  : REASONLESS_SOLANA_ERROR;
51
53
  }
54
+ /** `SlippageExceeded` in `august_vault`'s error enum (ordinal 18 + Anchor's 6000 offset). */
55
+ const SLIPPAGE_EXCEEDED_CODE = 6018;
56
+ /**
57
+ * A sentence to append when the program rejected the instruction for
58
+ * slippage, so the caller learns what to do rather than just what happened.
59
+ * Empty for every other error.
60
+ *
61
+ * Not merely a restatement of the program's reason string. Both checked
62
+ * instructions share error 6018, whose on-chain message is share-worded —
63
+ * "Received fewer shares than the caller's minimum" — so on a *redeem*, where
64
+ * the floor is denominated in assets, the program describes the wrong
65
+ * quantity. This sentence is what makes that case readable. The numeric code
66
+ * `describeSolanaError` renders alongside it is kept deliberately: it is the
67
+ * handle support and telemetry group on, and it survives a reword of the
68
+ * program's message.
69
+ */
70
+ function slippageHint(e) {
71
+ const anchor = e;
72
+ const code = anchor?.error?.errorCode?.number ?? anchor?.code;
73
+ const name = anchor?.error?.errorCode?.code;
74
+ return code === SLIPPAGE_EXCEEDED_CODE || name === 'SlippageExceeded'
75
+ ? ' The share price moved past your slippage tolerance between the quote and execution; retry, or pass a higher `slippageBps`.'
76
+ : '';
77
+ }
78
+ /** Largest value Anchor's `u64` encoder can represent. */
79
+ const U64_MAX = 18446744073709551615n;
80
+ /**
81
+ * Validate a caller-supplied slippage floor before it reaches Anchor's `u64`
82
+ * encoder.
83
+ *
84
+ * Anchor serializes a `BN` to `u64` via `toArrayLike`, which writes the
85
+ * magnitude and drops the sign — a `-1n` floor would reach the program as a
86
+ * floor of `1`, inverting the caller's intent instead of failing. Values above
87
+ * `u64` fare no better: they surface as an untyped "byte array longer than
88
+ * desired length" from inside the encoder, naming nothing the caller passed.
89
+ * Both are caught here, at the public-API boundary.
90
+ *
91
+ * @param value - The caller's `minSharesOut` / `minAssetsOut`, in raw base units.
92
+ * @param label - Option name, quoted in the error.
93
+ * @returns `value`, once known to fit an unsigned 64-bit integer.
94
+ * @throws {@link AugustValidationError} when it is not a `bigint` in `0 .. 2^64-1`.
95
+ */
96
+ function validateExplicitFloor(value, label) {
97
+ if (typeof value !== 'bigint' || value < 0n || value > U64_MAX) {
98
+ throw new core_1.AugustValidationError('INVALID_INPUT', `${label} must be a bigint between 0 and ${U64_MAX} raw base units, got ${String(value)}.`);
99
+ }
100
+ return value;
101
+ }
102
+ /**
103
+ * The vault state and share-mint supply as of a **single slot**.
104
+ *
105
+ * Both figures price the quote, so they have to come from one snapshot. Read
106
+ * independently — even concurrently, as two RPC requests — a deposit or
107
+ * redemption landing in between combines a supply and an asset total that
108
+ * never coexisted, and the quote is wrong in whichever direction the
109
+ * interleaving fell. Seeing a 10% deposit's new assets against the old supply
110
+ * quotes ~10% high, and the floor then rejects a redemption whose share price
111
+ * never moved; the opposite ordering quotes low and silently weakens the
112
+ * protection. `getMultipleAccountsInfo` is served from one slot, so the pair
113
+ * is always coherent — and it costs one round trip instead of two.
114
+ *
115
+ * @param program - Anchor program, used only for its account coder; the
116
+ * provider it was built with is irrelevant, so no read-only program is needed.
117
+ * @param vaultStatePda - Vault state account to decode.
118
+ * @param shareMintAddr - Share mint whose supply and decimals are read.
119
+ * @returns The decoded `VaultState`, the share mint's raw `supply`, and its
120
+ * `decimals` — all from the same slot.
121
+ * @throws {@link AugustSDKError} when either account is absent, or is not the
122
+ * account type it should be.
123
+ */
124
+ async function readPricingSnapshot({ connection, program, vaultStatePda, shareMintAddr, }) {
125
+ const [vaultStateInfo, shareMintInfo] = await connection.getMultipleAccountsInfo([vaultStatePda, shareMintAddr]);
126
+ if (!vaultStateInfo) {
127
+ throw new core_1.AugustSDKError('UNKNOWN', `Vault state account ${vaultStatePda.toBase58()} does not exist; it cannot be priced.`);
128
+ }
129
+ if (!shareMintInfo) {
130
+ throw new core_1.AugustSDKError('UNKNOWN', `Share mint ${shareMintAddr.toBase58()} does not exist; it cannot be priced.`);
131
+ }
132
+ // `vaultState`, not the IDL's own `VaultState`: `Program` runs the IDL
133
+ // through `convertIdlToCamelCase`, so its coder only answers to the
134
+ // camelCase name and the IDL spelling throws `Account not found`. (A coder
135
+ // built directly from the raw IDL behaves the opposite way — which is why
136
+ // this has to be checked against a real `Program`, as its test does.)
137
+ //
138
+ // Decoded by name rather than `decodeAny`, so a `vaultAddress` pointing at
139
+ // some other account of this program fails here instead of being decoded as
140
+ // whatever it happens to be.
141
+ let vaultStateData;
142
+ try {
143
+ vaultStateData = program.coder.accounts.decode('vaultState', vaultStateInfo.data);
144
+ }
145
+ catch (e) {
146
+ throw new core_1.AugustSDKError('UNKNOWN', `Account ${vaultStatePda.toBase58()} is not a vault state account for this program.`, { cause: e });
147
+ }
148
+ let mint;
149
+ try {
150
+ mint = (0, spl_token_1.unpackMint)(shareMintAddr, shareMintInfo, spl_token_1.TOKEN_PROGRAM_ID);
151
+ }
152
+ catch (e) {
153
+ throw new core_1.AugustSDKError('UNKNOWN', `Account ${shareMintAddr.toBase58()} is not an SPL Token mint.`, { cause: e });
154
+ }
155
+ return {
156
+ vaultStateData,
157
+ supply: mint.supply,
158
+ shareDecimals: mint.decimals,
159
+ };
160
+ }
52
161
  /**
53
162
  * Pick which token account to hand the vault program for a given mint, and
54
163
  * describe how to create it when the user has none.
@@ -65,7 +174,7 @@ function describeSolanaError(e) {
65
174
  * `.preInstructions()` it is atomic with the transfer, so there is no window
66
175
  * in which the vault instruction can reference an account that has not
67
176
  * landed. Sent as its own transaction — as this module used to — it raced
68
- * its own confirmation. Observed in production (AUGUST-7221, 2026-08-11):
177
+ * its own confirmation. Observed in production (2026-08-11):
69
178
  * a deposit failed with `Simulation failed … Logs: []` while the share-ATA
70
179
  * create was still in flight, then succeeded 17s later on retry. The empty
71
180
  * log array means the transaction never reached program execution, so there
@@ -152,11 +261,13 @@ async function resolveUserTokenAccountPair({ connection, owner, mints, }) {
152
261
  * non-refundable while the account stays open — on top of the network fee.
153
262
  * Callers should ensure the wallet holds enough SOL for both before
154
263
  * prompting the user to sign.
155
- * @remarks The on-chain `deposit` instruction has no `min_shares_out`
156
- * parameter; slippage cannot be enforced on-chain until the program ships
157
- * that argument.
264
+ * @remarks Sends `deposit_checked`, not `deposit`. Unless `options.minSharesOut`
265
+ * is given, the vault state and share mint are read to quote the shares this
266
+ * deposit should mint, and that quote lowered by `options.slippageBps`
267
+ * (default {@link DEFAULT_SLIPPAGE_BPS}) is passed as the floor; the program
268
+ * reverts with `SlippageExceeded` if execution would mint fewer.
158
269
  */
159
- async function handleSolanaDeposit({ provider, connection, network = constants_1.fallbackNetwork, vaultProgramId, vaultAddress, depositAmount, publicKey, idl, }) {
270
+ async function handleSolanaDeposit({ provider, connection, network = constants_1.fallbackNetwork, vaultProgramId, vaultAddress, depositAmount, publicKey, idl, options = {}, }) {
160
271
  try {
161
272
  if (!publicKey)
162
273
  throw new core_1.AugustValidationError('INVALID_INPUT', 'handleSolanaDeposit: wallet not connected');
@@ -167,6 +278,9 @@ async function handleSolanaDeposit({ provider, connection, network = constants_1
167
278
  throw new core_1.AugustValidationError('INVALID_INPUT', 'handleSolanaDeposit: depositAmount is required and must be > 0');
168
279
  if (!vaultProgramId)
169
280
  throw new core_1.AugustValidationError('INVALID_INPUT', 'handleSolanaDeposit: vaultProgramId is required');
281
+ // Before any RPC: an unusable floor should cost the caller nothing.
282
+ if (options.minSharesOut !== undefined)
283
+ validateExplicitFloor(options.minSharesOut, 'minSharesOut');
170
284
  const { depositMint, shareMint, vaultVersion } = await utils_1.SolanaUtils.getVaultMints({
171
285
  network,
172
286
  connection,
@@ -279,9 +393,33 @@ async function handleSolanaDeposit({ provider, connection, network = constants_1
279
393
  core_1.Logger.log.info('handleSolanaDeposit', 'Share mint', shareMintAddr.toBase58());
280
394
  core_1.Logger.log.info('handleSolanaDeposit', 'Deposit mint', _depositMint?.toBase58());
281
395
  core_1.Logger.log.info('handleSolanaDeposit', 'Signer', _publicKey.toBase58());
282
- // TODO(slippage): pass `min_shares_out` here when the program ships it.
396
+ let minSharesOut;
397
+ if (options.minSharesOut !== undefined) {
398
+ minSharesOut = options.minSharesOut;
399
+ }
400
+ else {
401
+ // One read the unguarded `deposit` never needed: the vault state (assets
402
+ // and offset) and the share mint (supply) in a single snapshot, since
403
+ // pricing against a mismatched pair is worse than not quoting at all —
404
+ // see `readPricingSnapshot`. A caller already holding a quote can pass
405
+ // `minSharesOut` and skip it.
406
+ const { vaultStateData, supply } = await readPricingSnapshot({
407
+ connection,
408
+ program,
409
+ vaultStatePda,
410
+ shareMintAddr,
411
+ });
412
+ minSharesOut = (0, pricing_1.quoteDepositFloor)({
413
+ supply,
414
+ totalAssets: (0, pricing_1.totalAssetsOf)(vaultStateData),
415
+ amount: BigInt(depositAmountRaw.toString()),
416
+ offset: (0, pricing_1.resolveShareOffset)(vaultStateData.shareOffset),
417
+ slippageBps: options.slippageBps ?? pricing_1.DEFAULT_SLIPPAGE_BPS,
418
+ });
419
+ }
420
+ core_1.Logger.log.info('handleSolanaDeposit', 'Min shares out (raw)', minSharesOut.toString());
283
421
  const tx = await program.methods
284
- .deposit(depositAmountRaw)
422
+ .depositChecked(depositAmountRaw, new anchor_1.BN(minSharesOut.toString()))
285
423
  .accounts({
286
424
  vaultState: vaultStatePda,
287
425
  vaultTokenAta: vaultTokenAtaPda,
@@ -320,7 +458,7 @@ async function handleSolanaDeposit({ provider, connection, network = constants_1
320
458
  vaultAddress: vaultAddress ? String(vaultAddress) : undefined,
321
459
  depositAmount: depositAmountForLog,
322
460
  });
323
- throw new core_1.AugustSDKError('UNKNOWN', `Solana deposit failed: ${describeSolanaError(e)}`, {
461
+ throw new core_1.AugustSDKError('UNKNOWN', `Solana deposit failed: ${describeSolanaError(e)}${slippageHint(e)}`, {
324
462
  cause: e,
325
463
  context: {
326
464
  vaultProgramId: String(vaultProgramId),
@@ -334,8 +472,12 @@ async function handleSolanaDeposit({ provider, connection, network = constants_1
334
472
  * Redeem vault shares back into the underlying mint on a Solana August vault.
335
473
  *
336
474
  * @param redeemShares `bigint` is treated as raw share-token units;
337
- * `number` is treated as a UI amount. See {@link handleSolanaDeposit} for
338
- * the same caveat about the missing on-chain slippage guard.
475
+ * `number` is treated as a UI amount.
476
+ * @remarks Sends `redeem_checked`, not `redeem`. Unless `options.minAssetsOut`
477
+ * is given, the payout is quoted from the vault state and share supply the
478
+ * handler already reads, **net of the withdrawal fee**, and that quote
479
+ * lowered by `options.slippageBps` (default {@link DEFAULT_SLIPPAGE_BPS}) is
480
+ * passed as the floor; the program reverts with `SlippageExceeded` below it.
339
481
  * @throws AugustValidationError on missing wallet/programId or invalid amount,
340
482
  * or when the wallet holds fewer shares than `redeemShares`.
341
483
  * @throws AugustSDKError when a candidate token account's balance cannot be
@@ -347,7 +489,7 @@ async function handleSolanaDeposit({ provider, connection, network = constants_1
347
489
  * non-refundable, on top of the network fee. Callers should ensure the
348
490
  * wallet holds enough SOL for all of it before prompting the user to sign.
349
491
  */
350
- async function handleSolanaRedeem({ provider, connection, vaultProgramId, vaultAddress, publicKey, redeemShares, idl, }) {
492
+ async function handleSolanaRedeem({ provider, connection, vaultProgramId, vaultAddress, publicKey, redeemShares, idl, options = {}, }) {
351
493
  try {
352
494
  if (!publicKey)
353
495
  throw new core_1.AugustValidationError('INVALID_INPUT', 'handleSolanaRedeem: wallet not connected');
@@ -358,6 +500,9 @@ async function handleSolanaRedeem({ provider, connection, vaultProgramId, vaultA
358
500
  throw new core_1.AugustValidationError('INVALID_INPUT', 'handleSolanaRedeem: redeemShares is required and must be > 0');
359
501
  if (!vaultProgramId)
360
502
  throw new core_1.AugustValidationError('INVALID_INPUT', 'handleSolanaRedeem: vaultProgramId is required');
503
+ // Before any RPC: an unusable floor should cost the caller nothing.
504
+ if (options.minAssetsOut !== undefined)
505
+ validateExplicitFloor(options.minAssetsOut, 'minAssetsOut');
361
506
  const { depositMint, shareMint, vaultVersion } = await utils_1.SolanaUtils.getVaultMints({
362
507
  network: provider.connection.rpcEndpoint.includes('devnet')
363
508
  ? 'devnet'
@@ -385,13 +530,16 @@ async function handleSolanaRedeem({ provider, connection, vaultProgramId, vaultA
385
530
  // Use on-chain share mint from vault state instead of deriving a PDA,
386
531
  // since PDA derivation assumes one share mint per program (single-vault only).
387
532
  const shareMintAddr = new web3_js_1.PublicKey(shareMint);
388
- // Get share mint info to handle decimals
389
- const shareMintInfo = await connection.getParsedAccountInfo(shareMintAddr);
390
- if (!shareMintInfo.value) {
391
- throw new Error('Could not fetch share mint info');
392
- }
393
- const shareDecimals = shareMintInfo.value.data.parsed.info
394
- .decimals;
533
+ // Share-mint decimals and supply plus the vault state, from one slot. This
534
+ // replaces a `getParsedAccountInfo` here and a `vaultState.fetch` further
535
+ // down — one round trip rather than two, and supply and assets can no
536
+ // longer be read either side of someone else's deposit.
537
+ const { vaultStateData, supply: shareSupply, shareDecimals, } = await readPricingSnapshot({
538
+ connection,
539
+ program,
540
+ vaultStatePda,
541
+ shareMintAddr,
542
+ });
395
543
  let redeemSharesRaw;
396
544
  if (typeof redeemShares === 'bigint') {
397
545
  redeemSharesRaw = new anchor_1.BN(redeemShares.toString());
@@ -447,14 +595,22 @@ async function handleSolanaRedeem({ provider, connection, vaultProgramId, vaultA
447
595
  'so it cannot receive the redemption proceeds.');
448
596
  }
449
597
  const senderTokenAccount = payoutAccount.address;
450
- // Get the fee recipient from vault state
451
- const readOnlyProvider = utils_1.SolanaUtils.getReadOnlyProvider({ connection });
452
- const readOnlyProgram = utils_1.SolanaUtils.getProgram({
453
- provider: readOnlyProvider,
454
- idl,
455
- programId: _vaultProgramId.toBase58(),
456
- });
457
- const vaultStateData = await readOnlyProgram.account.vaultState.fetch(vaultStatePda);
598
+ // No extra reads here: the share mint (supply) and vault state (assets,
599
+ // offset, fee, fee recipient) came from the snapshot above.
600
+ let minAssetsOut;
601
+ if (options.minAssetsOut !== undefined) {
602
+ minAssetsOut = options.minAssetsOut;
603
+ }
604
+ else {
605
+ minAssetsOut = (0, pricing_1.quoteRedeemFloor)({
606
+ supply: shareSupply,
607
+ totalAssets: (0, pricing_1.totalAssetsOf)(vaultStateData),
608
+ shares: BigInt(redeemSharesRaw.toString()),
609
+ offset: (0, pricing_1.resolveShareOffset)(vaultStateData.shareOffset),
610
+ feePpm: (0, pricing_1.toBigInt)(vaultStateData.withdrawalFee, 'withdrawalFee'),
611
+ slippageBps: options.slippageBps ?? pricing_1.DEFAULT_SLIPPAGE_BPS,
612
+ });
613
+ }
458
614
  // Get the fee recipient's token account
459
615
  const feeRecipientTokenAccount = await (0, spl_token_1.getAssociatedTokenAddress)(_depositMint, vaultStateData.feeRecipient);
460
616
  // Every account this handler might have to create is created in the same
@@ -483,8 +639,9 @@ async function handleSolanaRedeem({ provider, connection, vaultProgramId, vaultA
483
639
  core_1.Logger.log.info('handleSolanaRedeem', 'Share mint:', shareMintAddr.toBase58());
484
640
  core_1.Logger.log.info('handleSolanaRedeem', 'Deposit mint:', _depositMint?.toBase58());
485
641
  core_1.Logger.log.info('handleSolanaRedeem', 'Signer:', _publicKey.toBase58());
642
+ core_1.Logger.log.info('handleSolanaRedeem', 'Min assets out, net of fee (raw):', minAssetsOut.toString());
486
643
  const tx = await program.methods
487
- .redeem(redeemSharesRaw)
644
+ .redeemChecked(redeemSharesRaw, new anchor_1.BN(minAssetsOut.toString()))
488
645
  .accounts({
489
646
  vaultState: vaultStatePda,
490
647
  vaultDepositAta: vaultTokenAtaPda,
@@ -516,7 +673,7 @@ async function handleSolanaRedeem({ provider, connection, vaultProgramId, vaultA
516
673
  vaultAddress: vaultAddress ? String(vaultAddress) : undefined,
517
674
  redeemShares: redeemSharesForLog,
518
675
  });
519
- throw new core_1.AugustSDKError('UNKNOWN', `Solana redeem failed: ${describeSolanaError(e)}`, {
676
+ throw new core_1.AugustSDKError('UNKNOWN', `Solana redeem failed: ${describeSolanaError(e)}${slippageHint(e)}`, {
520
677
  cause: e,
521
678
  context: {
522
679
  vaultProgramId: String(vaultProgramId),
@@ -25,8 +25,8 @@ export declare function handleStellarDeposit(params: IStellarDepositParams): Pro
25
25
  * Side effect on failure: when the *vault* cannot serve the redemption — it
26
26
  * rejected the call, or its ledger state needs restoring — the failure is
27
27
  * reported to that vault's curator. Stellar vaults are instant-redeem only, so
28
- * this is the curator's only signal that their depositors cannot get out
29
- * (AUGUST-7162). Fire-and-forget and deduped; see
28
+ * this is the curator's only signal that their depositors cannot get out.
29
+ * Fire-and-forget and deduped; see
30
30
  * {@link reportRedeemFailure} and {@link REPORTED_BUILD_STAGES}.
31
31
  *
32
32
  * Note this includes a caller-caused rejection such as redeeming more shares
@@ -81,8 +81,8 @@ async function handleStellarDeposit(params) {
81
81
  * Side effect on failure: when the *vault* cannot serve the redemption — it
82
82
  * rejected the call, or its ledger state needs restoring — the failure is
83
83
  * reported to that vault's curator. Stellar vaults are instant-redeem only, so
84
- * this is the curator's only signal that their depositors cannot get out
85
- * (AUGUST-7162). Fire-and-forget and deduped; see
84
+ * this is the curator's only signal that their depositors cannot get out.
85
+ * Fire-and-forget and deduped; see
86
86
  * {@link reportRedeemFailure} and {@link REPORTED_BUILD_STAGES}.
87
87
  *
88
88
  * Note this includes a caller-caused rejection such as redeeming more shares
@@ -32,7 +32,7 @@ export declare const getStellarVault: (tokenizedVault: ITokenizedVault, options:
32
32
  * (e.g. 13). A consumer that sizes a redeem trusting a silent fallback 7 would
33
33
  * under-redeem by `10^offset`. Callers that settle a redeem from this position
34
34
  * MUST refuse (surface an error) when `decimalsFromFallback` is `true` rather
35
- * than trusting `decimals`. See AUGUST-6381 (follow-up to AUGUST-6380).
35
+ * than trusting `decimals`.
36
36
  *
37
37
  * @param vaultAddress - Stellar vault contract ID (C… address)
38
38
  * @param walletAddress - User's Stellar account (G… address); validated upfront
@@ -22,7 +22,7 @@ const soroban_1 = require("./soroban");
22
22
  * Returns `{ decimals, fromFallback }`. When the `decimals()` retval is missing
23
23
  * or unparseable, `decimals` is STELLAR_FALLBACK_DECIMALS (7) and `fromFallback`
24
24
  * is `true` — the signal callers need to avoid trusting a fabricated scale (a
25
- * silent 7 under-redeems ERC4626 offset vaults; see AUGUST-6381). A successful
25
+ * silent 7 under-redeems ERC4626 offset vaults). A successful
26
26
  * parse returns the on-chain value with `fromFallback: false`.
27
27
  */
28
28
  function parseDecimals(scVal, context, vaultAddress) {
@@ -172,7 +172,7 @@ exports.getStellarVault = getStellarVault;
172
172
  * (e.g. 13). A consumer that sizes a redeem trusting a silent fallback 7 would
173
173
  * under-redeem by `10^offset`. Callers that settle a redeem from this position
174
174
  * MUST refuse (surface an error) when `decimalsFromFallback` is `true` rather
175
- * than trusting `decimals`. See AUGUST-6381 (follow-up to AUGUST-6380).
175
+ * than trusting `decimals`.
176
176
  *
177
177
  * @param vaultAddress - Stellar vault contract ID (C… address)
178
178
  * @param walletAddress - User's Stellar account (G… address); validated upfront
@@ -112,7 +112,7 @@ export declare class StellarAdapter {
112
112
  * @returns The position `{ shares, decimals, decimalsFromFallback }`, or null
113
113
  * if the balance read fails. When `decimalsFromFallback` is `true` the
114
114
  * `decimals()` read failed and `decimals` is the fallback (7) — callers sizing
115
- * a redeem MUST refuse rather than trust it (see AUGUST-6381).
115
+ * a redeem MUST refuse rather than trust it.
116
116
  */
117
117
  getUserPosition(vaultAddress: string, walletAddress: string): Promise<IStellarUserPosition | null>;
118
118
  /**
@@ -167,7 +167,7 @@ class StellarAdapter {
167
167
  * @returns The position `{ shares, decimals, decimalsFromFallback }`, or null
168
168
  * if the balance read fails. When `decimalsFromFallback` is `true` the
169
169
  * `decimals()` read failed and `decimals` is the fallback (7) — callers sizing
170
- * a redeem MUST refuse rather than trust it (see AUGUST-6381).
170
+ * a redeem MUST refuse rather than trust it.
171
171
  */
172
172
  async getUserPosition(vaultAddress, walletAddress) {
173
173
  return StellarGetters.getStellarUserPosition(vaultAddress, walletAddress, this._network, this._sorobanRpcUrl);
@@ -37,8 +37,7 @@ export interface IStellarRedeemParams {
37
37
  * (7) and `decimalsFromFallback` is set to `true`. Callers that size a redeem
38
38
  * from this position MUST check `decimalsFromFallback` and refuse to settle
39
39
  * when it is `true` — trusting a fabricated 7 against an ERC4626 offset vault
40
- * (share decimals = asset + offset) under-redeems by `10^offset`. See
41
- * AUGUST-6381.
40
+ * (share decimals = asset + offset) under-redeems by `10^offset`.
42
41
  */
43
42
  export interface IStellarUserPosition {
44
43
  /** Raw share balance in smallest unit, as a non-negative integer string */
@@ -64,6 +64,9 @@ exports.METHOD_CATEGORIES = {
64
64
  getVaultWithdrawals: 'read.redemption',
65
65
  getWithdrawalRequestsWithStatus: 'read.redemption',
66
66
  previewRedemption: 'read.redemption',
67
+ getBurnableAmountByReceiver: 'read.redemption',
68
+ getRequirementByDate: 'read.redemption',
69
+ getScheduledTransactionsByDate: 'read.redemption',
67
70
  getPrice: 'read.price',
68
71
  getUserPoints: 'read.points',
69
72
  fetchPointsLeaderboard: 'read.points',
@@ -111,6 +114,9 @@ exports.METHOD_CATEGORIES = {
111
114
  allowance: 'read.evm',
112
115
  balanceOf: 'read.evm',
113
116
  maxDeposit: 'read.vault',
117
+ getIdleLiquidity: 'read.vault',
118
+ lagDuration: 'read.vault',
119
+ getWithdrawalEpoch: 'read.vault',
114
120
  vaultDeposit: 'write.deposit',
115
121
  depositNative: 'write.deposit',
116
122
  swapAndDeposit: 'write.deposit',
@@ -118,6 +124,7 @@ exports.METHOD_CATEGORIES = {
118
124
  depositNativeViaSwapRouter: 'write.deposit',
119
125
  swapRouterDeposit: 'write.deposit',
120
126
  vaultRedeem: 'write.redeem',
127
+ claimWithdrawal: 'write.redeem',
121
128
  vaultRequestRedeem: 'write.redeem',
122
129
  rwaRedeemAsset: 'write.redeem',
123
130
  vaultApprove: 'write.approve',
@@ -3,4 +3,4 @@
3
3
  * Generated during publish from package.json version
4
4
  * This file is gitignored and created at publish time
5
5
  */
6
- export declare const SDK_VERSION = "9.3.0";
6
+ export declare const SDK_VERSION = "9.4.0";
@@ -6,5 +6,5 @@ exports.SDK_VERSION = void 0;
6
6
  * Generated during publish from package.json version
7
7
  * This file is gitignored and created at publish time
8
8
  */
9
- exports.SDK_VERSION = '9.3.0';
9
+ exports.SDK_VERSION = '9.4.0';
10
10
  //# sourceMappingURL=version.js.map
@@ -148,8 +148,8 @@ export declare class AugustBase {
148
148
  */
149
149
  constructor({ appName, providers, keys, monitoring, analytics, versionCheck, timeoutMs, publicApiBaseUrl, attribution, }: IAugustBase);
150
150
  /**
151
- * Verify API keys and authorize SDK usage.
152
- * TODO: initialize class with appropriate keys and verify august key
151
+ * Verify the configured August API key and mark this instance as authorized.
152
+ * @throws Error when `keys.august` is missing or rejected by the API.
153
153
  */
154
154
  init(): Promise<void>;
155
155
  /**
@@ -87,8 +87,8 @@ class AugustBase {
87
87
  });
88
88
  }
89
89
  /**
90
- * Verify API keys and authorize SDK usage.
91
- * TODO: initialize class with appropriate keys and verify august key
90
+ * Verify the configured August API key and mark this instance as authorized.
91
+ * @throws Error when `keys.august` is missing or rejected by the API.
92
92
  */
93
93
  async init() {
94
94
  const [augustCheck] = await Promise.all([
@@ -3,10 +3,24 @@
3
3
  */
4
4
  import type { IAddress, VaultAddress } from '../../types';
5
5
  /**
6
- * Request timeout in milliseconds.
7
- * Set to 90 seconds to accommodate slow API responses.
6
+ * Default per-request timeout, in milliseconds, for every August HTTP fetcher
7
+ * (`fetchAugustPublic`, `fetchAugustWithKey`, `fetchAugustWithBearer`).
8
+ *
9
+ * Previously 90s. That was longer than any realistic caller was willing to
10
+ * wait: server-rendered integrations run inside serverless functions whose own
11
+ * execution budget is well under 90s, so the request had already been abandoned
12
+ * upstream by the time the abort fired — the timeout only ever garbage-collected
13
+ * a dead request, while the socket stayed open holding backend capacity and
14
+ * amplifying the stall for every concurrent caller.
15
+ *
16
+ * 15s is above the p99 of a healthy August API response and below every common
17
+ * upstream budget (Vercel/Lambda defaults, browser patience, upstream gateway
18
+ * timeouts), so a stalled request now fails fast and frees its connection.
19
+ *
20
+ * Callers that genuinely need longer override per-request via
21
+ * `IFetchAugustOptions.timeoutMs`, or process-wide via `setSdkRequestTimeout`.
8
22
  */
9
- export declare const REQUEST_TIMEOUT_MS = 90000;
23
+ export declare const REQUEST_TIMEOUT_MS = 15000;
10
24
  export declare const PRICE_SERVER_URL = "https://prices.augustdigital.io";
11
25
  export declare const WEBSERVER_URL: {
12
26
  production: string;
@@ -33,10 +33,24 @@ function subaccountSegment(subaccount) {
33
33
  : encodeURIComponent(subaccount);
34
34
  }
35
35
  /**
36
- * Request timeout in milliseconds.
37
- * Set to 90 seconds to accommodate slow API responses.
36
+ * Default per-request timeout, in milliseconds, for every August HTTP fetcher
37
+ * (`fetchAugustPublic`, `fetchAugustWithKey`, `fetchAugustWithBearer`).
38
+ *
39
+ * Previously 90s. That was longer than any realistic caller was willing to
40
+ * wait: server-rendered integrations run inside serverless functions whose own
41
+ * execution budget is well under 90s, so the request had already been abandoned
42
+ * upstream by the time the abort fired — the timeout only ever garbage-collected
43
+ * a dead request, while the socket stayed open holding backend capacity and
44
+ * amplifying the stall for every concurrent caller.
45
+ *
46
+ * 15s is above the p99 of a healthy August API response and below every common
47
+ * upstream budget (Vercel/Lambda defaults, browser patience, upstream gateway
48
+ * timeouts), so a stalled request now fails fast and frees its connection.
49
+ *
50
+ * Callers that genuinely need longer override per-request via
51
+ * `IFetchAugustOptions.timeoutMs`, or process-wide via `setSdkRequestTimeout`.
38
52
  */
39
- exports.REQUEST_TIMEOUT_MS = 90000;
53
+ exports.REQUEST_TIMEOUT_MS = 15000;
40
54
  exports.PRICE_SERVER_URL = 'https://prices.augustdigital.io';
41
55
  exports.WEBSERVER_URL = {
42
56
  production: 'https://backend.fractalprotocol.org',
@@ -103,6 +103,7 @@ exports.VAULT_FUNCTIONS_V1 = [
103
103
  'withdrawalFee',
104
104
  'lagDuration',
105
105
  'withdrawalsPaused',
106
+ 'depositsPaused',
106
107
  'maxDepositAmount',
107
108
  ];
108
109
  exports.VAULT_FUNCTIONS_V2 = [
@@ -113,7 +114,10 @@ exports.VAULT_FUNCTIONS_V2 = [
113
114
  'maxDepositAmount',
114
115
  'lagDuration',
115
116
  'withdrawalsPaused',
117
+ 'depositsPaused',
116
118
  'depositCap',
119
+ // MUST stay last: `getEvmVaultV2` reads the receipt token positionally as
120
+ // the final entry of this list.
117
121
  'lpTokenAddress',
118
122
  ];
119
123
  exports.VAULT_FUNCTIONS_V2_RECEIPT = [