@augustdigital/sdk 7.0.1 → 8.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/lib/abis/SwapRouter.d.ts +1042 -0
  2. package/lib/abis/SwapRouter.js +739 -0
  3. package/lib/abis/index.d.ts +1 -0
  4. package/lib/abis/index.js +1 -0
  5. package/lib/adapters/evm/index.d.ts +4 -0
  6. package/lib/adapters/evm/index.js +12 -0
  7. package/lib/adapters/stellar/types.d.ts +0 -1
  8. package/lib/core/analytics/method-taxonomy.js +3 -0
  9. package/lib/core/analytics/version.d.ts +1 -1
  10. package/lib/core/analytics/version.js +1 -1
  11. package/lib/core/base.class.d.ts +0 -1
  12. package/lib/core/constants/swap-router.d.ts +8 -0
  13. package/lib/core/constants/swap-router.js +18 -0
  14. package/lib/core/helpers/swap-router.d.ts +4 -0
  15. package/lib/core/helpers/swap-router.js +22 -0
  16. package/lib/core/index.d.ts +2 -0
  17. package/lib/core/index.js +2 -0
  18. package/lib/index.d.ts +1 -0
  19. package/lib/index.js +1 -0
  20. package/lib/main.d.ts +2 -1
  21. package/lib/main.js +1 -1
  22. package/lib/modules/vaults/fetcher.js +2 -2
  23. package/lib/modules/vaults/getters.d.ts +5 -14
  24. package/lib/modules/vaults/getters.js +54 -13
  25. package/lib/modules/vaults/main.d.ts +1 -1
  26. package/lib/modules/vaults/main.js +3 -1
  27. package/lib/modules/vaults/write.actions.d.ts +7 -0
  28. package/lib/modules/vaults/write.actions.js +260 -1
  29. package/lib/services/coingecko/fetcher.js +15 -5
  30. package/lib/services/debank/fetcher.js +6 -3
  31. package/lib/services/debank/utils.js +7 -6
  32. package/lib/services/octavfi/fetcher.js +10 -5
  33. package/lib/services/subgraph/vaults.js +6 -6
  34. package/lib/services/swap-quotes/index.d.ts +25 -0
  35. package/lib/services/swap-quotes/index.js +51 -0
  36. package/lib/services/swap-quotes/paraswap.d.ts +26 -0
  37. package/lib/services/swap-quotes/paraswap.js +116 -0
  38. package/lib/types/vaults.d.ts +40 -0
  39. package/lib/types/vaults.js +6 -1
  40. package/lib/types/web3.d.ts +0 -1
  41. package/package.json +1 -1
@@ -15,9 +15,13 @@ exports.vaultRequestRedeem = vaultRequestRedeem;
15
15
  exports.vaultRedeem = vaultRedeem;
16
16
  exports.depositNative = depositNative;
17
17
  exports.rwaRedeemAsset = rwaRedeemAsset;
18
+ exports.swapAndDeposit = swapAndDeposit;
19
+ exports.depositViaSwapRouter = depositViaSwapRouter;
20
+ exports.depositNativeViaSwapRouter = depositNativeViaSwapRouter;
18
21
  const ethers_1 = require("ethers");
19
22
  const abis_1 = require("../../abis");
20
23
  const core_1 = require("../../core");
24
+ const swap_quotes_1 = require("../../services/swap-quotes");
21
25
  const adapter_helpers_1 = require("./adapter.helpers");
22
26
  const utils_1 = require("./utils");
