augustdigital-sdk 8.20.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.
- package/LICENSE +21 -0
- package/README.md +349 -0
- package/lib/abis/AddressResolver.d.ts +28 -0
- package/lib/abis/AddressResolver.js +23 -0
- package/lib/abis/ChainlinkV3.d.ts +87 -0
- package/lib/abis/ChainlinkV3.js +117 -0
- package/lib/abis/ERC20.d.ts +168 -0
- package/lib/abis/ERC20.js +226 -0
- package/lib/abis/ERC20_Bytes32.d.ts +139 -0
- package/lib/abis/ERC20_Bytes32.js +196 -0
- package/lib/abis/ERC4626.d.ts +364 -0
- package/lib/abis/ERC4626.js +507 -0
- package/lib/abis/ERC721.d.ts +231 -0
- package/lib/abis/ERC721.js +321 -0
- package/lib/abis/FeeOracle.d.ts +120 -0
- package/lib/abis/FeeOracle.js +162 -0
- package/lib/abis/LendingPool.d.ts +1393 -0
- package/lib/abis/LendingPool.js +1807 -0
- package/lib/abis/LendingPoolV2.d.ts +1413 -0
- package/lib/abis/LendingPoolV2.js +1833 -0
- package/lib/abis/LendingPoolV3.d.ts +1677 -0
- package/lib/abis/LendingPoolV3.js +1160 -0
- package/lib/abis/Loan.d.ts +837 -0
- package/lib/abis/Loan.js +1080 -0
- package/lib/abis/MultiAssetNativeDepositWrapper.d.ts +137 -0
- package/lib/abis/MultiAssetNativeDepositWrapper.js +125 -0
- package/lib/abis/Multicall3.d.ts +30 -0
- package/lib/abis/Multicall3.js +97 -0
- package/lib/abis/OFT.d.ts +116 -0
- package/lib/abis/OFT.js +85 -0
- package/lib/abis/PoolAdapter.d.ts +36 -0
- package/lib/abis/PoolAdapter.js +51 -0
- package/lib/abis/RewardDistributor.d.ts +267 -0
- package/lib/abis/RewardDistributor.js +352 -0
- package/lib/abis/RwaRedeemSubaccount.d.ts +747 -0
- package/lib/abis/RwaRedeemSubaccount.js +548 -0
- package/lib/abis/SmartAccount.d.ts +17 -0
- package/lib/abis/SmartAccount.js +19 -0
- package/lib/abis/SwapRouter.d.ts +1043 -0
- package/lib/abis/SwapRouter.js +740 -0
- package/lib/abis/TextResolver.d.ts +16 -0
- package/lib/abis/TextResolver.js +16 -0
- package/lib/abis/TokenizedVaultV2.d.ts +1364 -0
- package/lib/abis/TokenizedVaultV2.js +1041 -0
- package/lib/abis/TokenizedVaultV2DepositWithPermit.d.ts +1456 -0
- package/lib/abis/TokenizedVaultV2DepositWithPermit.js +1878 -0
- package/lib/abis/TokenizedVaultV2Receipt.d.ts +1568 -0
- package/lib/abis/TokenizedVaultV2Receipt.js +1061 -0
- package/lib/abis/TokenizedVaultV2SenderAllocationWhitelist.d.ts +454 -0
- package/lib/abis/TokenizedVaultV2SenderAllocationWhitelist.js +327 -0
- package/lib/abis/TokenizedVaultV2WhitelistedAllocation.d.ts +1466 -0
- package/lib/abis/TokenizedVaultV2WhitelistedAllocation.js +1092 -0
- package/lib/abis/TokenizedVaultV2WhitelistedAssets.d.ts +274 -0
- package/lib/abis/TokenizedVaultV2WhitelistedAssets.js +167 -0
- package/lib/abis/UniversalResolverResolve.d.ts +69 -0
- package/lib/abis/UniversalResolverResolve.js +35 -0
- package/lib/abis/UniversalSignatureValidator.d.ts +17 -0
- package/lib/abis/UniversalSignatureValidator.js +30 -0
- package/lib/abis/WrapperAdapter.d.ts +71 -0
- package/lib/abis/WrapperAdapter.js +77 -0
- package/lib/abis/index.d.ts +34 -0
- package/lib/abis/index.js +51 -0
- package/lib/adapters/evm/getters.d.ts +19 -0
- package/lib/adapters/evm/getters.js +209 -0
- package/lib/adapters/evm/index.d.ts +353 -0
- package/lib/adapters/evm/index.js +434 -0
- package/lib/adapters/evm/utils.d.ts +8 -0
- package/lib/adapters/evm/utils.js +51 -0
- package/lib/adapters/solana/constants.d.ts +33 -0
- package/lib/adapters/solana/constants.js +52 -0
- package/lib/adapters/solana/getters.d.ts +11 -0
- package/lib/adapters/solana/getters.js +165 -0
- package/lib/adapters/solana/idl/vault-idl.d.ts +272 -0
- package/lib/adapters/solana/idl/vault-idl.js +1084 -0
- package/lib/adapters/solana/index.d.ts +233 -0
- package/lib/adapters/solana/index.js +291 -0
- package/lib/adapters/solana/types.d.ts +67 -0
- package/lib/adapters/solana/types.js +3 -0
- package/lib/adapters/solana/utils.d.ts +141 -0
- package/lib/adapters/solana/utils.js +595 -0
- package/lib/adapters/solana/vault.actions.d.ts +57 -0
- package/lib/adapters/solana/vault.actions.js +379 -0
- package/lib/adapters/stellar/actions.d.ts +28 -0
- package/lib/adapters/stellar/actions.js +77 -0
- package/lib/adapters/stellar/constants.d.ts +43 -0
- package/lib/adapters/stellar/constants.js +53 -0
- package/lib/adapters/stellar/getters.d.ts +68 -0
- package/lib/adapters/stellar/getters.js +290 -0
- package/lib/adapters/stellar/index.d.ts +114 -0
- package/lib/adapters/stellar/index.js +175 -0
- package/lib/adapters/stellar/soroban.d.ts +123 -0
- package/lib/adapters/stellar/soroban.js +613 -0
- package/lib/adapters/stellar/submit.d.ts +34 -0
- package/lib/adapters/stellar/submit.js +149 -0
- package/lib/adapters/stellar/types.d.ts +58 -0
- package/lib/adapters/stellar/types.js +6 -0
- package/lib/adapters/stellar/utils.d.ts +24 -0
- package/lib/adapters/stellar/utils.js +34 -0
- package/lib/adapters/sui/constants.d.ts +14 -0
- package/lib/adapters/sui/constants.js +29 -0
- package/lib/adapters/sui/getters.d.ts +9 -0
- package/lib/adapters/sui/getters.js +60 -0
- package/lib/adapters/sui/index.d.ts +45 -0
- package/lib/adapters/sui/index.js +101 -0
- package/lib/adapters/sui/transformer.d.ts +10 -0
- package/lib/adapters/sui/transformer.js +107 -0
- package/lib/adapters/sui/types.d.ts +66 -0
- package/lib/adapters/sui/types.js +3 -0
- package/lib/adapters/sui/utils.d.ts +10 -0
- package/lib/adapters/sui/utils.js +29 -0
- package/lib/core/analytics/chain-name.d.ts +9 -0
- package/lib/core/analytics/chain-name.js +34 -0
- package/lib/core/analytics/constants.d.ts +5 -0
- package/lib/core/analytics/constants.js +9 -0
- package/lib/core/analytics/env.d.ts +29 -0
- package/lib/core/analytics/env.js +59 -0
- package/lib/core/analytics/index.d.ts +36 -0
- package/lib/core/analytics/index.js +79 -0
- package/lib/core/analytics/instrumentation.d.ts +29 -0
- package/lib/core/analytics/instrumentation.js +277 -0
- package/lib/core/analytics/method-taxonomy.d.ts +19 -0
- package/lib/core/analytics/method-taxonomy.js +128 -0
- package/lib/core/analytics/metrics.d.ts +33 -0
- package/lib/core/analytics/metrics.js +116 -0
- package/lib/core/analytics/sanitize.d.ts +44 -0
- package/lib/core/analytics/sanitize.js +260 -0
- package/lib/core/analytics/sentry-runtime.d.ts +15 -0
- package/lib/core/analytics/sentry-runtime.js +97 -0
- package/lib/core/analytics/sentry.d.ts +67 -0
- package/lib/core/analytics/sentry.js +613 -0
- package/lib/core/analytics/types.d.ts +48 -0
- package/lib/core/analytics/types.js +3 -0
- package/lib/core/analytics/user-identity.d.ts +41 -0
- package/lib/core/analytics/user-identity.js +141 -0
- package/lib/core/analytics/version.d.ts +6 -0
- package/lib/core/analytics/version.js +10 -0
- package/lib/core/attribution.d.ts +111 -0
- package/lib/core/attribution.js +142 -0
- package/lib/core/auth/index.d.ts +1 -0
- package/lib/core/auth/index.js +18 -0
- package/lib/core/auth/verify.d.ts +2 -0
- package/lib/core/auth/verify.js +31 -0
- package/lib/core/base.class.d.ts +152 -0
- package/lib/core/base.class.js +172 -0
- package/lib/core/cache.d.ts +9 -0
- package/lib/core/cache.js +31 -0
- package/lib/core/constants/adapters.d.ts +103 -0
- package/lib/core/constants/adapters.js +180 -0
- package/lib/core/constants/core.d.ts +133 -0
- package/lib/core/constants/core.js +209 -0
- package/lib/core/constants/swap-router.d.ts +150 -0
- package/lib/core/constants/swap-router.js +169 -0
- package/lib/core/constants/vaults.d.ts +93 -0
- package/lib/core/constants/vaults.js +273 -0
- package/lib/core/constants/web3.d.ts +91 -0
- package/lib/core/constants/web3.js +229 -0
- package/lib/core/errors/index.d.ts +114 -0
- package/lib/core/errors/index.js +183 -0
- package/lib/core/fetcher.d.ts +198 -0
- package/lib/core/fetcher.js +903 -0
- package/lib/core/helpers/adapters.d.ts +13 -0
- package/lib/core/helpers/adapters.js +39 -0
- package/lib/core/helpers/chain-address.d.ts +13 -0
- package/lib/core/helpers/chain-address.js +47 -0
- package/lib/core/helpers/chain-error.d.ts +207 -0
- package/lib/core/helpers/chain-error.js +682 -0
- package/lib/core/helpers/chain-support.d.ts +80 -0
- package/lib/core/helpers/chain-support.js +115 -0
- package/lib/core/helpers/core.d.ts +68 -0
- package/lib/core/helpers/core.js +285 -0
- package/lib/core/helpers/explorer-link.d.ts +16 -0
- package/lib/core/helpers/explorer-link.js +26 -0
- package/lib/core/helpers/multicall.d.ts +68 -0
- package/lib/core/helpers/multicall.js +103 -0
- package/lib/core/helpers/revert-decode.d.ts +248 -0
- package/lib/core/helpers/revert-decode.js +515 -0
- package/lib/core/helpers/signer.d.ts +52 -0
- package/lib/core/helpers/signer.js +145 -0
- package/lib/core/helpers/swap-router.d.ts +211 -0
- package/lib/core/helpers/swap-router.js +480 -0
- package/lib/core/helpers/vault-version.d.ts +23 -0
- package/lib/core/helpers/vault-version.js +75 -0
- package/lib/core/helpers/vaults.d.ts +89 -0
- package/lib/core/helpers/vaults.js +235 -0
- package/lib/core/helpers/web3.d.ts +353 -0
- package/lib/core/helpers/web3.js +992 -0
- package/lib/core/index.d.ts +23 -0
- package/lib/core/index.js +40 -0
- package/lib/core/logger/index.d.ts +98 -0
- package/lib/core/logger/index.js +144 -0
- package/lib/core/logger/slack.d.ts +16 -0
- package/lib/core/logger/slack.js +57 -0
- package/lib/core/vault-metadata.d.ts +12 -0
- package/lib/core/vault-metadata.js +42 -0
- package/lib/core/version-check.d.ts +58 -0
- package/lib/core/version-check.js +182 -0
- package/lib/evm/index.d.ts +2 -0
- package/lib/evm/index.js +19 -0
- package/lib/evm/methods/crossChainVault.d.ts +128 -0
- package/lib/evm/methods/crossChainVault.js +853 -0
- package/lib/evm/methods/crossChainVaultRegistry.d.ts +93 -0
- package/lib/evm/methods/crossChainVaultRegistry.js +240 -0
- package/lib/evm/methods/index.d.ts +2 -0
- package/lib/evm/methods/index.js +19 -0
- package/lib/evm/types/crossChain.d.ts +363 -0
- package/lib/evm/types/crossChain.js +20 -0
- package/lib/evm/types/index.d.ts +1 -0
- package/lib/evm/types/index.js +18 -0
- package/lib/index.d.ts +30 -0
- package/lib/index.js +52 -0
- package/lib/main.d.ts +527 -0
- package/lib/main.js +601 -0
- package/lib/modules/api/fetcher.d.ts +82 -0
- package/lib/modules/api/fetcher.js +150 -0
- package/lib/modules/api/index.d.ts +1 -0
- package/lib/modules/api/index.js +6 -0
- package/lib/modules/api/main.d.ts +313 -0
- package/lib/modules/api/main.js +479 -0
- package/lib/modules/sub-accounts/fetcher.d.ts +53 -0
- package/lib/modules/sub-accounts/fetcher.js +120 -0
- package/lib/modules/sub-accounts/index.d.ts +2 -0
- package/lib/modules/sub-accounts/index.js +19 -0
- package/lib/modules/sub-accounts/main.d.ts +243 -0
- package/lib/modules/sub-accounts/main.js +205 -0
- package/lib/modules/sub-accounts/utils.d.ts +106 -0
- package/lib/modules/sub-accounts/utils.js +112 -0
- package/lib/modules/vaults/adapter.helpers.d.ts +64 -0
- package/lib/modules/vaults/adapter.helpers.js +184 -0
- package/lib/modules/vaults/fetcher.d.ts +147 -0
- package/lib/modules/vaults/fetcher.js +368 -0
- package/lib/modules/vaults/getters.d.ts +570 -0
- package/lib/modules/vaults/getters.js +3051 -0
- package/lib/modules/vaults/index.d.ts +20 -0
- package/lib/modules/vaults/index.js +44 -0
- package/lib/modules/vaults/main.d.ts +601 -0
- package/lib/modules/vaults/main.js +1623 -0
- package/lib/modules/vaults/prefetch.d.ts +65 -0
- package/lib/modules/vaults/prefetch.js +120 -0
- package/lib/modules/vaults/read.actions.d.ts +225 -0
- package/lib/modules/vaults/read.actions.js +596 -0
- package/lib/modules/vaults/types.d.ts +71 -0
- package/lib/modules/vaults/types.js +3 -0
- package/lib/modules/vaults/utils/call-data-decoder.d.ts +61 -0
- package/lib/modules/vaults/utils/call-data-decoder.js +194 -0
- package/lib/modules/vaults/utils/date-utils.d.ts +50 -0
- package/lib/modules/vaults/utils/date-utils.js +84 -0
- package/lib/modules/vaults/utils.d.ts +140 -0
- package/lib/modules/vaults/utils.js +799 -0
- package/lib/modules/vaults/write.actions.d.ts +529 -0
- package/lib/modules/vaults/write.actions.js +1749 -0
- package/lib/polyfills.d.ts +1 -0
- package/lib/polyfills.js +12 -0
- package/lib/sdk.d.ts +26721 -0
- package/lib/services/coingecko/fetcher.d.ts +15 -0
- package/lib/services/coingecko/fetcher.js +67 -0
- package/lib/services/coingecko/index.d.ts +2 -0
- package/lib/services/coingecko/index.js +19 -0
- package/lib/services/coingecko/utils.d.ts +1 -0
- package/lib/services/coingecko/utils.js +24 -0
- package/lib/services/debank/fetcher.d.ts +126 -0
- package/lib/services/debank/fetcher.js +47 -0
- package/lib/services/debank/index.d.ts +2 -0
- package/lib/services/debank/index.js +19 -0
- package/lib/services/debank/utils.d.ts +38 -0
- package/lib/services/debank/utils.js +297 -0
- package/lib/services/layerzero/deposits.d.ts +49 -0
- package/lib/services/layerzero/deposits.js +166 -0
- package/lib/services/layerzero/redeems.d.ts +20 -0
- package/lib/services/layerzero/redeems.js +92 -0
- package/lib/services/layerzero/utils.d.ts +9 -0
- package/lib/services/layerzero/utils.js +22 -0
- package/lib/services/octavfi/fetcher.d.ts +9 -0
- package/lib/services/octavfi/fetcher.js +103 -0
- package/lib/services/octavfi/index.d.ts +3 -0
- package/lib/services/octavfi/index.js +20 -0
- package/lib/services/octavfi/types.d.ts +34 -0
- package/lib/services/octavfi/types.js +3 -0
- package/lib/services/octavfi/utils.d.ts +16 -0
- package/lib/services/octavfi/utils.js +212 -0
- package/lib/services/subgraph/fetcher.d.ts +2 -0
- package/lib/services/subgraph/fetcher.js +61 -0
- package/lib/services/subgraph/index.d.ts +2 -0
- package/lib/services/subgraph/index.js +19 -0
- package/lib/services/subgraph/schema.d.ts +45 -0
- package/lib/services/subgraph/schema.js +75 -0
- package/lib/services/subgraph/vaults.d.ts +25 -0
- package/lib/services/subgraph/vaults.js +1106 -0
- package/lib/services/swap-quotes/index.d.ts +105 -0
- package/lib/services/swap-quotes/index.js +77 -0
- package/lib/services/swap-quotes/paraswap.d.ts +51 -0
- package/lib/services/swap-quotes/paraswap.js +138 -0
- package/lib/types/api.d.ts +280 -0
- package/lib/types/api.js +3 -0
- package/lib/types/index.d.ts +12 -0
- package/lib/types/index.js +28 -0
- package/lib/types/points.d.ts +28 -0
- package/lib/types/points.js +3 -0
- package/lib/types/pools.d.ts +144 -0
- package/lib/types/pools.js +3 -0
- package/lib/types/staking.d.ts +28 -0
- package/lib/types/staking.js +3 -0
- package/lib/types/sub-accounts.d.ts +140 -0
- package/lib/types/sub-accounts.js +3 -0
- package/lib/types/subgraph.d.ts +74 -0
- package/lib/types/subgraph.js +3 -0
- package/lib/types/typed-contract.d.ts +102 -0
- package/lib/types/typed-contract.js +3 -0
- package/lib/types/user.d.ts +1 -0
- package/lib/types/user.js +3 -0
- package/lib/types/vaults.d.ts +714 -0
- package/lib/types/vaults.js +24 -0
- package/lib/types/web3.d.ts +51 -0
- package/lib/types/web3.js +14 -0
- package/lib/types/webserver.d.ts +698 -0
- package/lib/types/webserver.js +3 -0
- package/package.json +78 -0
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.vaultUsesSwapRouter = void 0;
|
|
4
|
+
exports.getSwapRouterAddress = getSwapRouterAddress;
|
|
5
|
+
exports.getSwapRouterName = getSwapRouterName;
|
|
6
|
+
exports.isSwapRouterEligible = isSwapRouterEligible;
|
|
7
|
+
exports.resolveOriginCode = resolveOriginCode;
|
|
8
|
+
exports.getSwapRouterDepositResult = getSwapRouterDepositResult;
|
|
9
|
+
exports.getSwapRouterWhitelistedTokens = getSwapRouterWhitelistedTokens;
|
|
10
|
+
exports.getSwapRouterEligibleVaults = getSwapRouterEligibleVaults;
|
|
11
|
+
const ethers_1 = require("ethers");
|
|
12
|
+
const swap_router_1 = require("../constants/swap-router");
|
|
13
|
+
const abis_1 = require("../../abis");
|
|
14
|
+
const errors_1 = require("../errors");
|
|
15
|
+
const cache_1 = require("../cache");
|
|
16
|
+
const logger_1 = require("../logger");
|
|
17
|
+
const web3_1 = require("./web3");
|
|
18
|
+
const multicall_1 = require("./multicall");
|
|
19
|
+
/**
|
|
20
|
+
* Resolve the `SwapRouter` address for a chain.
|
|
21
|
+
*
|
|
22
|
+
* @param chainId - EVM chain ID.
|
|
23
|
+
* @returns The router address, or `undefined` if no SwapRouter is deployed.
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* const router = getSwapRouterAddress(1);
|
|
27
|
+
* // '0xAC771209FF2b71EECfF6E85a9AD01db8Ff2618B0'
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
function getSwapRouterAddress(chainId) {
|
|
31
|
+
return swap_router_1.SWAP_ROUTER_ADDRESSES[chainId];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Resolve the human-readable display name of the `SwapRouter` periphery
|
|
35
|
+
* contract for a chain.
|
|
36
|
+
*
|
|
37
|
+
* The contract exposes no name on-chain, so this reads the SDK-maintained
|
|
38
|
+
* {@link SWAP_ROUTER_NAMES} registry. Intended for UI surfaces that label the
|
|
39
|
+
* contract a swap-and-deposit routes through (e.g. a "Router" row in a
|
|
40
|
+
* transaction overview) — display metadata only, never routing logic.
|
|
41
|
+
*
|
|
42
|
+
* @param chainId - EVM chain ID.
|
|
43
|
+
* @returns The display name (e.g. `'Upshift Swap Router'`), or `undefined`
|
|
44
|
+
* when no SwapRouter is deployed on the chain — callers should omit the
|
|
45
|
+
* label rather than show an address.
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* const name = getSwapRouterName(1);
|
|
49
|
+
* // 'Upshift Swap Router'
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
function getSwapRouterName(chainId) {
|
|
53
|
+
return swap_router_1.SWAP_ROUTER_NAMES[chainId];
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Whether a vault is eligible for the any-token `SwapRouter` deposit surface
|
|
57
|
+
* (the SwapRouter is `enableVault`-ed for it on-chain). Address comparison is
|
|
58
|
+
* case-insensitive.
|
|
59
|
+
*
|
|
60
|
+
* This gates the (flag-controlled) swap-router deposit UI and can fail-fast a
|
|
61
|
+
* {@link swapRouterDeposit} call. It does **not** affect {@link vaultDeposit},
|
|
62
|
+
* which is always the native/multiasset/adapter path.
|
|
63
|
+
*
|
|
64
|
+
* @param vaultAddress - August vault address.
|
|
65
|
+
* @returns `true` when the vault is in {@link SWAP_ROUTER_ELIGIBLE_VAULTS}.
|
|
66
|
+
* @deprecated Superseded by {@link getSwapRouterEligibleVaults}, which resolves
|
|
67
|
+
* eligibility from the router's on-chain `VaultEnabled` history + current
|
|
68
|
+
* `vaultInfo` registration instead of this static snapshot. Kept functional as
|
|
69
|
+
* the zero-RPC sync fallback (seed data, fail-fast checks); migrate UI gates
|
|
70
|
+
* to the async resolver.
|
|
71
|
+
*/
|
|
72
|
+
function isSwapRouterEligible(vaultAddress) {
|
|
73
|
+
return swap_router_1.SWAP_ROUTER_ELIGIBLE_VAULTS.has(vaultAddress.toLowerCase());
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* @deprecated Renamed to {@link isSwapRouterEligible} (itself now superseded by
|
|
77
|
+
* {@link getSwapRouterEligibleVaults}, the on-chain-derived resolver). The
|
|
78
|
+
* meaning also changed: it no longer implies `vaultDeposit` routes the vault
|
|
79
|
+
* through the SwapRouter (that behavior was removed) — it only reports
|
|
80
|
+
* swap-router *eligibility* for the opt-in deposit surface. Kept as an alias
|
|
81
|
+
* for one release; migrate to the async resolver.
|
|
82
|
+
*/
|
|
83
|
+
exports.vaultUsesSwapRouter = isSwapRouterEligible;
|
|
84
|
+
/**
|
|
85
|
+
* Normalize an optional origin code to the value to send on-chain.
|
|
86
|
+
*
|
|
87
|
+
* Returns the caller-supplied code when present, otherwise the default
|
|
88
|
+
* (all-zero) sentinel from {@link ORIGIN_CODES}. Validates that any
|
|
89
|
+
* supplied code is exactly 32 bytes (66 chars including the `0x` prefix);
|
|
90
|
+
* the on-chain SwapRouter reverts with `InvalidOrigin` otherwise, but
|
|
91
|
+
* surfacing the failure here as a typed SDK error gives partners a
|
|
92
|
+
* grepable Sentry event instead of a generic `execution reverted`.
|
|
93
|
+
*
|
|
94
|
+
* @param provided - Optional caller-supplied origin code.
|
|
95
|
+
* @returns The 32-byte origin code to pass to the router.
|
|
96
|
+
* @throws {@link AugustValidationError} when `provided` is not a 32-byte hex string.
|
|
97
|
+
*/
|
|
98
|
+
function resolveOriginCode(provided) {
|
|
99
|
+
if (provided === undefined)
|
|
100
|
+
return swap_router_1.ORIGIN_CODES.default;
|
|
101
|
+
if (!/^0x[0-9a-fA-F]{64}$/.test(provided)) {
|
|
102
|
+
throw new errors_1.AugustValidationError('INVALID_INPUT', `resolveOriginCode: originCode must be a 32-byte hex string (66 chars incl. 0x), got "${provided}" (${provided.length} chars)`, { context: { provided, expectedLength: 66 } });
|
|
103
|
+
}
|
|
104
|
+
return provided;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Resolves the real, post-execution outcome of a SwapRouter deposit from its
|
|
108
|
+
* mined transaction receipt. The SwapRouter contract itself emits no
|
|
109
|
+
* deposit/amount-out event — only the vault does, via its own `Deposit` event
|
|
110
|
+
* — so this decodes that log directly rather than trusting the pre-trade quote
|
|
111
|
+
* a UI shows before the user submits (the true post-swap amount depends on
|
|
112
|
+
* execution-time price and can differ from that estimate).
|
|
113
|
+
*
|
|
114
|
+
* Works for both vault generations without the caller resolving the version
|
|
115
|
+
* first: evm-1 (ERC-4626-style `Deposit(sender, owner, assets, shares)`) and
|
|
116
|
+
* evm-2 (`Deposit(assetIn, amountIn, shares, senderAddr, receiverAddr)`) have
|
|
117
|
+
* different event signatures (different topic0), so both are registered and
|
|
118
|
+
* whichever matches the vault's actual log is decoded.
|
|
119
|
+
*
|
|
120
|
+
* @param signer - ethers `Signer` or `Wallet` connected to a provider (used
|
|
121
|
+
* read-only here — no transaction is sent).
|
|
122
|
+
* @param options - {@link ISwapRouterDepositResultOptions}.
|
|
123
|
+
* @returns The decoded {@link ISwapRouterDepositResult}, or `null` if the
|
|
124
|
+
* receipt isn't found yet or carries no `Deposit` log from `vault` (e.g. the
|
|
125
|
+
* hash is wrong, or the tx hasn't mined).
|
|
126
|
+
* @throws {@link AugustValidationError} if `signer` has no connected provider.
|
|
127
|
+
* @worstCaseRpcCalls 1 — a single `getTransactionReceipt` call; decoding is
|
|
128
|
+
* local.
|
|
129
|
+
* @example
|
|
130
|
+
* ```ts
|
|
131
|
+
* const hash = await augustSdk.evm.swapRouterDeposit({ ... });
|
|
132
|
+
* const result = await augustSdk.evm.getSwapRouterDepositResult({
|
|
133
|
+
* txHash: hash,
|
|
134
|
+
* vault: '0x74ad2f789ed583dbd141bbdafc673fe1f033718b',
|
|
135
|
+
* });
|
|
136
|
+
* // result?.amountOut — actual reference-asset amount received after the swap
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
async function getSwapRouterDepositResult(signer, { txHash, vault }) {
|
|
140
|
+
const provider = signer.provider;
|
|
141
|
+
if (!provider) {
|
|
142
|
+
throw new errors_1.AugustValidationError('INVALID_INPUT', 'getSwapRouterDepositResult: signer has no connected provider');
|
|
143
|
+
}
|
|
144
|
+
const receipt = await provider.getTransactionReceipt(txHash);
|
|
145
|
+
if (!receipt)
|
|
146
|
+
return null;
|
|
147
|
+
const iface = new ethers_1.ethers.Interface([
|
|
148
|
+
'event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares)',
|
|
149
|
+
'event Deposit(address assetIn, uint256 amountIn, uint256 shares, address indexed senderAddr, address indexed receiverAddr)',
|
|
150
|
+
]);
|
|
151
|
+
for (const log of receipt.logs) {
|
|
152
|
+
if (log.address.toLowerCase() !== vault.toLowerCase())
|
|
153
|
+
continue;
|
|
154
|
+
let parsed;
|
|
155
|
+
try {
|
|
156
|
+
parsed = iface.parseLog(log);
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (parsed?.name !== 'Deposit')
|
|
162
|
+
continue;
|
|
163
|
+
// Discriminate on the matched event fragment, not on probing a
|
|
164
|
+
// possibly-absent named arg. Only the evm-2 signature declares `assetIn`,
|
|
165
|
+
// so its presence in the fragment inputs uniquely identifies the version.
|
|
166
|
+
// (Reading `parsed.args.assetIn` on the evm-1 log would couple correctness
|
|
167
|
+
// to ethers' `Result`-proxy behavior for unknown names.)
|
|
168
|
+
const isEvm2 = parsed.fragment.inputs.some((i) => i.name === 'assetIn');
|
|
169
|
+
if (isEvm2) {
|
|
170
|
+
// evm-2 TokenizedVault: Deposit(assetIn, amountIn, shares, sender, receiver)
|
|
171
|
+
return {
|
|
172
|
+
amountOut: BigInt(parsed.args.amountIn),
|
|
173
|
+
sharesOut: BigInt(parsed.args.shares),
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
// evm-1 ERC-4626-style: Deposit(sender, owner, assets, shares)
|
|
177
|
+
return {
|
|
178
|
+
amountOut: BigInt(parsed.args.assets),
|
|
179
|
+
sharesOut: BigInt(parsed.args.shares),
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
/** Cache TTL for a chain's resolved SwapRouter token allowlist (5 minutes). */
|
|
185
|
+
const SWAP_ROUTER_WHITELIST_TTL_MS = 5 * 60 * 1000;
|
|
186
|
+
/**
|
|
187
|
+
* Resolve the ERC-20 tokens currently whitelisted for the `SwapRouter` on a
|
|
188
|
+
* chain — the any-token set a UI can offer as swap-and-deposit inputs.
|
|
189
|
+
*
|
|
190
|
+
* The router exposes its allowlist only as `mapping(address => bool)
|
|
191
|
+
* whitelistedTokens` with **no on-chain enumeration**, so this cannot be a
|
|
192
|
+
* single view call. It runs in two stages:
|
|
193
|
+
* 1. Scan the router's `TokenEnabled(address)` event history (from the chain's
|
|
194
|
+
* {@link SWAP_ROUTER_DEPLOY_BLOCKS} floor, in `eth_getLogs` chunks sized by
|
|
195
|
+
* {@link determineBlockSkipInternal}) to reconstruct the candidate set of
|
|
196
|
+
* every token ever enabled.
|
|
197
|
+
* 2. Re-read `whitelistedTokens(token)` for each candidate — batched via
|
|
198
|
+
* Multicall3 where verified, else per-call — and keep only those the
|
|
199
|
+
* mapping currently returns `true` for. This step makes later disables (and
|
|
200
|
+
* disable-then-re-enable) correct without replaying `TokenDisabled`, and is
|
|
201
|
+
* the fail-closed source of truth: a token surfaces only on a definite
|
|
202
|
+
* on-chain `true`.
|
|
203
|
+
*
|
|
204
|
+
* The resolved list is cached per chain for 5 minutes — the allowlist changes
|
|
205
|
+
* only via an admin `enableToken`/`disableToken` transaction, so a short TTL
|
|
206
|
+
* keeps the (multi-RPC) scan off the hot path without going stale for long.
|
|
207
|
+
*
|
|
208
|
+
* @param chainId - EVM chain ID. Chains without a {@link SWAP_ROUTER_ADDRESSES}
|
|
209
|
+
* entry resolve to `[]` with no RPC.
|
|
210
|
+
* @param options - `rpcUrl` (required) must point at `chainId`'s network;
|
|
211
|
+
* `fromBlock` overrides the default deploy-block scan floor (e.g. to widen a
|
|
212
|
+
* scan on a chain missing from {@link SWAP_ROUTER_DEPLOY_BLOCKS}).
|
|
213
|
+
* @returns Checksummed addresses of the currently-whitelisted tokens, deduped.
|
|
214
|
+
* Empty when no router is deployed or none are enabled. Callers still filter
|
|
215
|
+
* out a given vault's natively-accepted assets (those deposit without a swap).
|
|
216
|
+
* @throws AugustValidationError when `rpcUrl` is missing/empty.
|
|
217
|
+
* @throws AugustSDKError when an `eth_getLogs` chunk fails — surfaced (not
|
|
218
|
+
* swallowed) so a partial scan never masquerades as a complete allowlist.
|
|
219
|
+
* @worstCaseRpcCalls On mainnet, 1 `eth_blockNumber` + ~4 `eth_getLogs` chunks
|
|
220
|
+
* (router-lifetime ÷ 50k-block window) + 1 Multicall3 `eth_call` ≈ 6; scales
|
|
221
|
+
* with the router's on-chain age, not with candidate count.
|
|
222
|
+
* @example
|
|
223
|
+
* ```ts
|
|
224
|
+
* const tokens = await getSwapRouterWhitelistedTokens(1, {
|
|
225
|
+
* rpcUrl: 'https://eth-mainnet.example/v2/KEY',
|
|
226
|
+
* });
|
|
227
|
+
* // ['0xA0b8…', '0xdAC1…', '0xC02a…', '0x2260…'] (USDC, USDT, WETH, WBTC)
|
|
228
|
+
* ```
|
|
229
|
+
*/
|
|
230
|
+
async function getSwapRouterWhitelistedTokens(chainId, options) {
|
|
231
|
+
const router = getSwapRouterAddress(chainId);
|
|
232
|
+
if (!router)
|
|
233
|
+
return [];
|
|
234
|
+
const cacheKey = `swap-router-whitelisted-tokens-${chainId}-${router.toLowerCase()}`;
|
|
235
|
+
const cached = await (0, cache_1.getSafeCache)(cacheKey);
|
|
236
|
+
if (cached)
|
|
237
|
+
return cached;
|
|
238
|
+
const provider = (0, web3_1.createProvider)(options.rpcUrl, chainId);
|
|
239
|
+
const contract = (0, web3_1.createContract)({
|
|
240
|
+
address: router,
|
|
241
|
+
provider,
|
|
242
|
+
abi: abis_1.ABI_SWAP_ROUTER,
|
|
243
|
+
});
|
|
244
|
+
if (!contract)
|
|
245
|
+
return [];
|
|
246
|
+
// Stage 1 — reconstruct the candidate set from TokenEnabled logs, scanning
|
|
247
|
+
// the router's lifetime in chunks to respect per-request eth_getLogs limits.
|
|
248
|
+
const currentBlock = await provider.getBlockNumber();
|
|
249
|
+
const fromBlock = Math.max(0, options.fromBlock ?? swap_router_1.SWAP_ROUTER_DEPLOY_BLOCKS[chainId] ?? 0);
|
|
250
|
+
const blockSkip = (0, web3_1.determineBlockSkipInternal)(chainId);
|
|
251
|
+
const ranges = [];
|
|
252
|
+
for (let end = currentBlock; end >= fromBlock; end -= blockSkip + 1) {
|
|
253
|
+
ranges.push({ from: Math.max(end - blockSkip, fromBlock), to: end });
|
|
254
|
+
}
|
|
255
|
+
const settled = await Promise.allSettled(ranges.map((r) => contract.queryFilter('TokenEnabled', BigInt(r.from), BigInt(r.to))));
|
|
256
|
+
const failed = settled.find((s) => s.status === 'rejected');
|
|
257
|
+
if (failed) {
|
|
258
|
+
const reason = failed.reason instanceof Error
|
|
259
|
+
? failed.reason.message
|
|
260
|
+
: String(failed.reason);
|
|
261
|
+
throw new errors_1.AugustSDKError('NETWORK_ERROR', `getSwapRouterWhitelistedTokens: TokenEnabled log scan failed on chain ${chainId}: ${reason}`);
|
|
262
|
+
}
|
|
263
|
+
const candidates = new Set();
|
|
264
|
+
for (const s of settled) {
|
|
265
|
+
if (s.status !== 'fulfilled')
|
|
266
|
+
continue;
|
|
267
|
+
for (const log of s.value) {
|
|
268
|
+
const raw = log.args?.tokenAddr;
|
|
269
|
+
if (typeof raw === 'string' && (0, ethers_1.isAddress)(raw)) {
|
|
270
|
+
candidates.add((0, ethers_1.getAddress)(raw));
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
if (candidates.size === 0) {
|
|
275
|
+
cache_1.CACHE.set(cacheKey, [], { ttl: SWAP_ROUTER_WHITELIST_TTL_MS });
|
|
276
|
+
return [];
|
|
277
|
+
}
|
|
278
|
+
// Stage 2 — keep only tokens the mapping currently reports as whitelisted.
|
|
279
|
+
const list = [...candidates];
|
|
280
|
+
let enabled;
|
|
281
|
+
if ((0, multicall_1.isMulticall3Supported)(chainId)) {
|
|
282
|
+
const calls = list.map((token) => ({
|
|
283
|
+
target: router,
|
|
284
|
+
abi: abis_1.ABI_SWAP_ROUTER,
|
|
285
|
+
functionName: 'whitelistedTokens',
|
|
286
|
+
args: [token],
|
|
287
|
+
}));
|
|
288
|
+
const results = await (0, multicall_1.multicall3Aggregate)(provider, chainId, calls);
|
|
289
|
+
enabled = list.filter((_, i) => results[i]?.success && results[i]?.value === true);
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
const bools = await Promise.all(list.map(async (token) => {
|
|
293
|
+
try {
|
|
294
|
+
return (await contract.whitelistedTokens(token));
|
|
295
|
+
}
|
|
296
|
+
catch (e) {
|
|
297
|
+
logger_1.Logger.log.warn('getSwapRouterWhitelistedTokens', `whitelistedTokens(${token}) read failed — omitting`, e);
|
|
298
|
+
return false;
|
|
299
|
+
}
|
|
300
|
+
}));
|
|
301
|
+
enabled = list.filter((_, i) => bools[i] === true);
|
|
302
|
+
}
|
|
303
|
+
cache_1.CACHE.set(cacheKey, enabled, { ttl: SWAP_ROUTER_WHITELIST_TTL_MS });
|
|
304
|
+
return enabled;
|
|
305
|
+
}
|
|
306
|
+
/** Cache TTL for a chain's resolved SwapRouter eligible-vault set (5 minutes). */
|
|
307
|
+
const SWAP_ROUTER_ELIGIBLE_VAULTS_TTL_MS = 5 * 60 * 1000;
|
|
308
|
+
/**
|
|
309
|
+
* Minimal `vaultInfo` fragment declaring the four static outputs as a single
|
|
310
|
+
* named tuple. The ABI encoding of `(uint256,uint8,address,address)` returned
|
|
311
|
+
* as four values is byte-identical to the same four static types returned as
|
|
312
|
+
* one tuple, and {@link multicall3Aggregate} surfaces only the FIRST decoded
|
|
313
|
+
* output — so decoding against this fragment makes that first output the whole
|
|
314
|
+
* struct, giving batched access to `referenceAsset` (the registration marker)
|
|
315
|
+
* without changing the shared multicall helper.
|
|
316
|
+
*/
|
|
317
|
+
const ABI_SWAP_ROUTER_VAULT_INFO_TUPLE = [
|
|
318
|
+
{
|
|
319
|
+
inputs: [{ internalType: 'address', name: '', type: 'address' }],
|
|
320
|
+
name: 'vaultInfo',
|
|
321
|
+
outputs: [
|
|
322
|
+
{
|
|
323
|
+
components: [
|
|
324
|
+
{ internalType: 'uint256', name: 'swapFee', type: 'uint256' },
|
|
325
|
+
{ internalType: 'uint8', name: 'vaultType', type: 'uint8' },
|
|
326
|
+
{ internalType: 'address', name: 'referenceAsset', type: 'address' },
|
|
327
|
+
{ internalType: 'address', name: 'lpTokenAddress', type: 'address' },
|
|
328
|
+
],
|
|
329
|
+
internalType: 'struct SwapRouter.VaultInfo',
|
|
330
|
+
name: 'info',
|
|
331
|
+
type: 'tuple',
|
|
332
|
+
},
|
|
333
|
+
],
|
|
334
|
+
stateMutability: 'view',
|
|
335
|
+
type: 'function',
|
|
336
|
+
},
|
|
337
|
+
];
|
|
338
|
+
/**
|
|
339
|
+
* Extract `referenceAsset` from a decoded `vaultInfo` result (ethers `Result`
|
|
340
|
+
* proxies expose named tuple components as properties). Returns `undefined`
|
|
341
|
+
* for anything that doesn't carry a string `referenceAsset` — treated as
|
|
342
|
+
* unregistered by the caller (fail-closed).
|
|
343
|
+
*/
|
|
344
|
+
function referenceAssetOf(value) {
|
|
345
|
+
const ref = value
|
|
346
|
+
?.referenceAsset;
|
|
347
|
+
return typeof ref === 'string' ? ref : undefined;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Resolve the vaults currently eligible for the any-token `SwapRouter` deposit
|
|
351
|
+
* surface on a chain — i.e. every vault the router has `enableVault`-ed that is
|
|
352
|
+
* still registered on-chain.
|
|
353
|
+
*
|
|
354
|
+
* The router stores registrations as `mapping(address => VaultInfo) vaultInfo`
|
|
355
|
+
* with **no on-chain enumeration**, so (exactly like
|
|
356
|
+
* {@link getSwapRouterWhitelistedTokens}) this runs in two stages:
|
|
357
|
+
* 1. Scan the router's `VaultEnabled(address)` event history (from the chain's
|
|
358
|
+
* {@link SWAP_ROUTER_DEPLOY_BLOCKS} floor, in `eth_getLogs` chunks sized by
|
|
359
|
+
* {@link determineBlockSkipInternal}) to reconstruct the candidate set of
|
|
360
|
+
* every vault ever enabled.
|
|
361
|
+
* 2. Re-read `vaultInfo(vault)` for each candidate — batched via Multicall3
|
|
362
|
+
* where verified, else per-call — and keep only those whose
|
|
363
|
+
* `referenceAsset != address(0)` (an unregistered vault reverts with
|
|
364
|
+
* `InvalidVault` at deposit time). This makes later disables correct
|
|
365
|
+
* without replaying `VaultDisabled`, and is the fail-closed source of
|
|
366
|
+
* truth: a vault surfaces only on a definite on-chain registration.
|
|
367
|
+
*
|
|
368
|
+
* This is the dynamic successor to the static
|
|
369
|
+
* {@link SWAP_ROUTER_ELIGIBLE_VAULTS} snapshot / {@link isSwapRouterEligible}.
|
|
370
|
+
* It reports **on-chain eligibility only** — app-level policy (e.g. excluding
|
|
371
|
+
* OVault-enabled vaults that have their own deposit flow) remains the caller's
|
|
372
|
+
* responsibility, as does the flag gating of the UI surface.
|
|
373
|
+
*
|
|
374
|
+
* The resolved list is cached per chain for 5 minutes — registrations change
|
|
375
|
+
* only via an admin `enableVault`/`disableVault` transaction, so a short TTL
|
|
376
|
+
* keeps the (multi-RPC) scan off the hot path without going stale for long.
|
|
377
|
+
*
|
|
378
|
+
* @param chainId - EVM chain ID. Chains without a {@link SWAP_ROUTER_ADDRESSES}
|
|
379
|
+
* entry resolve to `[]` with no RPC.
|
|
380
|
+
* @param options - `rpcUrl` (required) must point at `chainId`'s network;
|
|
381
|
+
* `fromBlock` overrides the default deploy-block scan floor.
|
|
382
|
+
* @returns Checksummed addresses of the currently-registered eligible vaults,
|
|
383
|
+
* deduped. Empty when no router is deployed or none are registered.
|
|
384
|
+
* @throws AugustValidationError when `rpcUrl` is missing/empty.
|
|
385
|
+
* @throws AugustSDKError when an `eth_getLogs` chunk fails — surfaced (not
|
|
386
|
+
* swallowed) so a partial scan never masquerades as the complete set.
|
|
387
|
+
* @worstCaseRpcCalls On mainnet, 1 `eth_blockNumber` + ~4 `eth_getLogs` chunks
|
|
388
|
+
* (router-lifetime ÷ 50k-block window) + 1 Multicall3 `eth_call` ≈ 6; scales
|
|
389
|
+
* with the router's on-chain age, not with candidate count.
|
|
390
|
+
* @example
|
|
391
|
+
* ```ts
|
|
392
|
+
* const vaults = await getSwapRouterEligibleVaults(1, {
|
|
393
|
+
* rpcUrl: 'https://eth-mainnet.example/v2/KEY',
|
|
394
|
+
* });
|
|
395
|
+
* // ['0x74aD…718b', '0xE9B7…9D32'] (Sentora USD, Upshift Core USDC)
|
|
396
|
+
* ```
|
|
397
|
+
*/
|
|
398
|
+
async function getSwapRouterEligibleVaults(chainId, options) {
|
|
399
|
+
const router = getSwapRouterAddress(chainId);
|
|
400
|
+
if (!router)
|
|
401
|
+
return [];
|
|
402
|
+
const cacheKey = `swap-router-eligible-vaults-${chainId}-${router.toLowerCase()}`;
|
|
403
|
+
const cached = await (0, cache_1.getSafeCache)(cacheKey);
|
|
404
|
+
if (cached)
|
|
405
|
+
return cached;
|
|
406
|
+
const provider = (0, web3_1.createProvider)(options.rpcUrl, chainId);
|
|
407
|
+
const contract = (0, web3_1.createContract)({
|
|
408
|
+
address: router,
|
|
409
|
+
provider,
|
|
410
|
+
abi: abis_1.ABI_SWAP_ROUTER,
|
|
411
|
+
});
|
|
412
|
+
if (!contract)
|
|
413
|
+
return [];
|
|
414
|
+
// Stage 1 — reconstruct the candidate set from VaultEnabled logs, scanning
|
|
415
|
+
// the router's lifetime in chunks to respect per-request eth_getLogs limits.
|
|
416
|
+
const currentBlock = await provider.getBlockNumber();
|
|
417
|
+
const fromBlock = Math.max(0, options.fromBlock ?? swap_router_1.SWAP_ROUTER_DEPLOY_BLOCKS[chainId] ?? 0);
|
|
418
|
+
const blockSkip = (0, web3_1.determineBlockSkipInternal)(chainId);
|
|
419
|
+
const ranges = [];
|
|
420
|
+
for (let end = currentBlock; end >= fromBlock; end -= blockSkip + 1) {
|
|
421
|
+
ranges.push({ from: Math.max(end - blockSkip, fromBlock), to: end });
|
|
422
|
+
}
|
|
423
|
+
const settled = await Promise.allSettled(ranges.map((r) => contract.queryFilter('VaultEnabled', BigInt(r.from), BigInt(r.to))));
|
|
424
|
+
const failed = settled.find((s) => s.status === 'rejected');
|
|
425
|
+
if (failed) {
|
|
426
|
+
const reason = failed.reason instanceof Error
|
|
427
|
+
? failed.reason.message
|
|
428
|
+
: String(failed.reason);
|
|
429
|
+
throw new errors_1.AugustSDKError('NETWORK_ERROR', `getSwapRouterEligibleVaults: VaultEnabled log scan failed on chain ${chainId}: ${reason}`);
|
|
430
|
+
}
|
|
431
|
+
const candidates = new Set();
|
|
432
|
+
for (const s of settled) {
|
|
433
|
+
if (s.status !== 'fulfilled')
|
|
434
|
+
continue;
|
|
435
|
+
for (const log of s.value) {
|
|
436
|
+
const raw = log.args?.vaultAddr;
|
|
437
|
+
if (typeof raw === 'string' && (0, ethers_1.isAddress)(raw)) {
|
|
438
|
+
candidates.add((0, ethers_1.getAddress)(raw));
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
if (candidates.size === 0) {
|
|
443
|
+
cache_1.CACHE.set(cacheKey, [], { ttl: SWAP_ROUTER_ELIGIBLE_VAULTS_TTL_MS });
|
|
444
|
+
return [];
|
|
445
|
+
}
|
|
446
|
+
// Stage 2 — keep only vaults whose current on-chain registration is live
|
|
447
|
+
// (referenceAsset set). Fail-closed: unreadable/zero → excluded.
|
|
448
|
+
const list = [...candidates];
|
|
449
|
+
let registered;
|
|
450
|
+
if ((0, multicall_1.isMulticall3Supported)(chainId)) {
|
|
451
|
+
const calls = list.map((vault) => ({
|
|
452
|
+
target: router,
|
|
453
|
+
abi: ABI_SWAP_ROUTER_VAULT_INFO_TUPLE,
|
|
454
|
+
functionName: 'vaultInfo',
|
|
455
|
+
args: [vault],
|
|
456
|
+
}));
|
|
457
|
+
const results = await (0, multicall_1.multicall3Aggregate)(provider, chainId, calls);
|
|
458
|
+
registered = list.filter((_, i) => {
|
|
459
|
+
if (!results[i]?.success)
|
|
460
|
+
return false;
|
|
461
|
+
const ref = referenceAssetOf(results[i]?.value);
|
|
462
|
+
return !!ref && ref !== ethers_1.ethers.ZeroAddress;
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
else {
|
|
466
|
+
const refs = await Promise.all(list.map(async (vault) => {
|
|
467
|
+
try {
|
|
468
|
+
return referenceAssetOf(await contract.vaultInfo(vault));
|
|
469
|
+
}
|
|
470
|
+
catch (e) {
|
|
471
|
+
logger_1.Logger.log.warn('getSwapRouterEligibleVaults', `vaultInfo(${vault}) read failed — omitting`, e);
|
|
472
|
+
return undefined;
|
|
473
|
+
}
|
|
474
|
+
}));
|
|
475
|
+
registered = list.filter((_, i) => !!refs[i] && refs[i] !== ethers_1.ethers.ZeroAddress);
|
|
476
|
+
}
|
|
477
|
+
cache_1.CACHE.set(cacheKey, registered, { ttl: SWAP_ROUTER_ELIGIBLE_VAULTS_TTL_MS });
|
|
478
|
+
return registered;
|
|
479
|
+
}
|
|
480
|
+
//# sourceMappingURL=swap-router.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ITokenizedVault, IVaultVersion, ChainType } from '../../types';
|
|
2
|
+
/** Classify an address by chain family (evm / solana / stellar / sui). */
|
|
3
|
+
export declare function getAddressChainType(address: string): ChainType;
|
|
4
|
+
/**
|
|
5
|
+
* Classify a vault's protocol version from its address alone.
|
|
6
|
+
*
|
|
7
|
+
* @deprecated Use {@link getVaultVersionV2} instead. This V1 classifier can only
|
|
8
|
+
* recognise a multi-asset vault (`evm-2`) if its address is hard-coded in the
|
|
9
|
+
* static `MULTI_ASSET_VAULTS` list. Any multi-asset vault missing from that list
|
|
10
|
+
* is silently misclassified as `evm-1`, which broke deposit preview/simulation in
|
|
11
|
+
* the 2026-07-06 Sentora incident. `getVaultVersionV2` reads the backend
|
|
12
|
+
* `internal_type` (falling back to the static list only as a safety net), so new
|
|
13
|
+
* vaults classify correctly without a code change. Retained as a non-breaking
|
|
14
|
+
* shim; scheduled for removal in the next major.
|
|
15
|
+
*
|
|
16
|
+
* @param vault - The vault contract address (EVM `0x…`, Solana, or Stellar).
|
|
17
|
+
* @returns The vault version slug, or `undefined` for empty/invalid input.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getVaultVersion(vault: string): IVaultVersion | undefined;
|
|
20
|
+
export declare function getVaultVersionV2(vault: (Pick<ITokenizedVault, 'address'> & {
|
|
21
|
+
chain_type?: string;
|
|
22
|
+
internal_type?: string;
|
|
23
|
+
}) | undefined | null): IVaultVersion | undefined;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getAddressChainType = getAddressChainType;
|
|
4
|
+
exports.getVaultVersion = getVaultVersion;
|
|
5
|
+
exports.getVaultVersionV2 = getVaultVersionV2;
|
|
6
|
+
const ethers_1 = require("ethers");
|
|
7
|
+
const vaults_1 = require("../constants/vaults");
|
|
8
|
+
const chain_address_1 = require("./chain-address");
|
|
9
|
+
/** Classify an address by chain family (evm / solana / stellar / sui). */
|
|
10
|
+
function getAddressChainType(address) {
|
|
11
|
+
if ((0, chain_address_1.isStellarAddress)(address))
|
|
12
|
+
return 'stellar';
|
|
13
|
+
if ((0, chain_address_1.isSolanaAddress)(address))
|
|
14
|
+
return 'solana';
|
|
15
|
+
if ((0, chain_address_1.isSuiAddress)(address))
|
|
16
|
+
return 'sui';
|
|
17
|
+
return 'evm';
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Classify a vault's protocol version from its address alone.
|
|
21
|
+
*
|
|
22
|
+
* @deprecated Use {@link getVaultVersionV2} instead. This V1 classifier can only
|
|
23
|
+
* recognise a multi-asset vault (`evm-2`) if its address is hard-coded in the
|
|
24
|
+
* static `MULTI_ASSET_VAULTS` list. Any multi-asset vault missing from that list
|
|
25
|
+
* is silently misclassified as `evm-1`, which broke deposit preview/simulation in
|
|
26
|
+
* the 2026-07-06 Sentora incident. `getVaultVersionV2` reads the backend
|
|
27
|
+
* `internal_type` (falling back to the static list only as a safety net), so new
|
|
28
|
+
* vaults classify correctly without a code change. Retained as a non-breaking
|
|
29
|
+
* shim; scheduled for removal in the next major.
|
|
30
|
+
*
|
|
31
|
+
* @param vault - The vault contract address (EVM `0x…`, Solana, or Stellar).
|
|
32
|
+
* @returns The vault version slug, or `undefined` for empty/invalid input.
|
|
33
|
+
*/
|
|
34
|
+
function getVaultVersion(vault) {
|
|
35
|
+
if (!vault)
|
|
36
|
+
return;
|
|
37
|
+
const chainType = getAddressChainType(vault);
|
|
38
|
+
if (chainType === 'stellar')
|
|
39
|
+
return 'stellar-0';
|
|
40
|
+
if (chainType === 'solana')
|
|
41
|
+
return 'sol-0';
|
|
42
|
+
if (!(0, ethers_1.isAddress)(vault))
|
|
43
|
+
return;
|
|
44
|
+
if (vaults_1.OLD_LENDING_POOLS.includes((0, ethers_1.getAddress)(vault))) {
|
|
45
|
+
return 'evm-0';
|
|
46
|
+
}
|
|
47
|
+
else if (vaults_1.MULTI_ASSET_VAULTS.includes((0, ethers_1.getAddress)(vault))) {
|
|
48
|
+
return 'evm-2';
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
return 'evm-1';
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function getVaultVersionV2(vault) {
|
|
55
|
+
if (!vault)
|
|
56
|
+
return;
|
|
57
|
+
const chainType = getAddressChainType(vault.address);
|
|
58
|
+
if (vault.chain_type === 'stellar' || chainType === 'stellar')
|
|
59
|
+
return 'stellar-0';
|
|
60
|
+
if (vault.chain_type === 'solana' || chainType === 'solana')
|
|
61
|
+
return 'sol-0';
|
|
62
|
+
if (!(0, ethers_1.isAddress)(vault.address))
|
|
63
|
+
return;
|
|
64
|
+
if (vaults_1.OLD_LENDING_POOLS.includes((0, ethers_1.getAddress)(vault.address))) {
|
|
65
|
+
return 'evm-0';
|
|
66
|
+
}
|
|
67
|
+
else if (vault.internal_type === 'multiAssetVault' ||
|
|
68
|
+
vaults_1.MULTI_ASSET_VAULTS.includes(vault.address)) {
|
|
69
|
+
return 'evm-2';
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
return 'evm-1';
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=vault-version.js.map
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { IAddress, IContractRunner } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Bad transactions that should be ignored
|
|
4
|
+
* these transactions are usually from tests and can skew data
|
|
5
|
+
*/
|
|
6
|
+
export declare const isBadTransaction: (hash: string, chainId: number) => boolean;
|
|
7
|
+
export declare const isBadVault: (address?: string) => boolean;
|
|
8
|
+
import { getAddressChainType, getVaultVersion, getVaultVersionV2 } from './vault-version';
|
|
9
|
+
export { getAddressChainType, getVaultVersion, getVaultVersionV2 };
|
|
10
|
+
export declare const REWARD_DISTRIBUTOR_ADDRESS: (chainId: number) => string[];
|
|
11
|
+
export declare const AVAX_PRICE_FEED_ADDRESS: (chainId: number) => "0x" | "0xFF3EEb22B5E3dE6e705b44749C2559d704923FD7";
|
|
12
|
+
export declare function getVaultSymbol(vault: IAddress, provider: IContractRunner): Promise<string | undefined>;
|
|
13
|
+
/**
|
|
14
|
+
* @deprecated
|
|
15
|
+
* Replaced by SUBGRAPH_VAULT_URLS which are subgraphs deployed on Goldsky.
|
|
16
|
+
*/
|
|
17
|
+
export declare const SUBGRAPH_POOL_URLS: (apiKey: string, chainId?: number, pool?: IAddress) => {
|
|
18
|
+
1: string;
|
|
19
|
+
8453: string;
|
|
20
|
+
43114: string;
|
|
21
|
+
42161: string;
|
|
22
|
+
56: string;
|
|
23
|
+
} | {
|
|
24
|
+
999: string;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Previously fabricated a Goldsky subgraph URL from the chain name and vault
|
|
28
|
+
* symbol. That guess is unreliable and produced dead endpoints:
|
|
29
|
+
* - The path segment `/v1/subgraphs/name/goldsky/` is legacy hosted-service
|
|
30
|
+
* syntax, not Goldsky's current scheme (cf. {@link SUBGRAPH_VAULT_URLS}).
|
|
31
|
+
* - The chain name isn't the subgraph slug — ethers reports Citrea's network as
|
|
32
|
+
* `unknown`, and mainnet as `mainnet` where the subgraph uses `eth`.
|
|
33
|
+
* - A vault's symbol isn't its subgraph name — e.g. on-chain `EctUSD` vs the
|
|
34
|
+
* deployed `earn-ctusd`.
|
|
35
|
+
*
|
|
36
|
+
* A fabricated URL 404s silently, so a missing subgraph reads as "no data"
|
|
37
|
+
* rather than an error (this masked the Citrea Earn ctUSD outage). Subgraph URLs
|
|
38
|
+
* must now come from backend vault metadata (`fetchVaultMetadata → subgraph`).
|
|
39
|
+
* This returns `undefined` so callers hit their existing "Missing Subgraph"
|
|
40
|
+
* branch (warn + Slack alert) instead of querying a dead endpoint.
|
|
41
|
+
*
|
|
42
|
+
* @param _network - Unused. Kept for call-site compatibility.
|
|
43
|
+
* @param _symbol - Unused. Kept for call-site compatibility.
|
|
44
|
+
* @returns `undefined` — the SDK no longer guesses subgraph URLs.
|
|
45
|
+
* @deprecated Resolve subgraph URLs from `fetchVaultMetadata`; do not rely on a
|
|
46
|
+
* generated fallback.
|
|
47
|
+
*/
|
|
48
|
+
export declare const getDefaultSubgraphUrl: (_network: string, _symbol: string) => string | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Resolve whether a single fee (management or performance) is currently waived.
|
|
51
|
+
*
|
|
52
|
+
* Backend-driven, per AUGUST-5584. This centralizes logic that previously lived —
|
|
53
|
+
* and diverged — across two upshift-app components. The resolution is deliberately
|
|
54
|
+
* split between the backend and the SDK:
|
|
55
|
+
*
|
|
56
|
+
* - The backend `isFeeWaivedToggle` (`platform_fee_override.is_fee_waived`) is both
|
|
57
|
+
* the master enable AND the TVL latch. Retool config takes precedence over live
|
|
58
|
+
* TVL, and the backend flips this flag `false` once live TVL crosses the
|
|
59
|
+
* configured threshold. That flip is one-way: if TVL later falls back below the
|
|
60
|
+
* threshold the waiver does NOT re-apply. The SDK therefore does no TVL math and
|
|
61
|
+
* never reads `latest_reported_tvl` here — trusting the flag preserves the latch.
|
|
62
|
+
* - The **date** window is time-dependent, so it cannot be a static DB flag; the SDK
|
|
63
|
+
* evaluates it live against the clock.
|
|
64
|
+
*
|
|
65
|
+
* Resolution:
|
|
66
|
+
* - Toggle off → never waived (also the only "hide" path once TVL trips the latch).
|
|
67
|
+
* - Toggle on, both date and TVL blank → indefinite manual waiver → waived.
|
|
68
|
+
* - Toggle on with a date window → waived while `now < waivedUntilDate`.
|
|
69
|
+
* - Toggle on with a TVL threshold configured → waived (the backend keeps the toggle
|
|
70
|
+
* on only while live TVL is under the threshold).
|
|
71
|
+
*
|
|
72
|
+
* @param isFeeWaivedToggle - Backend master/TVL-latch flag. `false` ⇒ never waived.
|
|
73
|
+
* @param waivedUntilDate - ISO datetime string the waiver runs until, or `null` for
|
|
74
|
+
* no date window. An unparseable string yields `NaN`, which is never `> now`, so
|
|
75
|
+
* it correctly contributes no date-based waiver.
|
|
76
|
+
* @param waivedUntilTvl - Configured TVL threshold in whole USD, or `null`. Used only
|
|
77
|
+
* to detect that a TVL-based waiver was set (values `<= 0` are treated as unset);
|
|
78
|
+
* the threshold comparison itself is owned by the backend.
|
|
79
|
+
* @param now - Clock, injected for deterministic testing. Defaults to `new Date()`.
|
|
80
|
+
* @returns `true` if the UI should present this fee as "Fee Waived" right now.
|
|
81
|
+
* @example
|
|
82
|
+
* ```ts
|
|
83
|
+
* // Toggle on, 30-day window still open → waived.
|
|
84
|
+
* resolveFeeWaived(true, '2099-01-01T00:00:00Z', null); // true
|
|
85
|
+
* // Toggle off overrides everything → not waived.
|
|
86
|
+
* resolveFeeWaived(false, '2099-01-01T00:00:00Z', 10_000_000); // false
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export declare function resolveFeeWaived(isFeeWaivedToggle: boolean, waivedUntilDate: string | null, waivedUntilTvl: number | null, now?: Date): boolean;
|