@augustdigital/sdk 8.5.0 → 8.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/README.md +207 -117
  2. package/lib/adapters/evm/index.d.ts +4 -4
  3. package/lib/adapters/evm/index.js +2 -0
  4. package/lib/adapters/solana/constants.d.ts +1 -1
  5. package/lib/adapters/solana/getters.d.ts +1 -1
  6. package/lib/adapters/solana/index.d.ts +4 -4
  7. package/lib/adapters/solana/index.js +4 -0
  8. package/lib/adapters/solana/types.d.ts +1 -1
  9. package/lib/adapters/solana/utils.d.ts +3 -3
  10. package/lib/adapters/solana/vault.actions.d.ts +4 -4
  11. package/lib/adapters/stellar/actions.d.ts +1 -1
  12. package/lib/adapters/stellar/index.d.ts +24 -2
  13. package/lib/adapters/stellar/index.js +25 -2
  14. package/lib/adapters/stellar/soroban.d.ts +1 -1
  15. package/lib/adapters/stellar/soroban.js +1 -1
  16. package/lib/adapters/stellar/submit.d.ts +20 -3
  17. package/lib/adapters/stellar/submit.js +74 -8
  18. package/lib/adapters/sui/getters.d.ts +1 -1
  19. package/lib/adapters/sui/index.d.ts +1 -1
  20. package/lib/adapters/sui/index.js +2 -0
  21. package/lib/adapters/sui/transformer.d.ts +2 -2
  22. package/lib/adapters/sui/transformer.js +1 -0
  23. package/lib/adapters/sui/types.d.ts +1 -1
  24. package/lib/core/analytics/instrumentation.js +7 -11
  25. package/lib/core/analytics/sentry-runtime.js +1 -1
  26. package/lib/core/analytics/sentry.d.ts +3 -3
  27. package/lib/core/analytics/sentry.js +31 -5
  28. package/lib/core/analytics/types.d.ts +1 -1
  29. package/lib/core/analytics/user-identity.d.ts +2 -2
  30. package/lib/core/analytics/user-identity.js +1 -1
  31. package/lib/core/analytics/version.d.ts +1 -1
  32. package/lib/core/analytics/version.js +1 -1
  33. package/lib/core/base.class.d.ts +3 -3
  34. package/lib/core/base.class.js +10 -4
  35. package/lib/core/constants/adapters.d.ts +1 -1
  36. package/lib/core/constants/core.d.ts +2 -0
  37. package/lib/core/constants/core.js +6 -0
  38. package/lib/core/constants/swap-router.d.ts +37 -1
  39. package/lib/core/constants/swap-router.js +41 -1
  40. package/lib/core/constants/vaults.d.ts +1 -1
  41. package/lib/core/constants/web3.d.ts +1 -1
  42. package/lib/core/constants/web3.js +0 -3
  43. package/lib/core/errors/index.d.ts +2 -2
  44. package/lib/core/errors/index.js +9 -0
  45. package/lib/core/fetcher.d.ts +39 -39
  46. package/lib/core/fetcher.js +75 -57
  47. package/lib/core/helpers/adapters.d.ts +1 -1
  48. package/lib/core/helpers/chain-error.d.ts +66 -0
  49. package/lib/core/helpers/chain-error.js +174 -0
  50. package/lib/core/helpers/core.d.ts +21 -18
  51. package/lib/core/helpers/core.js +22 -20
  52. package/lib/core/helpers/explorer-link.d.ts +1 -1
  53. package/lib/core/helpers/signer.d.ts +1 -1
  54. package/lib/core/helpers/swap-router.d.ts +1 -1
  55. package/lib/core/helpers/vault-version.d.ts +1 -1
  56. package/lib/core/helpers/vaults.d.ts +1 -1
  57. package/lib/core/helpers/web3.d.ts +2 -2
  58. package/lib/core/helpers/web3.js +9 -9
  59. package/lib/core/index.d.ts +1 -0
  60. package/lib/core/index.js +1 -0
  61. package/lib/core/vault-metadata.d.ts +1 -1
  62. package/lib/core/version-check.js +1 -1
  63. package/lib/evm/methods/crossChainVault.js +1 -1
  64. package/lib/evm/types/crossChain.js +1 -1
  65. package/lib/main.d.ts +1 -1
  66. package/lib/main.js +7 -0
  67. package/lib/modules/sub-accounts/fetcher.d.ts +2 -2
  68. package/lib/modules/sub-accounts/main.d.ts +2 -2
  69. package/lib/modules/sub-accounts/main.js +1 -1
  70. package/lib/modules/sub-accounts/utils.d.ts +1 -1
  71. package/lib/modules/vaults/adapter.helpers.d.ts +3 -3
  72. package/lib/modules/vaults/fetcher.d.ts +25 -0
  73. package/lib/modules/vaults/fetcher.js +51 -1
  74. package/lib/modules/vaults/getters.d.ts +50 -50
  75. package/lib/modules/vaults/getters.js +68 -67
  76. package/lib/modules/vaults/main.js +3 -1
  77. package/lib/modules/vaults/read.actions.d.ts +2 -2
  78. package/lib/modules/vaults/read.actions.js +26 -12
  79. package/lib/modules/vaults/utils/call-data-decoder.d.ts +1 -1
  80. package/lib/modules/vaults/utils.d.ts +19 -3
  81. package/lib/modules/vaults/utils.js +39 -6
  82. package/lib/modules/vaults/write.actions.js +73 -7
  83. package/lib/polyfills.js +3 -3
  84. package/lib/sdk.d.ts +1409 -1198
  85. package/lib/services/coingecko/fetcher.d.ts +10 -9
  86. package/lib/services/coingecko/fetcher.js +22 -18
  87. package/lib/services/debank/fetcher.d.ts +1 -1
  88. package/lib/services/debank/utils.d.ts +1 -1
  89. package/lib/services/debank/utils.js +1 -1
  90. package/lib/services/layerzero/deposits.d.ts +1 -1
  91. package/lib/services/layerzero/redeems.d.ts +1 -1
  92. package/lib/services/octavfi/fetcher.d.ts +1 -1
  93. package/lib/services/octavfi/types.d.ts +1 -1
  94. package/lib/services/octavfi/utils.d.ts +2 -2
  95. package/lib/services/subgraph/fetcher.js +1 -1
  96. package/lib/services/subgraph/vaults.js +86 -3
  97. package/lib/services/swap-quotes/index.d.ts +9 -0
  98. package/lib/services/swap-quotes/index.js +2 -1
  99. package/lib/services/swap-quotes/paraswap.d.ts +8 -0
  100. package/lib/services/swap-quotes/paraswap.js +8 -0
  101. package/lib/types/pools.d.ts +2 -2
  102. package/lib/types/staking.d.ts +1 -1
  103. package/lib/types/sub-accounts.d.ts +1 -1
  104. package/lib/types/subgraph.d.ts +10 -1
  105. package/lib/types/vaults.d.ts +26 -0
  106. package/lib/types/web3.d.ts +1 -1
  107. package/lib/types/webserver.d.ts +2 -2
  108. package/package.json +1 -1