23
27
  function safeBigInt(value, context = 'safeBigInt') {
@@ -50,6 +54,8 @@ async function resolveDepositTokenDecimals(args) {
50
54
  return readErc20Decimals(actualDepositAsset);
51
55
  }
52
56
  function resolveSpender(args) {
57
+ if (args.swapRouterAddress)
58
+ return args.swapRouterAddress;
53
59
  if (args.isMultiAssetVault)
54
60
  return args.target;
55
61
  if (args.isAdapterDeposit && args.adapterWrapperAddress)
@@ -202,11 +208,16 @@ async function approveCore(signer, options) {
202
208
  if (isNativeToken)
203
209
  return { kind: 'native' };
204
210
  const isAdapterDeposit = actualDepositAsset.toLowerCase() !== underlyingAsset.toLowerCase();
211
+ const resolvedChainId = options.chainId ?? tokenizedVault?.chain;
212
+ const swapRouterAddress = resolvedChainId !== undefined && (0, core_1.vaultUsesSwapRouter)(target)
213
+ ? (0, core_1.getSwapRouterAddress)(resolvedChainId)
214
+ : undefined;
205
215
  const spenderAddress = resolveSpender({
206
216
  target,
207
217
  isMultiAssetVault,
208
218
  isAdapterDeposit,
209
219
  adapterWrapperAddress: adapterConfig?.wrapperAddress,
220
+ swapRouterAddress,
210
221
  });
211
222
  const depositTokenDecimals = await resolveDepositTokenDecimals({
212
223
  actualDepositAsset,
@@ -318,7 +329,23 @@ async function vaultDeposit(signer, options) {
318
329
  actualDepositAsset === '0x0000000000000000000000000000000000000000';
319
330
  const isAdapterDeposit = actualDepositAsset.toLowerCase() !== underlyingAsset.toLowerCase();
320
331
  const isMultiAssetVault = vaultVersion === 'evm-2';
321
- if (isAdapterDeposit && !isMultiAssetVault && !adapterConfig) {
332
+ const resolvedChainId = chainId ?? tokenizedVault?.chain;
333
+ const wantsSwapRouter = (0, core_1.vaultUsesSwapRouter)(target);
334
+ const swapRouterAddress = wantsSwapRouter && resolvedChainId !== undefined
335
+ ? (0, core_1.getSwapRouterAddress)(resolvedChainId)
336
+ : undefined;
337
+ if (wantsSwapRouter && !swapRouterAddress) {
338
+ throw new core_1.AugustValidationError('INVALID_CHAIN', resolvedChainId === undefined
339
+ ? `vaultDeposit: vault ${target} requires SwapRouter routing but chainId could not be resolved — pass options.chainId or ensure tokenized-vault metadata is loaded`
340
+ : `vaultDeposit: vault ${target} is registered on SwapRouter but no SwapRouter is deployed for chainId ${resolvedChainId}`, { context: { vault: target, chainId: resolvedChainId } });
341
+ }
342
+ if (wantsSwapRouter && options?.isDepositWithPermit) {
343
+ throw new core_1.AugustValidationError('INVALID_INPUT', `vaultDeposit: isDepositWithPermit is not supported on SwapRouter-routed vaults (${target}). Call vaultDeposit without isDepositWithPermit, or use the legacy vault.deposit path directly.`, { context: { vault: target } });
344
+ }
345
+ if (isAdapterDeposit &&
346
+ !isMultiAssetVault &&
347
+ !adapterConfig &&
348
+ !swapRouterAddress) {
322
349
  throw new core_1.AugustValidationError('INVALID_INPUT', `vaultDeposit: depositAsset ${actualDepositAsset} differs from vault underlying ${underlyingAsset} but no adapter is configured for vault ${target}`);
323
350
  }
324
351
  const depositTokenDecimals = await resolveDepositTokenDecimals({
@@ -337,6 +364,23 @@ async function vaultDeposit(signer, options) {
337
364
  },
338
365
  });
339
366
  const normalizedAmt = (0, core_1.toNormalizedBn)(amount, depositTokenDecimals);
367
+ if (swapRouterAddress && resolvedChainId !== undefined) {
368
+ return dispatchViaSwapRouter({
369
+ signer,
370
+ routerAddress: swapRouterAddress,
371
+ chainId: resolvedChainId,
372
+ target,
373
+ wallet,
374
+ receiver: options.receiver,
375
+ actualDepositAsset,
376
+ underlyingAsset,
377
+ isNativeToken,
378
+ depositTokenDecimals,
379
+ normalizedAmt,
380
+ slippageBps: options.slippageBps,
381
+ wait,
382
+ });
383
+ }
340
384
  if (!isNativeToken) {
341
385
  const spenderAddress = resolveSpender({
342
386
  target,
@@ -666,4 +710,219 @@ async function rwaRedeemAsset(signer, options) {
666
710
  throw new core_1.AugustSDKError('UNKNOWN', `RWA redeem failed: ${e instanceof Error ? e.message : 'Unknown error'}`, { cause: e, context: { target, asset, amount, minOut } });
667
711
  }
668
712
  }
713
+ async function dispatchViaSwapRouter(args) {
714
+ const amountRaw = BigInt(args.normalizedAmt.raw);
715
+ const sharesReceiver = args.receiver ?? args.wallet;
716
+ if (args.isNativeToken) {
717
+ const wrappedNative = core_1.SWAP_ROUTER_WRAPPED_NATIVE[args.chainId];
718
+ if (!wrappedNative ||
719
+ args.underlyingAsset.toLowerCase() !== wrappedNative.toLowerCase()) {
720
+ throw new core_1.AugustValidationError('INVALID_INPUT', `vaultDeposit (SwapRouter): native deposit is only supported when the vault's reference asset is the chain's wrapped-native token. Vault ${args.target} underlying ${args.underlyingAsset} is not. Wrap to ${wrappedNative ?? 'WETH'} first and call again with depositAsset = the wrapped token.`, {
721
+ context: {
722
+ vault: args.target,
723
+ underlying: args.underlyingAsset,
724
+ chainId: args.chainId,
725
+ wrappedNative,
726
+ },
727
+ });
728
+ }
729
+ return depositNativeViaSwapRouter(args.signer, {
730
+ chainId: args.chainId,
731
+ vault: args.target,
732
+ receiver: sharesReceiver,
733
+ amount: amountRaw,
734
+ wait: args.wait,
735
+ });
736
+ }
737
+ const isUnderlying = args.actualDepositAsset.toLowerCase() ===
738
+ args.underlyingAsset.toLowerCase();
739
+ if (isUnderlying) {
740
+ return depositViaSwapRouter(args.signer, {
741
+ chainId: args.chainId,
742
+ vault: args.target,
743
+ receiver: sharesReceiver,
744
+ asset: args.actualDepositAsset,
745
+ amount: amountRaw,
746
+ wait: args.wait,
747
+ });
748
+ }
749
+ const underlyingErc20 = (0, core_1.createContract)({
750
+ address: args.underlyingAsset,
751
+ provider: args.signer,
752
+ abi: abis_1.ABI_ERC20,
753
+ });
754
+ const underlyingDecimals = Number(await underlyingErc20.decimals());
755
+ const quote = await (0, swap_quotes_1.fetchSwapQuote)({
756
+ chainId: args.chainId,
757
+ srcToken: args.actualDepositAsset,
758
+ srcDecimals: args.depositTokenDecimals,
759
+ destToken: args.underlyingAsset,
760
+ destDecimals: underlyingDecimals,
761
+ amount: amountRaw,
762
+ receiver: args.routerAddress,
763
+ slippageBps: args.slippageBps,
764
+ });
765
+ return swapAndDeposit(args.signer, {
766
+ chainId: args.chainId,
767
+ vault: args.target,
768
+ receiver: sharesReceiver,
769
+ swaps: [
770
+ {
771
+ tokenIn: args.actualDepositAsset,
772
+ tokenOut: args.underlyingAsset,
773
+ amountIn: amountRaw,
774
+ minAmountOut: quote.minAmountOut,
775
+ router: quote.router,
776
+ payload: quote.payload,
777
+ },
778
+ ],
779
+ wait: args.wait,
780
+ });
781
+ }
782
+ function resolveSwapRouterOrThrow(chainId) {
783
+ const router = (0, core_1.getSwapRouterAddress)(chainId);
784
+ if (!router) {
785
+ throw new core_1.AugustValidationError('INVALID_CHAIN', `SwapRouter: no deployment registered for chainId ${chainId}`, { context: { chainId } });
786
+ }
787
+ return router;
788
+ }
789
+ async function ensureAllowance(signer, token, owner, spender, amount) {
790
+ const tokenContract = (0, core_1.createContract)({
791
+ address: token,
792
+ provider: signer,
793
+ abi: abis_1.ABI_ERC20,
794
+ });
795
+ const current = safeBigInt(await tokenContract.allowance(owner, spender), 'swapRouter:allowance');
796
+ if (current >= amount)
797
+ return;
798
+ const { hash } = await safeSendTx(() => tokenContract.connect(signer).approve(spender, amount), signer, true);
799
+ core_1.Logger.log.info('swapRouter:approve:tx_hash', hash);
800
+ }
801
+ function ensureSwapsValid(swaps) {
802
+ if (swaps.length === 0) {
803
+ throw new core_1.AugustValidationError('INVALID_INPUT', 'swapAndDeposit: at least one swap leg is required');
804
+ }
805
+ if (swaps.length > core_1.SWAP_ROUTER_MAX_SWAPS) {
806
+ throw new core_1.AugustValidationError('INVALID_INPUT', `swapAndDeposit: too many swaps (${swaps.length} > ${core_1.SWAP_ROUTER_MAX_SWAPS})`, { context: { count: swaps.length, max: core_1.SWAP_ROUTER_MAX_SWAPS } });
807
+ }
808
+ for (let i = 0; i < swaps.length; i += 1) {
809
+ validateSwapParams(swaps[i], i);
810
+ }
811
+ }
812
+ function validateSwapParams(swap, index) {
813
+ const where = `swapAndDeposit: swaps[${index}]`;
814
+ if (!(0, core_1.checkAddress)(swap.tokenIn, console, 'contract')) {
815
+ throw new core_1.AugustValidationError('INVALID_ADDRESS', `${where}.tokenIn is not a valid address`);
816
+ }
817
+ if (!(0, core_1.checkAddress)(swap.tokenOut, console, 'contract')) {
818
+ throw new core_1.AugustValidationError('INVALID_ADDRESS', `${where}.tokenOut is not a valid address`);
819
+ }
820
+ if (!(0, core_1.checkAddress)(swap.router, console, 'contract')) {
821
+ throw new core_1.AugustValidationError('INVALID_ADDRESS', `${where}.router is not a valid address`);
822
+ }
823
+ if (swap.tokenIn.toLowerCase() === swap.tokenOut.toLowerCase()) {
824
+ throw new core_1.AugustValidationError('INVALID_INPUT', `${where}: tokenIn and tokenOut are identical — no swap needed`);
825
+ }
826
+ if (swap.amountIn <= 0n) {
827
+ throw new core_1.AugustValidationError('INVALID_INPUT', `${where}.amountIn must be greater than zero`);
828
+ }
829
+ if (swap.minAmountOut <= 0n) {
830
+ throw new core_1.AugustValidationError('INVALID_INPUT', `${where}.minAmountOut must be greater than zero — slippage protection cannot be disabled`);
831
+ }
832
+ if (!/^0x[0-9a-fA-F]+$/.test(swap.payload) || swap.payload.length < 10) {
833
+ throw new core_1.AugustValidationError('INVALID_INPUT', `${where}.payload must be ABI-encoded calldata (got "${swap.payload.slice(0, 12)}…")`);
834
+ }
835
+ }
836
+ function totalInputPerToken(swaps) {
837
+ const totals = new Map();
838
+ for (const swap of swaps) {
839
+ const key = swap.tokenIn.toLowerCase();
840
+ totals.set(key, (totals.get(key) ?? 0n) + swap.amountIn);
841
+ }
842
+ return totals;
843
+ }
844
+ async function resolveSignerEOA(signer, callerContext) {
845
+ const getAddress = signer.getAddress;
846
+ if (typeof getAddress !== 'function') {
847
+ throw new core_1.AugustValidationError('INVALID_INPUT', `${callerContext}: signer must implement getAddress(); got ${typeof getAddress}`);
848
+ }
849
+ const eoa = await getAddress.call(signer);
850
+ if (!eoa || !(0, core_1.checkAddress)(eoa, console, 'wallet')) {
851
+ throw new core_1.AugustValidationError('INVALID_ADDRESS', `${callerContext}: signer.getAddress() returned an invalid address: ${String(eoa)}`);
852
+ }
853
+ return eoa;
854
+ }
855
+ async function swapAndDeposit(signer, options) {
856
+ const { chainId, vault, receiver, swaps, originCode, wait } = options;
857
+ const goodVault = (0, core_1.checkAddress)(vault, console, 'contract');
858
+ const goodReceiver = (0, core_1.checkAddress)(receiver, console, 'wallet');
859
+ if (!goodVault || !goodReceiver) {
860
+ throw new core_1.AugustValidationError('INVALID_ADDRESS', `swapAndDeposit: invalid ${!goodVault ? 'vault' : 'receiver'} address`);
861
+ }
862
+ ensureSwapsValid(swaps);
863
+ const routerAddress = resolveSwapRouterOrThrow(chainId);
864
+ const eoa = await resolveSignerEOA(signer, 'swapAndDeposit');
865
+ for (const [tokenIn, totalIn] of totalInputPerToken(swaps)) {
866
+ await ensureAllowance(signer, tokenIn, eoa, routerAddress, totalIn);
867
+ }
868
+ const routerContract = (0, core_1.createContract)({
869
+ address: routerAddress,
870
+ provider: signer,
871
+ abi: abis_1.ABI_SWAP_ROUTER,
872
+ });
873
+ const { hash } = await safeSendTx(() => routerContract
874
+ .connect(signer)
875
+ .swapAndDeposit((0, core_1.resolveOriginCode)(originCode), vault, receiver, swaps), signer, wait);
876
+ core_1.Logger.log.info('swapAndDeposit:tx_hash', hash);
877
+ return hash;
878
+ }
879
+ async function depositViaSwapRouter(signer, options) {
880
+ const { chainId, vault, receiver, asset, amount, originCode, wait } = options;
881
+ const goodVault = (0, core_1.checkAddress)(vault, console, 'contract');
882
+ const goodReceiver = (0, core_1.checkAddress)(receiver, console, 'wallet');
883
+ const goodAsset = (0, core_1.checkAddress)(asset, console, 'contract');
884
+ if (!goodVault || !goodReceiver || !goodAsset) {
885
+ throw new core_1.AugustValidationError('INVALID_ADDRESS', 'depositViaSwapRouter: invalid address');
886
+ }
887
+ if (amount === 0n) {
888
+ throw new core_1.AugustValidationError('INVALID_INPUT', 'depositViaSwapRouter: amount must be greater than zero');
889
+ }
890
+ const routerAddress = resolveSwapRouterOrThrow(chainId);
891
+ const eoa = await resolveSignerEOA(signer, 'depositViaSwapRouter');
892
+ await ensureAllowance(signer, asset, eoa, routerAddress, amount);
893
+ const routerContract = (0, core_1.createContract)({
894
+ address: routerAddress,
895
+ provider: signer,
896
+ abi: abis_1.ABI_SWAP_ROUTER,
897
+ });
898
+ const { hash } = await safeSendTx(() => routerContract
899
+ .connect(signer)
900
+ .deposit((0, core_1.resolveOriginCode)(originCode), amount, vault, asset, receiver), signer, wait);
901
+ core_1.Logger.log.info('depositViaSwapRouter:tx_hash', hash);
902
+ return hash;
903
+ }
904
+ async function depositNativeViaSwapRouter(signer, options) {
905
+ const { chainId, vault, receiver, amount, originCode, wait } = options;
906
+ const goodVault = (0, core_1.checkAddress)(vault, console, 'contract');
907
+ const goodReceiver = (0, core_1.checkAddress)(receiver, console, 'wallet');
908
+ if (!goodVault || !goodReceiver) {
909
+ throw new core_1.AugustValidationError('INVALID_ADDRESS', 'depositNativeViaSwapRouter: invalid address');
910
+ }
911
+ if (amount === 0n) {
912
+ throw new core_1.AugustValidationError('INVALID_INPUT', 'depositNativeViaSwapRouter: amount must be greater than zero');
913
+ }
914
+ const routerAddress = resolveSwapRouterOrThrow(chainId);
915
+ const routerContract = (0, core_1.createContract)({
916
+ address: routerAddress,
917
+ provider: signer,
918
+ abi: abis_1.ABI_SWAP_ROUTER,
919
+ });
920
+ const { hash } = await safeSendTx(() => routerContract
921
+ .connect(signer)
922
+ .depositNativeToken((0, core_1.resolveOriginCode)(originCode), vault, receiver, {
923
+ value: amount,
924
+ }), signer, wait);
925
+ core_1.Logger.log.info('depositNativeViaSwapRouter:tx_hash', hash);
926
+ return hash;
927
+ }
669
928
  //# sourceMappingURL=write.actions.js.map
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.fetchTokenPricesFromCoinGecko = fetchTokenPricesFromCoinGecko;
4
+ const logger_1 = require("../../core/logger");
4
5
  const utils_1 = require("./utils");
5
6
  async function fetchTokenPricesFromCoinGecko(symbol, coinGeckoKey) {
6
7
  const coinId = utils_1.COINGECKO_COIN_ID_MAP[symbol.toLowerCase()];
@@ -19,17 +20,26 @@ async function fetchTokenPricesFromCoinGecko(symbol, coinGeckoKey) {
19
20
  },
20
21
  });
21
22
  if (!response.ok) {
22
- console.error('\n\n❌ CoinGecko API Error:', response.statusText, coinId, '\n\n');
23
- throw new Error(`❌ CoinGecko API Error: ${response.statusText}`);
23
+ const err = new Error(`CoinGecko API error: ${response.status} ${response.statusText}`);
24
+ logger_1.Logger.log.error('fetchTokenPricesFromCoinGecko', err, {
25
+ status: response.status,
26
+ statusText: response.statusText,
27
+ coinId,
28
+ symbol,
29
+ });
30
+ throw err;
24
31
  }
25
32
  const data = (await response.json());
26
- if (data && data.length) {
27
- return data.prices[data.length - 1][1];
33
+ if (data?.prices?.length) {
34
+ return data.prices[data.prices.length - 1][1];
28
35
  }
29
36
  return null;
30
37
  }
31
38
  catch (error) {
32
- console.error('❌ Error fetching CoinGecko prices:', `${error} for ${coinId} ${symbol}`);
39
+ logger_1.Logger.log.error('fetchTokenPricesFromCoinGecko', error, {
40
+ coinId,
41
+ symbol,
42
+ });
33
43
  return null;
34
44
  }
35
45
  }
@@ -10,18 +10,21 @@ async function fetchVaultDebankResponse(vaultAddress, headers) {
10
10
  const data = (await response.json());
11
11
  return data;
12
12
  }
13
- console.error('#fetchVaultDebankResponse::', response.status, response.statusText);
13
+ core_1.Logger.log.error('fetchVaultDebankResponse', new Error(`HTTP ${response.status} ${response.statusText}`), { status: response.status, statusText: response.statusText });
14
14
  return false;
15
15
  }
16
16
  catch (e) {
17
- console.error('#fetchVaultDebankResponse::', e);
17
+ core_1.Logger.log.error('fetchVaultDebankResponse', e);
18
18
  return false;
19
19
  }
20
20
  }
21
21
  async function fetchDebankResponse(address, headers) {
22
22
  const debankResponse = await (0, core_1.fetchAugustWithKey)(undefined, core_1.WEBSERVER_ENDPOINTS.subaccount.debank(address), { override: true, headers: headers });
23
23
  if (debankResponse.status !== 200) {
24
- console.error('#getVaultAllocations::defi:', debankResponse.status, debankResponse.statusText);
24
+ core_1.Logger.log.error('fetchDebankResponse', new Error(`HTTP ${debankResponse.status} ${debankResponse.statusText}`), {
25
+ status: debankResponse.status,
26
+ statusText: debankResponse.statusText,
27
+ });
25
28
  return false;
26
29
  }
27
30
  else if (debankResponse.status === 200) {
@@ -3,12 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseVaultLevelDebank = parseVaultLevelDebank;
4
4
  exports.getVaultExposure = getVaultExposure;
5
5
  exports.parseLoanLevelDebank = parseLoanLevelDebank;
6
- const core_1 = require("../../core/helpers/core");
6
+ const core_1 = require("../../core");
7
+ const core_2 = require("../../core/helpers/core");
7
8
  function addToTokenExposure(token, tokenExposure, exposureType, protocol, exposurePerCategory, netValue, borrower) {
8
9
  const usdAmount = Number(token?.price || 0) * Number(token?.amount);
9
10
  if (exposureType === 'wallet'
10
- ? !(0, core_1.filterOutBySize)(usdAmount)
11
- : !(0, core_1.filterOutBySize)(usdAmount))
11
+ ? !(0, core_2.filterOutBySize)(usdAmount)
12
+ : !(0, core_2.filterOutBySize)(usdAmount))
12
13
  return;
13
14
  if (exposureType === 'borrow') {
14
15
  netValue.value -= usdAmount;
@@ -73,7 +74,7 @@ function parseVaultLevelDebank(debankRes, protocolExposure, tokenExposure, borro
73
74
  });
74
75
  const foundExistingProtocolExposure = protocolExposure.find((exp) => exp.id === pos.id);
75
76
  if (!foundExistingProtocolExposure &&
76
- (0, core_1.filterOutBySize)(protoReturnObj.netUsdValue)) {
77
+ (0, core_2.filterOutBySize)(protoReturnObj.netUsdValue)) {
77
78
  protocolExposure.push(protoReturnObj);
78
79
  }
79
80
  else if (foundExistingProtocolExposure) {
@@ -126,7 +127,7 @@ function parseVaultLevelDebank(debankRes, protocolExposure, tokenExposure, borro
126
127
  });
127
128
  const foundExistingProtocolExposure = protocolExposure.find((exp) => exp.id === pos.id);
128
129
  if (!foundExistingProtocolExposure &&
129
- (0, core_1.filterOutBySize)(protoReturnObj.netUsdValue)) {
130
+ (0, core_2.filterOutBySize)(protoReturnObj.netUsdValue)) {
130
131
  protocolExposure.push(protoReturnObj);
131
132
  }
132
133
  else if (foundExistingProtocolExposure) {
@@ -272,7 +273,7 @@ function parseLoanLevelDebank(debankRes) {
272
273
  exposure = uniqueExposure;
273
274
  }
274
275
  catch (err) {
275
- console.error('#getPoolLoansData::strategies:', err);
276
+ core_1.Logger.log.error('getPoolLoansData.strategies', err);
276
277
  }
277
278
  return { exposure, positions };
278
279
  }
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.fetchOctavfiPortfolios = fetchOctavfiPortfolios;
4
4
  const ethers_1 = require("ethers");
5
5
  const utils_1 = require("../../adapters/solana/utils");
6
+ const core_1 = require("../../core");
6
7
  const BASE_URL = 'https://api.octav.fi';
7
8
  const OCTAVFI_API_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwczovL2hhc3VyYS5pby9qd3QvY2xhaW1zIjp7IngtaGFzdXJhLWRlZmF1bHQtcm9sZSI6InVzZXIiLCJ4LWhhc3VyYS1hbGxvd2VkLXJvbGVzIjpbInVzZXIiXSwieC1oYXN1cmEtdXNlci1pZCI6ImF1Z3VzdDEyMjM0In19.zaMUtrtdC82uaDh6XSZrsneEcKO3PFOE6FyX3G-MR6c';
8
9
  function filterEvmAndSolanaAddresses(addresses) {
@@ -15,7 +16,7 @@ function filterEvmAndSolanaAddresses(addresses) {
15
16
  if (utils_1.SolanaUtils.isSolanaAddress(address)) {
16
17
  return true;
17
18
  }
18
- console.log(`Excluding address: ${address} (not EVM or Solana)`);
19
+ core_1.Logger.log.info('filterEvmAndSolanaAddresses.excluded', { address });
19
20
  return false;
20
21
  });
21
22
  }
@@ -30,16 +31,20 @@ async function fetchSinglePortfolio(address) {
30
31
  });
31
32
  if (!response.ok) {
32
33
  const errorText = await response.text();
33
- console.error(`Failed to fetch portfolio for ${address}: ${response.status} ${response.statusText}. ${errorText}`);
34
+ core_1.Logger.log.error('fetchSinglePortfolio', new Error(`HTTP ${response.status} ${response.statusText}: ${errorText}`), {
35
+ address,
36
+ status: response.status,
37
+ statusText: response.statusText,
38
+ });
34
39
  return null;
35
40
  }
36
41
  const data = await response.json();
37
42
  if (!data || typeof data !== 'object') {
38
- console.error(`Unexpected response type for ${address}:`, typeof data);
43
+ core_1.Logger.log.error('fetchSinglePortfolio.unexpected-type', new Error(`unexpected response type: ${typeof data}`), { address });
39
44
  return null;
40
45
  }
41
46
  if (data.error) {
42
- console.error(`API error for ${address}:`, data.error);
47
+ core_1.Logger.log.error('fetchSinglePortfolio.api-error', new Error(String(data.error)), { address });
43
48
  return null;
44
49
  }
45
50
  let portfolio = data;
@@ -57,7 +62,7 @@ async function fetchSinglePortfolio(address) {
57
62
  return portfolio;
58
63
  }
59
64
  catch (error) {
60
- console.error(`Error fetching portfolio for ${address}:`, error);
65
+ core_1.Logger.log.error('fetchSinglePortfolio', error, { address });
61
66
  return null;
62
67
  }
63
68
  }
@@ -297,7 +297,7 @@ async function getSubgraphWithdrawProccessed(pool, provider, slackWebookUrl = sl
297
297
  const requests = [];
298
298
  if (!goldskyUrl) {
299
299
  const chainId = await (0, core_1.getChainId)(provider);
300
- console.error('#getSubgraphWithdrawProccessed: goldsky url is undefined:', chainId, vaultSymbol, pool);
300
+ core_1.Logger.log.error('getSubgraphWithdrawProccessed.missing-subgraph-url', new Error('goldsky url is undefined'), { chainId, vaultSymbol, pool });
301
301
  slack_1.SLACK.error({
302
302
  title: 'Missing Subgraph',
303
303
  error: '#getSubgraphWithdrawProccessed: goldsky url is undefined',
@@ -326,7 +326,7 @@ async function getSubgraphWithdrawProccessed(pool, provider, slackWebookUrl = sl
326
326
  }
327
327
  }`, GOLDSKY_API_KEY);
328
328
  if (result.status !== 200) {
329
- console.error('#getSubgraphWithdrawProccessed:', result.status, result.statusText, pool);
329
+ core_1.Logger.log.error('getSubgraphWithdrawProccessed', new Error(`HTTP ${result.status} ${result.statusText}`), { status: result.status, statusText: result.statusText, pool });
330
330
  return [];
331
331
  }
332
332
  const json = (await result.json());
@@ -334,7 +334,7 @@ async function getSubgraphWithdrawProccessed(pool, provider, slackWebookUrl = sl
334
334
  return requests;
335
335
  }
336
336
  catch (e) {
337
- console.error('#getSubgraphWithdrawProccessed::', pool, e);
337
+ core_1.Logger.log.error('getSubgraphWithdrawProccessed', e, { pool });
338
338
  return [];
339
339
  }
340
340
  }
@@ -638,7 +638,7 @@ async function getSubgraphVaultHistory(provider, pool, slackWebookUrl = slack_1.
638
638
  }
639
639
  }`, GOLDSKY_API_KEY);
640
640
  if (result.status !== 200) {
641
- console.error('#getSubgraphVaultHistory:', result.status, result.statusText);
641
+ core_1.Logger.log.error('getSubgraphVaultHistory', new Error(`HTTP ${result.status} ${result.statusText}`), { status: result.status, statusText: result.statusText });
642
642
  return requests;
643
643
  }
644
644
  const json = (await result.json());
@@ -648,7 +648,7 @@ async function getSubgraphVaultHistory(provider, pool, slackWebookUrl = slack_1.
648
648
  return formattedRequests;
649
649
  }
650
650
  catch (e) {
651
- console.error('#getSubgraphVaultHistory::', pool, e);
651
+ core_1.Logger.log.error('getSubgraphVaultHistory', e, { pool });
652
652
  return [];
653
653
  }
654
654
  }
@@ -740,7 +740,7 @@ async function getSubgraphUserTransfers(user, provider, pool, slackWebookUrl = s
740
740
  return userTransfers;
741
741
  }
742
742
  catch (e) {
743
- console.error('#getSubgraphUserTransfers::', pool, ':', e);
743
+ core_1.Logger.log.error('getSubgraphUserTransfers', e, { pool });
744
744
  return [];
745
745
  }
746
746
  }
@@ -0,0 +1,25 @@
1
+ import type { IAddress } from '../../types';
2
+ export type ISwapQuoteProvider = 'paraswap';
3
+ export interface ISwapQuoteRequest {
4
+ chainId: number;
5
+ srcToken: IAddress;
6
+ srcDecimals: number;
7
+ destToken: IAddress;
8
+ destDecimals: number;
9
+ amount: bigint;
10
+ receiver: IAddress;
11
+ slippageBps?: number;
12
+ partner?: string;
13
+ partnerAddress?: IAddress;
14
+ fetchImpl?: typeof fetch;
15
+ signal?: AbortSignal;
16
+ }
17
+ export type ISwapQuoteResult = {
18
+ provider: 'paraswap';
19
+ router: IAddress;
20
+ payload: `0x${string}`;
21
+ expectedAmountOut: bigint;
22
+ minAmountOut: bigint;
23
+ fetchedAt: number;
24
+ };
25
+ export declare function fetchSwapQuote(request: ISwapQuoteRequest): Promise<ISwapQuoteResult>;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fetchSwapQuote = fetchSwapQuote;
4
+ const errors_1 = require("../../core/errors");
5
+ const paraswap_1 = require("./paraswap");
6
+ const DEFAULT_SLIPPAGE_BPS = 100;
7
+ const BPS_DENOMINATOR = 10000n;
8
+ async function fetchSwapQuote(request) {
9
+ validateRequest(request);
10
+ const slippageBps = request.slippageBps ?? DEFAULT_SLIPPAGE_BPS;
11
+ const fetchImpl = request.fetchImpl ?? globalThis.fetch;
12
+ const { router, payload, expectedAmountOut, fetchedAt } = await (0, paraswap_1.fetchParaswapQuote)({
13
+ chainId: request.chainId,
14
+ srcToken: request.srcToken,
15
+ srcDecimals: request.srcDecimals,
16
+ destToken: request.destToken,
17
+ destDecimals: request.destDecimals,
18
+ amount: request.amount,
19
+ receiver: request.receiver,
20
+ slippageBps,
21
+ partner: request.partner ?? paraswap_1.PARASWAP_DEFAULTS.partner,
22
+ partnerAddress: request.partnerAddress ?? paraswap_1.PARASWAP_DEFAULTS.partnerAddress,
23
+ fetchImpl,
24
+ signal: request.signal,
25
+ });
26
+ const minAmountOut = applySlippage(expectedAmountOut, slippageBps);
27
+ return {
28
+ provider: 'paraswap',
29
+ router,
30
+ payload,
31
+ expectedAmountOut,
32
+ minAmountOut,
33
+ fetchedAt,
34
+ };
35
+ }
36
+ function validateRequest(req) {
37
+ if (req.slippageBps !== undefined &&
38
+ (req.slippageBps < 0 || req.slippageBps >= 10000)) {
39
+ 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.`);
40
+ }
41
+ if (req.amount === 0n) {
42
+ throw new errors_1.AugustValidationError('INVALID_INPUT', 'fetchSwapQuote: amount must be greater than zero');
43
+ }
44
+ if (req.srcToken.toLowerCase() === req.destToken.toLowerCase()) {
45
+ throw new errors_1.AugustValidationError('INVALID_INPUT', 'fetchSwapQuote: srcToken and destToken are identical — no swap needed');
46
+ }
47
+ }
48
+ function applySlippage(amount, slippageBps) {
49
+ return (amount * (BPS_DENOMINATOR - BigInt(slippageBps))) / BPS_DENOMINATOR;
50
+ }
51
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,26 @@
1
+ import type { IAddress } from '../../types';
2
+ export interface IParaswapQuoteInput {
3
+ chainId: number;
4
+ srcToken: IAddress;
5
+ srcDecimals: number;
6
+ destToken: IAddress;
7
+ destDecimals: number;
8
+ amount: bigint;
9
+ receiver: IAddress;
10
+ slippageBps: number;
11
+ partner: string;
12
+ partnerAddress: IAddress;
13
+ fetchImpl: typeof fetch;
14
+ signal?: AbortSignal;
15
+ }
16
+ export interface IParaswapQuoteOutput {
17
+ router: IAddress;
18
+ payload: `0x${string}`;
19
+ expectedAmountOut: bigint;
20
+ fetchedAt: number;
21
+ }
22
+ export declare function fetchParaswapQuote(input: IParaswapQuoteInput): Promise<IParaswapQuoteOutput>;
23
+ export declare const PARASWAP_DEFAULTS: {
24
+ readonly partner: "august";
25
+ readonly partnerAddress: `0x${string}`;
26
+ };