> For the complete documentation index, see [llms.txt](https://docs.augustdigital.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.augustdigital.io/developers/typescript-sdk/changelog.md).

# Changelog

{% updates format="full" %}
{% update date="2026-08-18" %}

## 8.24.0

{% hint style="info" %}
**Integrator highlights**

* **Breaking:** getAttributionSuffix(chainId?) now returns undefined when chains restriction is configured without chainId passed
* **Action:** Pass chainId through to attribution methods if unattributed writes were relied upon with chains restriction set
* **New:** isAttributionEnabled() exported to report attribution config presence independent of chain gate
* **New:** approveCrossChain takes optional trailing chainId parameter to gate dataSuffix
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 6e3caa0: fix: ERC-8021 attribution chain gate is fail-closed, unblocking Ledger approvals

  `attribution.chains` used to fail open: a write whose chain ID could not be determined got the suffix anyway, on the reasoning that over-attribution is harmless. It is not. The suffix makes calldata longer than the ABI encoding of the call, which breaks clear-signing on hardware wallets — a Ledger rejects an over-long ERC-20 `approve` with `EthAppCommandError: Invalid data 6a80`, so a user on an unattributed chain could not transact at all. Reported against a mainnet vault deposit from Rabby + Ledger Nano S.

  * **`getAttributionSuffix(chainId?)`** returns `undefined` when a `chains` restriction is configured and no chain ID is passed. Unrestricted attribution (no `chains`) is unchanged and still attributes every chain.
  * **`wrapSignerWithAttribution`** sends the transaction unattributed when the provider network lookup fails, instead of appending blind. Its enabled check now uses the new `isAttributionEnabled()`, so the chain gate no longer turns the whole wrap into a pass-through.
  * **`isAttributionEnabled()`** (new, exported) reports config presence independent of the chain gate.
  * **`approveCrossChain`** takes an optional trailing `chainId` and gates its `dataSuffix` on it; both call sites in `crossChainVault` pass the chain they already resolve (`props.userChainId`, `props.config.hubChainId`). This was the one remaining write that appended the suffix with no chain check — and an `approve`, the exact call Ledger refuses.

  Integrators that set `attribution.chains` and rely on unknown-chain writes being attributed will now see those writes go out clean; pass the chain ID through if the attribution matters more than clear-signing.

</details>
{% endupdate %}

{% update date="2026-08-14" %}

## 8.23.0

{% hint style="info" %}
**Integrator highlights**

* **Action:** Set AUGUST\_SDK\_SLACK\_WEBHOOK\_URL environment variable or Slack alerts from subgraph readers will be disabled
* **Action:** Migrate from deprecated DEFAULT\_SLACK\_WEBHOOK\_URL and use resolveSlackWebhookUrl() instead
* **New:** august.sdk\_version Sentry tag added for querying consumer SDK build version
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* b2a1376: fix: let consumers configure their own Slack webhook, and stop shipping August's

  Every `slackWebookUrl` parameter in the subgraph readers defaulted to `DEFAULT_SLACK_WEBHOOK_URL`, a hardcoded webhook path baked into the published bundle and the generated `.d.ts`. A Slack webhook path is a bearer credential, so this both exposed an internal August channel to anyone who installed the SDK and sent consumers' vault alerts to that channel with no way to redirect them.

  The webhook is now resolved at call time: an explicit argument wins, otherwise `AUGUST_SDK_SLACK_WEBHOOK_URL` from the environment, otherwise alerting is disabled (a one-time console warning, rather than defaulting to somebody else's channel). Both the full `https://hooks.slack.com/services/…` URL and the bare `T…/B…/x…` path are accepted.

  **Action required for deployments that relied on the default:** set `AUGUST_SDK_SLACK_WEBHOOK_URL`, or Slack alerts from the subgraph readers will be silently disabled.

  `DEFAULT_SLACK_WEBHOOK_URL` is now `''` and deprecated; it is removed in the next major. Use `resolveSlackWebhookUrl()` instead.

### Patch Changes

* 0ad9bd8: feat: add `august.sdk_version` Sentry tag so a consumer's SDK build is queryable

  `sdk.version` is a reserved Sentry field — Sentry populates it with the version of its own client, so querying it returned `@sentry/core`'s version for every consumer rather than the August SDK's. The real value was only reachable as `tags[sdk.version]`.

  The same value is now also tagged as `august.sdk_version`, which Sentry does not shadow. `sdk.version` is still set for back-compat with existing saved queries, dashboards, and alert rules; it is deprecated and will be removed in the next major.
* 82091ae: fix: retry rate-limited eth\_getLogs chunks in getVaultRedemptionHistory and lower batch size to 8
* 7fc29b2: fix: stop the four highest-volume production error paths
  * `getVaultAvailableRedemptions` no longer fails outright on vaults that do not implement `lagDuration()`. The empty `eth_call` response is retried, then treated as "no claim lag" — previously it threw, which both raised an error per call and returned an empty redemption list for the affected vaults.
  * `getVaultRedemptionHistory` retries `eth_getLogs` chunks rejected by a provider rate limit, and lowers batch concurrency from 20 to 8. A transient cap used to abort the entire scan.
  * `getDecimals` records a transient transport fault as a breadcrumb rather than an error. Its contract is unchanged: it still never throws, still does not retry, and still resolves `undefined` on failure.
  * CeFi/OTC subaccount enrichment treats a `400` ("borrower not tracked") like `404`/`204` — a breadcrumb. `401` and `5xx` stay error-level.
* 4c6ed05: fix: demote CeFi/OTC subaccount enrichment 400 to breadcrumb severity

</details>
{% endupdate %}

{% update date="2026-08-11" %}

## 8.21.1

{% hint style="info" %}
**Integrator highlights**

* **New:** X Layer (chain 196) is now registered with RPC endpoint and Multicall3 support
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* de20993: feat: register X Layer (chain 196)

  X Layer (OKX's Polygon-CDK zkEVM, native OKB, 18 decimals) joins the EVM chains the SDK understands:

  * **`NETWORKS[196]`** — `X Layer`, explorer `https://xlayerscan.com`. This is what `explorerLink` uses for tx/address links, and what `chainIdToTagValue` slugifies for the `sdk.chain` Sentry tag (`x-layer` instead of `unknown:196`). It also lands the chain in `AVAILABLE_CHAINS`.
  * **`FALLBACK_RPC_URLS[196]`** — `https://rpc.xlayer.tech`, used when a caller supplies no provider for the chain. Verified live on 2026-08-11: returns `eth_chainId` `0xc4` and sends `access-control-allow-origin: *`, so a browser-side read works without a proxy.
  * **`MULTICALL3_VERIFIED_CHAINS`** — 196 added. `eth_getCode` at `0xcA11bde05977b3631167028862bE2a173976CA11` returned the canonical 3808-byte runtime on 2026-08-11, so vault prefetch batches its reads rather than falling back to the per-call path. Deployment presence was verified on-chain, not assumed from the deterministic deployer.

  No vault is served on chain 196 yet — this is chain registration only, so no subgraph slug mapping is added.

</details>
{% endupdate %}

{% update date="2026-08-11" %}

## 8.21.0

{% hint style="info" %}
**Integrator highlights**

* **Breaking:** Pass `undefined` as `sendTransaction` positional argument to `vaultDeposit` and `vaultRedeem`
* **Action:** Deposit and redeem now throw before submission if balance cannot be established or is insufficient
* **Action:** Update calls to provider methods if you relied on implicit `'confirmed'` commitment behavior
* **Action:** Review frozen token account handling — deposit and redeem now reject frozen accounts with an error
* **New:** Configurable Solana commitment level via `AugustSDK` and `SolanaAdapter` options
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 8ad6c43: fix: Solana deposit/redeem create token accounts atomically, and every balance read now agrees with the write path (AUGUST-7221)

  `handleSolanaDeposit` and `handleSolanaRedeem` treated SPL token accounts as preconditions, and where they did create one they sent it as its own transaction without awaiting confirmation. Two production failures traced to this.

  **Deposit no longer races its own ATA creation.** When the depositor had no share account, the SDK fired `createAssociatedTokenAccountInstruction` via `sendTransaction` and then immediately simulated the deposit. Observed in production on 2026-08-11: the deposit failed with `Simulation failed … Logs: []` while the create was still in flight, then succeeded 17s later on retry. The empty log array means the transaction never reached program execution, so nothing was written on-chain to debug from. The on-chain program cannot self-heal here: `Deposit.sender_share_account` is a plain `InterfaceAccount<TokenAccount>` with no `init_if_needed`. Creation is now prepended to the deposit via `.preInstructions()`, so it is atomic with the transfer and costs one signature instead of two. This affected every first-time depositor into a vault.

  **Redeem no longer requires the payout account to pre-exist.** Redeem rejected any wallet holding no deposit-mint account with `No token account found for deposit mint`. That is backwards — redeeming is precisely how a holder first receives the deposit mint — and it left shares acquired by transfer, airdrop, or market buy unredeemable through this SDK. The payout account is now created inline when absent. (A zero-balance account already satisfied the old guard, so this affected only wallets that had never held the deposit token at all.)

  **Idempotent creation.** All account creation uses `createAssociatedTokenAccountIdempotentInstruction`, so a concurrent create (another tab, a wallet auto-provisioning the account) is a no-op rather than a failure. The fee-recipient account is created unconditionally on redeem, replacing a `getAccountInfo` read followed by a separate transaction and a hard-coded `setTimeout(1000)`.

  **One selection rule for every read and write.** A wallet's account of record for a mint is now the one holding the largest balance, applied uniformly across `fetchUserTokenBalance`, `fetchUserShareBalance`, `fetchUserShareBalanceRaw` and both vault handlers. Previously each took whichever account the RPC happened to return first, an ordering `getParsedTokenAccountsByOwner` does not guarantee — so for a wallet holding more than one account for a mint, the balance shown and the account transacted against could be different accounts. The rule is an internal helper, not part of the public API surface.

  An unreadable balance — an RPC response whose `amount` is not a u64 string — is now treated as *unknown* rather than as zero, since scoring it zero would silently demote a funded account below a dust one and reinstate the behaviour this rule exists to prevent. **On the write paths this surfaces**: deposit and redeem throw rather than transact against an account whose balance could not be established. The three balance readers keep their existing never-throw contract and still return their documented zero fallback, logging the failure — so read behaviour is unchanged for consumers.

  **Deposit and redeem now check the balance, not just that an account exists.** A wallet with an empty or under-funded account previously passed the guard and paid a signature to discover an on-chain insufficient-funds revert. The balance is already in hand from the account lookup, so this costs no extra RPC. Both handlers throw `AugustValidationError` before submitting.

  **Commitment is now explicit and configurable — the default is unchanged.** `SolanaAdapter` previously passed no commitment when constructing its `Connection` and no `commitment` to `.rpc()`, so reads *and* confirmations both fell through to the RPC's own `'finalized'` default. That default is now stated explicitly and exposed:

  ```ts
  new AugustSDK({ solana: { rpcUrl, network, commitment: "confirmed" } });
  // or directly:
  new SolanaAdapter(endpoint, network, commitment /* default: 'finalized' */);
  ```

  The one setting covers reads and write-confirmations together — the vault handlers and both Anchor providers (`SolanaUtils.getProvider`, `getReadOnlyProvider`) all derive their commitment from the same `Connection` rather than hard-coding one, so nothing can drift apart. Pass `'confirmed'` for a markedly faster round trip (seconds rather than tens of seconds), accepting that the state you act on can still, in principle, be rolled back.

  > **Action required if you call `getProgram(...).methods…rpc()` directly.** Both provider factories previously hard-coded `commitment: 'confirmed'`, while the connection they wrapped read at `'finalized'` — the inconsistency this change removes. Writes issued through that public API *without* a per-call `commitment` therefore confirmed at `'confirmed'` before this release and now confirm at the adapter default, `'finalized'`. They are strictly safer but noticeably slower (tens of seconds rather than seconds). To keep the previous latency, configure `commitment: 'confirmed'` — which now applies to reads and writes alike — or pass `commitment` per call to `.rpc()`. Consumers who only use `vaultDeposit` / `vaultRedeem` are unaffected: those already confirmed at `'finalized'`.

  Configuring Solana through the legacy `providers` map leaves the commitment at the default: `ISolanaConfig` requires `rpcUrl` and `network`, so a commitment-only object alongside that path is not expressible in TypeScript.

  **Frozen accounts are no longer selected for transfers.** A token issuer can freeze an account, and tokens can move neither out of nor into a frozen one. Selection now prefers a spendable account over a richer frozen one, and when every account for a mint is frozen, deposit and redeem raise `AugustValidationError` naming the cause instead of reverting with a bare SPL `0x11` after the user signs. This covers all four roles: the deposit's funding account and share destination, and the redeem's share source and payout destination. The balance readers are unchanged — they still report a frozen balance, because the user does own it.

  **Sub-unit amounts are rejected before submission.** A positive UI amount below one raw unit (`1e-7` into a 6-decimal mint) truncates to zero when scaled. Both handlers now re-check the *scaled* amount, so this raises `AugustValidationError` instead of clearing the balance gate (`0n < 0n` is false) and submitting a no-op transfer.

  **One confirmation per transaction.** Both handlers fetched a blockhash that was never used to build the transaction (`.rpc()` builds and signs with its own), then ran a second `confirmTransaction` against that unrelated hash after Anchor had already confirmed. `.rpc()` now owns submission and confirmation, with `commitment` passed explicitly.

  **`sendTransaction` is now ignored** by `SolanaAdapter.vaultDeposit`, `SolanaAdapter.vaultRedeem`, and both underlying handlers — there is no longer a second transaction to send, and signing goes through the provider's wallet. Existing call sites keep compiling.

  > On the two adapter methods it is a **positional** parameter sitting immediately before `vaultAddress`. **Pass `undefined` in that position — do not delete the argument.** Deleting it shifts your vault address into the `sendTransaction` slot and leaves `vaultAddress` undefined, which falls back to the legacy single-vault PDA derivation and targets a different vault. On the underlying handlers the parameter is a named object property, so it can simply be omitted.

  Note that deposit and redeem may debit SOL rent from the signer for accounts they create (\~0.00204 SOL each; on redeem this can include the vault's fee-recipient account). This was already true of the old two-transaction flow; it is now documented on both handlers.

</details>
{% endupdate %}

{% update date="2026-08-10" %}

## 8.20.1

{% hint style="info" %}
**Integrator highlights**

* **Action:** Review `getVaultRedemptionHistory` calls if using Alchemy, Infura, dRPC or QuickNode — default block range now 10k instead of 50k.
* **Action:** If using Solana or Stellar vaults, re-test `getVaultAllocations` as non-EVM identifiers are now URL-encoded instead of checksummed.
* **New:** New `determineRpcBatchMaxCount` export to derive batch size from RPC endpoint host.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 3bd6e3f: fix: honour provider RPC limits, stop crashing on non-EVM subaccounts, and cut duplicate error reporting

  Five production failures, in descending event volume:

  * **dRPC batch rejection.** `createProvider` hard-coded `batchMaxCount: 10`, but dRPC's free tier rejects batches larger than 3 — and rejects the *whole* batch, so every Mezo read failed with `server response 500 … "Batch of more than 3 requests are not allowed"`. Batch size is now derived from the endpoint host via the new `determineRpcBatchMaxCount` export.
  * **Non-EVM subaccounts.** Every `WEBSERVER_ENDPOINTS.subaccount.*` builder ran the identifier through ethers' `getAddress()`, so a Solana or Stellar vault operator threw `TypeError: invalid address` before any request was made — breaking `getVaultAllocations` for mixed-chain vaults. EVM addresses are still checksummed; other identifiers are URL-encoded.
  * **`BigInt(undefined)`.** `getVaultAvailableRedemptions` read the amount field of the other subgraph schema (`assets` vs `shares`) and threw `TypeError: Cannot convert undefined to a BigInt`, which emptied the returned redemption list — a claimable withdrawal silently disappeared. Absent or non-numeric amounts now coerce to `0n`.
  * **`eth_getLogs` range.** `determineBlockSkipInternal` defaulted to 50 000 blocks; Alchemy, Infura, dRPC and QuickNode all cap the range at 10 000 and reject with JSON-RPC `-32600`, failing `getVaultRedemptionHistory` on Ethereum mainnet. The default is now 10 000 (15 batched `eth_getLogs` calls per 150k-block lookback instead of 3).
  * **Duplicate reporting.** A failed log-fetch chunk was captured as an issue and then re-thrown into a catch block that captured it again.

  Reporting changes (no behaviour change for callers):

  * Per-borrower CeFi/OTC lookups that return 204/404 ("this subaccount has no such position" — the common case) are breadcrumbs instead of captured errors.
  * A missing portfolio fetcher for a chain type (Stellar, Sui) is a breadcrumb, and no longer forces `getVaultAllocations` to throw `failure to fetch debank response` — Stellar vaults now return the CeFi/OTC/loan allocations that did resolve.
  * `AugustHistoryUnavailableError` is no longer reported: it is a designed outcome thrown to the caller, not an SDK fault.
  * Mezo (chain 31612) errors are dropped entirely. Its public dRPC endpoint failed often enough to dominate the error stream without describing an SDK defect. This is a deliberate blind spot — genuine Mezo bugs are silenced too; remove the `MUTED_CHAIN_SLUGS` entry in `core/analytics/sentry.ts` to restore reporting.
  * Identical SDK errors are rate-limited to 3 per signature per minute before reaching Sentry, with the suppressed count attached to the next event that is sent (`sdk.suppressed_since_last`).

</details>
{% endupdate %}

{% update date="2026-08-10" %}

## 8.20.0

{% hint style="info" %}
**Integrator highlights**

* **Breaking:** `getVault`, `getVaultLoans`, `getVaultSubaccountLoans`, `getVaultAllocations` now throw `AugustValidationError` code `INVALID_CHAIN` instead of continuing with undefined RPC URL.
* **Breaking:** `assertKnownChainId` now only rejects truly unknown chain IDs, not EVM chains with missing `NETWORKS` entries if a provider is configured.
* **Action:** Wrap calls to vault methods in try-catch to handle new `AugustValidationError` with code `INVALID_CHAIN`.
* **Action:** If passing an unconfigured EVM chain ID, provide the RPC URL to the constructor or remove the unsupported chain from your calls.
* **New:** New exports: `isEvmChainId`, `isKnownChainId`, `assertKnownChainId`, `assertEvmProviderConfigured`, `SUI_CHAIN_ID`, `NON_EVM_CHAIN_IDS`.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 2c391b8: fix: vault methods now fail fast on an unroutable `chainId` instead of continuing without an RPC URL

  `getVault`, `getVaultLoans`, `getVaultSubaccountLoans` and `getVaultAllocations` previously logged `Missing RPC URL for chainId N` and carried on with an undefined RPC URL. That surfaced as a cascade of misleading downstream failures — `connect ECONNREFUSED 127.0.0.1:8545` (ethers falling back to its localhost default), `missing revert data` on `decimals()` reads issued against the wrong chain, and `TypeError: Cannot read properties of undefined`. Entirely unknown chain IDs were swallowed the same way.

  These methods now throw a typed `AugustValidationError` with code `INVALID_CHAIN`:

  * **Unknown chain ID** (not a supported EVM chain and not Solana `-1` / Stellar `-3` / Sui `101`) — the call site is wrong.
  * **Supported EVM chain with no configured RPC URL** — remediated by passing one to the constructor; the error message names the chain and shows the fix.

  Non-EVM chain IDs are exempt from the RPC-URL check: Solana, Stellar and Sui vaults route through their adapters and never read the `providers` map.

  New exported helpers: `isEvmChainId`, `isKnownChainId`, `assertKnownChainId`, `assertEvmProviderConfigured`, plus the `SUI_CHAIN_ID` and `NON_EVM_CHAIN_IDS` constants.

  Callers that previously relied on these methods continuing past a missing provider will now see an error at the call site rather than an opaque RPC failure later.

### Patch Changes

* 47f7e69: fix: `assertKnownChainId` no longer rejects an EVM chain ID missing from `NETWORKS` when the caller configured a provider for it (e.g. chain 10 / Optimism, which ships fallback RPCs and oracle addresses but has no `NETWORKS` entry). Previously such a chain was rejected as "unknown" before the provider check ever ran, breaking a previously-working call.

</details>
{% endupdate %}

{% update date="2026-08-07" %}

## 8.19.0

{% hint style="info" %}
**Integrator highlights**

* **New:** New `attribution` constructor option with `builderCodes` and optional `chains` appends ERC-8021 calldata suffix to EVM writes.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 8ab81d0: feat: ERC-8021 attribution (Base Builder Codes) — new `attribution` constructor option (`{ builderCodes, chains? }`) appends the ERC-8021 calldata suffix to every EVM write: ethers vault writes via the normalized-signer wrap and cross-chain OVault viem writes via `dataSuffix`. Off by default; no viem version requirement.

</details>
{% endupdate %}

{% update date="2026-08-06" %}

## 8.18.0

{% hint style="info" %}
**Integrator highlights**

* **Action:** Check if your UI handles the new `confirmationUnknown` flag to show pending instead of failed on lost confirmations.
* **Action:** Re-quote or refresh token decimals before submit if using custom decimals logic, as the SDK now caches more aggressively.
* **New:** `isRetryableRpcError` classifies transient JSON-RPC transport faults vs. genuine reverts.
* **New:** `isEmptyViewResponse` detects empty responses to argument-free ERC-20 view calls.
* **New:** `retryOnTransientRpc` retries with bounded exponential backoff on transient provider faults.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 32f2bc7: fix: stop reporting mined transactions as failed when the RPC hiccups mid-receipt-poll

  Bumped `minor` rather than `patch` per CLAUDE.md §3: although the driver is a bug fix, the change adds six exported symbols (`isRetryableRpcError`, `isEmptyViewResponse`, `retryOnTransientRpc`, `getDecimalsOrThrow`, `getReceiptTokenAddressOrThrow`, `LP_TOKEN_ADDRESS_SELECTOR`) to the public surface via `core`'s `export *`. No existing signature or behavior is removed or changed.

  `safeWaitForTx` previously only recovered from malformed-nonce RPC responses. Any other failure out of `tx.wait()` — most commonly a transient JSON-RPC transport fault while polling `eth_getTransactionReceipt` (`could not coalesce error (error={ "code": -32603 … })`) — was rethrown, so `vaultRequestRedeem` and every other write path reported a transaction that had already been broadcast and mined as FAILED. Users then retried and hit `ERC20InsufficientBalance`.

  * Adds `isRetryableRpcError(error)`, which classifies JSON-RPC `-32603`/`-32000`, ethers' "could not coalesce error", `eth_getTransactionReceipt` failures, network/timeout/fetch faults and HTTP 429/5xx as transient transport errors — while explicitly *not* matching genuine contract reverts (`CALL_EXCEPTION` carrying revert data, `execution reverted`, or a receipt with `status === 0`). `missing revert data` is intentionally excluded so this predicate never contradicts `isExpectedRevertError`.
  * Adds `isEmptyViewResponse(error, selector?)` for the one `missing revert data` shape that really is a provider artefact: an empty response to an argument-free ERC-20 view call (`decimals()`, `symbol()`, `name()`, `totalSupply()`), which a deployed token cannot legitimately revert on.
  * `safeWaitForTx` now re-polls `provider.waitForTransaction()` with bounded exponential backoff (3 attempts, 250ms base) on those transport faults. It still throws on a `status === 0` receipt and on a wait that times out with no receipt, and the existing nonce-parse fallback is unchanged.
  * **Failed writes now say whether the transaction reached the chain.** When a write is broadcast and only its confirmation is lost, the thrown `AugustSDKError.context` carries `txHash`, `broadcast: true` and `confirmationUnknown: true` — enough for a UI to render a pending state instead of "failed" (and to *not* prompt a retry, which is how a redeem gets double-submitted). A definitive on-chain revert reports `confirmationUnknown: false`, and a write that never left carries no `txHash` at all. Wired through `vaultDeposit`, `vaultRequestRedeem`, `vaultRedeem`, `depositNative`, `rwaRedeemAsset` and the approval path. No return type or call signature changed.
  * Every `decimals()` read in the write paths (approve, deposit, redeem, native deposit and the SwapRouter paths) now goes through a new `getDecimalsOrThrow`, which shares the **same cache namespace and the same in-flight dedup map** as the existing `getDecimals` used by read paths. So a read-then-write flow against the same token costs one `decimals()` RPC in total instead of two, and concurrent callers for an uncached token collapse to one call. `getDecimalsOrThrow` differs from `getDecimals` only in that it surfaces failures instead of resolving `undefined` (an `undefined` decimals reaching amount encoding silently means 18) and retries the transient ones.
  * **Every `lpTokenAddress()` read is now retried the same bounded way.** The evm-2 receipt-token lookup sits one line above those `decimals()` reads on the approve, deposit, request-redeem and SwapRouter-deposit paths, and was still a bare call — so a single truncated `eth_call` response failed the whole write with `missing revert data (action="call", data="0xf5ae497a", …)` (observed in production against the mainnet Tori Ecosystem Vault, whose `lpTokenAddress()` returns a real address when the provider is healthy). `0xf5ae497a` is added to the argument-free view selectors and exported as `LP_TOKEN_ADDRESS_SELECTOR`, and a new `getReceiptTokenAddressOrThrow` routes the read through `retryOnTransientRpc`. Applied at every call site: `vaultApprove`, `vaultDeposit`, `vaultRequestRedeem`, `swapRouterDeposit`, the cached `getReceiptTokenAddress` reader, `getVaultUserLifetimePnl`, `getPreviewRedemption`, and the evm-2 LP branch of `fetchTokenPrice` (which inlines the same retry because `core/helpers/web3` imports from `core/fetcher`, so sharing the helper would be a cycle). **This deliberately does not hide a misrouted vault.** `lpTokenAddress()` exists only on evm-2 vaults, so empty returndata is also the only signal that version routing put a vault in the wrong branch — and it is byte-identical to a provider blip. The retry is therefore bounded (3 attempts, \~750ms), rethrows the **original** error object once they are spent (identity, message, `code` and `transaction.data` intact, so `AugustSDKError.cause` and Sentry grouping are unchanged), and has no fallback: it never substitutes another address and never resolves `null`/`undefined`. A transient blip is absorbed; a deterministic misroute still fails exactly as loudly as before. Unlike `decimals`, the result is **not** cached — no vault→receipt-token mapping is memoized on the money path in this pass. Success-path RPC cost is unchanged at one `eth_call` per read.
  * `providerScope` now unwraps a runner to its provider before scoping the cache key. This is a **no-op for providers** (ethers' `AbstractProvider` defines `get provider() { return this; }`), so read paths key exactly as before; it is what lets a signer-backed write share a cache entry with a provider-backed read on the same chain instead of falling back to the `unknown` scope.
  * The retry loop (`retryOnTransientRpc`) is exported from `core/helpers/chain-error` so the receipt-poll fallback and the decimals reader share one implementation.

  Per CLAUDE.md §7.2: `isRetryableRpcError`, `isEmptyViewResponse`, `retryOnTransientRpc` and `getReceiptTokenAddressOrThrow` are **deliberately excluded from the benchmark suite**. The last is, on its success path, exactly the single `lpTokenAddress()` `eth_call` the evm-2 write paths already made (no cache, no extra round trip), so its latency is already covered by the existing `vaultDeposit` / `vaultRequestRedeem` entries. The first two are pure synchronous classifiers over an already-caught error (string `includes` plus property reads, no RPC or I/O) that only run on a failure path already dominated by the RPC round trip that failed; the third's cost is a fixed, deliberate 250/500ms backoff, not a regression surface. The rationale is recorded alongside the other benchmark exemptions in `benchmarks/suites/sdk-methods.js`. All three are covered by unit tests instead.

### Patch Changes

* 32b60bc: fix: report the correct broadcast state when a `depositWithPermit` deposit's confirmation is lost to a transient RPC fault

  `vaultDeposit`'s permit sub-path sends its single main transaction through `safeSendTx` and returns immediately on success, so the hoisted `depositTx` local — which every other sub-path assigns and which the catch block used to read the broadcast marker — was never set. If that internal wait hit a transient transport fault, the thrown error carried no `txHash` in its context, so a broadcast-but-unconfirmed permit deposit was reported as never sent, reintroducing the retry-into-double-submit window `retryable-rpc-transport-errors` closed for the other write paths. The catch now falls back to reading the marker off the error itself (`errorTxBroadcastContext`) when `depositTx` is unset — the same mechanism already used by `vaultRedeem`, `rwaRedeemAsset` and `approveCore` for their single-tx paths.
* 7c7c074: chore: route SDK telemetry to the `august-js-sdk-v2` Sentry project

</details>
{% endupdate %}

{% update date="2026-08-06" %}

## 8.17.1

{% hint style="info" %}
**Integrator highlights**

* **Action:** Monitor Slack alerts for 'Missing Subgraph' per-pool notifications, now including HTTP status reasons for subgraph failures.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* f0dd06d: fix: stop billing a dead subgraph as a Sentry error on every read

  The subgraph readers logged a missing subgraph URL, and a non-200 from a resolved one, at `error` level. Both conditions are per-vault, but the readers run on every portfolio/history request, so a handful of vaults with retired subgraphs produced over 2M Sentry error events in 30 days — the single largest consumer of the org's error quota.

  These paths now log at `warn` (a breadcrumb, still attached to any real error that follows) and route the durable signal through the existing per-pool, TTL-deduped "Missing Subgraph" Slack alert. The non-200 branches did not alert at all before, so a URL pointing at a deleted subgraph was previously only visible as error spam; it now raises the same one-per-pool alert as a missing URL, with the HTTP status as the reason.

  Every reader already resolves its chain id at the top of the function for its own use, so the alert reuses that value rather than making a second `getChainId` round trip on a cold provider.

  Behaviour is otherwise unchanged: every reader still returns its empty result on failure. Keeping the alert is deliberate — a 404 makes these readers fall back to empty history, and silently-empty subgraph history is what made the 2026-07-09 PnL overinflation incident hard to diagnose.

</details>
{% endupdate %}

{% update date="2026-08-04" %}

## 8.17.0

{% hint style="info" %}
**Integrator highlights**

* **New:** IVault now exposes `withdrawalMarginSeconds` (number | null) for withdrawal period display buffer.
* **New:** IVault now exposes `iatTraders` (string\[] | null) for IAT trader wallet addresses.
* **New:** `withdrawalMarginSeconds` property on `IVault` for display buffer configuration
* **New:** `iatTraders` property on `IVault` listing IAT trader wallet addresses
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 5d9f67e: Surface two backend tokenized-vault fields on `IVault`:
  * `withdrawalMarginSeconds` (number | null) from `withdrawal_margin_seconds` — the display buffer added on top of the on-chain lag for the withdrawal period shown to users. Null means the backend has not configured a margin and consumers should apply their own default; an explicit 0 is a real "no margin" value.
  * `iatTraders` (string\[] | null) from `iat_traders` — IAT trader wallet addresses for the vault, in the vault chain's address format. Null when not configured.

</details>
{% endupdate %}

{% update date="2026-07-30" %}

## 8.16.1

{% hint style="info" %}
**Integrator highlights**

* **Action:** getVaultUserLifetimePnl now computes totalDeposited from face value instead of live oracle quotes; lifetimePnl now correctly includes vault fees.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* efffd48: fix: `getVaultUserLifetimePnl` now computes `totalDeposited` from the face value of what a user actually deposited, rescaled to the vault's own decimals, instead of re-quoting each deposit through a live price oracle. Previously, `totalDeposited` (and therefore `lifetimePnl`) drifted between calls purely from stablecoin peg noise, and approximately re-inflated deposits back toward face value — which silently excluded the vault's entry/exit fees from PnL. `lifetimePnl` now correctly reflects those fees as a cost.

</details>
{% endupdate %}

{% update date="2026-07-27" %}

## 8.16.0

{% hint style="info" %}
**Integrator highlights**

* **Breaking:** getProgram and getProgramId now throw AugustValidationError instead of TypeError when program not deployed on network.
* **Breaking:** Removed testnet entry from programIds mapping; canonical august\_vault program is not deployed on Solana testnet.
* **Action:** Solana adapter now targets shared august\_vault program (up12…) on all networks; update integrations using retired per-vault programs.
* **Action:** APY rates on IVaultApy are percentages (7.95 means 7.95%); do not rescale these fields.
* **New:** IVault.freshness surface exposes apyComputedAt, shareRatioSnapshotAt, and cachedAt timestamps.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* f3dc1e6: fix(solana): target the shared august\_vault program and ship the deployed IDL
  * Point the Solana adapter at the shared, canonical program — `up12…`, now deployed under the same id on every network — instead of the retired per-vault SyrupBTC program (`7B8n…`) or the interim devnet deploy (`C8B1…`).
  * `getProgram` resolves the program id from an explicit `programId` or the per-network `programIds` map, independent of the IDL passed — the IDL's embedded `address` (a build stamp) is only a last-resort fallback when no `network` is known. This closes a sharp edge where a non-reference-equal copy of the built-in IDL on a non-mainnet network could resolve to the embedded mainnet program id.
  * Refresh the shipped IDL to the deployed versioned multi-vault interface (fetched from the devnet on-chain IDL), replacing the stale pre-versioned copy. Read paths (`VaultState` decode) and the `deposit`/`redeem` instructions are unchanged; the refresh adds `close_vault`/`set_aum_limits`/`update_share_token_metadata` and the versioned `initialize`. A CI drift guard (`solana-idl-drift`) fails if the committed IDL diverges from the deployed devnet program.
* 2da4cad: fix(solana): honour custom IDL program addresses, drop the undeployed testnet mapping
  * `SolanaAdapter.getProgram` now accepts an optional `programId` override and no longer discards the `address` on a caller-supplied IDL. Resolution order is explicit `programId` → custom IDL `address` → per-network default → the IDL's embedded build stamp. A copy of the SDK's bundled `vaultIdl` still defers to the network default, so the devnet-silently-targets-mainnet edge stays closed.
  * Removed the `testnet` entry from `programIds`: the canonical `august_vault` program is not deployed on Solana testnet, so the mapping handed callers an address with no executable behind it. `getProgram` and `SolanaAdapter.getProgramId` now throw `AugustValidationError` naming the deployed networks instead of returning a dead address (`getProgramId` previously threw a bare `TypeError`).
  * The Solana IDL drift guard now validates the program the SDK actually targets (`up12…`) by pinning its deployed binary across devnet/mainnet and decoding live `VaultState` accounts against the committed layout, rather than only comparing the structurally-matching `C8B1…` reference IDL.
* 8c306f7: feat: surface per-vault data-provenance timestamps as `IVault.freshness`

  Maps the backend's new `freshness` object onto `IVault` for every tokenized-vault read on both the August and Upshift surfaces: `apyComputedAt` (when `historical_apy` / TVL / drawdown were last recomputed), `shareRatioSnapshotAt` (newest persisted share-price snapshot), and `cachedAt` (when the backend assembled the response body). A `shareRatioSnapshotAt` later than `apyComputedAt` means a snapshot has landed that the APY has not been recomputed from yet — the staleness signal a UI needs to render "data as of X" instead of implying share price and APY are equally current (AUGUST-6124).

  All three are independently nullable and are never defaulted from one another. `shareRatioSnapshotAt` is populated regardless of `load_snapshots`, so it is present on the basic and sub-accounts views too. Values are passed through verbatim as RFC 3339 UTC strings with the trailing `Z`. Additive and non-breaking: `freshness` is null when the backend does not report it, and the existing top-level `cachedAt` is unchanged.

  `freshness` is read off the same response body as `historical_apy`, so the timestamps always describe the payload they annotate — including when that body is served from the SDK's in-process response cache.

  No new RPC or network calls — the field rides along on responses the SDK already fetches, and the mapping is a synchronous three-key rename.

### Patch Changes

* 75d5168: docs: document the unit contract on `IVaultApy`

  Every rate on `IVaultApy` (`apy`, `liquidApy`, `pointsApy`, `campaignApy`, `underlyingApy`) is a percentage — `7.95` means 7.95%. The backend reports decimal fractions and the SDK multiplies by 100 exactly once, uniformly, across all of them. That convention was never written down, which let a consumer scale a subset of the fields twice and display 1/100th of their real contribution (AUGUST-6967).

  Documentation only — no behaviour or value changes. `rewardsClaimable` / `rewardsCompounded` are also now marked as token amounts rather than rates.

</details>
{% endupdate %}

{% update date="2026-07-23" %}

## 8.15.0

{% hint style="info" %}
**Integrator highlights**

* **Action:** Check `is_show_compound_apy` flag to decide whether display simple or compound APY to users
* **Action:** `getVaultUserLifetimePnl` now throws `AugustHistoryUnavailableError` when deposit/withdrawal history unavailable
* **New:** `historical_compound_apy` field on `/tokenized_vault` with `apy_override.is_show_compound_apy` flag
* **New:** `AugustHistoryUnavailableError` and `assertPnlHistoryConsistent` exported for history validation
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 2277991: feat: expose compound-annualized historical APY (AUGUST-6765)

  `/tokenized_vault` now returns `historical_compound_apy` (same 1/7/30-day horizon shape as `historical_apy`) plus `apy_override.is_show_compound_apy` selecting which annualization convention the UI should display. The SDK now types both fields and passes `historical_compound_apy` through `buildBackendVault` / `buildFormattedVault` onto `IVault`, so consumers can honor the flag. Both fields are optional; absence means simple (existing behavior).
* ab1df85: feat: guard lifetime PnL against unavailable transaction history

  `getVaultUserLifetimePnl` now throws a typed `AugustHistoryUnavailableError` (code `HISTORY_UNAVAILABLE`) when a wallet holds a live on-chain position but the deposit/withdrawal history failed to load (empty deposits and empty withdrawals). Previously this state degenerated to reporting the entire position as profit — the 2026-07-09 over-inflation incident. Adds the exported `assertPnlHistoryConsistent` guard and the `AugustHistoryUnavailableError` error class.

</details>
{% endupdate %}

{% update date="2026-07-23" %}

## 8.14.0

{% hint style="info" %}
**Integrator highlights**

* **Breaking:** IVault.fees.isManagementWaived and isPerformanceWaived now return fully-resolved booleans instead of raw backend flags.
* **Action:** Review code reading isManagementWaived or isPerformanceWaived to confirm resolved boolean semantics match your use case.
* **New:** resolveFeeWaived helper function to evaluate fee-waiver state against clock and TVL latch.
* **New:** decodeRevertData, extractRevertFromErrorText, lookupSelector, simulateCall, and readTokenState helpers for transaction failure diagnostics.
* **New:** Non-EVM fee-waiver path now correctly resolves state instead of hardcoding false.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* fae58f3: feat: resolve fee-waiver state in the SDK (AUGUST-5584). `IVault.fees.isManagementWaived` and `isPerformanceWaived` now carry the fully-resolved "show Fee Waived right now?" boolean instead of the raw backend `platform_fee_override.is_fee_waived` flag. Adds the pure helper `resolveFeeWaived(isFeeWaivedToggle, waivedUntilDate, waivedUntilTvl, now?)`: the backend toggle is the master enable and one-way TVL latch (SDK does no TVL math, never reads `latest_reported_tvl`), while the SDK evaluates the date window live against the clock. Also fixes the non-EVM (Solana/Stellar/Sui) mapping path, which previously hardcoded both booleans to `false`. The `*_waived_until_date` / `*_waived_until_tvl` raw fields remain exposed for tooltip rendering. Behavioral change for consumers reading the two booleans — they were unresolved before.
* 70c960b: feat: add revert-decode helpers — `decodeRevertData` (offline decode of `Error(string)`, `Panic(uint256)`, and custom errors against an OZ ERC-6093 / SafeERC20 / LayerZero / vault-ABI corpus, extendable via `extraAbis`), `extractRevertFromErrorText` (recovers revert data, action, code, and transaction fields from an ethers v6 error string, tolerant of truncation), `lookupSelector` (openchain.xyz / 4byte.directory signature lookup for unknown selectors), `simulateCall` (`eth_call` replay that returns fresh, auto-decoded revert data), and `readTokenState` (bounded symbol/decimals/balance/allowance probe set plus issuer compliance getters `isAccountFrozen` / `isBlacklisted` / `isFrozen`). Together these let alert-triage tooling decode why a transaction failed at `estimateGas`, where no transaction hash ever exists.

</details>
{% endupdate %}

{% update date="2026-07-21" %}

## 8.13.0

{% hint style="info" %}
**Integrator highlights**

* **Action:** `getVaultVersion` (V1) is deprecated; migrate to `getVaultVersionV2` for correct multi-asset classification
* **Action:** Static `SWAP_ROUTER_ELIGIBLE_VAULTS` and `isSwapRouterEligible` are deprecated in favor of on-chain resolvers
* **New:** `getSwapRouterEligibleVaults(chainId)` resolves eligible vaults on-chain with 5-min cache
* **New:** `getSwapRouterWhitelistedTokens(chainId)` resolves chain token allowlist by scanning events
* **New:** `SWAP_ROUTER_NAMES` and `getSwapRouterName(chainId)` provide router display names
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 802b24f: feat: add `getSwapRouterEligibleVaults(chainId)` — resolves the SwapRouter's eligible-vault set on-chain (`VaultEnabled` event scan + `vaultInfo.referenceAsset` verification, fail-closed, 5-min cache) on the SDK root and `AugustVaults`; add `SWAP_ROUTER_NAMES` / `getSwapRouterName(chainId)` for the periphery contract's display name ('Upshift Swap Router' on mainnet). Deprecates the static `SWAP_ROUTER_ELIGIBLE_VAULTS` set and `isSwapRouterEligible` (kept functional as zero-RPC fallbacks) in favor of the on-chain resolver.
* b52a1ab: feat: add `getSwapRouterWhitelistedTokens(chainId)` — resolves a chain's SwapRouter token allowlist by scanning `TokenEnabled` events and verifying each against the on-chain `whitelistedTokens` mapping (the mapping is not enumerable). Exposed on the SDK root and the vaults module; lets UIs render swap-and-deposit token options without a hardcoded candidate list.

### Patch Changes

* 823b5d9: deprecate: `getVaultVersion` (V1) is now marked `@deprecated` in favour of `getVaultVersionV2`. V1 classifies multi-asset vaults only against the static `MULTI_ASSET_VAULTS` list, so any vault missing from it is misclassified as `evm-1` (the root cause of the 2026-07-06 Sentora preview/simulation break). `getVaultVersionV2` reads the backend `internal_type` and falls back to the static list only as a safety net. V1 is retained as a non-breaking shim and scheduled for removal in the next major.

</details>
{% endupdate %}

{% update date="2026-07-16" %}

## 8.12.0

{% hint style="info" %}
**Integrator highlights**

* **New:** `getSwapRouterDepositResult` resolves post-execution deposit amount and shares from mined SwapRouter events.
* **New:** `IVaultUserHistoryItem` now exposes `assetIn` and `shares` fields.
* **New:** `SWAP_ROUTER_DEX_AGGREGATOR` includes a `name` field for human-readable aggregator display.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* b3ea699: feat: add `getSwapRouterDepositResult` (and `EVMAdapter.getSwapRouterDepositResult`) to resolve the real, post-execution amount and shares from a mined SwapRouter deposit's own `Deposit` event, instead of relying on the pre-trade quote. Also adds a `name` field to `SWAP_ROUTER_DEX_AGGREGATOR` for displaying the aggregator's human-readable name instead of its address.
* a093373: feat: expose `assetIn` and `shares` on `IVaultUserHistoryItem` — `assetIn` lets consumers render the actual deposited token for multi-asset (pre-deposit) vaults instead of guessing the vault's first deposit asset; `shares` surfaces the receipt-token amount burned on a withdraw request, whose settled asset value isn't known until processing

### Patch Changes

* 6d9738a: refactor: move `getSwapRouterDepositResult` from `modules/vaults/getters` down to `core/helpers/swap-router` to break the `adapters/evm` ↔ `modules/vaults/getters` circular dependency (the repo's zero-cycle CI gate). The symbol is re-exported from its original location, so every existing import path and the public API are unchanged; no behavior change.
* add shares
* 011740e: perf: batch the per-vault `balanceOf`/`lagDuration` reads behind `getVaults({ wallet })` and `getVaultPositions` into chunked Multicall3 `aggregate3` calls, grouped by chain (10 calls per chunk). Enabled only on chains where the canonical Multicall3 deployment was verified on-chain via `eth_getCode` (all `NETWORKS` chains except Citrea 4114, which keeps the per-call path, as do non-EVM vaults) — 15 chains verified 2026-07-14, Tempo verified in a follow-up pass on 2026-07-15. Each batched call uses `allowFailure`, so a single reverting vault (e.g. paused) falls back to its own per-vault reads instead of affecting the rest of the batch — failure behavior is unchanged from the per-call path. No public API change. Measured with `benchmarks/request-counter.js` (cold cache, wallet with 62 vaults across Ethereum + Avalanche): 83 → 54 RPC HTTP requests (\~35% fewer; 124 per-vault `eth_call`s collapse into \~13 aggregated calls). The prefetch's cold-cache receipt-token (`lpTokenAddress`) resolution for evm-2 vaults is capped at 10 concurrent reads per chain, so a wallet with many uncached evm-2 vaults can't burst an unbounded number of simultaneous reads before the batch fires.

</details>
{% endupdate %}

{% update date="2026-07-16" %}

## 8.11.0

{% hint style="info" %}
**Integrator highlights**

* **Action:** Pass optional `sorobanRpcUrl` to `AugustSDK` or `StellarAdapter` to inject a keyed Soroban RPC endpoint.
* **New:** `IVaultUserHistoryItem` now exposes `assetIn` field for multi-asset vault deposits.
* **New:** Stellar adapter supports health-gated RPC failover with optional `sorobanRpcUrl` override on SDK/adapter/per-call.
* **New:** Failover retries idempotent Soroban operations on node-specific simulation errors.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* a093373: feat: expose `assetIn` on `IVaultUserHistoryItem` so consumers can render the actual deposited token for multi-asset (pre-deposit) vaults instead of guessing the vault's first deposit asset
* 84f6a59: feat(stellar): health-gated Soroban RPC failover + optional consumer RPC override (AUGUST-6653)

  The Stellar adapter resolved a single Soroban RPC endpoint and ran every read, transaction build, and submit against it. When that provider node stalled — as `soroban-rpc.mainnet.stellar.gateway.fm` did at the Protocol 27 upgrade boundary, freezing behind the network head so every simulation failed with `setting ContractComputeV0 is not present in the snapshot` — there was no way to route around it, and deposits/reads failed with `AugustSDKError: Soroban simulation failed: …`. (The EVM path already had `FALLBACK_RPC_URLS`; Stellar had none.)

  **Health-gated failover.** `queryContract`, `buildSorobanTx`, and `submitStellarTransaction` now obtain their server from an internal `getHealthyServer`, which probes the configured endpoints in priority order via `getHealth()`, uses the first healthy one, and falls back to the first reachable endpoint (so the caller still surfaces the node's real error) when none report healthy. A malformed configured endpoint (e.g. a typo'd override) is skipped rather than aborting the probe, so a bad primary can't disable every fallback. Mainnet gains `https://mainnet.sorobanrpc.com` as a keyless public fallback. The healthy-endpoint choice is cached \~30s, and concurrent callers on a cold cache share a single in-flight probe (no stampede on the parallel-read hot path).

  **Operation-level failover.** Health-gating only proves an endpoint answered `getHealth()` — a node can still hang or return a method-specific error on the real call, and the choice is cached \~30s. So `queryContract` and `buildSorobanTx` now run their (idempotent) RPC work through a failover wrapper that retries the operation against the remaining endpoints on a retryable failure, time-boxed so a hung node can't stall the call. Crucially, retryable failures include node/snapshot *simulation* errors (e.g. the `… is not present in the snapshot` post-upgrade case): these arrive as a simulation error but are node-specific, so they fail over — only a genuine contract revert (and other deterministic outcomes: unfunded account, archived-state restore) is terminal and never retried across nodes. The wrapper skips the endpoint the health-gated attempt already used (no double timeout; a sole endpoint isn't retried for nothing) and promotes a working fallback into the cache so the next call starts there. During a sustained outage the endpoint set is negative-cached (short TTL) even on the read/build path, so subsequent reads fast-fail on the primary rather than re-probing and re-looping every endpoint per call — the load amplification the negative cache exists to prevent. Submission is deliberately excluded — re-sending a signed transaction across endpoints risks a double-submit, so it needs sequence/DUPLICATE-based idempotency rather than blind retry.

  **Optional consumer RPC override (new, additive API).** Mirroring the existing `solana` config, `new AugustSDK({ stellar: { rpcUrl, network } })` now injects a Soroban RPC endpoint (e.g. a keyed Alchemy URL) — the SDK does not embed any key. The override becomes the primary with the built-in public endpoints kept behind it as failover. Also exposed via the `StellarAdapter` constructor (`new StellarAdapter(network, { sorobanRpcUrl })`), an optional per-call `sorobanRpcUrl` on the deposit/redeem params and the getter/submit functions (a per-call value wins over the adapter-level one), and threaded into the `vaults` module so `getVaults`/`getVaultPositions` Stellar reads honor the override too. All additions are optional — existing callers are unaffected.

  **Log & telemetry safety.** Health-check warnings redact the RPC URL to protocol+host; the analytics sanitizer treats `sorobanRpcUrl`/`rpcUrl` as sensitive *and* scrubs provider path-embedded keys (e.g. Alchemy `/v2/<key>`) from free-form strings and object values (not just named fields); and the failover path scrubs every configured URL from the message and chained `cause` of the error it throws. So a keyed provider endpoint — whether a per-call override captured as an instrumented argument or embedded in an SDK error string — never leaks its API key into SDK logs, telemetry, crash reporters, or a surfaced error.

  RPC cost: adds one lightweight `getHealth` probe before Soroban operations, cached \~30s per endpoint set (keyed by the full ordered list) and de-duped across concurrent callers — not per call.

</details>
{% endupdate %}

{% update date="2026-07-11" %}

## 8.10.0

{% hint style="info" %}
**Integrator highlights**

* **Action:** Check for `ACCOUNT_NOT_FUNDED` error code in write operations to prompt user top-up instead of generic error handling.
* **New:** Write helpers (`vaultApprove`, `vaultDeposit`, `vaultRequestRedeem`, `vaultRedeem`, `depositNative`, `rwaRedeemAsset`) now throw typed `AugustValidationError` with code `ACCOUNT_NOT_FUNDED` for insufficient gas/L1-fee failures.
* **New:** Export `isInsufficientFundsError(error)` classifier to detect insufficient-funds conditions.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* b774e66: feat: classify insufficient-gas/L1-fee failures on vault write paths

  When a chain node rejects a write because the sender can't cover gas — or, on rollups such as Citrea, the extra L1 data-availability fee — ethers v6 surfaces an opaque `CALL_EXCEPTION` / "missing revert data" that was previously wrapped as a generic `UNKNOWN` error and logged as an SDK fault. The real reason lives only in the nested provider error (`error.info.error.message`).

  The write helpers (`vaultApprove`, `vaultDeposit`, `vaultRequestRedeem`, `vaultRedeem`, `depositNative`, `rwaRedeemAsset`) now detect this case and throw a typed `AugustValidationError` with code `ACCOUNT_NOT_FUNDED`, so a consuming UI can branch on `err.code` to prompt the user to top up instead of string-matching. These failures are also demoted in telemetry (breadcrumb, not a billed Sentry issue) since they are a wallet-funding prompt, not a defect.

  Adds an exported `isInsufficientFundsError(error)` classifier for callers that want to detect the same condition directly.

</details>
{% endupdate %}

{% update date="2026-07-11" %}

## 8.9.0

{% hint style="info" %}
**Integrator highlights**

* **New:** `AugustApi` adds `getTimelockRequests`, `getVaultPerformanceFees`, `getVaultOracleClassification` for governance and metrics.
* **New:** `AugustApi` adds `getOtcPositions`, `getOtcMarginRequirements`, `getCuratorVaultSubaccounts`, `getCuratorVaultWhitelist` for OTC and curator operations.
* **New:** `AugustApi` adds `getDashboardLoans`, `getDiscountFactors`, `getCollateralExcessOrDeficit`, `simulateCollateral` for loan-book and risk.
* **New:** `AugustSubAccounts` adds `getSubaccountTransactions`, `getSubaccountLoanByAddress`, `getSubaccountDebank`, and `AugustApi.getRevertReason`.
* **New:** `AugustSubAccounts.getAllSubaccounts` returns paginated directory of all August subaccounts (admin-only).
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 29936be: feat: add governance & metrics read methods to `AugustApi` (`sdk.apiModule`) — `getTimelockRequests` (timelock/governance requests for a vault+chain), `getVaultPerformanceFees` (backend-computed performance fees over a period), and `getVaultOracleClassification` (public NAV-oracle classification table), with `ITimelockRequest`, `IVaultPerformanceFees`, `IOracleClassification`, and `IOracleClassificationRow` response types.
* 29936be: feat: add OTC & curator read methods to `AugustApi` (`sdk.apiModule`) — `getOtcPositions` (all tracked OTC positions), `getOtcMarginRequirements` (margin requirements, optionally filtered by counterparty/payer), `getCuratorVaultSubaccounts` (subaccounts linked to a vault), and `getCuratorVaultWhitelist` (EVM-only on-chain whitelist status), with `IOtcPositionRead`, `IOtcMarginRequirement`, and `ICuratorWhitelistStatus` response types (`getCuratorVaultSubaccounts` reuses `IWSSubaccountListItem`).
* 29936be: feat: add loan-book & risk read methods to `AugustApi` (`sdk.apiModule`) — `getDashboardLoans` (admin-only global loan book), `getDiscountFactors` (token collateral-haircut ladders), `getCollateralExcessOrDeficit` (per-subaccount collateral excess/deficit), and `simulateCollateral` (read-only collateral simulation), with `ILoanBookInfo`, `IDiscountFactorLadder`, `ICollateralExcessOrDeficit`, `ICollateralSimulationInput`, and `ICollateralSimulationResults` response types. `AugustApi` now extends `AugustBase` so it can reach the configured August API key.
* 29936be: feat: add tx-triage & activity read methods — `AugustSubAccounts.getSubaccountTransactions` (authenticated `/transactions/v2`), `AugustSubAccounts.getSubaccountLoanByAddress` (admin-only single-loan detail), `AugustSubAccounts.getSubaccountDebank` (cross-chain DeBank positions), and `AugustApi.getRevertReason` (public transaction revert-reason decode), with `ISubaccountTransaction`, `ILoanBookInfo` (reused), `ISubaccountDebank` / `IDebankAccountData`, and `IRevertReason` response types.
* acf2a4d: feat: add `AugustSubAccounts.getAllSubaccounts` — paginated directory of all August subaccounts (admin-only `GET /subaccount` backend endpoint), with `IWSSubaccountListItem` / `IWSSubaccountListChain` response types

### Patch Changes

* 7c86f9f: fix: register the Monarq XRP Yield Vault (Flare) in `VAULT_ALLOCATION_SUBACCOUNTS` so its Lending Allocation Breakdown and borrower subaccount surface (AUGUST-6485). Covered by a regression test that pins the entry.

</details>
{% endupdate %}

{% update date="2026-07-09" %}

## 8.8.0

{% hint style="info" %}
**Integrator highlights**

* **Action:** Deposit history now resolves decimals from each deposit's `assetIn` token instead of vault decimals; re-fetch and re-render deposit amounts if previously cached.
* **Action:** Native deposits now normalize against 18 decimals via `EVM_NATIVE_DECIMALS` constant; verify rendered native deposit amounts match expected values.
* **New:** Optional `publicApiBaseUrl` in SDK constructor config to override the public vault-catalog API base URL.
* **New:** New `setPublicApiBaseUrl` and `getPublicApiBaseUrl` fetcher overrides following the `timeoutMs` pattern.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 98176f4: feat: allow overriding the `public` vault-catalog API base URL

  Adds an optional `publicApiBaseUrl` to the SDK constructor config (backed by a new `setPublicApiBaseUrl` / `getPublicApiBaseUrl` fetcher override, mirroring the existing `timeoutMs` / `setSdkRequestTimeout` pattern). It repoints the unauthenticated `public` server base — the one `getVault` / `getVaults` / `fetchTokenizedVault` read from via `fetchAugustPublic` — so a non-prod deployment can serve its vault catalog from an isolated backend (e.g. a staging API serving staging-only vaults).

  Defaults to the compiled-in prod base (`https://api.augustdigital.io/api/v1`) when omitted, so production behaviour is unchanged. Invalid or non-http(s) URLs are ignored (warned) so a bad env value can't break fetches.

### Patch Changes

* 13f0dc9: fix: normalize deposit history against the deposited asset's own decimals

  Multi-asset (pre-deposit / evm-2) vaults accept deposit tokens whose decimals differ from the vault share token. User- and vault-history reads tagged every deposit with the vault's decimals, so an 18-decimal RLUSD deposit into the 6-decimal Sentora USD vault rendered \~1e12× too large ("500B TOKEN"). Deposit rows now resolve decimals from their `assetIn` token; single-asset vaults are unchanged.
* a5e4370: fix: normalize native-token subgraph deposits against 18 decimals instead of 0/vault decimals

  Native deposits carry a sentinel `assetIn` (the zero address or the EIP-7528 `NATIVE_ADDRESS`) that has no on-chain `decimals()`. `getDecimals(ZeroAddress)` returned `0` (which the `?? decimals` fallback can't override) and `getDecimals(NATIVE_ADDRESS)` reverted to the vault's decimals — either could misrender a native deposit's amount by up to \~1e18×. `buildDepositAssetDecimals` now maps both sentinels to the new `EVM_NATIVE_DECIMALS` (18) constant.

</details>
{% endupdate %}

{% update date="2026-07-09" %}

## 8.7.2

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 64d4e2b: Add Tempo network configuration and RPC URL

</details>
{% endupdate %}

{% update date="2026-07-08" %}

## 8.7.1

{% hint style="info" %}
**Integrator highlights**

* **Action:** Provide subgraph URLs via backend vault metadata instead of relying on SDK URL fabrication.
* **Action:** Non-EVM vaults (Solana/Stellar) now correctly skip EVM subgraph routing and no longer fail on history fetch.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 62c42c2: fix: stop fabricating dead subgraph URLs and stop routing non-EVM vaults through the EVM history path

  Two fixes surfaced while debugging missing Citrea vault data:

  1. `getDefaultSubgraphUrl` no longer fabricates a Goldsky URL from the chain name and vault symbol. That guess was unreliable — the chain name isn't the subgraph slug (ethers reports Citrea as `unknown`), a vault's symbol isn't its subgraph name (`EctUSD` vs `earn-ctusd`), and the path used a legacy hosted-service segment. The bogus URL 404'd silently, so a missing subgraph read as "no data". It now returns `undefined`, so callers hit their existing "Missing Subgraph" branch (warn + alert). Subgraph URLs must come from backend vault metadata. That alert branch was previously unreachable (the fabricated URL was always truthy); it is now deduped per pool so a metadata-less vault surfaces once rather than flooding the webhook on every read.
  2. `getUserHistory` and `getSubgraphUserHistory` no longer route non-EVM (Solana / Stellar) vaults into the EVM subgraph path. The Solana RPC is registered under chainId -1, so Solana vaults previously passed the provider filter and triggered `eth_chainId` against the Solana RPC, failing with "eth\_chainId is not available on SOLANA\_MAINNET" on every history fetch. Both the dispatch filter and the function now gate on an EVM address.
* e8b862a: fix: detect subgraph schema at runtime so History and Pending Withdrawals populate for every vault

  Subgraph reads chose their field schema (old snake\_case vs new camelCase) from whether the vault symbol appeared in the deprecated `SUBGRAPH_VAULT_URLS` map. A newly-added vault whose subgraph was deployed from the old template (e.g. `august-citrea-earn-ctusd`) is absent from that map, so the SDK queried new-schema field names (`blockNumber`/`blockTimestamp`/`transactionHash`) the subgraph does not expose. The subgraph returned GraphQL errors with no `data`, and the reads collapsed to empty — silently emptying the Portfolio's Pending Withdrawals and History tabs while the vault, provider and RPC were all healthy.

  The schema is now probed once per subgraph URL (`resolveSubgraphSchema`, cached) and drives the field selection in every subgraph read — withdrawal requests, processed withdrawals, combined withdrawals, user history, and vault history. Across a page's reads this adds at most one lightweight query per subgraph; the result is transparent to callers, which continue to see the internal (snake\_case) shape.

</details>
{% endupdate %}

{% update date="2026-07-08" %}

## 8.7.0

{% hint style="info" %}
**Integrator highlights**

* **Breaking:** vaultDeposit no longer routes through SwapRouter; use swapRouterDeposit for swap-based deposits.
* **Breaking:** VAULTS\_USING\_SWAP\_ROUTER renamed to SWAP\_ROUTER\_ELIGIBLE\_VAULTS; vaultUsesSwapRouter renamed to isSwapRouterEligible.
* **Action:** Migrate from deprecated VAULTS\_USING\_SWAP\_ROUTER and vaultUsesSwapRouter to new names before next major version.
* **Action:** Re-quote and call swapRouterDeposit if you were relying on implicit SwapRouter routing via vaultDeposit.
* **New:** New swapRouterDeposit method for explicit SwapRouter deposit routing with asset path selection.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 1d92be0: feat(swap-router): add explicit `swapRouterDeposit` deposit method

  New high-level method `augustSdk.evm.swapRouterDeposit(options)` (and the standalone `swapRouterDeposit(signer, options)` export) that always routes a deposit through the on-chain `SwapRouter`, reading the vault's reference asset and decimals on-chain and picking the correct path from `depositAsset` (direct deposit, native wrap, or a swap to the reference asset with a fail-closed aggregator quote).

  This gives the client an explicit opt-in to SwapRouter deposits instead of depending on `vaultDeposit`'s implicit `VAULTS_USING_SWAP_ROUTER` allowlist routing — the mechanism that accidentally swapped a native-deposit multi-asset vault (Sentora USD). `vaultDeposit` is unchanged; use it for native/adapter deposits and `swapRouterDeposit` for SwapRouter deposits.
* 282dc2b: feat: expand the MCP server into a fuller read/analytics suite (19 new tools)

  **SDK** — new `getVaultActivity({ vault, chainId, sinceTs, untilTs, types })`: the vault-wide counterpart to `getVaultUserHistory`, returning every deposit/withdrawal event for a pool (not scoped to one wallet). Its subgraph reader now paginates past the 1000-row page cap and stops early once it pages past the `sinceTs` window, so busy vaults are no longer silently truncated.

  **MCP** — 19 new tools:

  * Activity/flow: `vault_activity` (per-vault flow feed + computed summary: deposit/withdrawal counts, volumes, net flow, unique actors), `activity_ranking` ("which vaults had the most deposits last week"), `user_activity`, `user_transfers`.
  * Reads: `total_deposited`, `token_price`, `vault_withdrawals`, `vault_pnl`, `vault_annualized_apy`, `withdrawal_requests_status`.
  * Subaccounts: `subaccount_summary`, `subaccount_health_factor`, `subaccount_loans`, `subaccount_cefi_positions`, `subaccount_otc_positions`.
  * Ops: `ops_health`, `ops_redemptions` (parity with the `august ops` CLI).
  * LayerZero: `layerzero_deposits`, `layerzero_redeems`.

  **config** — new Zod result schemas backing all of the above.
* ef0bdf6: feat(swap-router): fully separate SwapRouter routing from `vaultDeposit`

  `vaultDeposit` no longer auto-routes any vault through the SwapRouter — it is now purely the native / multi-asset / adapter path. This removes the implicit, registry-driven routing that could silently swap a natively-accepted asset (e.g. depositing RLUSD/PYUSD/USDT into the multi-asset Sentora USD vault, or forcing a non-underlying token through a swap). Any-token swap deposits are the explicit, opt-in job of `swapRouterDeposit`.

  The registry is now eligibility metadata, not a routing switch:

  * `VAULTS_USING_SWAP_ROUTER` → renamed `SWAP_ROUTER_ELIGIBLE_VAULTS`
  * `vaultUsesSwapRouter` → renamed `isSwapRouterEligible`

  Both old names remain as `@deprecated` aliases for one release. The set now marks vaults whose UI may offer the (opt-in) swap-router deposit surface — consumed by app UIs and, optionally, by `swapRouterDeposit` as a fail-fast check — and is **never** read by `vaultDeposit`. Sentora USD is the initial eligible vault; its native assets still deposit via `vaultDeposit`, only foreign tokens route through `swapRouterDeposit`.

### Patch Changes

* 3f74779: fix(solana): surface the real Anchor revert reason in deposit/redeem errors

  `handleSolanaDeposit` / `handleSolanaRedeem` built their wrapped error from `e instanceof Error ? e.message : 'Unknown error'`. When an Anchor program reverts with a recognized error code, `@coral-xyz/anchor`'s `translateError` returns a `ProgramError` whose constructor calls `super()` with no argument — so `.message` is the empty string by construction (the real reason lives on `.msg`/`.code`, and `AnchorError` puts it on `.error.errorMessage`/`.error.errorCode.number`). Every recognized on-chain revert therefore surfaced — and paged Slack — as `"Solana deposit failed: "` with nothing after the colon, discarding the numeric code needed to tell `VaultPaused` (6008) from `InsufficientAmount` (6002) from an account-constraint violation.

  Both catch blocks now route the caught error through a new `describeSolanaError` helper that prefers `AnchorError.error.errorMessage`/`errorCode.number`, then `ProgramError.msg`/`code`, then a non-empty `.message`, then `.toString()`, and only falls back to an actionable `"please try again"` for a genuinely reason-less throwable (rather than an "unknown error" admission to the user; the raw throwable is still preserved on `cause` and in telemetry). The message becomes e.g. `Solana deposit failed: Vault is paused (code 6008)`. `cause` and structured `context` on the thrown `AugustSDKError` are unchanged; no public API changes.

</details>
{% endupdate %}

{% update date="2026-06-30" %}

## 8.6.1

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 543442d: fix: show pending withdrawals for new-schema vaults (e.g. Clearstar Prism)

  `getWithdrawalRequestsWithStatus` prunes requests outside a block-based lookback window via `Number(req.block_number) >= blockCutoff`. New-schema subgraphs expose the block height as `blockNumber`, but `NEW_WITHDRAWALS_REQUESTED_QUERY_PROPS` returned it un-aliased, so `req.block_number` was `undefined`, `Number(undefined)` was `NaN`, and `NaN >= blockCutoff` dropped every request. The endpoint returned `[]`, silently emptying the Pending Withdrawals tab for every vault on the new subgraph schema (any metadata-sourced vault not in the legacy `SUBGRAPH_VAULT_URLS` list) — while transaction history, which is sourced independently, still listed the redeem.

  The new-schema withdrawal query props now alias `block_number: blockNumber`, matching the existing aliasing used for `transactionHash_`/`timestamp_` (and already applied in the transfer props). The aliases on the processed/withdrawals prop sets are not read today but are added for consistency with the shared `ISubgraphBase` contract to prevent the same `NaN` prune recurring. No public API or thrown-error behaviour changes.
* a5dd13b: fix: reduce Sentry transaction volume and fix data quality issues in analytics instrumentation
  * Reduce default `tracesSampleRate` from `1.0` to `0.1` — captures a statistically valid 10% sample while cutting transaction event volume by \~90%
  * Remove `captureConsoleIntegration` — SDK errors already route through `Logger.setSentrySink`; the integration was redundantly capturing consumer app `console.error` calls as SDK error events
  * Add `beforeSendTransaction` sub-sampling for the `network` category (switchNetwork, updateWallet, clearWallet, setSigner) — these fire on every wallet/chain update and are high-frequency relative to their dashboard signal value; effective rate drops to \~1% of calls
  * Remove redundant `setTag` calls for `sdk.category`, `sdk.chain`, and `sdk.last_chainId` from `trackMethodCall` — these values are already recorded as span attributes; the global mutations were contaminating subsequent unrelated events with stale tag values
  * Remove `setMeasurement` calls from the sync method tracking path — sync methods have no span of their own, so measurements were attaching to a random parent transaction and overwriting its counters
* 14c56ca: fix: stop billing user-rejected transactions and expected on-chain reverts as Sentry issues

  Wallet user-rejections (deposit/redeem/approve) and routine read reverts (probing a function a vault doesn't implement) were logged at `error` level, turning normal product behaviour into high-volume billed Sentry issues. They are now classified via a new `isUserRejectionError` / `isExpectedRevertError` helper and demoted to `warn` (Sentry breadcrumbs, not issues); genuine failures are unchanged and still surface as errors. A narrow `ignoreErrors` backstop also drops user-rejection and localhost-node (`:8545`) noise at the transport. No public API or thrown-error behaviour changes.

</details>
{% endupdate %}

{% update date="2026-06-24" %}

## 8.6.0

{% hint style="info" %}
**Integrator highlights**

* **Action:** Update code using `getVaultTvl` — it now returns assets under management, not share count.
* **Action:** Check `fetchTokenPricesFromCoinGecko` for typed errors: `AugustValidationError` for unmapped symbols, `AugustRateLimitError` for 429 responses.
* **Action:** Verify archived-vault user history calculations; deposit asset decimals now propagate through PnL correctly.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 15c99c1: feat: serve user history for archived vaults from the backend Mongo snapshot

  `getVaultUserHistory` / `getSubgraphUserHistory` now route archived vaults to the backend `/upshift/vault_history` REST endpoint instead of their Goldsky subgraph, so deposit/withdraw history survives retiring those subgraphs. The archived set is fetched from the backend (`fetchArchivedVaults`, cached) — the routing source of truth — so a vault is only rerouted once its history has been backfilled. Adds `fetchArchivedVaults` and async `isArchivedVault`, plus the `tokenizedVault.userHistory` / `tokenizedVault.archivedVaults` endpoints. Return shape (`ISubgraphUserHistoryItem`, types deposit / withdraw-processed / withdraw-request) is unchanged.
* cd53624: feat(stellar): classify unfunded Stellar accounts under a dedicated `ACCOUNT_NOT_FUNDED` error code (AUGUST-6468)

  When a Soroban deposit/redeem targets a source account that has never been activated, `buildSorobanTx` now throws an `AugustValidationError` with the new `ACCOUNT_NOT_FUNDED` code instead of the generic `INVALID_INPUT`. This is an expected, user-actionable condition (the address just needs ≥1 XLM), so giving it its own code lets it group on its own key in telemetry rather than spamming the generic-error alert bucket. The remediation message and structured context (`sourceAddress`, `method`, `contractId`, original error as `cause`) are unchanged.

  `ACCOUNT_NOT_FUNDED` is added to the exported `AugustErrorCode` union and to the codes accepted by `AugustValidationError` — additive, so existing consumers narrowing on `AugustErrorCode` are unaffected.
* 5f47a00: fix(swap-router): pin ParaSwap to a single contract method and fail closed on router/selector drift

  `vaultDeposit` through the SwapRouter now constrains ParaSwap to one generic contract method (`swapExactAmountIn`) via the `/prices` `includeContractMethods` filter, so the resulting calldata's selector is deterministic. After fetching the quote it asserts the quote's `router` and payload selector match the new `SWAP_ROUTER_DEX_AGGREGATOR` entry for the chain, throwing a clear `AugustValidationError` instead of letting the deposit revert on-chain with `InvalidRouter()` / `InvalidNotWhitelisted()`.

  Adds the exported `SWAP_ROUTER_DEX_AGGREGATOR` constant (the single source of truth tying the off-chain swap-leg builder to the on-chain router whitelist) and an optional `contractMethod` field on `fetchSwapQuote`'s request.
* 93a983c: feat: surface per-reward backend logos via `additionalPointsDetailed`

  `getVaultRewards` now emits `additionalPointsDetailed` on `IVaultRewards`, pairing each reward's display label with its backend-provided `img_url`. Consumers can resolve a reward's logo from this `imgUrl` first and fall back to a bundled asset only when absent — so a newly-added reward with a backend logo (e.g. "Cores") renders its icon without any client-side keyword mapping. Adds the `IVaultRewardDetail` type, which carries the reward's stable `id` as the join key (labels are display-only and not guaranteed unique).

### Patch Changes

* 34dc7c6: chore: bump TypeScript `target`/`lib` to es2022 so modern APIs (e.g. `Object.hasOwn`) type-check. Emitted output now targets es2022 — requires Node 16.9+ / modern browsers.
* 1b106e7: fix(coingecko): surface typed errors for unmapped symbols and non-2xx responses

  `fetchTokenPricesFromCoinGecko` previously silently returned `null` for every failure, making rate-limits and server errors indistinguishable from "no price data". Two latent defects fixed:

  * Unmapped symbols now throw `AugustValidationError` (`INVALID_INPUT`) before any network call is made, avoiding a wasted round-trip with `"undefined"` in the URL.
  * A 429 response now throws `AugustRateLimitError`; any other non-2xx throws `AugustServerError`. JSON parse errors and network-level failures continue to return `null` (unchanged).
* 4db12d7: chore: resolve biome and tsdoc lint warnings in `core/fetcher.ts` and `core/helpers/core.ts` — replace `any` with `unknown`/generics, use template literals and `Date.now()`, drop non-null assertions and unused catch bindings, and add the missing `@param` hyphens. No behavior change.
* b9b59c4: fix: carry the deposit asset (`assetIn`/decimals) through archived-vault history so mixed-decimal pre-deposit vaults compute lifetime PnL correctly. Without it, an 18-decimal deposit (e.g. USDS) into a 6-decimal-vault was normalized at the vault's decimals, inflating the cost basis \~1e12 and showing -100% / multi-billion PnL.
* 50a29b4: fix: archived-vault user history now sorts ascending by timestamp (matching the subgraph path's ordering contract) and drops rows with an unparseable timestamp instead of emitting a "NaN" stamp
* 34dc7c6: fix: drop unused `@ts-expect-error` in Buffer polyfill; use `globalThis` cast instead of bare `global`
* 03ba56b: docs(readme): fix broken quick-start snippet and sub-accounts accessor in the package README

  The `@augustdigital/sdk` package README (rendered on npmjs.com and bundled in the tarball) used a named import `import { AugustSDK } from '@augustdigital/sdk'`, but the package only exposes `AugustSDK` as a default export — so the copy-pasted snippet resolved to `undefined` and `new AugustSDK(...)` threw. Switched to the default import `import AugustSDK from '@augustdigital/sdk'`.

  Also corrected the Sub-Accounts section heading from `sdk.subaccounts` (a private field) to the public accessor `sdk.subAccountsModule`.
* a8a9c74: fix: correct vault LP share-price math and `round()` on bigints
  * `fetchTokenPrice` computed a vault LP token's share price by integer-dividing the raw `totalAssets`/`totalSupply` bigints, which floored a \~1.05 ratio to `1` and re-normalized it to \~1e-18 — collapsing the LP price to \~0 (and throwing on a zero-supply vault). Share price is now derived from the normalized values.
  * `round()` threw `TypeError` when called on a `bigint` without an options object, because the bigint branch read `options.decimals` instead of `options?.decimals`. It now falls back to the default decimals as documented.
* c2cfd5c: fix: correct current-TVL value, loan-cache staleness, and the musd CoinGecko price
  * `getVaultTvl` (current/non-historical path) returned the vault's `totalSupply()` (shares minted) instead of assets under management. It now reads `getTotalAssets()` (evm-2) / `totalAssets()` (v1), matching the historical path. TVL is no longer understated by the share-price ratio.
  * `fetchTokenizedVaultLoans` / `fetchTokenizedVaultSubaccountLoans` read the shared LRU cache twice (`if (CACHE.get(key)) loans = CACHE.get(key)`). Because the cache allows stale reads and deletes a stale entry on first `get`, a stale hit returned `undefined` instead of refetching. They now use `getSafeCache`/`setSafeCache`, which refetch on expiry like the rest of the SDK.
  * `fetchTokenPricesFromCoinGecko` returned a nested tuple (`[['…', 1]]`) for the `musd` (mezo-usd) stablecoin while every other branch returns a scalar, yielding `NaN` (or a non-number "price") downstream. It now returns the scalar peg `1`.
* 093f09d: fix(stellar): surface the decoded Soroban transaction result code on submit failures (AUGUST-6412)

  `submitStellarTransaction` now decodes the transaction-level XDR result-code discriminant (e.g. `txBadSeq`, `txTooLate`) and attaches it as `resultCode` on both the thrown `AugustSDKError` context and the error log — on the send-time `ERROR` path and the confirm-time `FAILED` path. Previously the reason was only available buried inside the stringified XDR in the error message.

  Decoding is best-effort: if the RPC result is not a decoded union, `resultCode` is omitted (`undefined`) and the error still carries the stringified XDR, so the message text is unchanged. As a side effect of the refactor, the failure-detail guard changed from key-presence (`'errorResult' in sendResult`) to truthiness — a present-but-falsy result now yields an empty detail (the message falls back to the status) instead of the literal `"null"`.

  No public API surface changes.
* b57c70c: chore: resolve biome and tsdoc lint warnings in `modules/vaults/getters.ts` and `services/coingecko/fetcher.ts` — type the `poolTotalSupply` locals and `defiPerBorrower`/`renderStatus`/CoinGecko response shapes instead of `any`, initialize the redemption-date locals, drop non-null assertions, switch to optional chaining, and fix the `@param` hyphens, `{@link}` throws tags, and a brace-laden `@returns`. No behavior change.

</details>
{% endupdate %}

{% update date="2026-06-18" %}

## 8.5.0

{% hint style="info" %}
**Integrator highlights**

* **New:** CROSS\_CHAIN\_VAULT\_CONFIGS registry exports August LayerZero OVault deployments by address.
* **New:** getCrossChainVaultConfig, isCrossChainVault, getOVaultChains, isHubOnlyReceipt, getWithdrawDestinationChains helpers resolve cross-chain vault configuration.
* **New:** Pass ICrossChainVaultConfig directly to crossChainVaultDeposit and quoteCrossChainDeposit instead of assembling per-chain maps.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 621e098: feat(evm): add cross-chain OVault vault registry + resolver helpers

  Adds an address-keyed registry (`CROSS_CHAIN_VAULT_CONFIGS`) of August's LayerZero OVault deployments plus `getCrossChainVaultConfig`, `isCrossChainVault`, `getOVaultChains`, `isHubOnlyReceipt`, and `getWithdrawDestinationChains`. Consumers can now resolve a full `ICrossChainVaultConfig` by vault address — and pass it straight to `crossChainVaultDeposit` / `quoteCrossChainDeposit` — instead of hand-assembling per-chain contract maps and LayerZero EIDs. Mirrors the SwapRouter registry pattern.

</details>
{% endupdate %}

{% update date="2026-06-18" %}

## 8.4.0

{% hint style="info" %}
**Integrator highlights**

* **Action:** Review `getVaults` behavior — closed vaults are excluded by default; pass `includeClosed: true` for portfolio/position-tracking use cases.
* **New:** New `AugustApi` backend module with `getVaultUnrealizedPnlHistory()` and `getLatestUnrealizedPnl()` methods.
* **New:** `getVaults` now accepts optional `includeClosed` flag to include closed vaults in results.
* **New:** Published type declarations now include full TSDoc and exclude `@internal` helpers from autocomplete.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 70e1792: feat: new `AugustApi` backend module — `sdk.apiModule` (methods also exposed directly on `AugustSDK`) for backend-computed data with no on-chain equivalent:

  * `getVaultUnrealizedPnlHistory({ vault, limit? })` — a vault's unrealized-PnL snapshot series, newest first.
  * `getLatestUnrealizedPnl()` — the most recent unrealized-PnL snapshot for every tracked vault.

  Both methods hit the public (unauthenticated) August API with exactly one HTTPS request and no RPC calls, validate inputs up front (`AugustValidationError`), throw typed errors on HTTP failures and response-contract mismatches, and return camelCased `IUnrealizedPnlSnapshot` objects.
* 8191dc7: feat: `getVaults` gains an opt-in `includeClosed` flag for portfolio use. By default `getVaults` excludes closed vaults, so marketplace/discovery callers never receive a `status: 'closed'` vault and don't have to filter it out themselves. When `includeClosed: true` is passed, closed vaults are returned (regardless of `is_visible`, since closed + invisible vaults bucket as closed) so a consumer joining user positions can render a position held in a closed vault. In that mode, loans/allocations enrichment is also skipped for closed vaults — they have none, and `getVaultAllocations` otherwise re-throws (no debank data / no subaccounts), which previously dropped the vault into the `failed` bucket and silently removed it from the result. Additionally, `includeClosed` now propagates down to the per-vault EVM getter (`getEvmVaultV1`/`getEvmVaultV2`), which otherwise returns `null` for any `status: 'closed'` + `is_visible: false` vault ("skip closed staging vaults") — that null caused `getVault` to return null and the vault to vanish from `getVaults` even with the closed bucket spread in. With `includeClosed`, closed + invisible vaults resolve their metadata. Active vaults are always fully enriched and unaffected.
* 1e1d1b1: feat: trim `@internal` helpers from the published type surface and restore TSDoc in published declarations
  * `package.json#types` now points at an api-extractor rollup (`lib/sdk.d.ts`) that omits every export tagged `@internal` (`safeBigInt`, `safeSendTx`, `safeWaitForTx`, `tryRecoverTxHash`, `resolveSpender`, `validateAmountPrecision`, and friends) so they no longer appear in integrator autocomplete or type resolution from the package root.
  * The SDK build no longer strips comments from emitted output, so the published `.d.ts` carries the full TSDoc — editors now show hover documentation for every public method.
  * Runtime exports are unchanged and deep `lib/**` imports still resolve; this is a types-surface change only. `walletClientToSigner` intentionally remains public until the viem-native signer path ships.
  * CI fails if an `@internal` export reappears in the public types (`scripts/check-internal-dts.mjs`).

### Patch Changes

* db5a53a: fix: Phase-2 review hardening
  * `@augustdigital/config`: result-schema `address` fields now accept Stellar (`G…` account / `C…` contract) addresses, matching the SDK and backend address contract — previously a Stellar vault passed input validation but failed output-schema validation with a misleading `SCHEMA_MISMATCH`.
  * `@augustdigital/mcp`: address validation now accepts Stellar `C…` contract addresses (parity with the SDK's `isStellarAddress`), and the HTTP transport compares bearer tokens in constant time via `crypto.timingSafeEqual`.
  * `@augustdigital/sdk`: the unrealized-PnL response guard validates every required snapshot field — including the numeric monetary fields — so backend contract drift throws a typed `AugustServerError` instead of silently emitting `undefined` PnL values.

</details>
{% endupdate %}

{% update date="2026-06-17" %}

## 8.3.2

{% hint style="info" %}
**Integrator highlights**

* **New:** Add `apyOverride` and `website_url` fields to vault types.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 572b363: feat: add apyOverride and website\_url fields to vault types

</details>
{% endupdate %}

{% update date="2026-06-17" %}

## 8.3.1

{% hint style="info" %}
**Integrator highlights**

* **New:** Add `apy_override` field to `ITokenizedVault` and `website_url` to `ITokenizedVaultStrategist`.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* a7077e3: feat: add `apy_override` field to `ITokenizedVault` and `website_url` to `ITokenizedVaultStrategist`

</details>
{% endupdate %}

{% update date="2026-06-16" %}

## 8.3.0

{% hint style="info" %}
**Integrator highlights**

* **Action:** IStellarUserPosition gains optional `decimalsFromFallback?: boolean`; callers sizing a redeem must refuse to settle when it is `true`.
* **Action:** Stellar Soroban transactions now use a 10-minute validity window anchored to network time, reducing `txTOO_LATE` errors on slow signers.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* ee58832: feat(telemetry): forward SDK-internal logs to Sentry in production

  `initializeSentry` now bridges the SDK's `Logger` to the resolved Sentry SDK. `Logger.log.error` is captured as a sanitized Sentry issue (the call-site label becomes the `sdk.origin` tag; structured context becomes scope extras), and `Logger.log.warn` is recorded as a `warning`-level breadcrumb that rides along with the next captured event.

  Previously these were no-ops in production unless an integrator manually wired a logger, so the SDK's own diagnostics never reached the partner-usage dashboard. The bridge is installed only when analytics is enabled (it respects every existing disable path — `analytics.enabled: false`, `AUGUST_SDK_DISABLE_ANALYTICS`, dev/test `NODE_ENV`, and localhost), never throws back into the caller, and is cleared by `resetAnalytics()`. The integrator-pluggable `Logger.setLogger` / `Logger.setStructuredLogger` slots are unchanged.
* 908c2c4: fix(stellar): anchor Soroban tx timebounds to the network clock and widen the validity window to 10 minutes (AUGUST-6386)

  Stellar Soroban deposit/redeem transactions could fail with `txTOO_LATE` after signing. `buildSorobanTx` stamped the transaction's `maxTime` from the signer's local clock via `.setTimeout(120)`, so:

  * a device clock lagging behind network time built an already-expired transaction, and
  * slow / asynchronous signing paths (hardware wallets, institutional approval flows) could not complete within the 120-second window.

  Changes:

  * `maxTime` is now anchored to the **network** clock. `buildSorobanTx` reads the latest ledger close time (`getLatestLedger` → `getLedgers().latestLedgerCloseTime`) and builds the tx with `setTimebounds(0, networkCloseTime + TX_TIMEOUT_SECONDS)`, immunizing the deadline against signer clock skew. The network read runs in parallel with the account fetch (no added latency) and falls back to the previous local-clock `setTimeout` window on any RPC failure, so it never regresses.
  * `TX_TIMEOUT_SECONDS` raised from 120 to 600 (10 minutes) to cover slow/async signing while staying within the Soroban footprint/ledger-entry TTL.

  No public API surface changes. The read-only `queryContract` path is unaffected.
* 15a6fcf: fix(stellar): surface a `decimals()` read failure on `getStellarUserPosition` instead of silently falling back to 7

  `getStellarUserPosition` reads `balance()` and `decimals()` in parallel. When `decimals()` failed but `balance()` succeeded, it returned a confident `{ shares, decimals: 7 }` indistinguishable from a genuine 7-decimal vault. A consumer sizing a `redeem` against an ERC4626 offset vault (share decimals = asset + offset, e.g. 13) would then under-redeem by `10^offset` — a silent money-correctness gap (AUGUST-6381, follow-up to AUGUST-6380).

  `IStellarUserPosition` now carries an optional `decimalsFromFallback?: boolean` (optional for source back-compat — existing consumer object literals still compile — but always populated by `getStellarUserPosition`). It is `true` when `decimals` is the fallback (the on-chain read failed) and `false` when it is the authoritative on-chain value. Callers that size a redeem MUST refuse to settle when it is `true` rather than trusting `decimals`. The SDK's own `getVaultPositions` now treats a fallback-decimals position as a failed read and reports a zero balance instead of a mis-scaled one. No change to the `null`-on-balance-failure behavior.

### Patch Changes

* d548100: chore: migrate tooling to Biome (lint + format) and add Knip (dead-code/unused-deps)

  Replaces ESLint + Prettier + oxlint with [Biome](https://biomejs.dev) for linting and formatting, and adds [Knip](https://knip.dev) for unused-file/dependency detection (report-only baseline). A minimal ESLint config is retained solely to run `eslint-plugin-tsdoc` (`pnpm lint:tsdoc`), which Biome has no equivalent for. Inline `// eslint-disable` directives that referenced now-Biome rules were translated to `// biome-ignore` / `// biome-ignore-all`. No runtime behavior or public API change.
* 769c982: refactor(logging): route remaining console.\* calls through Logger

  Swept the last non-Solana `console.{log,warn,error}` sites onto `Logger.log.{info,warn,error}`, each tagged with its originating function: `core/fetcher.ts`, `core/helpers/web3.ts`, `core/base.class.ts`, `adapters/sui/getters.ts`, and `modules/vaults/fetcher.ts`. Combined with the Logger→Sentry bridge, these diagnostics are now sanitized and (in production) forwarded to Sentry instead of leaking to the integrator's console.

  The `no-console` ESLint rule is tightened to flag every console method (previously `warn`/`error` were allowed). The logger module — the dev-mode floor (`core/logger/index.ts`) and the Slack transport (`core/logger/slack.ts`, which cannot import `Logger` without a cycle) — is exempted, and a few deliberately integrator-facing notices (the version-update nudge and the `override` deprecation warning) keep `console.warn` behind documented inline exceptions.

</details>
{% endupdate %}

{% update date="2026-06-10" %}

## 8.2.0

{% hint style="info" %}
**Integrator highlights**

* **Action:** Indexers watching vaults now in `VAULTS_USING_SWAP_ROUTER` must also index SwapRouter events (`Deposit`, `SwapExecuted`, etc.) as vault-direct deposit events no longer fire.
* **Action:** Call `vaultDeposit` with `slippageBps` option to override the default 1% slippage on SwapRouter-routed deposits.
* **New:** `EVMAdapter` gains `swapAndDeposit`, `depositViaSwapRouter`, and `depositNativeViaSwapRouter` for single-call swap-and-deposit flows.
* **New:** New `fetchSwapQuote` function builds calldata for the SwapRouter swap leg; results include `fetchedAt` for staleness detection.
* **New:** New `IContractWriteOptions.receiver` lets callers mint vault shares to an address other than `wallet`.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 0070001: feat: SwapRouter integration for vault deposits (AUGUST-5475).

  Adds the on-chain `SwapRouter` periphery contract to the SDK so users can deposit any whitelisted ERC-20 (or native ETH) into any opted-in August vault via a single atomic call. The SwapRouter swaps the input to the vault's reference asset and forwards the proceeds to the vault's deposit interface, normalizing ERC-4626 (v1/v3) and multi-asset (v2) flows behind one entry point.

  ### New public surface

  * New methods on `EVMAdapter`: `swapAndDeposit`, `depositViaSwapRouter`, `depositNativeViaSwapRouter` (all in `modules/vaults/write.actions.ts`). Each handles approval automatically against the SwapRouter as spender and returns the resulting tx hash.
  * New public function `fetchSwapQuote` in `services/swap-quotes` builds the calldata needed for a SwapRouter swap leg. v1 uses Paraswap; the result is shaped so 1inch/0x can be added later without breaking callers. Results include `fetchedAt` so UI integrators can detect stale quotes.
  * `vaultDeposit` now routes through the SwapRouter automatically when the target vault is in `VAULTS_USING_SWAP_ROUTER` and the chain has a registered router. The existing call signature is unchanged. New optional `IContractWriteOptions.receiver` lets callers mint shares to a different address than `wallet` (treasury / cold-storage flows).
  * New per-chain constants: `SWAP_ROUTER_ADDRESSES` (Ethereum mainnet: `0xAC771209FF2b71EECfF6E85a9AD01db8Ff2618B0`), `SWAP_ROUTER_WRAPPED_NATIVE` (mainnet: WETH), and `SWAP_ROUTER_MAX_SWAPS` (mirrors the on-chain `MAX_SWAPS = 9`). New vault opt-in set `VAULTS_USING_SWAP_ROUTER` and `ORIGIN_CODES` registry for partner/referral fee tracking.
  * New types: `ISwapParams`, `ISwapAndDepositOptions`, `ISwapRouterDirectDepositOptions`, `ISwapRouterNativeDepositOptions`, `SwapRouterVaultType` (values `1` for ERC-4626, `2` for TokenizedVaultV2 — mirrors the on-chain constants).
  * New ABI `ABI_SWAP_ROUTER`.

  ### Safety hardening (vs. naive integration)

  * Per-leg `ISwapParams` validation rejects `amountIn === 0n`, `minAmountOut === 0n` (slippage off), `tokenIn === tokenOut`, malformed router/payload at the SDK boundary.
  * `slippageBps` accepts `[0, 10_000)` — `10_000` (100% slippage = no protection) is rejected.
  * `originCode` must be a 32-byte hex string; the SDK throws a typed `AugustValidationError` instead of waiting for the on-chain `InvalidOrigin` revert.
  * Paraswap response shape is validated end-to-end: `priceRoute.destAmount` must be a numeric string, `to` must be a valid address, `data` must be hex calldata with at least a 4-byte selector.
  * Vaults in `VAULTS_USING_SWAP_ROUTER` cannot silently fall through to the legacy adapter path. If the chain has no SwapRouter deployed, or `chainId` cannot be resolved, the SDK throws `AugustValidationError('INVALID_CHAIN')` — never routes through the MEV-vulnerable legacy `minAmountOut: 0` path.
  * `isDepositWithPermit: true` on a SwapRouter-routed vault throws rather than silently dropping the permit signature.
  * Native ETH deposits target only vaults whose reference asset equals the chain's wrapped-native token; other configurations throw with actionable guidance.
  * `swapAndDeposit` strictly requires `signer.getAddress()` to return a valid EOA (no silent fallback to receiver). Smart-account integrators (Safe, ERC-4337) should be aware that the SwapRouter pulls from `msg.sender`, not the controlling EOA — for those flows the SDK currently expects the smart account itself to be the signer's address.
  * Paraswap quote fetches accept an optional `AbortSignal` for cancellation/timeout.

  ### Coexistence with legacy adapters

  Legacy adapter paths (Treehouse, Kelp, AVAX native, Paraswap `UniversalAdapter` for non-opted-in vaults) continue to work unchanged. The two systems coexist; vaults will converge onto the SwapRouter in follow-up PRs.

  ### Deployment checklist (operator)

  Before adding a vault to `VAULTS_USING_SWAP_ROUTER`, the contract owner must complete the following on the SwapRouter (`0xAC77…18B0` on mainnet):

  1. `enableVault(vaultAddr, vaultType, swapFee)` — register the vault with the correct `vaultType` (1 for ERC-4626, 2 for TokenizedVaultV2) and any per-vault swap fee in bps.
  2. `enableToken(token)` — per accepted input token (e.g. WBTC, cbBTC, tBTC for the BTC v2 vault).
  3. `enableRouter(routerAddr, tokenApprovalAddr, authorizedSelector)` — per DEX router the quote provider may target. Paraswap's "augustor" address is set per chain; the approval-target (`TokenTransferProxy`) and the selectors used by `/transactions` are admin inputs.
  4. For non-default origin codes, `addOrigin(originCode, originFee, originFeeCollector)`.
  5. For v2 multi-asset vaults: add the SwapRouter to the vault's sender whitelist.

  The forknet smoke test at `tests/vaults/forknet-swap-router-abi.test.js` reads `vaultInfo`, `whitelistedTokens`, and the contract constants from the deployed router and fails if any expected vault is unregistered. Run `pnpm test:forknet` to verify before release.

  ### Behavior change for indexers

  For vaults moved to the SwapRouter, deposits no longer emit from the vault contract directly — events are emitted by the SwapRouter (`Deposit`, `SwapExecuted`, `SwapFeeApplied`, `OriginFeeApplied`). Subgraphs that index the vault's deposit events for the BTC v2 vault should be updated to also index the SwapRouter.

### Patch Changes

* 7d4f38f: fix: sync `VAULTS_USING_SWAP_ROUTER` with on-chain `enableVault` state on the mainnet SwapRouter (`0xAC771209FF2b71EECfF6E85a9AD01db8Ff2618B0`).

  The set previously listed `0x8AcA0841…362C21` (uptBTC) as a placeholder, but no `VaultEnabled` event was ever emitted for that address — `vaultUsesSwapRouter` was reporting `true` for a vault that the on-chain router would reject with `InvalidVault` at deposit time.

  Replaces the set with the two vaults currently registered on the contract:

  * `0xE9B725010A9E419412ed67d0fA5f3A5f40159D32` — **Upshift Core USDC** (vaultType=1, ERC-4626, reference asset USDC).
  * `0x74aD2F789Ed583DBd141bbdafC673fE1F033718b` — **Sentora USD** (vaultType=2, Tokenized Vault V2, reference asset USDC).

  Verified via `vaultInfo(addr)` reads and the full `VaultEnabled` event log on the deployed router. Consumers gated on `vaultUsesSwapRouter` (notably `vaultDeposit` dispatch) will now route the two registered vaults through the SwapRouter and continue to fall back to the legacy adapter path for everything else.
* ea679fc: fix: SwapRouter dispatch now reads the underlying asset's on-chain decimals when fetching a swap quote (previously reused the vault share-token decimals, which diverge for multi-asset v2 vaults — e.g. the 18-decimal share over the 8-decimal WBTC reference asset on the BTC v2 vault — and yielded a mispriced Paraswap quote).

  fix: Paraswap calldata now embeds the slippage-adjusted minimum `destAmount` so the aggregator's own min-out check matches the SwapRouter's `minAmountOut`. Previously the calldata was built with the exact priceRoute `destAmount` (0% tolerance) and the DEX leg would revert on any adverse movement before the SwapRouter's slippage check could apply.

  feat: `IContractWriteOptions.slippageBps` lets callers of `vaultDeposit` override the default 1% slippage tolerance applied on SwapRouter-routed deposits that require a swap.
* 5242f18: fix: honor `IContractWriteOptions.receiver` on the SwapRouter swap-and-deposit path

  `vaultDeposit` dispatched through the SwapRouter was passing `wallet` as the share recipient on the swap leg, ignoring an explicit `receiver` override. The direct-deposit and native-deposit paths already honored it; the swap path now matches.

</details>
{% endupdate %}

{% update date="2026-06-05" %}

## 8.1.0

{% hint style="info" %}
**Integrator highlights**

* **Breaking:** Result record from `getHealthFactorOfBorrowersByVault` is now keyed by lowercased vault address; lookups using mixed-case addresses will miss.
* **Action:** Update vault-address lookup keys to use `address.toLowerCase()` when reading health-factor results.
* **New:** `AugustSDK.getVaultBorrowerHealthFactor` accepts an optional `vault` field to scope the fetch to a single vault.
* **New:** New exported type `IVaultBorrowerHealthFactor` replaces the previous inline result shape.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* bc5d468: feat: `getVaultBorrowerHealthFactor` is now vault-scopable and resilient to per-loan failures.

  * New optional `vault` field on `AugustSDK.getVaultBorrowerHealthFactor({ chainId, vault })` (and matching positional param on `AugustVaults.getVaultBorrowerHealthFactor`). When provided, only that vault's tokenized record is fetched and only its loans are walked — the all-vaults / all-chains fanout is skipped entirely.
  * Internal `getVaultBorrowerHealthFactor({ vault, options })` and `getHealthFactorOfBorrowersByVault({ options, vault? })` (both in `modules/vaults/getters.ts`) now use `Promise.allSettled` for the loan-state / borrower / per-vault iterations. A single bad loan contract (e.g. a test loan whose address isn't a real deployed contract, or whose `loanState()` reverts) drops that row from the result and is logged via `Logger.log.warn` instead of rejecting the whole batch. Same applies to the per-borrower August backend call.
  * The `Record<vault, …>` returned by `getHealthFactorOfBorrowersByVault` is now keyed by **lowercased** vault address. Callers must look entries up with `address.toLowerCase()`. The previous keys reflected whatever casing the upstream `/public/tokenized_vault/` endpoint returned, which silently caused lookups against `getAddress(pool)` to miss.
  * New exported type `IVaultBorrowerHealthFactor` replaces the previous inline `{ borrower, loan, health_factor? }` shape.

  Closes the upshift-app issue where the Allocation Breakdown HF column would render a perpetual loading skeleton on Upshift USDC because one bad test loan's RPC call sank the entire health-factor batch (AUGUST-6291).

</details>
{% endupdate %}

{% update date="2026-06-04" %}

## 8.0.0

{% hint style="info" %}
**Integrator highlights**

* **Breaking:** `StellarNetwork` type alias is removed; switch to `IStellarNetwork`.
* **Breaking:** Constructor `keys.octavfi` field is removed; passing it was always a no-op.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Major Changes

* ebeb2c6: chore: remove two unused symbols from the published type surface — the `@deprecated StellarNetwork` alias (use `IStellarNetwork` instead; the alias existed for back-compat and has 0 internal consumers across our repos) and the `octavfi?: string` field on the SDK constructor's `keys` config (the field was never read; the octavfi service uses a hardcoded API key, not this config). No runtime behavior changes. Consumers that referenced `StellarNetwork` should switch to `IStellarNetwork`; consumers that passed `keys.octavfi` can drop it — it was a no-op.

### Patch Changes

* 66b18f2: fix: `fetchTokenPricesFromCoinGecko` now returns the latest price on the success path. The previous `if (data && data.length)` guard checked the `length` property on an object response (`{ prices, market_caps, total_volumes }`) and silently collapsed every successful response to `null` — only the hardcoded `musd` short-circuit was returning a real value. Fixes defect #1 from `todo/32-coingecko-fetcher-defects.md`; defects #2 (typed errors on non-2xx) and #3 (up-front symbol validation) remain pending.
* 175da88: fix: `fetchVaultsBatch` no longer mis-routes successful fetches that resolve to a falsy value (`0`, `''`, `0n`, `null`, `false`) into the failed pile. The success/failure branch now keys on `result.success` only, respecting the function's documented contract that `data` is the source of truth when `success === true`.
* 10b3b85: fix: break circular dependency `core/index.ts → core/auth → core/fetcher.ts → services/coingecko/fetcher.ts → core/index.ts` by importing `Logger` from the `core/logger` leaf module in `services/coingecko/fetcher.ts` instead of the `core` barrel. Restores the zero-cycle invariant enforced by the `Circular Dependency Check` CI job.
* 66b18f2: chore: route all `console.*` calls under `packages/sdk/src.ts/services/` (coingecko, debank, octavfi, subgraph) through `Logger.log.{info,error}`. Each call is now tagged with the originating function name and carries structured context (status, statusText, pool, address, etc.) instead of the previous raw, unsanitized strings. Errors now flow through `sanitizeError` before reaching Sentry, and dashboards can group by function tag rather than by error-message text. A new `tests/services/services-logger-hygiene.test.ts` regression-tests the floor: no `console.*` in `services/`.

</details>
{% endupdate %}

{% update date="2026-06-03" %}

## 7.0.1

{% hint style="info" %}
**Integrator highlights**

* **Breaking:** `explorerLink` return type is restored to `string`; code relying on the brief `string | undefined` shape from 7.0.0 should remove undefined guards.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* ddbfa62: fix: restore `explorerLink` return type to `string` (regression in 7.0.0)

  The circular-dependency cleanup unintentionally tightened `explorerLink`'s return type to `string | undefined` by surfacing a branch that was previously masked by `strictNullChecks: false`. Consumers had always compiled against `string` via the emitted `.d.ts`. Restore the historical public shape by returning `''` when `chain` is falsy or unknown.

</details>
{% endupdate %}

{% update date="2026-06-03" %}

## 7.0.0

{% hint style="info" %}
**Integrator highlights**

* **Breaking:** Write helpers now throw `AugustValidationError` / `AugustSDKError` instead of returning `undefined` or throwing plain `Error`; callers must use `try/catch` and narrow on these types.
* **Breaking:** `handleSolanaDeposit` and `handleSolanaRedeem` now throw on failure instead of returning `null`; replace null-return checks with `try/catch`.
* **Breaking:** Solana/Stellar adapters now throw `AugustValidationError` for input validation failures; existing plain-`Error` message-string matches will break.
* **Action:** Cross-chain: call `isQuoteStale(quote)` before submitting a cross-chain deposit/redeem and re-quote when it returns `true`; `quotedAt`/`expiresAt` are now populated.
* **Action:** Solana deposit/redeem `depositAmount`/`redeemShares` now accept `bigint` for raw on-chain units; prefer `bigint` for money flows to avoid float precision loss.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Major Changes

* 7ede403: fix(audit): correctness, validation, and observability hardening across deposit / withdraw / redeem flows

  **Breaking** — write helpers now throw `AugustValidationError` on bad input and `AugustSDKError` on downstream failures (previously returned `undefined` or threw a plain `Error`). Callers that depended on the silent no-op or were matching on `Error` message strings need to wrap calls in `try`/`catch` and narrow on `AugustValidationError` / `AugustSDKError`.

  **Breaking** — `handleSolanaDeposit` and `handleSolanaRedeem` (the Solana adapter's `vaultDeposit` / `vaultRedeem`) now `throw` on failure instead of returning `null`. Callers checking for a `null` return must convert to `try`/`catch`.

  ### EVM `write.actions`

  * **vaultDeposit**: amount is now encoded against the *deposit token's* decimals (not the vault's share decimals). Fixes a silent mis-scaling on EVM-2 multi-asset vaults and any native-token deposit into a vault whose share decimals ≠ 18. Native deposits always use 18 decimals.
  * **vaultApprove**: now mirrors `vaultDeposit`'s routing — picks the wrapper as spender for adapter deposits and the vault for multi-asset / standard deposits. Compares the existing on-chain allowance against the required amount (was: only re-approved when allowance was exactly `0`).
  * **vaultRequestRedeem**: receipt-token approval now goes through `safeSendTx` so Monad-style RPCs that return malformed pending-tx fields don't throw during parsing.
  * **vaultRedeem** (dated-claim flow) and **rwaRedeemAsset**: both now use `safeSendTx` + `tryRecoverTxHash` for nonce-fallback parity with `vaultDeposit` / `vaultRequestRedeem`.
  * **rwaRedeemAsset**: doc fix — the **vault share** must be approved to the subaccount, not the redeemable (output) asset. Caller responsibility unchanged; the comment was wrong.
  * All write helpers (`vaultApprove`, `vaultDeposit`, `vaultRequestRedeem`, `vaultRedeem`, `depositNative`, `rwaRedeemAsset`) now throw `AugustValidationError` on invalid wallet/target/wrapper addresses or missing required inputs, and reject JS `number` amounts that exceed `Number.MAX_SAFE_INTEGER`.
  * `vaultDeposit` and `vaultRequestRedeem` now require `amount` (previously silently encoded as `0` via `toNormalizedBn(undefined)`).
  * `vaultDeposit` throws `AugustValidationError` when `depositAsset` differs from the vault's underlying but no adapter is configured for the vault (previously fell through to a cryptic on-chain revert).
  * `vaultDeposit` and `vaultRequestRedeem` always wait for the ERC-20 approval receipt before sending the deposit/redeem tx, regardless of the caller's `wait` flag — closes a race window where a follow-up tx could be re-ordered ahead of the approval on some RPCs.
  * Downstream tx failures (e.g. on-chain reverts) are now wrapped in `AugustSDKError` with the original error preserved on `cause` and a structured `context` payload, instead of a plain `Error("Deposit failed: …")`.
  * `safeBigInt` allowance read inside `vaultDeposit` now passes a `'vaultDeposit:allowance'` context so flaky-RPC warnings are discriminable from approve-path warnings.
  * **safeBigInt**: emits a `Logger.warn` on malformed RPC responses (e.g. bare `"0x"`) so flaky RPCs don't cause silent gas waste from spurious approvals.

  ### EVM cross-chain (`crossChainVault`)

  * **crossChainVaultDeposit**: now rejects unsupported user chains up front with a clear error (was: cryptic config-lookup or gas-estimation revert).
  * **approveCrossChain**: throws when the approval receipt reports `reverted` (was: returned the hash unconditionally).
  * Monkey-patch lock: timing out now **throws** instead of silently proceeding with conflicting concurrent patches.
  * Fee patch: warns via `Logger.warn` when the LayerZero SDK returns an unexpected `contractFunctionName`, so the in-place LZ-fee buffer being silently no-op'd is visible in telemetry.
  * TSDoc on `crossChainVaultDeposit`, `crossChainVaultRedeem`, `buildCrossChainVaultTx`, and `needsCrossChainApproval` now states the default slippage / fee / gas buffers and documents the "approval needed on RPC failure" defensive behavior.

  ### Solana

  * **handleSolanaRedeem**: replaced `parseInt` with the new `uiAmountToRawBn` BN-based helper. Fixes precision loss for any 18-decimal mint above a few thousandths or any 9-decimal mint above \~9M tokens.
  * **handleSolanaDeposit**: now uses the same helper for consistency.
  * Both handlers now throw `AugustValidationError` / `AugustSDKError` on failure instead of returning `null`, matching the EVM helpers' error contract.

  ### Stellar

  * **submitStellarTransaction**: polling now backs off geometrically (1.5x, capped at 8s) instead of fixed 2s — same worst-case ceiling on attempts, lower RPC pressure on long waits.
  * `handleStellarRedeem` TSDoc now documents the exact Soroban contract interface it assumes (`redeem(shares: i128, receiver, owner, operator)`).

  ### Telemetry

  * `rwaRedeemAsset` is now classified under `write.redeem` in `METHOD_CATEGORIES` (previously fell back to `'unknown'`).

  ### New exports

  * `uiAmountToRawBn` (from `adapters/solana/utils`).
  * `resolveDepositTokenDecimals`, `resolveSpender`, `validateAmountPrecision`, `safeBigInt`, `safeSendTx`, `safeWaitForTx`, `tryRecoverTxHash`, `isNonceParsing` from `modules/vaults/write.actions` (marked `@internal` — exported for unit testing).
  * New polling constants: `POLL_INTERVAL_MAX_MS`, `POLL_INTERVAL_BACKOFF`.

### Minor Changes

* ae03a7b: feat(sdk): new `approve` method returns a discriminated `ApproveResult`

  Adds `augustSdk.evm.approve(...)` (and the underlying `approve` export from `modules/vaults/write.actions`) that returns one of:

  ```ts
  type ApproveResult =
    | { kind: "sent"; hash: string }
    | { kind: "sufficient"; existing: bigint }
    | { kind: "native" };
  ```

  Lets callers tell apart "we sent a tx", "existing allowance already covers the amount", and "the resolved deposit asset is native (msg.value, no allowance applies)" without re-reading on-chain state.

  `vaultApprove` is unchanged — same `Promise<string | undefined>` shape, same spender routing, same allowance / native short-circuits. Both functions share the routing implementation via an internal helper so behavior stays identical.

  Method-taxonomy entry `approve → write.approve` added so Sentry rolls the new method up next to `vaultApprove`.
* dee70e0: feat(AUG-6139): partner-usage telemetry — isomorphic Sentry bootstrap, method taxonomy, dimension tags, and arg-shape capture
  * Node + browser Sentry resolved at runtime (`@sentry/node` added alongside `@sentry/browser`); CLI now emits telemetry from its top-level error handler.
  * Every method span carries `sdk.category`, `sdk.chain`, and `sdk.argShape` so dashboards can slice partner usage by intent, chain, and call shape without leaking values.
  * Fallback `partner.id = 'unverified:<appName>'` and `partner.tier = 'unverified'` tags ship until the verified-partner endpoint exists.
  * `setMeasurement('sdk.method.invocation' | 'sdk.method.error', …)` adds counter-style aggregates for sum-based dashboards.
  * New public exports: `getSentrySDK`, `getSentryRuntime`, `getMethodCategory`, `METHOD_CATEGORIES`, `chainIdToTagValue`, `computeArgShape`, `captureSdkException`.
* ae03a7b: feat(sdk): preview / allowance / balance / maxDeposit read helpers on the EVM adapter

  Adds five additive read methods to `augustSdk.evm` so consumers can stop reaching into raw ABIs for the most common vault reads:

  * `previewDeposit({ vault, amount, asset? })` — shares returned by a deposit. Routes EVM-1 vaults to `IERC4626.previewDeposit(uint256)` and EVM-2 multi- asset vaults to `previewDeposit(address, uint256)` (returns the share slot of the tuple).
  * `previewRedeem({ vault, shares })` — assets returned by a redeem. Routes EVM-1 vaults to `IERC4626.previewRedeem(uint256)` and EVM-2 to `previewRedemption(uint256, false)` (gross slot).
  * `allowance({ vault, owner, asset? })` — raw ERC-20 allowance the owner has granted the vault. When `asset` is omitted the SDK resolves the vault's underlying via `IERC4626.asset()`.
  * `balanceOf({ asset, owner })` — raw ERC-20 balance.
  * `maxDeposit({ vault, receiver? })` — vault deposit cap. EVM-2 multi-asset vaults resolve via `maxDepositAmount()`; EVM-1 vaults use `maxDeposit(receiver)` with a zero-address default.

  All helpers return a raw `bigint` so BigInt math stays precise. Existing helpers (`vaultAllowance`, `previewRedemption`) are unchanged.

  Notes:

  * These methods require a signer because they live on `EVMAdapter`, matching the existing read pattern (`vaultAllowance`, `sendersWhitelistAddress`, etc.). A read-only `JsonRpcProvider` wrapped via `Wallet.createRandom().connect(provider)` works for query-only use.
  * Method-taxonomy entries (`previewDeposit`, `previewRedeem`, `allowance`, `balanceOf`, `maxDeposit`) added so Sentry rolls them up correctly.
  * Benchmarks for these helpers are deferred — they need a signer plumbed into `packages/sdk/benchmarks/suites/sdk-methods.js`; unit tests with mocked contracts cover the routing and validation paths.
* ae03a7b: feat(sdk): constructor option `timeoutMs` overrides the request timeout default

  Adds an additive `timeoutMs` option to the `AugustSDK` constructor (via the shared `IAugustBase` config) that overrides the default request timeout used by every August fetcher helper. The compiled-in default (90 s) is preserved when the option is omitted; per-call `IFetchAugustOptions.timeoutMs` still wins over the SDK-level default.

  ```ts
  const sdk = new AugustSDK({
    appName: "acme-trader",
    providers: { 1: "..." },
    keys: { august: process.env.AUGUST_KEY },
    timeoutMs: 20_000, // shorten the default deadline to 20s for this instance
  });
  ```

  Also exports two helpers for advanced use:

  * `setSdkRequestTimeout(ms | null)` — apply / clear the override directly.
  * `getSdkRequestTimeout()` — read the active default (override or compiled-in).

  Notes:

  * This is process-global state. If you instantiate multiple `AugustSDK` objects in the same process with different timeouts, the last constructor call wins.
  * Lowering the default for the entire package was deliberately skipped — that change is behaviorally observable for current integrators and belongs on a major bump.
* e3d589e: feat(audit-followup): tx-flow audit fixes — Solana bigint amounts, cross-chain destination validation, quote staleness, Stellar account error

  Additive correctness improvements identified during the deposit / withdraw / redeem audit. No new exported types are renamed or removed.

  ### Solana (`adapters/solana`)

  * **`handleSolanaDeposit` / `handleSolanaRedeem`** now accept `bigint` for `depositAmount` / `redeemShares`, in addition to the existing `number` form. When `bigint` is passed it is treated as the raw on-chain unit and used directly — no `uiAmountToRawBn` round-trip through a JS float. Recommended for money flows so the value the wallet signs cannot drift from the value the UI displayed. The `number` form is still supported for back-compat.
  * The SDK wrapper methods `augustSdk.solana.vaultDeposit` and `vaultRedeem` widen their `depositAmount` / `redeemShares` parameter to `number | bigint` accordingly.
  * Both handlers reject `0n` (and `0`) via `AugustValidationError`.

  ### Cross-chain (`evm/methods/crossChainVault`)

  * **`buildCrossChainVaultTx`** now rejects requests where `destinationChainId` or `userChainId` (on `DEPOSIT`) is neither the configured `hubChainId` nor present in `config.layerZeroEids.spokes`. Previously the unknown chain ID silently fell back to the hub EID, routing user funds to a chain they did not pick. Behavior unchanged when the chain ID is omitted / equals the hub / is a configured spoke.
  * **`quoteCrossChainDeposit` / `quoteCrossChainRedeem`** now populate `quotedAt` and `expiresAt` on the returned `IQuoteCrossChainResult`. The UI should call `isQuoteStale(quote)` before submit and re-quote when it returns `true` — LayerZero fees drift between quote and submit.
  * New exports from `evm/types/crossChain`:
    * `CROSS_CHAIN_QUOTE_TTL_MS` (30 000 ms default validity window).
    * `isQuoteStale(quote, now?)` helper.

  ### Stellar (`adapters/stellar/soroban`)

  * **`buildSorobanTx`** now wraps `server.getAccount` failures: when the account does not exist or is unfunded, the SDK throws an `AugustValidationError` with copy that names the actual fix ("send at least 1 XLM to activate"). Detected via both `instanceof NotFoundError` (forward-compat) and the current `"Account not found: <addr>"` message the rpc server actually throws. Other RPC errors propagate unchanged.

  ### Known limitations (deferred)

  * The Solana `deposit` instruction's IDL does not yet accept a `min_shares_out` argument, so client-side slippage protection cannot be enforced on-chain for Solana vaults. A `TODO(slippage)` comment marks the call site in `vault.actions.ts`; on-chain enforcement requires a program update.

### Patch Changes

* a18ea6d: chore(benchmarks): per-iteration RPC/API request counting

  Adds `benchmarks/request-counter.js`, a `globalThis.fetch` wrapper that buckets requests as `rpc` (Alchemy, Helius, QuickNode, etc.) vs `api` (everything else, with a per-host breakdown). The harness now resets the counter before each measured iteration and surfaces `meanRpc`, `meanApi`, `meanRequests`, and a `hostBreakdown` on every result.

  Console + markdown reporters render the new columns when counts are present and append a "Total requests across all measured iterations" section so AUGUST-5835-style perf claims (in-flight dedup, whitelist cache, `parallelLimit` fix) can be measured directly instead of estimated from the diff.

  Counting is on by default. Set `BENCHMARK_ALCHEMY_REQUEST_COUNT=0` to skip the global fetch patch (e.g. in environments where another tool already wraps `fetch`). No behavior change to the SDK itself — this is a benchmark-tooling-only change.
* 0f92c9c: refactor(vaults/date-utils): lift duplicate `TIMESTAMP_MANIPULATION_WINDOW = 300` to module scope

  `computeClaimableDate` and `isClaimableNow` each re-declared the same `const TIMESTAMP_MANIPULATION_WINDOW = 300` inside their function bodies. Lifted to a single module-level constant mirroring `TimelockedVault.sol`'s 5-minute window. Pure refactor — identical observable behavior.

  Coverage was thin (no existing tests for `date-utils.ts`); adds `tests/vaults/date-utils.test.ts` covering `computeClaimableDate`, `isClaimableNow`, `formatDateKey`, `isValidClaimableDate`, and `getDaysInMonth` (8 tests, including UTC-day rollover and leap-February).
* 0f92c9c: perf(adapters/evm): parallelize receipt-token + whitelisted-assets fetch in `getEvmVaultV2`

  After the initial vault-contract `Promise.all` resolves, `getEvmVaultV2` previously fetched the receipt-token metadata batch (5 RPCs) and the whitelisted-assets list (1 RPC) **sequentially**, even though both depend only on `vaultContractCalls` and have no data dependency on each other. They now run inside a shared outer `Promise.all`, so the wall time per V2 vault read is bounded by the slower of the two batches instead of their sum.

  No change to the merged `combinedCalls` / `combinedFunctions` shape, so downstream `buildFormattedVault` sees identical inputs. Static regression test (`tests/adapters/evm-vault-v2-parallel-fetch.test.ts`) guards the wrapping pattern.
* 0f92c9c: docs(adapters/evm): TSDoc for `vaultAllowance`, `vaultDeposit`, `vaultRequestRedeem`, `depositNative`, and `vaultRedeem`

  The EVM adapter's public write methods shipped without TSDoc blocks, which CLAUDE.md section 1 requires for every exported symbol on the published surface. Integrators saw "(no description)" in their IDE and had to read `modules/vaults/write.actions.ts` to learn the parameter shape and return semantics. Each method now has a one-sentence summary, `@param` / `@returns` / `@throws` notes, and an `@example`. A static presence test (`tests/adapters/evm-write-tsdoc.test.ts`) guards against regression.

  No behavior change.
* 0f92c9c: refactor(vaults/utils): extract local `IEvmAssetMetadata` type

  `buildFormattedVault` declared the same `{ address: IAddress; symbol: string; decimals: number }` shape twice as inline types (once for `depositAssets[]`, once for `receipt`). Lifted to a single file-local `@internal` type `IEvmAssetMetadata`. Not exported — kept internal so the public surface doesn't grow. Pure refactor.
* 0f92c9c: perf(core/web3): in-flight request dedup for `getDecimals` and `getSymbol`

  `getDecimals` and `getSymbol` already cache results in the shared `lru-cache`, but concurrent identical calls (e.g. a fresh page-load with multiple components asking for the same token's decimals before any cache write lands) each fired their own RPC. The price-fetcher path already used an in-flight `Map<key, Promise>` to coalesce these — `PRICE_REQUESTS` in `core/fetcher.ts:250` — and this change applies the same pattern to `getDecimals` (`DECIMALS_REQUESTS`) and `getSymbol` (`SYMBOL_REQUESTS`).

  Behavior on a cold cache: the first caller initiates the RPC; subsequent callers within the same tick share that promise instead of starting their own. On error, the in-flight entry is cleared in a `finally` so the next caller can retry. Cache-hit and Solana-address fast paths are unchanged, so no observable difference for callers that aren't concurrent.

  Adds `tests/utils/getdecimals-getsymbol-dedup.test.ts` with three cases (coalescing, no-false-coalescing across addresses, getSymbol parity).
* 0f92c9c: perf(core/web3): in-flight request dedup for `getReceiptTokenAddress`

  `getReceiptTokenAddress` already caches results in the shared `lru-cache`, but concurrent identical reads (multiple components or vault paths resolving the same vault's receipt-token address before the first cache write lands) each fired their own `lpTokenAddress()` RPC. This change adds a `RECEIPT_TOKEN_REQUESTS` in-flight `Map<string, Promise>` so simultaneous identical reads share a single promise — same pattern as the existing `DECIMALS_REQUESTS`, `SYMBOL_REQUESTS`, and `WHITELISTED_ASSETS_REQUESTS` maps. The in-flight entry is cleared in a `finally` so the next caller can retry after a failure.

  Cache-hit and missing-arg fast paths are unchanged.

  Adds `tests/utils/getreceipttokenaddress-dedup.test.ts` (coalescing + no false-coalescing across addresses).
* 0f92c9c: perf(vaults/getters): lift duplicate `getReceiptTokenAddress` call in the V2 position-read path

  Inside the `version === 'evm-2'` branch of the position loop in `modules/vaults/getters.ts`, `getReceiptTokenAddress(provider, vault)` was awaited twice for the same vault in back-to-back lines — once to derive decimals, once again to construct the receipt contract for the balance read. The second call was a cache hit (so cheap in RPC terms) but still incurred a function call, a cache lookup, and a Promise hop per iteration. Both call sites now reuse a single `receiptAddress` local.

  Pure lift with no behavior change — same value returned in both spots either way, and the wallet-balance branch only runs when the first await would also have run.
* ae03a7b: fix(adapters): Solana / Stellar adapters now throw typed errors for input validation

  Replaces every `throw new Error(...)` in the Solana and Stellar adapter paths that represents an input-validation failure with `AugustValidationError`, and the Stellar submit / Soroban downstream failures with `AugustSDKError` / `AugustTimeoutError`. Consumers can now narrow:

  ```ts
  catch (err) {
    if (err instanceof AugustValidationError) { ... }
  }
  ```

  …on non-EVM paths, just like EVM. Error messages are unchanged, so existing substring assertions and Sentry message-based grouping continue to work; the class-based bucket gains signal.

  Affected files:

  * `adapters/stellar/actions.ts` — `validateContractAddress`, `validateAccountAddress`
  * `adapters/stellar/soroban.ts` — `toBigIntAmount`, simulation / assembly failures (now `AugustSDKError`)
  * `adapters/stellar/submit.ts` — submission failures (`AugustSDKError`), poll-timeout (`AugustTimeoutError`)
  * `adapters/stellar/getters.ts` — `getStellarUserPosition` / `convertToShares` address validators
  * `adapters/stellar/utils.ts` — `assertNotStellar` (now `INVALID_CHAIN`)
  * `adapters/solana/vault.actions.ts` — input-validation failures inside `handleSolanaDeposit` / `handleSolanaRedeem`
  * `adapters/solana/utils.ts` — wallet / program-id / vault-version validation and `uiAmountToRawBn` precision checks
* bb0873f: fix(perf-pr-review): address review findings on the perf-optimizations PR

  Bundle of small fixes responding to the code review of `AUGUST-5835-perf-optimizations`. No public-API change.

  * **`CACHE.has` vs `CACHE.get` truthy check** — flipped 4 sites in `core/helpers/web3.ts` (`getDecimals`, `getSymbol`, `getReceiptTokenAddress`, `getWhitelistedAssets`) from `if (CACHE.get(key))` to `if (CACHE.has(key))`. Tokens with `decimals === 0`, empty-string symbols, or empty whitelist arrays were silently re-fetching on every sequential call because the cached value was falsy. Resolves and supersedes `todo/29`.
  * **`getWhitelistedAssets` typed error** — replaced `throw new Error(...)` with `AugustValidationError('INVALID_INPUT', ...)`. The function stays `@internal`; the change keeps Sentry's error-grouping intact (raw `Error` collapsed to the generic bucket).
  * **`generatePermitSignature` Logger** — the `console.error('Could not fetch DOMAIN_SEPARATOR…')` that the Solana sweep had skipped is now `Logger.log.error('generatePermitSignature', error, { message: … })`, with the original throw preserved.
  * **Dead `name` write** — moved `let name` into the cache-miss discovery block (`const name = …`). The assignment on the cache-hit path was never read; `signTypedData` uses `matchingDomain` directly.
  * **`runWithConcurrency` correctness note** — one-line comment explaining why `nextIndex++` is safe across workers (JS single-threaded; increment finishes before any `await`).
  * **Parallel-fetch test upgrade** — `tests/adapters/evm-vault-v2-parallel-fetch.test.ts` is rewritten from a regex-on-source assertion to a behavior test that mocks `Contract` / `getDecimals` / `getSymbol` / `getWhitelistedAssets` with controlled delays and asserts wall time falls in the parallel range (`1.5×–2.5× RPC_DELAY`), not the serial range (`3× RPC_DELAY`).
  * **New regression test** — `tests/utils/cache-falsy-value-hit.test.ts` proves `getDecimals` returning `0` is cached and the second call doesn't re-fetch.
* 0f92c9c: perf(vaults/utils): cache matched permit domain per (chainId, token)

  `generatePermitSignature` previously, on every invocation, fetched the token's `name()` (RPC), built 4 candidate EIP-2612 domain configurations, hashed each with `TypedDataEncoder.hashDomain`, and — only if all 4 failed — fell back to fetching `version()` (another RPC). For integrators generating multiple permits against the same token in a session, every signature reran the full discovery.

  The matched `TypedDataDomain` is now cached in the SDK's shared `lru-cache` keyed `permit-domain-<chainId>-<token>` for 1 hour. The live `DOMAIN_SEPARATOR()` is still fetched on every call and compared against the cached domain's hash; on mismatch (e.g. an upgraded token contract) the cache entry is invalidated and the original discovery loop runs. On a cache hit the `name()` RPC, the 4-iteration hashing loop, and the rare `version()` fallback are all skipped.

  The function also pairs `nonces()` with `DOMAIN_SEPARATOR()` in a single `Promise.all` (they were previously sequential), shaving a round trip on the cache-miss path.

  Adds `tests/vaults/permit-domain-cache.test.ts` covering the discovery path and the cached fast-path.
* 0f92c9c: refactor(adapters/solana): route console.\* through Logger

  Replaces all 50 raw `console.log` / `console.warn` / `console.error` calls in `adapters/solana/{vault.actions,utils}.ts` with the equivalent `Logger.log.{info,warn,error}` calls. Output is now sanitized via the analytics pipeline and gated by `Logger.setDevMode()` / `Logger.setStructuredLogger()` rather than being printed unconditionally to stdout. Level mapping is preserved (`console.log` → `info`, `console.warn` → `warn`, `console.error` → `error`). No behavior change for callers that have not configured a logger; consumers that have already enabled dev mode or plugged in a structured logger will now receive Solana adapter events on the same channel as the rest of the SDK. A static test (`tests/adapters/solana-logger-hygiene.test.ts`) guards against regression.
* a18ea6d: fix(adapters/solana): propagate the underlying error from `getVaultMints` instead of swallowing it

  `SolanaUtils.getVaultMints` previously caught any failure inside `program.account.vaultState.fetch(vaultStatePda)` — Anchor discriminator mismatch, account-not-found, RPC error — logged it, and returned `{ depositMint: '', shareMint: '', vaultVersion: undefined }`. Downstream `handleSolanaDeposit` / `handleSolanaRedeem` checked the empty mints and threw the generic `"Failed to read vault mints from on-chain state"`, which carried zero diagnostic signal. Operators triaging a failed deposit on a specific vault (e.g. Sentora xBTC on the Upshift portfolio page) had nothing actionable in the user-visible error.

  `getVaultMints` now throws an `AugustSDKError` (`code: 'UNKNOWN'`) whose `message` includes the underlying cause and whose `context` carries `vaultProgramId` and `vaultAddress`. The original error is set as `.cause`. Successful reads still cache as before; the existing read-side `getVaultStateReadOnly` path is unchanged.

  The outer catch in `handleSolanaDeposit` already re-wraps SDK errors with `cause`, so the user-visible message becomes `"Solana deposit failed: Failed to read vault mints from on-chain state: <real cause>"` — pointing at whether the IDL is wrong, the PDA doesn't exist, or the RPC failed.

  Adds `tests/vaults/solana-vault-mints-error-propagation.test.ts` covering account-not-found and discriminator-mismatch causes, asserting the typed-error shape and that the cause string flows through.
* 0f92c9c: fix(vaults/fetcher): honor `parallelLimit` in batch + comprehensive vault fetchers

  `fetchVaultsBatch` and `fetchVaultsComprehensive` previously accepted a `parallelLimit` option but renamed it to `_parallelLimit` and ran every task in a batch concurrently via `Promise.all` — the option was a no-op. The default `getVaults` call site (`modules/vaults/main.ts`) passes `parallelLimit: 8` expecting it to take effect, so RPC fan-out for a typical batch of 15 vaults was running 15-wide instead of the intended 8-wide.

  Both fetchers now route their per-batch work through an internal `runWithConcurrency` helper that pulls tasks from a queue with a hard in-flight cap. The default `parallelLimit` is `batchSize`, so any caller that did not specify `parallelLimit` sees identical pre-fix concurrency (no regression). Callers that did specify it — including the SDK's own `getVaults` — now get the cap they asked for.

  Adds `tests/vaults/fetcher-parallel-limit.test.ts` covering: the cap, the default-preserves-prior-behavior path, and that every task still completes when `parallelLimit < batchSize`.
* 0f92c9c: perf(core/vaults): pre-compute lowercase `VAULT_SYMBOLS` lookup map

  `getVaultSymbol`'s hardcoded-fallback path used `Object.entries(VAULT_SYMBOLS).find(([k]) => k.toLowerCase() === address.toLowerCase())` — an O(n) scan over the table on every cache-miss / non-canonical-case lookup. The canonical-case fast path (`VAULT_SYMBOLS[address]`) is preserved; the case-insensitive fallback now reads from a module-level `VAULT_SYMBOLS_LOWERCASE` map built once via `Object.fromEntries`, making it O(1).

  The lookup precedence (backend metadata → hardcoded fallback → on-chain `getSymbol`) is unchanged. The hardcoded list is `@deprecated` per its existing TSDoc — backend remains canonical.

  Adds `tests/utils/get-vault-symbol-lowercase.test.ts` covering canonical-case, lowercase, and unknown-address paths.
* 0f92c9c: perf(core/web3): cache `getWhitelistedAssets` list per (chain, whitelist contract)

  V2 vault reads (`getEvmVaultV2`) call `getWhitelistedAssets` on the vault's whitelist contract on every invocation, and the returned list immediately fans out into per-asset `getDecimals` + `getSymbol` reads inside `buildFormattedVault`. The list itself rarely changes, so a new internal helper `getWhitelistedAssets` (in `core/helpers/web3.ts`) wraps the contract call with an `lru-cache` entry keyed `whitelisted-assets-<providerScope>-<whitelistAddress>` and a 5-minute TTL. Concurrent identical reads share an in-flight promise — same pattern as `getDecimals` / `getSymbol`.

  `getEvmVaultV2` now delegates to that helper instead of building the contract inline; the merge step that flattens `contractCalls.getWhitelistedAssets` into the formatted vault is unchanged, so callers see the same shape.

  Adds `tests/utils/get-whitelisted-assets-cache.test.ts` (in-flight coalescing, sequential cache-hit, no false-coalescing across addresses).

</details>
{% endupdate %}

{% update date="2026-05-26" %}

## 6.0.1

{% hint style="info" %}
**Integrator highlights**

* **Action:** Update any hardcoded Flare explorer URLs from `flare-explorer.flare.network` to `flarescan.com`.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* c7c508b: fix Flare chain explorer URL from flare-explorer.flare.network to flarescan.com

</details>
{% endupdate %}

{% update date="2026-05-22" %}

## 6.0.0

{% hint style="info" %}
**Integrator highlights**

* **Breaking:** `registerUserForPoints` now requires four additional parameters (`chainId`, `signature`, `nonce`, `expiry`) and no longer uses an admin API key; all existing call sites must be updated.
* **Action:** Callers must obtain an EIP-191 personal\_sign signature over the canonical message template before calling `registerUserForPoints`; see TSDoc for exact message format.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Major Changes

* 00c6ba9: `registerUserForPoints` now authenticates via a wallet signature instead of an admin API key. The function gains four required parameters — `chainId`, `signature`, `nonce`, `expiry` — and no longer reads `options.augustKey`. Callers must obtain a personal\_sign (EIP-191) signature over a canonical message containing the lowercased user address, lowercased referrer (or `"none"`), chain id, nonce, and expiry; the backend reconstructs the same message and verifies the signature against the claimed wallet (EOA recovery first, then EIP-1271 for smart-contract wallets such as Safe). `chainId` must be one of the chains Upshift supports (see backend `SUPPORTED_REGISTRATION_CHAINS`); unsupported chains return 422. The class method `AugustVaults#registerUserForPoints` and the top-level `Sdk#registerUserForPoints` add `chainId`, `signature`, `nonce`, `expiry` as required positional arguments after `referrerAddress`. See the TSDoc on `registerUserForPoints` for the exact message template and a worked example.

### Patch Changes

* 0422e61: patch an issue with version ts. This patches a broken import in v 5.1.0 and 5.1.1

</details>
{% endupdate %}

{% update date="2026-05-22" %}

## 5.1.1

{% hint style="info" %}
**Integrator highlights**

* **Action:** Upgrade from 5.1.0 to 5.1.1 immediately; the 5.1.0 npm tarball was built from a stale directory and is missing the Solana share-price and position fixes.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* Re-publish of 5.1.0 with a clean build. The 5.1.0 tarball on npm was shipped from a stale `lib/` directory and was missing the Solana share-price + position fixes described in the 5.1.0 changelog below — `lib/adapters/solana/getters.js` still read only `deployedAum` for `totalAssets`. Anyone on `@augustdigital/sdk@5.1.0` should bump to `5.1.1`.
* Added a `prepublishOnly` script (`pnpm clean && pnpm build`) so subsequent publishes refuse to ship a stale `lib/` and force a fresh transpile. The 5.1.0 mishap was caused by a manual `pnpm publish` run without a preceding `pnpm build`; the new hook makes that impossible by construction.

</details>
{% endupdate %}

{% update date="2026-05-22" %}

## 5.1.0

{% hint style="info" %}
**Integrator highlights**

* **Action:** Solana vault share prices and position sizes were previously mis-calculated; verify any redemption-sizing or max-action logic that relied on those values.
* **Action:** Upgrade from any prior 5.x release to pick up the corrected Borsh IDL field order; earlier builds may have deserialized vault state fields from wrong byte offsets.
* **New:** New `SolanaAdapter.fetchUserShareBalanceRaw({ publicKey, shareMint })` returns raw share balance and decimals.
* **New:** SDK constructor now accepts a dedicated `solana: { rpcUrl, network }` config entry so Solana can be configured without polluting the EVM `providers` map.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 9dbc693: fix(solana): use `local_aum + deployed_aum` for vault total assets; add BigInt-safe share-balance helper; stop dropping Solana from `getVaults` / `getVaultPositions`

  **Bump rationale (minor, not patch):** this release is bug-fix-driven but adds two purely additive public-surface elements — `SolanaAdapter.fetchUserShareBalanceRaw()` and the dedicated `IAugustBase.solana = { rpcUrl, network }` config entry point. Per the additive-public-API rule a minor bump is required even though no existing API breaks.

  **Root causes**

  * `getSolanaVault` read only `vaultState.deployedAum` for `totalAssets`, but the on-chain `VaultState::total_assets()` is `local_aum + deployed_aum`. The displayed share price dropped below 1.0 the instant the operator deployed any portion of the vault, even with zero PnL (jitoSOL showed `0.7370` against a 1:1 share supply).
  * `getVaultPositions` Solana branch passed `uiAmount` (a JS number) into `toNormalizedBn` with no decimals argument. It defaulted to 18 and produced a `walletBalance.raw` off by `10**(18 − mintDecimals)`, breaking redemption sizing and max-action math even though the displayed `normalized` looked plausible.
  * The provider-availability filter (`vaultsPerAvailableProviders`) had an explicit Stellar pass-through but no Solana one — Solana vaults were silently dropped from both the vault list and position list on any SDK instance whose `providers` map didn't register chainId `-1`.
  * The IDL (`vault-idl.ts` / `.json`) and `ISolanaVaultState` were missing `local_aum`, `aum_increase_limit`, `aum_decrease_limit`, and `vault_version` — fields that exist in the Rust `VaultState` struct (see `programs/august-vault/src/state/vault.rs`). Because the missing fields sat *after* `deployed_aum`, the earlier fields still deserialized correctly but every field after the drift (`pda_bump`, `paused`, `padding`) read from the wrong bytes. `paused` happening to read `0x00` is why this didn't blow up in production sooner.

  **Changes**

  * `adapters/solana/getters.ts`: sum `localAum + deployedAum` for `totalAssets`. Falls back to backend TVL when on-chain is unavailable.
  * `adapters/solana/utils.ts`: new `fetchUserShareBalanceRaw({ publicKey, shareMint })` returning `{ amount: string; decimals: number | null }` from a single `getParsedTokenAccountsByOwner`.
  * `adapters/solana/index.ts`: expose the helper on `SolanaAdapter` with TSDoc and a worst-case RPC note.
  * `adapters/solana/types.ts`: extend `ISolanaVaultState` with `localAum`, `aumIncreaseLimit`, `aumDecreaseLimit`, and the (re-positioned) `vaultVersion`.
  * `adapters/solana/idl/vault-idl.{ts,json}`: re-sync `VaultState` field order with the Rust source.
  * `main.ts`: construct `SolanaAdapter` from either `providers[-1]` or the dedicated `solana: { rpcUrl, network }` config, so partner SDK instances can opt into Solana without polluting their EVM providers map.
  * `modules/vaults/main.ts`: pass `chain_type === 'solana'` through the provider filter when `this.solanaService` is available — mirrors the existing Stellar clause.
  * `modules/vaults/getters.ts`: Solana branch now reads via the raw helper, uses the mint's true decimals, drops the `as any` on `vaultState`, and returns `vault: v.address` instead of the outer parameter (mirrors the Stellar branch).
  * `modules/vaults/types.ts`: `ISolanaService.fetchUserShareBalanceRaw` is required (only impl is the in-package `SolanaAdapter`, which now always provides it).

  **No behaviour change for EVM or Stellar paths.**

  **Verification**

  * Borsh layout sanity-checked against `programs/august-vault/src/state/vault.rs:36-50` and against the live jitoSOL vault state at `2tmMcVv2Ene7wFGebPivhwYhAZyjaJoibMz1GYVaXsB1`: 455-byte account decodes cleanly with the new field order — `local_aum=564_529_610`, `deployed_aum=1_582_093_475`, `aum_increase_limit=20`, `aum_decrease_limit=20`, `pda_bump=[254]`, `vault_version=[0]`, `paused=false`, padding all-zero. `local_aum + deployed_aum` equals the share-mint supply at parity. Every byte accounted for.
  * Benchmark entry added at `benchmarks/suites/sdk-methods.js`: `fetchUserShareBalanceRaw() [cold, no account]`. Gated on `BENCHMARK_SOLANA_RPC_URL` so the existing EVM-only CI run isn't affected; set the env var to opt in. Uses the jitoSOL share mint with the system-program key as wallet — deterministic "no account" path that measures `getParsedTokenAccountsByOwner` round-trip plus the short-circuit return, which is the hot path on the vault grid for users without a position.

</details>
{% endupdate %}

{% update date="2026-05-21" %}

## 5.0.0

{% hint style="info" %}
**Integrator highlights**

* **Breaking:** AugustSDK constructor now requires `appName` (kebab-case slug, 3–64 chars); throws synchronously if missing or invalid.
* **Breaking:** fetchAugustWithKey(undefined, …) now throws `AugustAuthError` instead of returning a synthetic `{status:500}` response.
* **Breaking:** Removed `name` field from `AugustSDK`; use `appName` on `AugustBase` instead.
* **Action:** Add `appName: '<your-slug>'` to every `new AugustSDK({…})` call before upgrading.
* **Action:** Replace any `if (res.status === 500)` missing-auth checks; missing key now throws `AugustAuthError` instead.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Major Changes

* 8881c9b: Integrator experience: require `appName`, add a runtime version-nudge.

  **Breaking — required `appName`.** `appName` is now a required field on the `AugustSDK` constructor (and `IAugustBase`). Pass a stable kebab-case slug identifying your application — e.g. `new AugustSDK({ appName: 'acme-trader', ... })`. Despite the friendly name the value is identifier-shaped: 3–64 chars, `[a-zA-Z0-9._-]` only (it's used as a Sentry tag and HTTP header). Use a slug like `'acme-trader'`, not a display name like `'Acme Trader'`. The SDK throws synchronously from the constructor when the value is missing, empty, or out of the allowed shape.

  Why: the SDK now tags outbound analytics events with `app.name`, so the August Digital team can attribute error spikes to the right consuming application and reach out about breaking changes / critical bugs. See the "App Name" section in `packages/sdk/README.md`.

  Migration: add `appName: '<your-slug>'` to your existing `new AugustSDK({ ... })` call. No other changes required.

  **Additive — version-nudge on construction.** On non-production builds the SDK now performs one best-effort npm-registry check per session and prints a `console.warn` banner when a newer `@augustdigital/sdk` is available. The check never runs in `NODE_ENV=production`, can be silenced with `AUGUST_SDK_DISABLE_VERSION_CHECK=1`, or programmatically with `new AugustSDK({ versionCheck: { enabled: false }, ... })`. Never blocks construction; failures are silent. New exports: `runVersionCheck`, `IVersionCheckConfig`, `compareSemver`.

### Minor Changes

* c24003b: feat: production-grade hardening

  **Security & errors**

  * New typed error hierarchy: `AugustSDKError`, `AugustAuthError`, `AugustNetworkError`, `AugustTimeoutError`, `AugustValidationError`, `AugustRateLimitError`, `AugustServerError`, plus `isAugustSDKError` type guard. All extend `Error` so existing `instanceof Error` consumers are unaffected.
  * Secret sanitization in error messages, logger, and Slack adapter via `sanitizeString` / `sanitizeError` / `sanitizeForLogging`.
  * URL injection hardening: `buildAugustUrl` rejects unknown server keys, absolute URLs, and protocol-relative paths; origin check enforces same-origin.
  * `fetchAugustWithKey(undefined, …)` now throws `AugustAuthError(AUTH_MISSING_KEY)` instead of returning a synthetic `{status: 500}` response — callers using `if (res.status === 200)` previously misclassified missing-auth as a 500 server error; they now receive a proper typed error. `verifyAugustKey` short-circuits empty keys so `init()` behavior is unchanged.
  * `override` flag on `IFetchAugustOptions` is `@deprecated` with a one-time runtime warning; will be removed in the next major.
  * HTTP errors are now typed by status: 401 → `AugustAuthError`, 429 → `AugustRateLimitError`, else `AugustServerError`.
  * `Response.headers.get('x-correlation-id')` (was bracket-accessed; always `undefined`).

  **Transport**

  * Per-request `signal: AbortSignal` and `timeoutMs: number` on `IFetchAugustOptions`. Combined with the default timeout via `AbortSignal.any` (Node 22+) with a manual relay + cleanup fallback. Distinguishes caller-cancel from timeout via an internal `timedOut` flag.

  **Observability**

  * New `ILogger` interface and `Logger.setStructuredLogger()` alongside the existing Sentry-compatible `SDKLogger`. Pino-friendly: pass a context object as the first arg.

  **Performance**

  * Parallelized `getVault` loans + allocations (`Promise.allSettled`, preserves original control flow).
  * Removed redundant `fetchTokenizedVault` calls in `getVaultLoans` / `getVaultSubaccountLoans`.
  * `createProvider(rpcUrl, chainId?)` enables ethers' `staticNetwork` (skips the `eth_chainId` round-trip).
  * `getInfuraProvider` routes through `createProvider` (was rebuilding per call).
  * `decimals` / `symbol` / `receipt-token` caches are chain-scoped via `providerScope`.

  **Bundle**

  * Buffer polyfill extracted to `polyfills.ts`; guarded against clobbering a consumer-set `Buffer`.
  * `sideEffects: ["./lib/polyfills.js"]` lets bundlers tree-shake the rest of the SDK.
  * Source maps excluded from the npm tarball.

  **Bug fixes**

  * `fetchAugustWithBearer` no longer crashes when `options` is undefined (`options?.` everywhere).
  * `AbortSignal` fallback path now removes its `abort` listener on completion (no more leak across long-lived caller signals).
  * Slack adapter's webhook fetch has a 5s timeout.
  * `sanitizeError` preserves typed-error subclasses by cloning via prototype + own properties instead of calling the constructor (which would have misaligned positional args like `AugustAuthError(code, message, opts)`).
  * `AugustSDKError` and subclasses ship a `toJSON()` so `JSON.stringify(err)` no longer returns `"{}"`. `code`, `correlationId`, `status`, `timeoutMs`, `retryAfterMs`, and `cause` are all included.

  **No public API breaks.** All additions are opt-in. The only behavior change is `fetchAugustWithKey(undefined, …)` throwing instead of returning a fake 500 — the thrown value is still an `Error` instance.
* 8881c9b: feat(sdk): expose `getVaultRedemptionHistory` on the `AugustVaults` module and the top-level `AugustSDK` class. Wraps the existing module-level getter with the standard option-plumbing (RPC resolution from `chainId`, `augustKey`/`subgraphKey`/`headers` from the SDK instance), validates the vault input, and returns the same historical redemption records the underlying getter produces. Stellar vaults continue to return `[]` until on-chain indexing lands for that adapter.

### Patch Changes

* 7027223: fix: vault read paths no longer hang or surface ethers' `network is not available yet` when the configured RPC is unreachable or rate-limited

  Three related changes that together resolve `august vault tvl <addr> --chain <id>` failures (cryptic `NETWORK_ERROR` on a healthy RPC, infinite "JsonRpcProvider failed to detect network" retry loop on a 403/401 RPC):

  * `providerScope` (cache-key builder used by `getDecimals`, `getReceiptTokenAddress`, …) now tolerates ethers v6's lazy-network state. Reading `provider._network` is a *getter* that throws `network is not available yet` until the first successful request resolves the chain id; the throw was bubbling out of every cached vault read on freshly constructed providers.
  * `AugustVaults.getVaultTvl` now threads `chainId` into the getter options, and the EVM branch of `getVaultTvl` (`packages/sdk/src.ts/modules/vaults/getters.ts`) forwards it to `createProvider`. This sets ethers' `staticNetwork`, skipping the `eth_chainId` round-trip and, more importantly, preventing the indefinite network-detection retry loop when the RPC returns 4xx errors.
  * `createProvider` now throws a clear, remediable error when called with a missing or empty `rpcUrl`, instead of silently constructing a `JsonRpcProvider` pointed at `http://localhost:8545`.
* f0741e2: fix: HyperEVM RPC compatibility for `getWithdrawalRequestsWithStatus`
* c14c10b: chore: remove unused `name` field from `AugustSDK`. The field was declared but never assigned and never read — `appName` (on `AugustBase`) is the single source of truth for the app identifier.
* 0cb921a: fix: cap `fetchTokenizedVaults` cache at 10 minutes and avoid stale-get eviction

  `fetchTokenizedVaults` (bulk list) was calling `CACHE.set(key, value)` with no TTL override, falling back to the 24-hour global default — so vault config changes made on the backend (fee rates, fee waivers, etc.) could take up to 24h to surface to bulk-list consumers. The cache lookup also called `CACHE.get(key)` twice in a row; because the global `CACHE` is configured with `allowStale: true`, the first `.get()` on a stale entry returns it *and* evicts it, leaving the second `.get()` `undefined`. Switched to `getSafeCache` (which uses `.has()` and so never triggers stale-get eviction) and set an explicit 10-minute TTL to match `fetchTokenizedVault` (single).

</details>
{% endupdate %}

{% update date="2026-05-12" %}

## 4.27.3

{% hint style="info" %}
**Integrator highlights**

* **Action:** Blacklisted vault addresses are now excluded from `totalDeposited`; verify any TVL aggregations that relied on all vaults being counted.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 651d08f: feat: add a TVL exclusion list for vaults so blacklisted addresses no longer count toward `totalDeposited`.
* b07fd3f: chore: update Goldsky subgraph routes for improved query performance.

</details>
{% endupdate %}

{% update date="2026-05-12" %}

## 4.27.2

{% hint style="info" %}
**Integrator highlights**

* **Action:** Older withdrawal requests previously missed by `getWithdrawalRequestsWithStatus` will now appear; update any UI or logic that assumed a complete list.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 7fc6a6b: fix: correct the lookback block window in `getWithdrawalRequestsWithStatus` so older withdrawal requests are no longer missed.

</details>
{% endupdate %}

{% update date="2026-05-12" %}

## 4.27.1

{% hint style="info" %}
**Integrator highlights**

* **New:** Fluent network is now supported with a default RPC URL and block explorer.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 178dbfc: feat: add support for the Fluent network, including default RPC URL and block explorer.

</details>
{% endupdate %}

{% update date="2026-05-12" %}

## 4.27.0

{% hint style="info" %}
**Integrator highlights**

* **Breaking:** getWithdrawalRequestsWithStatus now requires a chainId argument; calls without it will break cross-chain queries.
* **Action:** Pass `chainId` to all existing `getWithdrawalRequestsWithStatus` calls.
* **New:** `AugustVaults.rwaRedeemAsset()` and `previewRwaRedemption()` added for RWA instant redemption flows.
* **New:** New `instant_redeem_config` field on `IVault` returned from `getVault`/`getVaults`.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 78231b6: feat: add RWA instant redemption — new `AugustVaults.rwaRedeemAsset()` and `previewRwaRedemption()` methods, plus an `instant_redeem_config` field on `IVault` returned from `getVault`/`getVaults`. The SDK automatically routes redemption calls to the correct `RwaRedeemSubaccount` for each vault.

### Patch Changes

* 5766173: fix: `getWithdrawalRequestsWithStatus` now requires a `chainId` argument so cross-chain queries return correct results.
* 8872391: feat: add helpers for OFT (LayerZero Omnichain Fungible Token) flows.

</details>
{% endupdate %}

{% update date="2026-04-14" %}

## 4.25.2

{% hint style="info" %}
**Integrator highlights**

* **Action:** Non-EVM Debank positions previously missing from `getVaultAllocations` now appear; update any allocation totals accordingly.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* f002124: fix: include non-EVM Debank positions in the response from `getVaultAllocations`.

</details>
{% endupdate %}

{% update date="2026-04-14" %}

## 4.25.1

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 3102191: fix: prevent `ethers v6 tx.wait()` from crashing on Monad RPC when pending transactions return a malformed nonce.

</details>
{% endupdate %}

{% update date="2026-04-14" %}

## 4.25.0

{% hint style="info" %}
**Integrator highlights**

* **Action:** New `show_cap_filled` field on tokenized vault responses can now drive cap-filled UI states.
* **New:** `getWithdrawalRequestsWithStatus` added for tracking withdrawal request statuses.
* **New:** New `getVaultPendingRedemptions` method added on `AugustVaults`.
* **New:** New `fetchTokenizedVaultSubaccountLoans` function available for subaccount loan data on tokenized vaults.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* a267145: feat: add a Stellar SDK adapter — Soroban RPC support, transaction building and submission, and end-to-end localnet test coverage.
* 455b625: feat: add `getWithdrawalRequestsWithStatus` for tracking the status of withdrawal requests.
* ad5ea73: chore: remove SUI points from vault responses.
* 7e5aa22: feat: add Stellar vault support (backend-only) including a Stellar adapter, routing, and a shared vault builder.

### Patch Changes

* 8f1bcee: chore: refactor Solana vault adapter getters into a shared `buildBackendVault` utility (no public API change).
* c721801: fix: include PnL data in LayerZero (LZ) vault responses.
* e12e957: fix: prevent silent data loss in `getWithdrawalRequestsWithStatus` when responses span multiple pages.
* d6e7f96: feat: add `fetchTokenizedVaultSubaccountLoans` for retrieving subaccount loan data on tokenized vaults.
* bba0483: feat: add `show_cap_filled` to the tokenized vault response so callers can render cap-filled UI states.
* fd90233: feat: add a `getVaultPendingRedemptions` method on `AugustVaults`.

</details>
{% endupdate %}

{% update date="2026-03-04" %}

## 4.24.10

{% hint style="info" %}
**Integrator highlights**

* **Action:** CeFi positions previously missing from allocations responses now appear; update any allocation aggregations.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* ac2bb72: fix: include CeFi positions that were previously missing from the allocations response.

</details>
{% endupdate %}

{% update date="2026-03-03" %}

## 4.24.9

{% hint style="info" %}
**Integrator highlights**

* **New:** Withdraw support added for the earnAUSD vault.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* ff68463: feat: add withdraw support for the earnAUSD vault.

</details>
{% endupdate %}

{% update date="2026-03-02" %}

## 4.24.8

{% hint style="info" %}
**Integrator highlights**

* **Action:** Solana share balances now reflect correct decimals via `uiAmount`; verify any balance display logic.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 78b4b2a: fix: use the parsed `uiAmount` when reading Solana share balances so they reflect the correct decimals.

</details>
{% endupdate %}

{% update date="2026-03-02" %}

## 4.24.7

{% hint style="info" %}
**Integrator highlights**

* **New:** Vault version is now supported in Solana PDA derivation.
* **New:** Additional fields are available on vault response objects.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 40e6410: feat: support vault version in Solana PDA derivation; remove unused vault token-balance fetching.
* bad15e1: feat: add additional fields to vault responses.

</details>
{% endupdate %}

{% update date="2026-02-26" %}

## 4.24.6

{% hint style="info" %}
**Integrator highlights**

* **Action:** CommonJS builds previously had `AugustBase` undefined due to circular imports; upgrade to fix.
* **Action:** Solana multi-vault programs now correctly read the share mint from on-chain state instead of PDA derivation.
* **New:** earnAUSD support added over LayerZero.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* bf55850: feat: add earnAUSD support over LayerZero.
* 301e84e: fix: resolve a circular dependency in the Solana adapter imports that caused `AugustBase` to be undefined in CommonJS builds.
* e0a1135: fix: forward `vaultAddress` to `getVaultState` from `getVaultPositions` so PDA derivation no longer returns the wrong address.
* 40d8d3f: fix: read the share mint from on-chain vault state (instead of PDA derivation) so multi-vault Solana programs are supported correctly.
* ebefff4: fix: ensure the tokenized vault API call always issues its query.

</details>
{% endupdate %}

{% update date="2026-02-19" %}

## 4.24.5

{% hint style="info" %}
**Integrator highlights**

* **New:** `default_apy_horizon` field is now exposed on vault responses.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 6ab5765: feat: expose `default_apy_horizon` on vault responses.

</details>
{% endupdate %}

{% update date="2026-02-17" %}

## 4.24.4

{% hint style="info" %}
**Integrator highlights**

* **New:** A staging API URL is now available for non-production environments.
* **New:** Deposits made through LayerZero relayers are now supported.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* a3bf6eb: feat: add a staging API URL for use in non-production environments.
* 4365252: feat: support deposits made through LayerZero relayers.

</details>
{% endupdate %}

{% update date="2026-02-12" %}

## 4.24.3

{% hint style="info" %}
**Integrator highlights**

* **New:** Citrea chain support added to explorer link helpers.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 4cd81a9: feat: add Citrea chain support to explorer link helpers.

</details>
{% endupdate %}

{% update date="2026-02-06" %}

## 4.24.2

{% hint style="info" %}
**Integrator highlights**

* **New:** `getSubaccountSummary` method added for fetching summarized subaccount data.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* c53ae5e: feat: add `getSubaccountSummary` for fetching summarized subaccount data.

</details>
{% endupdate %}

{% update date="2026-02-04" %}

## 4.24.1

{% hint style="info" %}
**Integrator highlights**

* **Action:** `getVaultUserLifetimePnl` now excludes invalid transactions and handles multi-asset deposit vaults correctly; verify PnL calculations.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 6213fb9: fix: `getVaultUserLifetimePnl` now excludes invalid transactions when computing PnL.
* 52cc399: fix: `getVaultUserLifetimePnl` correctly handles vaults that accept multi-asset deposits.

</details>
{% endupdate %}

{% update date="2026-02-02" %}

## 4.24.0

{% hint style="info" %}
**Integrator highlights**

* **New:** Sender-whitelist allocations are now supported on the vault contract.
* **New:** The `withdrawal_only` field is now included on vault responses.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 654d3f2: feat: support sender-whitelist allocations on the vault contract; fix: include the `withdrawal_only` field on vault responses.

</details>
{% endupdate %}

{% update date="2026-01-29" %}

## 4.23.2

{% hint style="info" %}
**Integrator highlights**

* **New:** `cachedAt` is now exposed on cached responses so callers can reason about staleness.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* cec539b: perf: improve loading speed of `getVaultPositions`.
* a498e6e: feat: expose `cachedAt` on cached responses so callers can reason about staleness.

</details>
{% endupdate %}

{% update date="2026-01-23" %}

## 4.23.1

{% hint style="info" %}
**Integrator highlights**

* **New:** Debank service is now exposed publicly, allowing consumers to access raw Debank data directly.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 2d5af1c: feat: expose the Debank service so consumers can access raw Debank data directly.

</details>
{% endupdate %}

{% update date="2026-01-23" %}

## 4.23.0

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 9bbcc06: chore: internal version bump — no customer-facing changes.

</details>
{% endupdate %}

{% update date="2026-01-23" %}

## 4.22.0

{% hint style="info" %}
**Integrator highlights**

* **Action:** CJS consumers should update to restore CommonJS compatibility broken by the prior `uuid` version.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 1700a0c: fix: fetch earnAUSD exposures from the Debank API.
* e1c36f3: fix: downgrade the `uuid` dependency to a version that ships CommonJS, restoring CJS consumer compatibility.

</details>
{% endupdate %}

{% update date="2026-01-21" %}

## 4.20.1

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* e6d592f: fix: improve type safety of the contract wrapper.

</details>
{% endupdate %}

{% update date="2026-01-21" %}

## 4.20.0

{% hint style="info" %}
**Integrator highlights**

* **New:** Sentry integration for SDK error reporting is now available as an opt-in feature.
* **New:** A strongly typed ABI-driven contract class is introduced for safer on-chain reads and writes.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 9c456e8: feat: integrate Sentry for SDK observability and error reporting (opt-in).

### Patch Changes

* 0252a45: feat: introduce a strongly typed ABI-driven contract class for safer reads and writes.

</details>
{% endupdate %}

{% update date="2026-01-14" %}

## 4.18.1

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 444f2d9: fix: add a hardcoded subaccount address for earnAUSD where on-chain discovery is not available.

</details>
{% endupdate %}

{% update date="2026-01-13" %}

## 4.18.0

{% hint style="info" %}
**Integrator highlights**

* **New:** New write function available for depositing native assets into multi-asset vaults.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* a765147: feat: add a write function for depositing native assets into multi-asset vaults.

</details>
{% endupdate %}

{% update date="2026-01-12" %}

## 4.17.0

{% hint style="info" %}
**Integrator highlights**

* **New:** The SUI limited vault is now exposed via the SDK.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* dd2bc24: feat: expose the SUI limited vault.

</details>
{% endupdate %}

{% update date="2026-01-09" %}

## 4.16.0

{% hint style="info" %}
**Integrator highlights**

* **New:** Subgraph URLs and vault symbols are now fetched from the backend at runtime; new vaults appear without an SDK release.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* d7b8729: feat: remove hardcoded subgraph URLs and vault symbols — these are now fetched from the backend at runtime, so new vaults can appear without an SDK release.

</details>
{% endupdate %}

{% update date="2026-01-06" %}

## 4.15.4

{% hint style="info" %}
**Integrator highlights**

* **Action:** Instant redemption fee values may change; the corrected fetch function is now used.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 3f45029: fix: correct the function used to fetch the instant redemption fee.

</details>
{% endupdate %}

{% update date="2026-01-05" %}

## 4.15.3

{% hint style="info" %}
**Integrator highlights**

* **New:** EVM2 instant withdrawal logic is now supported.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 1e34016: chore: generalize the Goldsky URL for better scaling; feat: add EVM2 instant withdrawal logic.

</details>
{% endupdate %}

{% update date="2026-01-01" %}

## 4.15.2

{% hint style="info" %}
**Integrator highlights**

* **Action:** `toNormalizeBN` now correctly handles exponential notation values; verify dependent calculations.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 769b4c7: fix: `toNormalizeBN` now correctly handles values represented in exponential notation.

</details>
{% endupdate %}

{% update date="2025-12-23" %}

## 4.15.1

{% hint style="info" %}
**Integrator highlights**

* **New:** `previewRedemption()` method is now available.
* **New:** `campaignApy` field is now included on `IVault`.
* **New:** sentUSD is now available in subgraph configuration.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* e79ced7: feat: add sentUSD to the subgraph configuration.
* fff8076: feat: add `previewRedemption()`; perf: cache the tokenized vault API response in `fetchTokenizedVault`; fix: add the missing `campaignApy` field to `IVault`.

</details>
{% endupdate %}

{% update date="2025-12-19" %}

## 4.15.0

{% hint style="info" %}
**Integrator highlights**

* **New:** `getTotalDeposit()`, `depositCap`, `maxDepositAmount`, `enabled_historical_price_horizons`, and `latest_reported_tvl` are now exposed on vault responses.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* c7422f7: feat: expose `getTotalDeposit()`, `depositCap`, `maxDepositAmount`, `enabled_historical_price_horizons`, and `latest_reported_tvl` on vault responses.

</details>
{% endupdate %}

{% update date="2025-12-19" %}

## 4.14.1

{% hint style="info" %}
**Integrator highlights**

* **New:** Campaign APY is now included in the tokenized vault response.
* **New:** earnXRP and Tydro vaults are now supported.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 1d6fae6: chore: upgrade the supported Node.js version to 22.
* 04c9281: feat: include campaign APY in the tokenized vault response.
* cfc7f40: feat: add support for the earnXRP and Tydro vaults.

</details>
{% endupdate %}

{% update date="2025-12-16" %}

## 4.14.0

{% hint style="info" %}
**Integrator highlights**

* **New:** Campaign APY is now included in the tokenized vault response.
* **New:** earnXRP and Tydro vaults are now supported.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 1d6fae6: chore: upgrade the supported Node.js version to 22.
* 04c9281: feat: include campaign APY in the tokenized vault response.
* cfc7f40: feat: add support for the earnXRP and Tydro vaults.

</details>
{% endupdate %}

{% update date="2025-12-20" %}

## 4.14.0

{% hint style="info" %}
**Integrator highlights**

* **Action:** Migrate `IVaultAnnualizedApy.hgETH30dLiquidAPY` to `liquidAPY30Day` before 2026-01-01.
* **Action:** Migrate `IVaultAnnualizedApy.hgETH7dLiquidAPY` to `liquidAPY7Day` before 2026-01-01.
* **New:** `getVaultAnnualizedApy`, `getVaultSummary`, and `getVaultWithdrawals` methods are now available.
* **New:** New types `IVaultAnnualizedApy`, `IVaultSummary`, and `IVaultWithdrawals` are exported.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 0364b53: feat: add new vault API methods.

  **New Methods:**

  * `getVaultAnnualizedApy` — fetch annualized APY metrics for vaults (cUSDO, tETH, wstETH, rsETH).
  * `getVaultSummary` — fetch a summary of a vault (name, type, chain, recent returns).
  * `getVaultWithdrawals` — fetch a withdrawal summary and the pending withdrawal queue.

  **New Types:**

  * `IVaultAnnualizedApy`
  * `IVaultSummary`
  * `IVaultWithdrawals`

  **Deprecation Notice:**

  * `IVaultAnnualizedApy.hgETH30dLiquidAPY` — use `liquidAPY30Day` instead (removal: 2026-01-01).
  * `IVaultAnnualizedApy.hgETH7dLiquidAPY` — use `liquidAPY7Day` instead (removal: 2026-01-01).

  **Documentation:**

  * Vault method documentation added to `docs/02-vaults.md`.

</details>
{% endupdate %}

{% update date="2025-12-11" %}

## 4.13.2

{% hint style="info" %}
**Integrator highlights**

* **Action:** Migrate from deprecated `getVaultApy` to `getVaultHistoricalTimeseries`.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* c6d5ad5: fix: update the type of historical APY values; deprecate `getVaultApy` — use `getVaultHistoricalTimeseries` instead.

</details>
{% endupdate %}

{% update date="2025-12-10" %}

## 4.13.1

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* e67bb0c: fix: make subaccount and snapshot loading optional in `fetchVaultsComprehensive` to reduce unneeded RPC volume.

</details>
{% endupdate %}

{% update date="2025-12-10" %}

## 4.13.0

{% hint style="info" %}
**Integrator highlights**

* **Action:** Migrate from deprecated `historical_snapshots` on vault response to `getVaultHistoricalTimeseries`.
* **New:** Katana chain is now supported.
* **New:** Subgraph configuration added for superMON, earnMON, and k3EUROP vaults.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 01f6203: feat: add support for the Katana chain.

### Patch Changes

* e58170f: fix: improve observability when Goldsky subgraph requests fail.
* d417f0b: feat: add subgraph configuration for the superMON, earnMON, and k3EUROP vaults.
* fe74f64: fix: update the query parameters used by the tokenized vault endpoints; deprecate `historical_snapshots` on the vault response — use `getVaultHistoricalTimeseries` instead.

</details>
{% endupdate %}

{% update date="2025-12-09" %}

## 4.12.1

{% hint style="info" %}
**Integrator highlights**

* **New:** getVaultTimeSeries endpoint is now exposed on the AugustSDK class.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 01cb0b6: feat: expose the `getVaultTimeSeries` endpoint on the `AugustSDK` class.

</details>
{% endupdate %}

{% update date="2025-12-09" %}

## 4.12.0

{% hint style="info" %}
**Integrator highlights**

* **New:** New vault time-series endpoint added to the SDK.
* **New:** getTokenizedVault accepts a new optional loadSubaccounts parameter.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 8ef93e5: feat: add a vault time-series endpoint; fix: add an optional `loadSubaccounts` parameter to the get tokenized vault endpoint.

</details>
{% endupdate %}

{% update date="2025-12-07" %}

## 4.11.6

{% hint style="info" %}
**Integrator highlights**

* **New:** New getVaultPnl method available for fetching vault-level PnL.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* b842e02: feat: add `getVaultPnl` for fetching vault-level PnL.

</details>
{% endupdate %}

{% update date="2025-12-04" %}

## 4.11.5

{% hint style="info" %}
**Integrator highlights**

* **Action:** getVaultUserLifetimePnl now uses share price for position derivation; verify PnL values against previous results.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* f4eb84c: fix: `getVaultUserLifetimePnl` now derives the user's current position from the share price for a more accurate PnL.

</details>
{% endupdate %}

{% update date="2025-12-04" %}

## 4.11.4

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 3f210b1: fix: update the Monad block explorer URL.

</details>
{% endupdate %}

{% update date="2025-12-03" %}

## 4.11.3

{% hint style="info" %}
**Integrator highlights**

* **Action:** getVaultUserLifetimePnl calculation logic corrected; re-verify any cached or displayed PnL values.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 623f3ec: fix: correct the calculation logic in `getVaultUserLifetimePnl`.

</details>
{% endupdate %}

{% update date="2025-12-02" %}

## 4.11.2

{% hint style="info" %}
**Integrator highlights**

* **Action:** lagDuration calculation corrected; results depending on this value may change.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 73636bd: fix: correct the `lagDuration` calculation.

</details>
{% endupdate %}

{% update date="2025-12-02" %}

## 4.11.1

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 38dbaa8: fix: additional fixes for the Hyena vaults.

</details>
{% endupdate %}

{% update date="2025-12-02" %}

## 4.11.0

{% hint style="info" %}
**Integrator highlights**

* **New:** New external points interface added for vaults integrating third-party point programs.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 74af6be: feat: add an external points interface for vaults that integrate third-party point programs.

</details>
{% endupdate %}

{% update date="2025-12-02" %}

## 4.10.0

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* a23bce0: perf: optimize `getVaultUserLifetimePnl` for faster execution.

</details>
{% endupdate %}

{% update date="2025-11-26" %}

## 4.9.0

{% hint style="info" %}
**Integrator highlights**

* **New:** New `getVaultUserLifetimePnl` function retrieves a user's lifetime PnL for a vault.
* **New:** Subgraph history queries now support the EVM2 network.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 83ee1e1: feat: add `getVaultUserLifetimePnl` for retrieving a user's lifetime PnL on a vault.

### Patch Changes

* f2582b9: feat: support EVM2 for subgraph history queries.

</details>
{% endupdate %}

{% update date="2025-11-21" %}

## 4.7.3

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* f2e0046: chore: update Monad Goldsky subgraph endpoints.

</details>
{% endupdate %}

{% update date="2025-11-20" %}

## 4.7.2

{% hint style="info" %}
**Integrator highlights**

* **Breaking:** The `getVault` family of functions has been renamed to `fetchTokenizedVault`; update all call sites.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 545dd1b: refactor: rename the `getVault` family of functions to `fetchTokenizedVault`.

</details>
{% endupdate %}

{% update date="2025-11-21" %}

## 4.7.2

{% hint style="info" %}
**Integrator highlights**

* **New:** Vault response objects now include additional fields.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* acd34a8: feat: include additional fields on vault responses.

</details>
{% endupdate %}

{% update date="2025-11-19" %}

## 4.7.1

{% hint style="info" %}
**Integrator highlights**

* **Action:** A regression was introduced in tokenized vault fetching; update to this patch to restore correct behavior.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 4ffaeeb: fix: revert a recent change to the tokenized vault fetch logic that introduced regressions.

</details>
{% endupdate %}

{% update date="2025-11-19" %}

## 4.7.0

{% hint style="info" %}
**Integrator highlights**

* **New:** Added support for the Ink and Flare chains.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 88e5d79: feat: add support for the Ink and Flare chains.

</details>
{% endupdate %}

{% update date="2025-11-14" %}

## 4.6.1

{% hint style="info" %}
**Integrator highlights**

* **Action:** Deposit cap is no longer fetched on initial vault load; ensure your integration handles on-demand loading.
* **New:** Tokenized vault response now includes a `historical_apy` field.
* **New:** New deposit-with-permit function allows depositing using EIP-2612 signatures.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 79c3917: feat: add `historical_apy` to the tokenized vault response.
* b01879f: feat: add a deposit-with-permit function so callers can deposit using EIP-2612 signatures.
* 5506682: perf: reduce RPC calls during vault fetching.
* c7b052e: perf: remove the deposit cap query from the initial vault fetch — it's loaded on demand instead.

</details>
{% endupdate %}

{% update date="2025-11-19" %}

## 4.6.1

{% hint style="info" %}
**Integrator highlights**

* **Action:** `integration` and `apy` fields are now sourced from the backend; verify values match your expectations.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 87c24b2: chore: source the `integration` and `apy` fields from the backend instead of computing them client-side.

</details>
{% endupdate %}

{% update date="2025-11-14" %}

## 4.6.0

{% hint style="info" %}
**Integrator highlights**

* **Breaking:** `getAvailableRedemptions` now uses the correct normalization function, which may change returned values.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 4cbe3b4: fix: `getAvailableRedemptions` now uses the correct normalization function.

</details>
{% endupdate %}

{% update date="2025-11-14" %}

## 4.5.2

{% hint style="info" %}
**Integrator highlights**

* **Action:** Available and pending withdrawal values have changed for accuracy; verify your withdrawal logic against updated results.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 50d47da: fix: improve the available and pending withdrawal logic for accuracy.

</details>
{% endupdate %}

{% update date="2025-11-12" %}

## 4.5.1

{% hint style="info" %}
**Integrator highlights**

* **New:** New `depositCap` contract call is exposed when the vault implements it.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 4d1c505: feat: expose the `depositCap` contract call when the vault implements it.

</details>
{% endupdate %}

{% update date="2025-11-07" %}

## 4.5.0

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 7e03e06: chore: update the SDK to consume the latest subgraph schema.

</details>
{% endupdate %}

{% update date="2025-11-06" %}

## 4.4.7

{% hint style="info" %}
**Integrator highlights**

* **Action:** Improved `bigint` arithmetic handling may change results for large amounts; verify calculations.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 3a43ccc: fix: improve `bigint` handling for safer arithmetic on large amounts.

</details>
{% endupdate %}

{% update date="2025-11-06" %}

## 4.4.6

{% hint style="info" %}
**Integrator highlights**

* **New:** New vault reader function available for direct on-chain reads.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 715c56f: feat: expose a vault reader function for direct on-chain reads.

</details>
{% endupdate %}

{% update date="2025-11-06" %}

## 4.4.5

{% hint style="info" %}
**Integrator highlights**

* **Breaking:** The `vaultRequestRedeem` function signature has changed; update all call sites.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 394a38e: feat: update the `vaultRequestRedeem` function signature.

</details>
{% endupdate %}

{% update date="2025-11-05" %}

## 4.4.4

{% hint style="info" %}
**Integrator highlights**

* **New:** `walletToSigner` helper added for converting a wallet to an ethers signer.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 9a77fbe: feat: add a `walletToSigner` helper for converting a wallet to an ethers signer.

</details>
{% endupdate %}

{% update date="2025-11-04" %}

## 4.4.3

{% hint style="info" %}
**Integrator highlights**

* **Breaking:** The `vaultDeposit` function signature has changed; update all call sites.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* e704bc7: feat: update the `vaultDeposit` function signature.

</details>
{% endupdate %}

{% update date="2025-11-03" %}

## 4.4.2

{% hint style="info" %}
**Integrator highlights**

* **New:** Monad chain is now supported.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* e76546f: feat: add support for the Monad chain.

</details>
{% endupdate %}

{% update date="2025-11-03" %}

## 4.4.1

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* cc0e6cf: chore: internal version bump — no customer-facing changes.

</details>
{% endupdate %}

{% update date="2025-10-31" %}

## 4.4.0

{% hint style="info" %}
**Integrator highlights**

* **New:** `getVault` API version has been bumped; responses may include new schema fields.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* d4bad1a: feat: bump the `getVault` API version.

</details>
{% endupdate %}

{% update date="2025-10-31" %}

## 4.3.5

{% hint style="info" %}
**Integrator highlights**

* **New:** Added support for the farmBOLD vault.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 19ffdd2: feat: add support for the farmBOLD vault.

</details>
{% endupdate %}

{% update date="2025-10-31" %}

## 4.3.4

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* f761bfb: chore: update EOA-operator types.

</details>
{% endupdate %}

{% update date="2025-10-30" %}

## 4.3.3

{% hint style="info" %}
**Integrator highlights**

* **New:** Points response now includes a `rank` field for the user.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 92a0cef: feat: add a user `rank` to the points response.

</details>
{% endupdate %}

{% update date="2025-10-30" %}

## 4.3.2

{% hint style="info" %}
**Integrator highlights**

* **New:** Vaults now support EOA operators.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* b79ab00: chore: update the Goldsky URL.
* 051fece: feat: support EOA operators on vaults.

</details>
{% endupdate %}

{% update date="2025-10-29" %}

## 4.3.1

{% hint style="info" %}
**Integrator highlights**

* **New:** `getVault` accepts updated/additional parameters.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* cf57cc7: feat: update the parameters accepted by `getVault`.

</details>
{% endupdate %}

{% update date="2025-10-29" %}

## 4.3.0

{% hint style="info" %}
**Integrator highlights**

* **Action:** Historical APY data URL corrected; verify APY results if you cache or depend on that endpoint.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* ebccf02: fix: correct the URL used to fetch historical APY data.

</details>
{% endupdate %}

{% update date="2025-10-29" %}

## 4.2.3

{% hint style="info" %}
**Integrator highlights**

* **New:** Added support for Sentora WBTC and Sentora USCC vaults.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* fa53783: feat: add support for the Sentora WBTC and Sentora USCC vaults.

</details>
{% endupdate %}

{% update date="2025-10-23" %}

## 4.2.1

{% hint style="info" %}
**Integrator highlights**

* **New:** Goldsky subgraph configuration added for new vaults.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* d5a62f1: feat: add Goldsky subgraph configuration for new vaults.

</details>
{% endupdate %}

{% update date="2025-10-23" %}

## 4.2.0

{% hint style="info" %}
**Integrator highlights**

* **Breaking:** `getVaultTVL` now requires a `chainId` parameter for cross-chain accuracy.
* **Action:** Pass `chainId` when calling `getVaultTVL` to ensure correct results.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* bc9a666: feat: `getVaultTVL` now takes a `chainId` for cross-chain accuracy.

</details>
{% endupdate %}

{% update date="2025-10-21" %}

## 4.1.0

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* d3cec8b: chore: update the strategists fallback list.

### Patch Changes

* 8ab6dab: chore: add hardcoded fallback values for some vault metadata.

</details>
{% endupdate %}

{% update date="2025-09-22" %}

## 3.16.1

{% hint style="info" %}
**Integrator highlights**

* **New:** Raw tokens response from Debank is now exposed directly in the SDK.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 0b615f9: expose raw tokens response from debank
* Updated dependencies \[0b615f9]
  * @augustdigital/services\@3.16.1
  * @augustdigital/vaults\@3.16.1
  * @augustdigital/pools\@3.16.1
  * @augustdigital/types\@3.16.1
  * @augustdigital/utils\@3.16.1
  * @augustdigital/abis\@3.16.1

</details>
{% endupdate %}

{% update date="2025-09-19" %}

## 3.16.0

{% hint style="info" %}
**Integrator highlights**

* **New:** An optional Sentry logger can now be configured in the SDK.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 2edc611: adding an optional logger for sentry

### Patch Changes

* Updated dependencies \[2edc611]
  * @augustdigital/services\@3.16.0
  * @augustdigital/vaults\@3.16.0
  * @augustdigital/pools\@3.16.0
  * @augustdigital/types\@3.16.0
  * @augustdigital/utils\@3.16.0
  * @augustdigital/abis\@3.16.0

</details>
{% endupdate %}

{% update date="2025-09-10" %}

## 3.15.2

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 23fcd01: add xhype subgraph
* Updated dependencies \[23fcd01]
  * @augustdigital/services\@3.15.2
  * @augustdigital/vaults\@3.15.2
  * @augustdigital/pools\@3.15.2
  * @augustdigital/types\@3.15.2
  * @augustdigital/utils\@3.15.2
  * @augustdigital/abis\@3.15.2

</details>
{% endupdate %}

{% update date="2025-09-09" %}

## 3.15.1

{% hint style="info" %}
**Integrator highlights**

* **New:** Debank response now includes an error field for failed responses.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 1ef7bfb: adding coingecko key to staking
* 04c7782: add error response to debank res
* Updated dependencies \[1ef7bfb]
* Updated dependencies \[04c7782]
  * @augustdigital/services\@3.15.1
  * @augustdigital/vaults\@3.15.1
  * @augustdigital/pools\@3.15.1
  * @augustdigital/types\@3.15.1
  * @augustdigital/utils\@3.15.1
  * @augustdigital/abis\@3.15.1

</details>
{% endupdate %}

{% update date="2025-09-09" %}

## 3.15.0

{% hint style="info" %}
**Integrator highlights**

* **New:** API fallback fetch behavior has been updated.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 3bf450e: update API fallback fetch

### Patch Changes

* Updated dependencies \[3bf450e]
  * @augustdigital/services\@3.15.0
  * @augustdigital/vaults\@3.15.0
  * @augustdigital/pools\@3.15.0
  * @augustdigital/types\@3.15.0
  * @augustdigital/utils\@3.15.0
  * @augustdigital/abis\@3.15.0

</details>
{% endupdate %}

{% update date="2025-08-19" %}

## 3.13.10

{% hint style="info" %}
**Integrator highlights**

* **New:** `getWithdraws` now includes withdraw events in its returned data.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* d2e7f94: adding withdraw event to getWithdraws
* Updated dependencies \[d2e7f94]
  * @augustdigital/services\@3.13.10
  * @augustdigital/vaults\@3.13.10
  * @augustdigital/pools\@3.13.10
  * @augustdigital/types\@3.13.10
  * @augustdigital/utils\@3.13.10
  * @augustdigital/abis\@3.13.10

</details>
{% endupdate %}

{% update date="2025-08-12" %}

## 3.13.6

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* a2ca1dd: update lendiingpoolv3
* Updated dependencies \[a2ca1dd]
  * @augustdigital/services\@3.13.6
  * @augustdigital/vaults\@3.13.6
  * @augustdigital/pools\@3.13.6
  * @augustdigital/types\@3.13.6
  * @augustdigital/utils\@3.13.6
  * @augustdigital/abis\@3.13.6

</details>
{% endupdate %}

{% update date="2025-08-12" %}

## 3.13.4

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 383cf57: add upGAMMAusdc subgraph
* Updated dependencies \[383cf57]
  * @augustdigital/services\@3.13.4
  * @augustdigital/vaults\@3.13.4
  * @augustdigital/pools\@3.13.4
  * @augustdigital/types\@3.13.4
  * @augustdigital/utils\@3.13.4
  * @augustdigital/abis\@3.13.4

</details>
{% endupdate %}

{% update date="2025-08-07" %}

## 3.13.3

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* Updated dependencies \[82d0738]
  * @augustdigital/utils\@3.13.3
  * @augustdigital/pools\@3.13.3
  * @augustdigital/services\@3.13.2
  * @augustdigital/vaults\@3.13.3

</details>
{% endupdate %}

{% update date="2025-08-05" %}

## 3.13.0

{% hint style="info" %}
**Integrator highlights**

* **Breaking:** Token exposure return value has been updated, which may require code changes.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 3c1913d: updating token exposure return value

### Patch Changes

* Updated dependencies \[3c1913d]
  * @augustdigital/vaults\@3.13.0
  * @augustdigital/pools\@3.13.0
  * @augustdigital/types\@3.13.0
  * @augustdigital/utils\@3.13.0
  * @augustdigital/abis\@3.13.0

</details>
{% endupdate %}

{% update date="2025-07-25" %}

## 3.12.2

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* Updated dependencies \[cbf643f]
  * @augustdigital/utils\@3.12.2
  * @augustdigital/pools\@3.12.2
  * @augustdigital/vaults\@3.12.2

</details>
{% endupdate %}

{% update date="2025-07-23" %}

## 3.12.1

{% hint style="info" %}
**Integrator highlights**

* **New:** earnAUSD subgraph support added.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 4ce6f73: add earnAUSD subgraph
* Updated dependencies \[4ce6f73]
  * @augustdigital/vaults\@3.12.1
  * @augustdigital/pools\@3.12.1
  * @augustdigital/types\@3.12.1
  * @augustdigital/utils\@3.12.1
  * @augustdigital/abis\@3.12.1

</details>
{% endupdate %}

{% update date="2025-07-21" %}

## 3.12.0

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 1aa9169: fix mezo explorer

### Patch Changes

* Updated dependencies \[1aa9169]
  * @augustdigital/vaults\@3.12.0
  * @augustdigital/pools\@3.12.0
  * @augustdigital/types\@3.12.0
  * @augustdigital/utils\@3.12.0
  * @augustdigital/abis\@3.12.0

</details>
{% endupdate %}

{% update date="2025-07-17" %}

## 3.11.0

{% hint style="info" %}
**Integrator highlights**

* **New:** mezo-mUSD asset support added.
* **New:** Unichain explorer support added.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 2ab0157: adding mezo-mUSD support

### Patch Changes

* b441f0b: add unichain explorer
* Updated dependencies \[b441f0b]
* Updated dependencies \[2ab0157]
  * @augustdigital/vaults\@3.11.0
  * @augustdigital/pools\@3.11.0
  * @augustdigital/types\@3.11.0
  * @augustdigital/utils\@3.11.0
  * @augustdigital/abis\@3.11.0

</details>
{% endupdate %}

{% update date="2025-07-10" %}

## 3.9.1

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* e1ee449: patch bump
* Updated dependencies \[e1ee449]
  * @augustdigital/vaults\@3.9.1
  * @augustdigital/pools\@3.9.1
  * @augustdigital/types\@3.9.1
  * @augustdigital/utils\@3.9.1
  * @augustdigital/abis\@3.9.1

</details>
{% endupdate %}

{% update date="2025-06-28" %}

## 3.6.0

{% hint style="info" %}
**Integrator highlights**

* **New:** Vault and services now surface handled errors instead of throwing silently.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 1eba6a4: handled errors in vault & services

### Patch Changes

* Updated dependencies \[1eba6a4]
  * @augustdigital/vaults\@3.6.0
  * @augustdigital/utils\@3.8.0
  * @augustdigital/abis\@3.6.0
  * @augustdigital/pools\@3.6.0
  * @augustdigital/types\@3.6.0

</details>
{% endupdate %}

{% update date="2025-06-26" %}

## 3.5.1

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* Updated dependencies \[b56895f]
  * @augustdigital/utils\@3.7.0
  * @augustdigital/pools\@3.5.1
  * @augustdigital/vaults\@3.5.1

</details>
{% endupdate %}

{% update date="2025-06-26" %}

## 3.5.0

{% hint style="info" %}
**Integrator highlights**

* **New:** HyperEVM transaction history for users is now available.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* f9edb34: add hyper evm history for user

### Patch Changes

* Updated dependencies \[f9edb34]
  * @augustdigital/abis\@3.5.0
  * @augustdigital/pools\@3.5.0
  * @augustdigital/types\@3.5.0
  * @augustdigital/utils\@3.6.0
  * @augustdigital/vaults\@3.5.0

</details>
{% endupdate %}

{% update date="2025-06-25" %}

## 3.4.1

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* Updated dependencies \[e945c91]
  * @augustdigital/utils\@3.5.0
  * @augustdigital/pools\@3.4.1
  * @augustdigital/vaults\@3.4.1

</details>
{% endupdate %}

{% update date="2025-06-23" %}

## 3.4.0

{% hint style="info" %}
**Integrator highlights**

* **New:** Vault objects now include risk data.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* f98bdf4: update vault with risk

### Patch Changes

* Updated dependencies \[f98bdf4]
  * @augustdigital/vaults\@3.4.0
  * @augustdigital/pools\@3.4.0
  * @augustdigital/types\@3.4.0
  * @augustdigital/utils\@3.4.0
  * @augustdigital/abis\@3.4.0

</details>
{% endupdate %}

{% update date="2025-06-18" %}

## 3.3.1

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* b364c2b: update fetching isVisible vault logic
* Updated dependencies \[b364c2b]
  * @augustdigital/vaults\@3.3.1
  * @augustdigital/pools\@3.3.1
  * @augustdigital/types\@3.3.1
  * @augustdigital/utils\@3.3.1
  * @augustdigital/abis\@3.3.1

</details>
{% endupdate %}

{% update date="2025-06-16" %}

## 3.3.0

{% hint style="info" %}
**Integrator highlights**

* **New:** Event objects now include a hash field for easier transaction lookup.
* **New:** User history fetching behavior has been updated.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* a86b316: update
* c5c2570: update hash in events
* c9b3c1a: update
* 705637a: update fetch user history
* b6e3aba: update version

### Patch Changes

* Updated dependencies \[a86b316]
* Updated dependencies \[c5c2570]
* Updated dependencies \[c9b3c1a]
* Updated dependencies \[705637a]
* Updated dependencies \[b6e3aba]
  * @augustdigital/pools\@3.3.0
  * @augustdigital/types\@3.3.0
  * @augustdigital/utils\@3.3.0
  * @augustdigital/abis\@3.3.0
  * @augustdigital/vaults\@3.3.0

</details>
{% endupdate %}

{% update date="2025-05-27" %}

## 3.1.0

{% hint style="info" %}
**Integrator highlights**

* **New:** Pools now expose an `isFeeWaived` boolean field.
* **New:** User history data has been updated with new information.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 81ab166: add isFeeWaived to pools
* 25bc103: update user history
* 2c4618a: remove console

### Patch Changes

* Updated dependencies \[81ab166]
* Updated dependencies \[25bc103]
* Updated dependencies \[2c4618a]
  * @augustdigital/pools\@3.1.0
  * @augustdigital/types\@3.1.0
  * @augustdigital/utils\@3.1.0
  * @augustdigital/abis\@3.1.0
  * @augustdigital/sdk\@3.1.0

</details>
{% endupdate %}

{% update date="2025-05-21" %}

## 2.18.11

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* Updated dependencies \[311a622]
  * @augustdigital/utils\@2.18.11
  * @augustdigital/pools\@2.18.11

</details>
{% endupdate %}

{% update date="2025-05-08" %}

## 2.18.5

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 7ebbe39: Update Injective Description
* Updated dependencies \[7ebbe39]
  * @augustdigital/pools\@2.18.5
  * @augustdigital/types\@2.18.5
  * @augustdigital/utils\@2.18.5
  * @augustdigital/abis\@2.18.5

</details>
{% endupdate %}

{% update date="2025-05-08" %}

## 2.18.4

{% hint style="info" %}
**Integrator highlights**

* **New:** A new Injective Vault USDT pool is now available.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* b6b86a0: Added Injective Vault USDT
* Updated dependencies \[b6b86a0]
  * @augustdigital/pools\@2.18.4
  * @augustdigital/types\@2.18.4
  * @augustdigital/utils\@2.18.4
  * @augustdigital/abis\@2.18.4

</details>
{% endupdate %}

{% update date="2025-04-19" %}

## 2.16.8

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* 70f3fa8: Mezo Vault Change
* Updated dependencies \[70f3fa8]
* Updated dependencies \[a3ad743]
  * @augustdigital/pools\@2.16.8
  * @augustdigital/types\@2.16.8
  * @augustdigital/utils\@2.16.8
  * @augustdigital/abis\@2.16.8

</details>
{% endupdate %}

{% update date="2025-04-18" %}

## 2.16.2

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* Updated dependencies \[ba9846d]
  * @augustdigital/utils\@2.16.2
  * @augustdigital/pools\@2.16.2

</details>
{% endupdate %}

{% update date="2025-04-17" %}

## 2.16.0

{% hint style="info" %}
**Integrator highlights**

* **New:** Vault whitelist address is now publicly exposed on vault/pool data.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 9cf59d6: expose vault whitelist address

### Patch Changes

* Updated dependencies \[9cf59d6]
  * @augustdigital/pools\@2.16.0
  * @augustdigital/types\@2.16.0
  * @augustdigital/utils\@2.16.0
  * @augustdigital/abis\@2.16.0

</details>
{% endupdate %}

{% update date="2025-04-11" %}

## 2.15.0

{% hint style="info" %}
**Integrator highlights**

* **New:** OTC positions are now available and can be fetched via the SDK.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* e32fce4: add otc positions

### Patch Changes

* Updated dependencies \[e32fce4]
  * @augustdigital/pools\@2.15.0
  * @augustdigital/types\@2.15.0
  * @augustdigital/utils\@2.15.0
  * @augustdigital/abis\@2.15.0

</details>
{% endupdate %}

{% update date="2025-03-31" %}

## 2.13.1

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* Updated dependencies \[f57d7e3]
  * @augustdigital/pools\@2.14.0
  * @augustdigital/utils\@2.14.0

</details>
{% endupdate %}

{% update date="2025-03-28" %}

## 2.13.0

{% hint style="info" %}
**Integrator highlights**

* **New:** DeBank response data is now supported in the SDK.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 83dc214: add debank response

### Patch Changes

* Updated dependencies \[83dc214]
  * @augustdigital/pools\@2.13.0
  * @augustdigital/types\@2.13.0
  * @augustdigital/utils\@2.13.0
  * @augustdigital/abis\@2.13.0

</details>
{% endupdate %}

{% update date="2025-03-25" %}

## 2.12.0

{% hint style="info" %}
**Integrator highlights**

* **New:** Protocol exposure data has been updated with new values.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* dd2cb76: update protocol exposure data

### Patch Changes

* Updated dependencies \[dd2cb76]
  * @augustdigital/pools\@2.12.0
  * @augustdigital/types\@2.12.0
  * @augustdigital/utils\@2.12.0
  * @augustdigital/abis\@2.12.0

</details>
{% endupdate %}

{% update date="2025-03-05" %}

## 2.10.2

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* Updated dependencies \[dcc926f]
  * @augustdigital/abis\@2.10.2
  * @augustdigital/pools\@2.10.2
  * @augustdigital/utils\@2.10.2

</details>
{% endupdate %}

{% update date="2025-03-05" %}

## 2.10.1

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* Updated dependencies \[f8f709d]
  * @augustdigital/abis\@2.10.1
  * @augustdigital/pools\@2.10.1
  * @augustdigital/utils\@2.10.1

</details>
{% endupdate %}

{% update date="2025-03-03" %}

## 2.10.0

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 034db45: spelling error

### Patch Changes

* Updated dependencies \[034db45]
  * @augustdigital/pools\@2.10.0
  * @augustdigital/types\@2.10.0
  * @augustdigital/utils\@2.10.0
  * @augustdigital/abis\@2.10.0

</details>
{% endupdate %}

{% update date="2025-03-03" %}

## 2.9.0

{% hint style="info" %}
**Integrator highlights**

* **New:** Idle capital data is now available in the SDK.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 31ae26a: add idle capital

### Patch Changes

* Updated dependencies \[31ae26a]
  * @augustdigital/pools\@2.9.0
  * @augustdigital/types\@2.9.0
  * @augustdigital/utils\@2.9.0
  * @augustdigital/abis\@2.9.0

</details>
{% endupdate %}

{% update date="2025-01-23" %}

## 2.6.5

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* Updated dependencies \[62619e1]
  * @augustdigital/pools\@2.6.5

</details>
{% endupdate %}

{% update date="2025-01-22" %}

## 2.6.2

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* Updated dependencies \[61d51d4]
  * @augustdigital/pools\@2.6.2

</details>
{% endupdate %}

{% update date="2025-01-21" %}

## 2.6.1

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* Updated dependencies \[8d45228]
  * @augustdigital/pools\@2.6.1
  * @augustdigital/utils\@2.5.1

</details>
{% endupdate %}

{% update date="2025-01-17" %}

## 2.6.0

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* update upshift rewards typography
* d56eb68: update AVAX rewards

### Patch Changes

* Updated dependencies
* Updated dependencies \[d56eb68]
  * @augustdigital/pools\@2.6.0
  * @augustdigital/types\@2.6.0
  * @augustdigital/utils\@2.5.0
  * @augustdigital/abis\@2.5.0

</details>
{% endupdate %}

{% update date="2025-01-17" %}

## 2.5.0

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* ca9514d: update rewards for AVAX

### Patch Changes

* Updated dependencies \[ca9514d]
  * @augustdigital/pools\@2.5.0
  * @augustdigital/types\@2.5.0
  * @augustdigital/utils\@2.4.1

</details>
{% endupdate %}

{% update date="2025-01-17" %}

## 2.4.1

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* Updated dependencies \[44876f7]
  * @augustdigital/pools\@2.4.1

</details>
{% endupdate %}

{% update date="2025-01-16" %}

## 2.4.0

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* ab136b2: update upshift points multiplier

### Patch Changes

* Updated dependencies \[ab136b2]
  * @augustdigital/pools\@2.4.0
  * @augustdigital/types\@2.4.0
  * @augustdigital/utils\@2.4.0
  * @augustdigital/abis\@2.4.0

</details>
{% endupdate %}

{% update date="2025-01-15" %}

## 2.3.1

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* Updated dependencies \[4c562dd]
  * @augustdigital/pools\@2.3.1

</details>
{% endupdate %}

{% update date="2025-01-13" %}

## 2.3.0

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 5515b33: override managementFee

### Patch Changes

* Updated dependencies \[5515b33]
  * @augustdigital/pools\@2.3.0
  * @augustdigital/types\@2.3.0
  * @augustdigital/utils\@2.3.0
  * @augustdigital/abis\@2.3.0

</details>
{% endupdate %}

{% update date="2025-01-10" %}

## 2.2.0

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* f47df7b: updated management fee call

### Patch Changes

* Updated dependencies \[f47df7b]
  * @augustdigital/pools\@2.2.0
  * @augustdigital/types\@2.2.0
  * @augustdigital/utils\@2.2.0
  * @augustdigital/abis\@2.2.0

</details>
{% endupdate %}

{% update date="2025-01-10" %}

## 2.1.2

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* Updated dependencies \[cf49466]
  * @augustdigital/pools\@2.1.1

</details>
{% endupdate %}

{% update date="2025-01-08" %}

## 2.1.1

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* Updated dependencies \[fe65b9d]
  * @augustdigital/pools\@2.1.0
  * @augustdigital/types\@2.1.0
  * @augustdigital/utils\@2.1.3

</details>
{% endupdate %}

{% update date="2025-01-08" %}

## 2.1.0

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 8c457fa: update static keys

</details>
{% endupdate %}

{% update date="2025-01-07" %}

## 2.0.4

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* Updated dependencies \[e96e036]
  * @augustdigital/pools\@2.0.4

</details>
{% endupdate %}

{% update date="2025-01-02" %}

## 2.0.3

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* Updated dependencies \[0ade132]
  * @augustdigital/utils\@2.1.2
  * @augustdigital/abis\@2.1.2
  * @augustdigital/pools\@2.0.3

</details>
{% endupdate %}

{% update date="2024-12-30" %}

## 2.0.2

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* Updated dependencies \[ac83b7d]
* Updated dependencies \[5c34d73]
  * @augustdigital/utils\@2.1.1
  * @augustdigital/abis\@2.1.1
  * @augustdigital/pools\@2.0.2

</details>
{% endupdate %}

{% update date="2024-12-30" %}

## 2.0.1

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* Updated dependencies \[4c16fd6]
  * @augustdigital/utils\@2.1.0
  * @augustdigital/abis\@2.1.0
  * @augustdigital/pools\@2.0.1

</details>
{% endupdate %}

{% update date="2024-12-27" %}

## 2.0.0

{% hint style="info" %}
**Integrator highlights**

* **Breaking:** This release contains breaking changes — see the full changelog below.
* **Action:** Ethena APY value has been updated; verify any hardcoded or cached APY values are refreshed.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Major Changes

* 4267b9a: update ethena apy val

### Patch Changes

* Updated dependencies \[4267b9a]
  * @augustdigital/pools\@2.0.0
  * @augustdigital/types\@2.0.0
  * @augustdigital/utils\@2.0.0
  * @augustdigital/abis\@2.0.0

</details>
{% endupdate %}

{% update date="2024-11-04" %}

## 1.3.0

{% hint style="info" %}
**Integrator highlights**

* **New:** Ava Labs aUSD pool is now available in the pools package.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* c9505a1: added ava labs ausd pool to pool package

### Patch Changes

* Updated dependencies \[c9505a1]
  * @augustdigital/pools\@1.3.0
  * @augustdigital/types\@1.3.0
  * @augustdigital/utils\@1.3.0
  * @augustdigital/abis\@1.3.0

</details>
{% endupdate %}

{% update date="2024-11-01" %}

## 1.2.0

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 3bfe99b: Added build to workflow

### Patch Changes

* Updated dependencies \[3bfe99b]
  * @augustdigital/pools\@1.2.0
  * @augustdigital/types\@1.2.0
  * @augustdigital/utils\@1.2.0
  * @augustdigital/abis\@1.2.0

</details>
{% endupdate %}

{% update date="2024-11-01" %}

## 1.1.0

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* 4504eda: Testing new github workflow"

### Patch Changes

* Updated dependencies \[4504eda]
  * @augustdigital/pools\@1.1.0
  * @augustdigital/types\@1.1.0
  * @augustdigital/utils\@1.1.0
  * @augustdigital/abis\@1.1.0

</details>
{% endupdate %}

{% update date="2024-10-26" %}

## 0.1.0

{% hint style="info" %}
**Integrator highlights**

* **New:** Pool fetchers now accept additional parameters for more granular data fetching.
  {% endhint %}

<details>

<summary>Full changelog</summary>

### Minor Changes

* f9df78f: added parameters to pool fetchers in sdk"

### Patch Changes

* Updated dependencies \[f9df78f]
  * @augustdigital/pools\@0.1.0
  * @augustdigital/types\@0.1.0
  * @augustdigital/utils\@0.1.0
  * @augustdigital/abis\@0.1.0

</details>
{% endupdate %}

{% update date="2024-10-08" %}

## 0.0.3

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* d72f854: (v0.0.3) testing github workflows
* 2f95c56: v0.0.3 edited readme and testing automated npm publish github workflow
* c388be5: (v0.0.2) changeset working appropriately
* Updated dependencies \[d72f854]
* Updated dependencies \[2f95c56]
* Updated dependencies \[c388be5]
  * @augustdigital/pools\@0.0.3
  * @augustdigital/types\@0.0.3
  * @augustdigital/utils\@0.0.3
  * @augustdigital/abis\@0.0.3

</details>
{% endupdate %}

{% update date="2024-10-08" %}

## 0.0.2

{% hint style="info" %}
**Integrator highlights** — internal changes only; no integrator action needed.
{% endhint %}

<details>

<summary>Full changelog</summary>

### Patch Changes

* (0.0.1) testing changeset
* Updated dependencies
  * @augustdigital/pools\@0.0.2
  * @augustdigital/types\@0.0.2
  * @augustdigital/utils\@0.0.2
  * @augustdigital/abis\@0.0.2

</details>
{% endupdate %}
{% endupdates %}