@@ -2,13 +2,14 @@
2
2
  * Fetch the latest USD price for a token symbol from CoinGecko's
3
3
  * `/market_chart/range` endpoint, mapped through `COINGECKO_COIN_ID_MAP`.
4
4
  *
5
- * @param symbol Token symbol (case-insensitive). Must be present in
6
- * `COINGECKO_COIN_ID_MAP`; unmapped symbols still hit the network and
7
- * 404 today (see todo/32-coingecko-fetcher-defects.md).
8
- * @param coinGeckoKey CoinGecko Pro API key passed as `x-cg-pro-api-key`.
9
- * @returns The latest price in USD on success; `null` on any failure
10
- * (non-2xx response, network error, JSON parse error, or missing
11
- * `prices` array). The `musd` short-circuit returns a tuple literal
12
- * for back-compat see todo/32 for the cleanup.
5
+ * @param symbol - Token symbol (case-insensitive). Must be present in
6
+ * `COINGECKO_COIN_ID_MAP`.
7
+ * @param coinGeckoKey - CoinGecko Pro API key passed as `x-cg-pro-api-key`.
8
+ * @returns The latest price in USD (a number) on success; `null` when the
9
+ * response contains an empty or missing `prices` array. `musd` (mezo-usd)
10
+ * is a USD-pegged stablecoin and short-circuits to a price of `1`.
11
+ * @throws {@link AugustValidationError} When `symbol` is not in `COINGECKO_COIN_ID_MAP`.
12
+ * @throws {@link AugustRateLimitError} On a 429 response from CoinGecko.
13
+ * @throws {@link AugustServerError} On any other non-2xx response.
13
14
  */
14
- export declare function fetchTokenPricesFromCoinGecko(symbol: string, coinGeckoKey: string): Promise<any>;
15
+ export declare function fetchTokenPricesFromCoinGecko(symbol: string, coinGeckoKey: string): Promise<number>;
@@ -2,26 +2,30 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.fetchTokenPricesFromCoinGecko = fetchTokenPricesFromCoinGecko;
4
4
  const logger_1 = require("../../core/logger");
5
+ const errors_1 = require("../../core/errors");
5
6
  const utils_1 = require("./utils");
6
7
  /**
7
8
  * Fetch the latest USD price for a token symbol from CoinGecko's
8
9
  * `/market_chart/range` endpoint, mapped through `COINGECKO_COIN_ID_MAP`.
9
10
  *
10
- * @param symbol Token symbol (case-insensitive). Must be present in
11
- * `COINGECKO_COIN_ID_MAP`; unmapped symbols still hit the network and
12
- * 404 today (see todo/32-coingecko-fetcher-defects.md).
13
- * @param coinGeckoKey CoinGecko Pro API key passed as `x-cg-pro-api-key`.
14
- * @returns The latest price in USD on success; `null` on any failure
15
- * (non-2xx response, network error, JSON parse error, or missing
16
- * `prices` array). The `musd` short-circuit returns a tuple literal
17
- * for back-compat see todo/32 for the cleanup.
11
+ * @param symbol - Token symbol (case-insensitive). Must be present in
12
+ * `COINGECKO_COIN_ID_MAP`.
13
+ * @param coinGeckoKey - CoinGecko Pro API key passed as `x-cg-pro-api-key`.
14
+ * @returns The latest price in USD (a number) on success; `null` when the
15
+ * response contains an empty or missing `prices` array. `musd` (mezo-usd)
16
+ * is a USD-pegged stablecoin and short-circuits to a price of `1`.
17
+ * @throws {@link AugustValidationError} When `symbol` is not in `COINGECKO_COIN_ID_MAP`.
18
+ * @throws {@link AugustRateLimitError} On a 429 response from CoinGecko.
19
+ * @throws {@link AugustServerError} On any other non-2xx response.
18
20
  */
19
21
  async function fetchTokenPricesFromCoinGecko(symbol, coinGeckoKey) {
20
22
  const coinId = utils_1.COINGECKO_COIN_ID_MAP[symbol.toLowerCase()];
21
23
  if (coinId === 'mezo-usd') {
22
- return [['175394880000', 1]];
24
+ return 1;
25
+ }
26
+ if (!coinId) {
27
+ throw new errors_1.AugustValidationError('INVALID_INPUT', `fetchTokenPricesFromCoinGecko: symbol "${symbol}" is not in COINGECKO_COIN_ID_MAP`, { context: { symbol } });
23
28
  }
24
- // this is what we do in FE - not sure if we really need 7d worth of data since we just want something but it'll do for now
25
29
  const sevendDaysInS = 7 * 24 * 60 * 60;
26
30
  const from = Date.now() / 1000 - sevendDaysInS;
27
31
  const url = `https://pro-api.coingecko.com/api/v3/coins/${coinId}/market_chart/range?vs_currency=usd&from=${from}&to=${Math.floor(Date.now() / 1000)}&interval=daily`;
@@ -34,14 +38,10 @@ async function fetchTokenPricesFromCoinGecko(symbol, coinGeckoKey) {
34
38
  },
35
39
  });
36
40
  if (!response.ok) {
37
- const err = new Error(`CoinGecko API error: ${response.status} ${response.statusText}`);
38
- logger_1.Logger.log.error('fetchTokenPricesFromCoinGecko', err, {
39
- status: response.status,
40
- statusText: response.statusText,
41
- coinId,
42
- symbol,
43
- });
44
- throw err;
41
+ if (response.status === 429) {
42
+ throw new errors_1.AugustRateLimitError(`CoinGecko rate-limited (429): symbol "${symbol}"`, { context: { symbol, coinId, status: response.status } });
43
+ }
44
+ throw new errors_1.AugustServerError(response.status, `CoinGecko API error ${response.status} ${response.statusText}: symbol "${symbol}"`, { context: { symbol, coinId } });
45
45
  }
46
46
  const data = (await response.json());
47
47
  // `/market_chart/range` returns `{ prices, market_caps, total_volumes }` —
@@ -57,6 +57,10 @@ async function fetchTokenPricesFromCoinGecko(symbol, coinGeckoKey) {
57
57
  coinId,
58
58
  symbol,
59
59
  });
60
+ // Re-throw typed SDK errors (AugustRateLimitError, AugustServerError, etc.)
61
+ // so callers can distinguish rate-limits and server errors from "no data".
62
+ if (error instanceof errors_1.AugustSDKError)
63
+ throw error;
60
64
  return null;
61
65
  }
62
66
  }
@@ -1,4 +1,4 @@
1
- import { IAddress, IWSMonitorHeaders } from '../../types';
1
+ import type { IAddress, IWSMonitorHeaders } from '../../types';
2
2
  export interface IDebankStatsObject {
3
3
  asset_usd_value: number;
4
4
  debt_usd_value: number;
@@ -1,4 +1,4 @@
1
- import { IAddress, IDebankProtocolExposure, IDebankTokenExposure } from '../../types';
1
+ import type { IAddress, IDebankProtocolExposure, IDebankTokenExposure } from '../../types';
2
2
  export interface IDebankNormalizedResponse {
3
3
  subaccount: {
4
4
  positions: any[];
@@ -263,7 +263,7 @@ function parseLoanLevelDebank(debankRes) {
263
263
  if (protocolExposures.length === 0) {
264
264
  if (debankRes?.subaccount?.tokens) {
265
265
  debankRes.subaccount.tokens.forEach((t) => {
266
- if (t?.amount && t?.price && t.amount * t.price >= 10000) {
266
+ if (t?.amount && t?.price && t.amount * t.price >= 10_000) {
267
267
  exposure.push({
268
268
  value: t?.id,
269
269
  label: t?.symbol,
@@ -2,7 +2,7 @@
2
2
  * LayerZero Deposits Service
3
3
  * Handles querying LayerZero USDC deposits from subgraphs
4
4
  */
5
- import { IAddress } from '../../types';
5
+ import type { IAddress } from '../../types';
6
6
  export declare const LAYERZERO_VAULTS: {
7
7
  coreUSDC: {
8
8
  address: IAddress;
@@ -2,7 +2,7 @@
2
2
  * LayerZero Redeems Service
3
3
  * Handles querying LayerZero earnAUSD redeems from subgraphs
4
4
  */
5
- import { IAddress } from '../../types';
5
+ import type { IAddress } from '../../types';
6
6
  export interface ILayerZeroRedeem {
7
7
  id: string;
8
8
  recipient: string;
@@ -1,4 +1,4 @@
1
- import { IOctavfiPortfolio } from './types';
1
+ import type { IOctavfiPortfolio } from './types';
2
2
  /**
3
3
  * Fetches portfolio data from Octavfi API.
4
4
  * Note: The API currently doesn't support multiple addresses in a single request,
@@ -1,4 +1,4 @@
1
- import { IAddress } from '../../types';
1
+ import type { IAddress } from '../../types';
2
2
  export type IOctavfiEndpoint = 'portfolio';
3
3
  export interface IOctavfiAsset {
4
4
  balance: string;
@@ -1,5 +1,5 @@
1
- import { IOctavfiPortfolio } from './types';
2
- import { IDebankNormalizedResponse } from '../debank/utils';
1
+ import type { IOctavfiPortfolio } from './types';
2
+ import type { IDebankNormalizedResponse } from '../debank/utils';
3
3
  /**
4
4
  * Transforms Octavfi portfolio response to DeBank-compatible format.
5
5
  * This allows Solana addresses to use Octavfi data while maintaining
@@ -47,7 +47,7 @@ async function fetchSubgraphWithRetry(graphUrl, query, apiKey, maxRetries = 3, b
47
47
  error.name === 'AbortError' ||
48
48
  error.message.includes('ETIMEDOUT') ||
49
49
  error.message.includes('timeout'))) {
50
- const delay = baseDelay * Math.pow(2, attempt); // Exponential backoff
50
+ const delay = baseDelay * 2 ** attempt; // Exponential backoff
51
51
  core_1.Logger.log.warn(`fetchSubgraph`, `${graphUrl?.includes('/subgraphs') ? graphUrl?.split('/subgraphs/')?.[1]?.split('/')?.[0] : graphUrl}: Attempt ${attempt + 1} failed, retrying in ${delay}ms`);
52
52
  await new Promise((resolve) => setTimeout(resolve, delay));
53
53
  continue;
@@ -183,12 +183,19 @@ const NEW_DEPOSIT_QUERY_PROPS = `
183
183
  senderAddr
184
184
  receiverAddr
185
185
  `;
186
+ // The `block_number: blockNumber` alias on these new-schema withdrawal prop
187
+ // sets is required, not cosmetic: getWithdrawalRequestsWithStatus prunes by
188
+ // `Number(req.block_number) >= blockCutoff` (per the ISubgraphBase contract).
189
+ // New-schema subgraphs expose the field as `blockNumber`, so without the alias
190
+ // it reads undefined → Number(undefined) is NaN → every request is pruned
191
+ // (AUGUST-6514). Only the REQUESTED set is read today; the processed/withdrawals
192
+ // aliases below are kept for the same type contract so the NaN prune can't recur.
186
193
  const NEW_WITHDRAWALS_REQUESTED_QUERY_PROPS = `
187
194
  id
188
195
  shares
189
196
  receiverAddr
190
197
  holderAddr
191
- blockNumber
198
+ block_number: blockNumber
192
199
  transactionHash_: transactionHash
193
200
  timestamp_: blockTimestamp
194
201
  `;
@@ -196,7 +203,7 @@ const NEW_WITHDRAWALS_PROCESSED_QUERY_PROPS = `
196
203
  id
197
204
  receiverAddr
198
205
  assetsAmount
199
- blockNumber
206
+ block_number: blockNumber
200
207
  transactionHash_: transactionHash
201
208
  timestamp_: blockTimestamp
202
209
  `;
@@ -204,7 +211,7 @@ const NEW_WITHDRAWALS_QUERY_PROPS = `
204
211
  id
205
212
  transactionHash_: transactionHash
206
213
  timestamp_: blockTimestamp
207
- blockNumber
214
+ block_number: blockNumber
208
215
  assets
209
216
  receiver
210
217
  sender
@@ -463,8 +470,84 @@ async function getSubgraphAllWithdrawals(pool, provider, slackWebookUrl = slack_
463
470
  };
464
471
  }
465
472
  }
473
+ /**
474
+ * Fetch a user's deposit/withdraw history for an archived vault from the backend
475
+ * Mongo snapshot (`/upshift/vault_history`) instead of its retired subgraph.
476
+ *
477
+ * Returns the same {@link ISubgraphUserHistoryItem} shape as the subgraph path,
478
+ * so the caller's downstream transform/normalization is unchanged. `amount` is
479
+ * the raw deposited-asset amount (base units); `decimals` is attached so the
480
+ * caller can normalize, mirroring the subgraph path.
481
+ *
482
+ * Pre-deposit vaults accept multiple deposit assets with differing decimals
483
+ * (e.g. USDS at 18, USDC at 6). When the backend supplies `asset_address` per
484
+ * row, it is propagated as {@link ISubgraphUserHistoryItem.assetIn} (and, when
485
+ * present, `asset_decimals` is used for that row's `decimals`) so lifetime PnL
486
+ * resolves each deposit against its own token rather than the vault decimals —
487
+ * without it, an 18-decimal deposit normalized at the vault's 6 decimals
488
+ * inflates the cost basis by ~1e12. This mirrors the subgraph path, whose
489
+ * deposit rows already carry `assetIn`.
490
+ *
491
+ * Side effects: one RPC read (`getDecimals`) and one HTTP GET to the public API.
492
+ *
493
+ * @param user - The wallet whose history to fetch.
494
+ * @param provider - Contract runner, used to read the vault's decimals.
495
+ * @param pool - The (archived) vault contract address.
496
+ * @returns The user's deposits and settled withdrawals. Empty on a non-200
497
+ * response.
498
+ */
499
+ async function getArchivedVaultUserHistory(user, provider, pool) {
500
+ const decimals = await (0, core_1.getDecimals)(provider, pool);
501
+ const response = await (0, core_1.fetchAugustPublic)(core_1.WEBSERVER_ENDPOINTS.public.tokenizedVault.userHistory(pool, user));
502
+ if (response.status !== 200) {
503
+ core_1.Logger.log.error('getArchivedVaultUserHistory', `non-200 from vault_history for ${pool}: ${response.status}`);
504
+ return [];
505
+ }
506
+ const rows = (await response.json());
507
+ // The backend already stores final ISubgraphUserHistoryItem.type values, so
508
+ // no translation is needed. Two row-level guards before mapping, since both
509
+ // bad shapes propagate destructively downstream:
510
+ // - amount_raw must be a non-negative integer: the caller does
511
+ // BigInt(amount) outside a try/catch, and one bad row would throw and
512
+ // wipe the user's entire (all-vault) history.
513
+ // - timestamp must parse to a real time: a malformed value makes getTime()
514
+ // return NaN, which stringifies to "NaN" and then sorts/normalizes
515
+ // incorrectly downstream. Drop the row rather than emit a "NaN" stamp.
516
+ return (rows
517
+ .filter((row) => /^\d+$/.test(row.amount_raw) &&
518
+ !Number.isNaN(new Date(row.timestamp).getTime()))
519
+ .map((row) => ({
520
+ id: row.transaction_hash,
521
+ contractId_: pool,
522
+ timestamp_: String(Math.floor(new Date(row.timestamp).getTime() / 1000)),
523
+ transactionHash_: row.transaction_hash,
524
+ block_number: row.block_number != null ? String(row.block_number) : '0',
525
+ address: row.wallet,
526
+ amount: row.amount_raw,
527
+ type: row.type,
528
+ // Per-asset decimals when known, else the vault's. PnL re-resolves
529
+ // decimals from `assetIn` anyway; this keeps display/normalization
530
+ // correct for any consumer that reads the row's `decimals` directly.
531
+ decimals: row.asset_decimals ?? decimals,
532
+ // Carry the deposit asset through so mixed-decimal deposits normalize
533
+ // against their own token, not the vault's. Omitted when unknown.
534
+ ...(row.asset_address ? { assetIn: row.asset_address } : {}),
535
+ }))
536
+ // Match the subgraph path's ordering contract: sortUserHistory sorts
537
+ // ascending by unix timestamp_, and downstream consumers rely on that
538
+ // chronology. The backend returns rows in arbitrary order, so re-sort here.
539
+ .sort((a, b) => Number(a.timestamp_) - Number(b.timestamp_)));
540
+ }
466
541
  async function getSubgraphUserHistory(user, provider, pool, slackWebookUrl = slack_1.DEFAULT_SLACK_WEBHOOK_URL) {
467
542
  try {
543
+ // Archived vaults: serve history from the backend Mongo snapshot instead of
544
+ // the (retired) subgraph. The archived set is fetched from the backend (the
545
+ // routing source of truth) so a vault is only rerouted once its history is
546
+ // backfilled. Same return shape keeps downstream unchanged.
547
+ const archivedVaults = await (0, fetcher_2.fetchArchivedVaults)();
548
+ if (archivedVaults.has(pool.toLowerCase())) {
549
+ return await getArchivedVaultUserHistory(user, provider, pool);
550
+ }
468
551
  // setup
469
552
  const chainId = await (0, core_1.getChainId)(provider);
470
553
  const requests = [];
@@ -29,6 +29,15 @@ export interface ISwapQuoteRequest {
29
29
  * in `[0, 10_000)` — 10_000 disables protection entirely and is rejected.
30
30
  */
31
31
  slippageBps?: number;
32
+ /**
33
+ * Optional aggregator contract-method filter. When set, the aggregator is
34
+ * constrained to this single method (ParaSwap's `/prices`
35
+ * `includeContractMethods`), so the returned calldata's leading 4-byte
36
+ * selector is deterministic — required when the on-chain SwapRouter only
37
+ * authorizes one selector per router. When omitted, the aggregator picks the
38
+ * optimal method freely and the selector may vary between quotes.
39
+ */
40
+ contractMethod?: string;
32
41
  /** Aggregator partner key. Defaults to `'august'`. */
33
42
  partner?: string;
34
43
  /** Aggregator partner-fee receiver. Defaults to the August partner address. */
@@ -45,6 +45,7 @@ async function fetchSwapQuote(request) {
45
45
  slippageBps,
46
46
  partner: request.partner ?? paraswap_1.PARASWAP_DEFAULTS.partner,
47
47
  partnerAddress: request.partnerAddress ?? paraswap_1.PARASWAP_DEFAULTS.partnerAddress,
48
+ contractMethod: request.contractMethod,
48
49
  fetchImpl,
49
50
  signal: request.signal,
50
51
  });
@@ -60,7 +61,7 @@ async function fetchSwapQuote(request) {
60
61
  }
61
62
  function validateRequest(req) {
62
63
  if (req.slippageBps !== undefined &&
63
- (req.slippageBps < 0 || req.slippageBps >= 10000)) {
64
+ (req.slippageBps < 0 || req.slippageBps >= 10_000)) {
64
65
  throw new errors_1.AugustValidationError('INVALID_INPUT', `fetchSwapQuote: slippageBps must be in [0, 10000), got ${req.slippageBps}. 10000 bps = 100% slippage and disables protection entirely; use a tighter bound.`);
65
66
  }
66
67
  if (req.amount === 0n) {
@@ -17,6 +17,14 @@ export interface IParaswapQuoteInput {
17
17
  slippageBps: number;
18
18
  partner: string;
19
19
  partnerAddress: IAddress;
20
+ /**
21
+ * Optional `includeContractMethods` value passed to Paraswap's `/prices`. When
22
+ * set, Paraswap is restricted to this single contract method so the resulting
23
+ * calldata's leading selector is deterministic and matches the one the
24
+ * SwapRouter authorizes for this router. When omitted, Paraswap is free to
25
+ * pick whichever method is optimal for the route.
26
+ */
27
+ contractMethod?: string;
20
28
  fetchImpl: typeof fetch;
21
29
  signal?: AbortSignal;
22
30
  }
@@ -42,6 +42,14 @@ async function getPriceRoute(input) {
42
42
  partnerAddress: input.partnerAddress,
43
43
  version: PARASWAP_VERSION,
44
44
  });
45
+ // Restrict the route to a single contract method when the caller pins one,
46
+ // so the calldata's selector is deterministic and matches the SwapRouter's
47
+ // per-router authorized selector. Without this the aggregator may return a
48
+ // route-optimized method (e.g. swapExactAmountInOnUniswapV3) whose selector
49
+ // the SwapRouter has not whitelisted, reverting with InvalidNotWhitelisted().
50
+ if (input.contractMethod) {
51
+ params.append('includeContractMethods', input.contractMethod);
52
+ }
45
53
  const url = `${PARASWAP_PRICES_URL}?${params.toString()}`;
46
54
  let response;
47
55
  try {
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * @deprecated
3
3
  */
4
- import { IAddress, INormalizedNumber } from './web3';
5
- import { IDebankProtocolExposure, IDebankTokenExposure, ITokenizedVaultStrategist, IWSSubaccountCefi } from './webserver';
4
+ import type { IAddress, INormalizedNumber } from './web3';
5
+ import type { IDebankProtocolExposure, IDebankTokenExposure, ITokenizedVaultStrategist, IWSSubaccountCefi } from './webserver';
6
6
  type ILabelValue = {
7
7
  label: string;
8
8
  value: string;
@@ -1,4 +1,4 @@
1
- import { IAddress, INormalizedNumber } from './web3';
1
+ import type { IAddress, INormalizedNumber } from './web3';
2
2
  export type IActiveStakingPosition = {
3
3
  stakingToken: {
4
4
  decimals: number;
@@ -1,4 +1,4 @@
1
- import { IAddress } from './web3';
1
+ import type { IAddress } from './web3';
2
2
  export interface IWSSubAccountHealthFactor {
3
3
  id: IAddress;
4
4
  datetime: string;
@@ -1,4 +1,4 @@
1
- import { IAddress } from './web3';
1
+ import type { IAddress } from './web3';
2
2
  export interface ISubgraphBase {
3
3
  id: string;
4
4
  contractId_: IAddress;
@@ -12,6 +12,15 @@ export interface ISubgraphUserHistoryItem extends ISubgraphBase {
12
12
  type: 'withdraw-request' | 'deposit' | 'withdraw-processed';
13
13
  decimals?: number;
14
14
  isInstant?: boolean;
15
+ /**
16
+ * Deposit asset token address, when known. Pre-deposit vaults accept
17
+ * multiple deposit assets with differing decimals (e.g. USDS at 18,
18
+ * USDC at 6), so `amount` cannot be normalized with the vault's own
19
+ * decimals alone — consumers (notably lifetime PnL) key off this address
20
+ * to resolve the correct per-asset decimals and USD price. Absent for
21
+ * single-asset vaults, where the vault `decimals` is correct.
22
+ */
23
+ assetIn?: IAddress;
15
24
  }
16
25
  export interface ISubgraphWithdrawProccessed extends ISubgraphBase {
17
26
  processedOn: string;
@@ -49,6 +49,26 @@ export type IVaultUserHistoryItem = {
49
49
  type: 'withdraw-request' | 'deposit' | 'withdraw-processed' | 'redeem';
50
50
  transactionHash: IAddress;
51
51
  };
52
+ /**
53
+ * A single reward paired with its backend-provided logo.
54
+ *
55
+ * `id` is the reward's stable backend identifier ({@link ITokenizedVaultReward.id})
56
+ * and is the key consumers should join on — it is unique even when two rewards
57
+ * share a multiplier and text. `label` is display-only: it mirrors the
58
+ * corresponding {@link IVaultRewards.additionalPoints} string (and so carries a
59
+ * leading space when `multiplier === 1`, e.g. `" Cores"`), so it is fine to
60
+ * print but must not be treated as a unique key.
61
+ *
62
+ * `imgUrl` is `null` when the backend has no logo for the reward, in which
63
+ * case consumers fall back to a bundled asset.
64
+ */
65
+ export type IVaultRewardDetail = {
66
+ id: string;
67
+ label: string;
68
+ text: string;
69
+ imgUrl: string | null;
70
+ multiplier: number;
71
+ };
52
72
  export type IVaultRewards = {
53
73
  points: string;
54
74
  multiplier: number;
@@ -57,6 +77,12 @@ export type IVaultRewards = {
57
77
  timestamp: number;
58
78
  }[];
59
79
  additionalPoints: string[];
80
+ /**
81
+ * Optional so this addition is non-breaking for external code that
82
+ * constructs an {@link IVaultRewards}. `getVaultRewards` always populates it;
83
+ * readers should treat an absent value as an empty list.
84
+ */
85
+ additionalPointsDetailed?: IVaultRewardDetail[];
60
86
  };
61
87
  export type IVaultExposureItem = {
62
88
  amount: number;
@@ -1,4 +1,4 @@
1
- import { Signer, Provider } from 'ethers';
1
+ import type { Signer, Provider } from 'ethers';
2
2
  export type IAddress = `0x${string}`;
3
3
  /**
4
4
  * Address type for vault contracts across all supported chains.
@@ -1,5 +1,5 @@
1
- import { IUserRoles } from './user';
2
- import { IAddress, type ChainType, type IStellarNetwork } from './web3';
1
+ import type { IUserRoles } from './user';
2
+ import type { IAddress, ChainType, IStellarNetwork } from './web3';
3
3
  /**
4
4
  * Table of Contents
5
5
  * 1) Subaccounts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@augustdigital/sdk",
3
- "version": "8.5.0",
3
+ "version": "8.6.1",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/sdk.d.ts",
6
6
  "keywords": [