@upshiftfinance/sdk 0.0.0-stage → 0.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 (344) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +408 -2
  3. package/lib/abis/AddressResolver.d.ts +28 -0
  4. package/lib/abis/AddressResolver.js +23 -0
  5. package/lib/abis/ChainlinkV3.d.ts +87 -0
  6. package/lib/abis/ChainlinkV3.js +117 -0
  7. package/lib/abis/ERC20.d.ts +168 -0
  8. package/lib/abis/ERC20.js +226 -0
  9. package/lib/abis/ERC20_Bytes32.d.ts +139 -0
  10. package/lib/abis/ERC20_Bytes32.js +196 -0
  11. package/lib/abis/ERC4626.d.ts +364 -0
  12. package/lib/abis/ERC4626.js +507 -0
  13. package/lib/abis/ERC721.d.ts +231 -0
  14. package/lib/abis/ERC721.js +321 -0
  15. package/lib/abis/FeeOracle.d.ts +120 -0
  16. package/lib/abis/FeeOracle.js +162 -0
  17. package/lib/abis/LendingPool.d.ts +1393 -0
  18. package/lib/abis/LendingPool.js +1807 -0
  19. package/lib/abis/LendingPoolV2.d.ts +1413 -0
  20. package/lib/abis/LendingPoolV2.js +1833 -0
  21. package/lib/abis/LendingPoolV3.d.ts +1677 -0
  22. package/lib/abis/LendingPoolV3.js +1160 -0
  23. package/lib/abis/Loan.d.ts +837 -0
  24. package/lib/abis/Loan.js +1080 -0
  25. package/lib/abis/MultiAssetNativeDepositWrapper.d.ts +137 -0
  26. package/lib/abis/MultiAssetNativeDepositWrapper.js +125 -0
  27. package/lib/abis/Multicall3.d.ts +30 -0
  28. package/lib/abis/Multicall3.js +97 -0
  29. package/lib/abis/OFT.d.ts +116 -0
  30. package/lib/abis/OFT.js +85 -0
  31. package/lib/abis/PoolAdapter.d.ts +36 -0
  32. package/lib/abis/PoolAdapter.js +51 -0
  33. package/lib/abis/RewardDistributor.d.ts +267 -0
  34. package/lib/abis/RewardDistributor.js +352 -0
  35. package/lib/abis/RwaRedeemSubaccount.d.ts +747 -0
  36. package/lib/abis/RwaRedeemSubaccount.js +548 -0
  37. package/lib/abis/SmartAccount.d.ts +17 -0
  38. package/lib/abis/SmartAccount.js +19 -0
  39. package/lib/abis/SwapRouter.d.ts +953 -0
  40. package/lib/abis/SwapRouter.js +1228 -0
  41. package/lib/abis/TextResolver.d.ts +16 -0
  42. package/lib/abis/TextResolver.js +16 -0
  43. package/lib/abis/TokenizedVaultV2.d.ts +1364 -0
  44. package/lib/abis/TokenizedVaultV2.js +1041 -0
  45. package/lib/abis/TokenizedVaultV2DepositWithPermit.d.ts +1456 -0
  46. package/lib/abis/TokenizedVaultV2DepositWithPermit.js +1878 -0
  47. package/lib/abis/TokenizedVaultV2Receipt.d.ts +1568 -0
  48. package/lib/abis/TokenizedVaultV2Receipt.js +1061 -0
  49. package/lib/abis/TokenizedVaultV2SenderAllocationWhitelist.d.ts +454 -0
  50. package/lib/abis/TokenizedVaultV2SenderAllocationWhitelist.js +327 -0
  51. package/lib/abis/TokenizedVaultV2WhitelistedAllocation.d.ts +1466 -0
  52. package/lib/abis/TokenizedVaultV2WhitelistedAllocation.js +1092 -0
  53. package/lib/abis/TokenizedVaultV2WhitelistedAssets.d.ts +274 -0
  54. package/lib/abis/TokenizedVaultV2WhitelistedAssets.js +167 -0
  55. package/lib/abis/UniversalResolverResolve.d.ts +69 -0
  56. package/lib/abis/UniversalResolverResolve.js +35 -0
  57. package/lib/abis/UniversalSignatureValidator.d.ts +17 -0
  58. package/lib/abis/UniversalSignatureValidator.js +30 -0
  59. package/lib/abis/WrapperAdapter.d.ts +71 -0
  60. package/lib/abis/WrapperAdapter.js +77 -0
  61. package/lib/abis/index.d.ts +34 -0
  62. package/lib/abis/index.js +51 -0
  63. package/lib/adapters/evm/getters.d.ts +19 -0
  64. package/lib/adapters/evm/getters.js +249 -0
  65. package/lib/adapters/evm/index.d.ts +539 -0
  66. package/lib/adapters/evm/index.js +656 -0
  67. package/lib/adapters/evm/utils.d.ts +8 -0
  68. package/lib/adapters/evm/utils.js +51 -0
  69. package/lib/adapters/solana/confirm.d.ts +88 -0
  70. package/lib/adapters/solana/confirm.js +291 -0
  71. package/lib/adapters/solana/constants.d.ts +42 -0
  72. package/lib/adapters/solana/constants.js +59 -0
  73. package/lib/adapters/solana/getters.d.ts +42 -0
  74. package/lib/adapters/solana/getters.js +275 -0
  75. package/lib/adapters/solana/idl/vault-idl.d.ts +700 -0
  76. package/lib/adapters/solana/idl/vault-idl.js +2101 -0
  77. package/lib/adapters/solana/idl/withdrawal-queue-idl.d.ts +795 -0
  78. package/lib/adapters/solana/idl/withdrawal-queue-idl.js +1864 -0
  79. package/lib/adapters/solana/index.d.ts +372 -0
  80. package/lib/adapters/solana/index.js +459 -0
  81. package/lib/adapters/solana/pricing.d.ts +184 -0
  82. package/lib/adapters/solana/pricing.js +239 -0
  83. package/lib/adapters/solana/queue-hints.d.ts +29 -0
  84. package/lib/adapters/solana/queue-hints.js +59 -0
  85. package/lib/adapters/solana/queue.actions.d.ts +97 -0
  86. package/lib/adapters/solana/queue.actions.js +468 -0
  87. package/lib/adapters/solana/token-reads.d.ts +108 -0
  88. package/lib/adapters/solana/token-reads.js +145 -0
  89. package/lib/adapters/solana/types.d.ts +325 -0
  90. package/lib/adapters/solana/types.js +3 -0
  91. package/lib/adapters/solana/utils.d.ts +229 -0
  92. package/lib/adapters/solana/utils.js +773 -0
  93. package/lib/adapters/solana/vault.actions.d.ts +140 -0
  94. package/lib/adapters/solana/vault.actions.js +657 -0
  95. package/lib/adapters/solana/withdrawal-queue.d.ts +125 -0
  96. package/lib/adapters/solana/withdrawal-queue.js +301 -0
  97. package/lib/adapters/stellar/actions.d.ts +41 -0
  98. package/lib/adapters/stellar/actions.js +126 -0
  99. package/lib/adapters/stellar/constants.d.ts +43 -0
  100. package/lib/adapters/stellar/constants.js +53 -0
  101. package/lib/adapters/stellar/getters.d.ts +68 -0
  102. package/lib/adapters/stellar/getters.js +290 -0
  103. package/lib/adapters/stellar/index.d.ts +126 -0
  104. package/lib/adapters/stellar/index.js +187 -0
  105. package/lib/adapters/stellar/invocation.d.ts +55 -0
  106. package/lib/adapters/stellar/invocation.js +92 -0
  107. package/lib/adapters/stellar/soroban.d.ts +131 -0
  108. package/lib/adapters/stellar/soroban.js +617 -0
  109. package/lib/adapters/stellar/submit.d.ts +42 -0
  110. package/lib/adapters/stellar/submit.js +195 -0
  111. package/lib/adapters/stellar/types.d.ts +57 -0
  112. package/lib/adapters/stellar/types.js +6 -0
  113. package/lib/adapters/stellar/utils.d.ts +24 -0
  114. package/lib/adapters/stellar/utils.js +34 -0
  115. package/lib/adapters/sui/client.d.ts +83 -0
  116. package/lib/adapters/sui/client.js +216 -0
  117. package/lib/adapters/sui/constants.d.ts +33 -0
  118. package/lib/adapters/sui/constants.js +31 -0
  119. package/lib/adapters/sui/index.d.ts +57 -0
  120. package/lib/adapters/sui/index.js +100 -0
  121. package/lib/adapters/sui/targets.d.ts +171 -0
  122. package/lib/adapters/sui/targets.js +225 -0
  123. package/lib/adapters/sui/utils.d.ts +8 -0
  124. package/lib/adapters/sui/utils.js +17 -0
  125. package/lib/core/analytics/app-name.d.ts +27 -0
  126. package/lib/core/analytics/app-name.js +48 -0
  127. package/lib/core/analytics/chain-name.d.ts +9 -0
  128. package/lib/core/analytics/chain-name.js +34 -0
  129. package/lib/core/analytics/constants.d.ts +15 -0
  130. package/lib/core/analytics/constants.js +28 -0
  131. package/lib/core/analytics/env.d.ts +46 -0
  132. package/lib/core/analytics/env.js +147 -0
  133. package/lib/core/analytics/index.d.ts +39 -0
  134. package/lib/core/analytics/index.js +83 -0
  135. package/lib/core/analytics/instrumentation.d.ts +29 -0
  136. package/lib/core/analytics/instrumentation.js +292 -0
  137. package/lib/core/analytics/method-taxonomy.d.ts +19 -0
  138. package/lib/core/analytics/method-taxonomy.js +156 -0
  139. package/lib/core/analytics/metrics.d.ts +48 -0
  140. package/lib/core/analytics/metrics.js +142 -0
  141. package/lib/core/analytics/sanitize.d.ts +57 -0
  142. package/lib/core/analytics/sanitize.js +272 -0
  143. package/lib/core/analytics/sentry-runtime.d.ts +15 -0
  144. package/lib/core/analytics/sentry-runtime.js +131 -0
  145. package/lib/core/analytics/sentry.d.ts +100 -0
  146. package/lib/core/analytics/sentry.js +696 -0
  147. package/lib/core/analytics/types.d.ts +55 -0
  148. package/lib/core/analytics/types.js +3 -0
  149. package/lib/core/analytics/user-identity.d.ts +55 -0
  150. package/lib/core/analytics/user-identity.js +218 -0
  151. package/lib/core/analytics/version.d.ts +6 -0
  152. package/lib/core/analytics/version.js +10 -0
  153. package/lib/core/attribution.d.ts +159 -0
  154. package/lib/core/attribution.js +194 -0
  155. package/lib/core/auth/index.d.ts +1 -0
  156. package/lib/core/auth/index.js +18 -0
  157. package/lib/core/auth/verify.d.ts +2 -0
  158. package/lib/core/auth/verify.js +35 -0
  159. package/lib/core/base.class.d.ts +193 -0
  160. package/lib/core/base.class.js +163 -0
  161. package/lib/core/cache.d.ts +9 -0
  162. package/lib/core/cache.js +31 -0
  163. package/lib/core/constants/adapters.d.ts +103 -0
  164. package/lib/core/constants/adapters.js +180 -0
  165. package/lib/core/constants/core.d.ts +162 -0
  166. package/lib/core/constants/core.js +281 -0
  167. package/lib/core/constants/swap-router.d.ts +180 -0
  168. package/lib/core/constants/swap-router.js +203 -0
  169. package/lib/core/constants/vaults.d.ts +93 -0
  170. package/lib/core/constants/vaults.js +277 -0
  171. package/lib/core/constants/web3.d.ts +106 -0
  172. package/lib/core/constants/web3.js +251 -0
  173. package/lib/core/errors/index.d.ts +177 -0
  174. package/lib/core/errors/index.js +257 -0
  175. package/lib/core/fetcher.d.ts +237 -0
  176. package/lib/core/fetcher.js +1103 -0
  177. package/lib/core/helpers/adapters.d.ts +13 -0
  178. package/lib/core/helpers/adapters.js +39 -0
  179. package/lib/core/helpers/chain-address.d.ts +13 -0
  180. package/lib/core/helpers/chain-address.js +47 -0
  181. package/lib/core/helpers/chain-error.d.ts +207 -0
  182. package/lib/core/helpers/chain-error.js +697 -0
  183. package/lib/core/helpers/chain-support.d.ts +98 -0
  184. package/lib/core/helpers/chain-support.js +139 -0
  185. package/lib/core/helpers/concurrency.d.ts +51 -0
  186. package/lib/core/helpers/concurrency.js +79 -0
  187. package/lib/core/helpers/core.d.ts +92 -0
  188. package/lib/core/helpers/core.js +368 -0
  189. package/lib/core/helpers/explorer-link.d.ts +16 -0
  190. package/lib/core/helpers/explorer-link.js +26 -0
  191. package/lib/core/helpers/multicall.d.ts +68 -0
  192. package/lib/core/helpers/multicall.js +103 -0
  193. package/lib/core/helpers/revert-decode.d.ts +248 -0
  194. package/lib/core/helpers/revert-decode.js +515 -0
  195. package/lib/core/helpers/signer.d.ts +61 -0
  196. package/lib/core/helpers/signer.js +184 -0
  197. package/lib/core/helpers/swap-router.d.ts +269 -0
  198. package/lib/core/helpers/swap-router.js +542 -0
  199. package/lib/core/helpers/vault-version.d.ts +24 -0
  200. package/lib/core/helpers/vault-version.js +83 -0
  201. package/lib/core/helpers/vaults.d.ts +89 -0
  202. package/lib/core/helpers/vaults.js +241 -0
  203. package/lib/core/helpers/web3.d.ts +366 -0
  204. package/lib/core/helpers/web3.js +1034 -0
  205. package/lib/core/index.d.ts +23 -0
  206. package/lib/core/index.js +40 -0
  207. package/lib/core/logger/curator-alert.d.ts +217 -0
  208. package/lib/core/logger/curator-alert.js +276 -0
  209. package/lib/core/logger/index.d.ts +99 -0
  210. package/lib/core/logger/index.js +163 -0
  211. package/lib/core/logger/slack.d.ts +49 -0
  212. package/lib/core/logger/slack.js +111 -0
  213. package/lib/core/vault-metadata.d.ts +12 -0
  214. package/lib/core/vault-metadata.js +42 -0
  215. package/lib/core/version-check.d.ts +58 -0
  216. package/lib/core/version-check.js +182 -0
  217. package/lib/evm/index.d.ts +2 -0
  218. package/lib/evm/index.js +19 -0
  219. package/lib/evm/methods/crossChainVault.d.ts +132 -0
  220. package/lib/evm/methods/crossChainVault.js +857 -0
  221. package/lib/evm/methods/crossChainVaultRegistry.d.ts +92 -0
  222. package/lib/evm/methods/crossChainVaultRegistry.js +239 -0
  223. package/lib/evm/methods/index.d.ts +2 -0
  224. package/lib/evm/methods/index.js +19 -0
  225. package/lib/evm/types/crossChain.d.ts +363 -0
  226. package/lib/evm/types/crossChain.js +20 -0
  227. package/lib/evm/types/index.d.ts +1 -0
  228. package/lib/evm/types/index.js +18 -0
  229. package/lib/index.d.ts +30 -0
  230. package/lib/index.js +52 -0
  231. package/lib/main.d.ts +596 -0
  232. package/lib/main.js +681 -0
  233. package/lib/modules/api/fetcher.d.ts +108 -0
  234. package/lib/modules/api/fetcher.js +187 -0
  235. package/lib/modules/api/index.d.ts +1 -0
  236. package/lib/modules/api/index.js +6 -0
  237. package/lib/modules/api/main.d.ts +587 -0
  238. package/lib/modules/api/main.js +911 -0
  239. package/lib/modules/sub-accounts/fetcher.d.ts +53 -0
  240. package/lib/modules/sub-accounts/fetcher.js +96 -0
  241. package/lib/modules/sub-accounts/index.d.ts +2 -0
  242. package/lib/modules/sub-accounts/index.js +19 -0
  243. package/lib/modules/sub-accounts/main.d.ts +249 -0
  244. package/lib/modules/sub-accounts/main.js +211 -0
  245. package/lib/modules/sub-accounts/utils.d.ts +106 -0
  246. package/lib/modules/sub-accounts/utils.js +112 -0
  247. package/lib/modules/vaults/adapter.helpers.d.ts +84 -0
  248. package/lib/modules/vaults/adapter.helpers.js +202 -0
  249. package/lib/modules/vaults/fetcher.d.ts +147 -0
  250. package/lib/modules/vaults/fetcher.js +357 -0
  251. package/lib/modules/vaults/getters.d.ts +1060 -0
  252. package/lib/modules/vaults/getters.js +4079 -0
  253. package/lib/modules/vaults/index.d.ts +20 -0
  254. package/lib/modules/vaults/index.js +44 -0
  255. package/lib/modules/vaults/main.d.ts +607 -0
  256. package/lib/modules/vaults/main.js +1687 -0
  257. package/lib/modules/vaults/prefetch.d.ts +65 -0
  258. package/lib/modules/vaults/prefetch.js +120 -0
  259. package/lib/modules/vaults/read.actions.d.ts +406 -0
  260. package/lib/modules/vaults/read.actions.js +891 -0
  261. package/lib/modules/vaults/types.d.ts +149 -0
  262. package/lib/modules/vaults/types.js +3 -0
  263. package/lib/modules/vaults/utils/call-data-decoder.d.ts +61 -0
  264. package/lib/modules/vaults/utils/call-data-decoder.js +194 -0
  265. package/lib/modules/vaults/utils/date-utils.d.ts +50 -0
  266. package/lib/modules/vaults/utils/date-utils.js +84 -0
  267. package/lib/modules/vaults/utils.d.ts +153 -0
  268. package/lib/modules/vaults/utils.js +818 -0
  269. package/lib/modules/vaults/write.actions.d.ts +812 -0
  270. package/lib/modules/vaults/write.actions.js +2377 -0
  271. package/lib/polyfills.d.ts +1 -0
  272. package/lib/polyfills.js +12 -0
  273. package/lib/sdk.d.ts +30173 -0
  274. package/lib/services/coingecko/fetcher.d.ts +15 -0
  275. package/lib/services/coingecko/fetcher.js +67 -0
  276. package/lib/services/coingecko/index.d.ts +2 -0
  277. package/lib/services/coingecko/index.js +19 -0
  278. package/lib/services/coingecko/utils.d.ts +1 -0
  279. package/lib/services/coingecko/utils.js +24 -0
  280. package/lib/services/debank/fetcher.d.ts +126 -0
  281. package/lib/services/debank/fetcher.js +47 -0
  282. package/lib/services/debank/index.d.ts +2 -0
  283. package/lib/services/debank/index.js +19 -0
  284. package/lib/services/debank/utils.d.ts +50 -0
  285. package/lib/services/debank/utils.js +325 -0
  286. package/lib/services/layerzero/deposits.d.ts +55 -0
  287. package/lib/services/layerzero/deposits.js +174 -0
  288. package/lib/services/layerzero/redeems.d.ts +20 -0
  289. package/lib/services/layerzero/redeems.js +92 -0
  290. package/lib/services/layerzero/utils.d.ts +9 -0
  291. package/lib/services/layerzero/utils.js +22 -0
  292. package/lib/services/octavfi/fetcher.d.ts +33 -0
  293. package/lib/services/octavfi/fetcher.js +39 -0
  294. package/lib/services/octavfi/index.d.ts +3 -0
  295. package/lib/services/octavfi/index.js +20 -0
  296. package/lib/services/octavfi/types.d.ts +34 -0
  297. package/lib/services/octavfi/types.js +3 -0
  298. package/lib/services/octavfi/utils.d.ts +16 -0
  299. package/lib/services/octavfi/utils.js +244 -0
  300. package/lib/services/subgraph/fetcher.d.ts +2 -0
  301. package/lib/services/subgraph/fetcher.js +66 -0
  302. package/lib/services/subgraph/index.d.ts +2 -0
  303. package/lib/services/subgraph/index.js +19 -0
  304. package/lib/services/subgraph/schema.d.ts +48 -0
  305. package/lib/services/subgraph/schema.js +87 -0
  306. package/lib/services/subgraph/vaults.d.ts +83 -0
  307. package/lib/services/subgraph/vaults.js +1282 -0
  308. package/lib/services/swap-quotes/index.d.ts +105 -0
  309. package/lib/services/swap-quotes/index.js +77 -0
  310. package/lib/services/swap-quotes/paraswap.d.ts +51 -0
  311. package/lib/services/swap-quotes/paraswap.js +138 -0
  312. package/lib/services/untangled/fetcher.d.ts +40 -0
  313. package/lib/services/untangled/fetcher.js +110 -0
  314. package/lib/services/untangled/index.d.ts +3 -0
  315. package/lib/services/untangled/index.js +20 -0
  316. package/lib/services/untangled/types.d.ts +83 -0
  317. package/lib/services/untangled/types.js +10 -0
  318. package/lib/services/untangled/utils.d.ts +91 -0
  319. package/lib/services/untangled/utils.js +339 -0
  320. package/lib/types/api.d.ts +498 -0
  321. package/lib/types/api.js +3 -0
  322. package/lib/types/index.d.ts +12 -0
  323. package/lib/types/index.js +28 -0
  324. package/lib/types/points.d.ts +28 -0
  325. package/lib/types/points.js +3 -0
  326. package/lib/types/pools.d.ts +144 -0
  327. package/lib/types/pools.js +3 -0
  328. package/lib/types/staking.d.ts +28 -0
  329. package/lib/types/staking.js +3 -0
  330. package/lib/types/sub-accounts.d.ts +150 -0
  331. package/lib/types/sub-accounts.js +3 -0
  332. package/lib/types/subgraph.d.ts +84 -0
  333. package/lib/types/subgraph.js +3 -0
  334. package/lib/types/typed-contract.d.ts +102 -0
  335. package/lib/types/typed-contract.js +3 -0
  336. package/lib/types/user.d.ts +1 -0
  337. package/lib/types/user.js +3 -0
  338. package/lib/types/vaults.d.ts +886 -0
  339. package/lib/types/vaults.js +30 -0
  340. package/lib/types/web3.d.ts +100 -0
  341. package/lib/types/web3.js +14 -0
  342. package/lib/types/webserver.d.ts +730 -0
  343. package/lib/types/webserver.js +3 -0
  344. package/package.json +79 -3
@@ -0,0 +1,542 @@
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.getOriginInfo = getOriginInfo;
10
+ exports.readOriginInfo = readOriginInfo;
11
+ exports.readVaultHasSendersWhitelist = readVaultHasSendersWhitelist;
12
+ exports.readSwapRouterPaused = readSwapRouterPaused;
13
+ exports.getSwapRouterWhitelistedTokens = getSwapRouterWhitelistedTokens;
14
+ exports.getSwapRouterEligibleVaults = getSwapRouterEligibleVaults;
15
+ const ethers_1 = require("ethers");
16
+ const swap_router_1 = require("../constants/swap-router");
17
+ const attribution_1 = require("../attribution");
18
+ const abis_1 = require("../../abis");
19
+ const errors_1 = require("../errors");
20
+ const cache_1 = require("../cache");
21
+ const concurrency_1 = require("./concurrency");
22
+ const fetcher_1 = require("../fetcher");
23
+ const logger_1 = require("../logger");
24
+ const web3_1 = require("./web3");
25
+ const multicall_1 = require("./multicall");
26
+ /**
27
+ * Resolve the `SwapRouter` address for a chain.
28
+ *
29
+ * @param chainId - EVM chain ID.
30
+ * @returns The router address, or `undefined` if no SwapRouter is deployed.
31
+ * @example
32
+ * ```ts
33
+ * const router = getSwapRouterAddress(1);
34
+ * // '0xC11c6d8fD8FfFB2045d57b149125C44414d8160B'
35
+ * ```
36
+ */
37
+ function getSwapRouterAddress(chainId) {
38
+ return swap_router_1.SWAP_ROUTER_ADDRESSES[chainId];
39
+ }
40
+ /**
41
+ * Resolve the human-readable display name of the `SwapRouter` periphery
42
+ * contract for a chain.
43
+ *
44
+ * The contract exposes no name on-chain, so this reads the SDK-maintained
45
+ * {@link SWAP_ROUTER_NAMES} registry. Intended for UI surfaces that label the
46
+ * contract a swap-and-deposit routes through (e.g. a "Router" row in a
47
+ * transaction overview) — display metadata only, never routing logic.
48
+ *
49
+ * @param chainId - EVM chain ID.
50
+ * @returns The display name (e.g. `'Upshift Swap Router'`), or `undefined`
51
+ * when no SwapRouter is deployed on the chain — callers should omit the
52
+ * label rather than show an address.
53
+ * @example
54
+ * ```ts
55
+ * const name = getSwapRouterName(1);
56
+ * // 'Upshift Swap Router'
57
+ * ```
58
+ */
59
+ function getSwapRouterName(chainId) {
60
+ return swap_router_1.SWAP_ROUTER_NAMES[chainId];
61
+ }
62
+ /**
63
+ * Whether a vault is eligible for the any-token `SwapRouter` deposit surface
64
+ * (swap tokens). Address comparison is case-insensitive.
65
+ *
66
+ * This gates the (flag-controlled) swap-router deposit UI and can fail-fast a
67
+ * {@link swapRouterDeposit} call. It does **not** affect {@link vaultDeposit},
68
+ * which never swaps (see `getDepositRoute` for when it uses the router).
69
+ *
70
+ * @param vaultAddress - Upshift vault address.
71
+ * @returns `true` when the vault is in {@link SWAP_ROUTER_ELIGIBLE_VAULTS}.
72
+ * @deprecated Superseded by {@link getSwapRouterEligibleVaults}, which resolves
73
+ * eligibility from the backend `swaps_enabled` flag instead of this static
74
+ * snapshot. Kept functional as
75
+ * the zero-RPC sync fallback (seed data, fail-fast checks); migrate UI gates
76
+ * to the async resolver.
77
+ */
78
+ function isSwapRouterEligible(vaultAddress) {
79
+ return swap_router_1.SWAP_ROUTER_ELIGIBLE_VAULTS.has(vaultAddress.toLowerCase());
80
+ }
81
+ /**
82
+ * @deprecated Renamed to {@link isSwapRouterEligible} (itself now superseded by
83
+ * {@link getSwapRouterEligibleVaults}, the `swaps_enabled` resolver). The
84
+ * meaning also changed: it no longer implies `vaultDeposit` routes the vault
85
+ * through the SwapRouter (that behavior was removed) — it only reports
86
+ * swap-router *eligibility* for the opt-in deposit surface. Kept as an alias
87
+ * for one release; migrate to the async resolver.
88
+ */
89
+ exports.vaultUsesSwapRouter = isSwapRouterEligible;
90
+ /**
91
+ * Normalize an optional origin code to the value to send on-chain.
92
+ *
93
+ * Returns the caller-supplied code when present (an explicit all-zero
94
+ * sentinel opts one call out), otherwise the SDK instance's
95
+ * `attribution.originCode` when `chainId` is in
96
+ * {@link ORIGIN_ATTRIBUTION_CHAINS} (Ethereum mainnet only), otherwise the
97
+ * default (all-zero) sentinel from {@link ORIGIN_CODES}. Validates that any
98
+ * supplied code is exactly 32 bytes (66 chars including the `0x` prefix);
99
+ * the on-chain SwapRouter reverts with `InvalidOrigin` otherwise, but
100
+ * surfacing the failure here as a typed SDK error gives partners a
101
+ * grepable Sentry event instead of a generic `execution reverted`.
102
+ *
103
+ * @param provided - Optional caller-supplied origin code.
104
+ * @param chainId - Chain the deposit is sent on. The instance code is never
105
+ * returned without it, or on a chain outside
106
+ * {@link ORIGIN_ATTRIBUTION_CHAINS}.
107
+ * @returns The 32-byte origin code to pass to the router.
108
+ * @throws {@link UpshiftValidationError} when `provided` is not a 32-byte hex string.
109
+ */
110
+ function resolveOriginCode(provided, chainId) {
111
+ if (provided === undefined) {
112
+ const instanceCode = (0, attribution_1.getOriginCode)();
113
+ return instanceCode &&
114
+ chainId !== undefined &&
115
+ swap_router_1.ORIGIN_ATTRIBUTION_CHAINS.includes(chainId)
116
+ ? instanceCode
117
+ : swap_router_1.ORIGIN_CODES.default;
118
+ }
119
+ if (!swap_router_1.ORIGIN_CODE_PATTERN.test(provided)) {
120
+ throw new errors_1.UpshiftValidationError('INVALID_INPUT', `resolveOriginCode: originCode must be a 32-byte hex string (66 chars incl. 0x), got "${provided}" (${provided.length} chars)`, { context: { provided, expectedLength: 66 } });
121
+ }
122
+ return provided;
123
+ }
124
+ /**
125
+ * Resolves the real, post-execution outcome of a SwapRouter deposit from its
126
+ * mined transaction receipt. The SwapRouter contract itself emits no
127
+ * deposit/amount-out event — only the vault does, via its own `Deposit` event
128
+ * — so this decodes that log directly rather than trusting the pre-trade quote
129
+ * a UI shows before the user submits (the true post-swap amount depends on
130
+ * execution-time price and can differ from that estimate).
131
+ *
132
+ * Works for both vault generations without the caller resolving the version
133
+ * first: evm-1 (ERC-4626-style `Deposit(sender, owner, assets, shares)`) and
134
+ * evm-2 (`Deposit(assetIn, amountIn, shares, senderAddr, receiverAddr)`) have
135
+ * different event signatures (different topic0), so both are registered and
136
+ * whichever matches the vault's actual log is decoded.
137
+ *
138
+ * @param signer - ethers `Signer` or `Wallet` connected to a provider (used
139
+ * read-only here — no transaction is sent).
140
+ * @param options - {@link ISwapRouterDepositResultOptions}.
141
+ * @returns The decoded {@link ISwapRouterDepositResult}, or `null` if the
142
+ * receipt isn't found yet or carries no `Deposit` log from `vault` (e.g. the
143
+ * hash is wrong, or the tx hasn't mined).
144
+ * @throws {@link UpshiftValidationError} if `signer` has no connected provider.
145
+ * @worstCaseRpcCalls 1 — a single `getTransactionReceipt` call; decoding is
146
+ * local.
147
+ * @example
148
+ * ```ts
149
+ * const hash = await upshiftSdk.evm.swapRouterDeposit({ ... });
150
+ * const result = await upshiftSdk.evm.getSwapRouterDepositResult({
151
+ * txHash: hash,
152
+ * vault: '0x74ad2f789ed583dbd141bbdafc673fe1f033718b',
153
+ * });
154
+ * // result?.amountOut — actual reference-asset amount received after the swap
155
+ * ```
156
+ */
157
+ async function getSwapRouterDepositResult(signer, { txHash, vault }) {
158
+ const provider = signer.provider;
159
+ if (!provider) {
160
+ throw new errors_1.UpshiftValidationError('INVALID_INPUT', 'getSwapRouterDepositResult: signer has no connected provider');
161
+ }
162
+ const receipt = await provider.getTransactionReceipt(txHash);
163
+ if (!receipt)
164
+ return null;
165
+ const iface = new ethers_1.ethers.Interface([
166
+ 'event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares)',
167
+ 'event Deposit(address assetIn, uint256 amountIn, uint256 shares, address indexed senderAddr, address indexed receiverAddr)',
168
+ ]);
169
+ for (const log of receipt.logs) {
170
+ if (log.address.toLowerCase() !== vault.toLowerCase())
171
+ continue;
172
+ let parsed;
173
+ try {
174
+ parsed = iface.parseLog(log);
175
+ }
176
+ catch {
177
+ continue;
178
+ }
179
+ if (parsed?.name !== 'Deposit')
180
+ continue;
181
+ // Discriminate on the matched event fragment, not on probing a
182
+ // possibly-absent named arg. Only the evm-2 signature declares `assetIn`,
183
+ // so its presence in the fragment inputs uniquely identifies the version.
184
+ // (Reading `parsed.args.assetIn` on the evm-1 log would couple correctness
185
+ // to ethers' `Result`-proxy behavior for unknown names.)
186
+ const isEvm2 = parsed.fragment.inputs.some((i) => i.name === 'assetIn');
187
+ if (isEvm2) {
188
+ // evm-2 TokenizedVault: Deposit(assetIn, amountIn, shares, sender, receiver)
189
+ return {
190
+ amountOut: BigInt(parsed.args.amountIn),
191
+ sharesOut: BigInt(parsed.args.shares),
192
+ };
193
+ }
194
+ // evm-1 ERC-4626-style: Deposit(sender, owner, assets, shares)
195
+ return {
196
+ amountOut: BigInt(parsed.args.assets),
197
+ sharesOut: BigInt(parsed.args.shares),
198
+ };
199
+ }
200
+ return null;
201
+ }
202
+ /** Cache TTL for resolved origin-code, vault and token registrations (5 minutes). */
203
+ const SWAP_ROUTER_ORIGIN_INFO_TTL_MS = 5 * 60 * 1000;
204
+ /**
205
+ * Read how an origin code is registered on a chain's `SwapRouter`: whether it
206
+ * exists, its origin fee, and its fee collector.
207
+ *
208
+ * Check a partner code with this before configuring it as
209
+ * `attribution.originCode` — the router reverts every deposit carrying an
210
+ * unregistered code with `InvalidOrigin`. A code is registered when its
211
+ * collector is non-zero (`addOrigin` always sets one); a zero-fee code is
212
+ * still registered but never emits `OriginFeeApplied`. Cached per (chain,
213
+ * router, code) for 5 minutes.
214
+ *
215
+ * @param options - {@link IGetOriginInfoOptions}.
216
+ * @returns {@link IOriginInfo}; `registered: false` with a zero fee and
217
+ * collector, and no RPC, on a chain with no SwapRouter deployment.
218
+ * @throws {@link UpshiftValidationError} when `originCode` is not a 32-byte hex
219
+ * string.
220
+ * @throws {@link UpshiftSDKError} when the `origins(bytes32)` read fails.
221
+ * @worstCaseRpcCalls 1 — one `origins(bytes32)` call; none on a cache hit.
222
+ * @example
223
+ * ```ts
224
+ * const info = await getOriginInfo({ chainId: 1, originCode, rpcUrl });
225
+ * if (!info.registered) throw new Error('origin code is not registered');
226
+ * ```
227
+ */
228
+ async function getOriginInfo({ chainId, originCode, rpcUrl, }) {
229
+ if (!swap_router_1.ORIGIN_CODE_PATTERN.test(originCode)) {
230
+ throw new errors_1.UpshiftValidationError('INVALID_INPUT', `getOriginInfo: originCode must be a 32-byte hex string (66 chars incl. 0x), got ${String(originCode).length} chars`, { context: { chainId, expectedLength: 66 } });
231
+ }
232
+ try {
233
+ return await readOriginInfo(chainId, originCode, () => (0, web3_1.createProvider)(rpcUrl, chainId));
234
+ }
235
+ catch (e) {
236
+ if (e instanceof errors_1.UpshiftSDKError)
237
+ throw e;
238
+ throw new errors_1.UpshiftSDKError('UNKNOWN', `getOriginInfo failed: ${e instanceof Error ? e.message : 'Unknown error'}`, { cause: e, context: { chainId } });
239
+ }
240
+ }
241
+ /**
242
+ * {@link getOriginInfo} without input validation, reading through a caller
243
+ * runner (created lazily, only on a cache miss). Shared with the deposit-route
244
+ * resolver so both hit the same cache entry.
245
+ * @internal
246
+ */
247
+ async function readOriginInfo(chainId, originCode, runner) {
248
+ const unregistered = {
249
+ registered: false,
250
+ originFeeBps: 0,
251
+ collector: ethers_1.ethers.ZeroAddress,
252
+ };
253
+ const router = getSwapRouterAddress(chainId);
254
+ if (!router)
255
+ return unregistered;
256
+ const cacheKey = `swap-router-origin-${chainId}-${router.toLowerCase()}-${originCode.toLowerCase()}`;
257
+ const cached = await (0, cache_1.getSafeCache)(cacheKey);
258
+ if (cached)
259
+ return cached;
260
+ const contract = (0, web3_1.createContract)({
261
+ address: router,
262
+ provider: runner(),
263
+ abi: abis_1.ABI_SWAP_ROUTER,
264
+ });
265
+ if (!contract)
266
+ return unregistered;
267
+ const [originFee, originFeeCollector] = await contract.origins(originCode);
268
+ const info = {
269
+ registered: originFeeCollector !== ethers_1.ethers.ZeroAddress,
270
+ originFeeBps: Number(originFee),
271
+ collector: originFeeCollector,
272
+ };
273
+ cache_1.CACHE.set(cacheKey, info, { ttl: SWAP_ROUTER_ORIGIN_INFO_TTL_MS });
274
+ return info;
275
+ }
276
+ /**
277
+ * Read whether a Tokenized Vault V2 restricts depositors with a senders
278
+ * whitelist (KYC), cached for 5 minutes like the router reads.
279
+ *
280
+ * The v2 SwapRouter accepts any vault, so this is the check that keeps KYC
281
+ * vaults off the router: such a vault only accepts deposits from whitelisted
282
+ * senders, so a router deposit either reverts `SenderNotWhitelisted` or, on an
283
+ * implementation that checks only `msg.sender`, would let any wallet deposit
284
+ * through a whitelisted router.
285
+ *
286
+ * @param runner - Provider or signer used for the read.
287
+ * @param chainId - Chain the vault is on (part of the cache key).
288
+ * @param vault - Tokenized Vault V2 address.
289
+ * @returns `true` when `sendersWhitelistAddress()` is non-zero.
290
+ * @throws When the `sendersWhitelistAddress()` read fails. Callers wrap it in
291
+ * their own error handling.
292
+ * @worstCaseRpcCalls 1 — one `sendersWhitelistAddress()` call; none on a cache hit.
293
+ * @internal
294
+ */
295
+ async function readVaultHasSendersWhitelist(runner, chainId, vault) {
296
+ const cacheKey = `vault-senders-whitelist-${chainId}-${vault.toLowerCase()}`;
297
+ const cached = await (0, cache_1.getSafeCache)(cacheKey);
298
+ if (cached !== null)
299
+ return cached;
300
+ const contract = (0, web3_1.createContract)({
301
+ address: vault,
302
+ provider: runner,
303
+ abi: abis_1.ABI_TOKENIZED_VAULT_V2,
304
+ });
305
+ const whitelist = (await contract.sendersWhitelistAddress());
306
+ const hasWhitelist = whitelist !== ethers_1.ethers.ZeroAddress;
307
+ cache_1.CACHE.set(cacheKey, hasWhitelist, { ttl: SWAP_ROUTER_ORIGIN_INFO_TTL_MS });
308
+ return hasWhitelist;
309
+ }
310
+ /**
311
+ * Cache TTL for a SwapRouter's pause state (15 seconds). Far shorter than the
312
+ * 5-minute TTL of the other router reads: the owner pauses the router to stop
313
+ * deposits during an incident, so a pause must reach the deposit-route
314
+ * resolver within seconds. Long enough that the resolver and the router write
315
+ * it hands off to share one `isPaused()` read.
316
+ */
317
+ const SWAP_ROUTER_PAUSED_TTL_MS = 15 * 1000;
318
+ /**
319
+ * Read whether a chain's `SwapRouter` is paused (`isPaused()`), cached for 15
320
+ * seconds. Every router entry point (`deposit`, `swapAndDeposit`,
321
+ * `depositNativeToken`) reverts with `ContractIsPaused` while the router is
322
+ * paused, so callers check this before routing a deposit or sending an
323
+ * approval to the router.
324
+ *
325
+ * @param runner - Contract runner (provider or signer) used for the read.
326
+ * @param chainId - EVM chain ID.
327
+ * @returns `true` while the router is paused; `false` when it is not, or on a
328
+ * chain with no SwapRouter (no RPC).
329
+ * @throws When the `isPaused()` read fails. Callers wrap it in
330
+ * {@link UpshiftSDKError}.
331
+ * @worstCaseRpcCalls 1 — one `isPaused()` call; none on a cache hit.
332
+ * @internal
333
+ */
334
+ async function readSwapRouterPaused(runner, chainId) {
335
+ const router = getSwapRouterAddress(chainId);
336
+ if (!router)
337
+ return false;
338
+ const cacheKey = `swap-router-paused-${chainId}-${router.toLowerCase()}`;
339
+ const cached = await (0, cache_1.getSafeCache)(cacheKey);
340
+ if (cached !== null)
341
+ return cached;
342
+ const contract = (0, web3_1.createContract)({
343
+ address: router,
344
+ provider: runner,
345
+ abi: abis_1.ABI_SWAP_ROUTER,
346
+ });
347
+ if (!contract)
348
+ return false;
349
+ const paused = (await contract.isPaused()) === true;
350
+ cache_1.CACHE.set(cacheKey, paused, { ttl: SWAP_ROUTER_PAUSED_TTL_MS });
351
+ return paused;
352
+ }
353
+ /**
354
+ * Upper bound on simultaneous `eth_getLogs` chunks during a router log scan.
355
+ *
356
+ * The scan covers the router's whole on-chain lifetime in
357
+ * `determineBlockSkipInternal`-sized windows (10k blocks on mainnet), and the
358
+ * chunk count grows by one every ~1.4 days of mainnet history. Firing every
359
+ * chunk at once (`Promise.allSettled` over the full range list) opened an
360
+ * unbounded number of concurrent requests against a single RPC origin, which
361
+ * is exactly what triggers provider rate limiting. 8 keeps a cold scan close
362
+ * to the fully-parallel latency while bounding the burst.
363
+ */
364
+ const SWAP_ROUTER_LOG_SCAN_CONCURRENCY = 8;
365
+ /** Cache TTL for a chain's resolved SwapRouter token allowlist (5 minutes). */
366
+ const SWAP_ROUTER_WHITELIST_TTL_MS = 5 * 60 * 1000;
367
+ /**
368
+ * Resolve the ERC-20 tokens currently whitelisted for the `SwapRouter` on a
369
+ * chain — the any-token set a UI can offer as swap-and-deposit inputs.
370
+ *
371
+ * The router exposes its allowlist only as `mapping(address => bool)
372
+ * whitelistedTokens` with **no on-chain enumeration**, so this cannot be a
373
+ * single view call. It runs in two stages:
374
+ * 1. Scan the router's `TokenEnabled(address)` event history (from the chain's
375
+ * {@link SWAP_ROUTER_DEPLOY_BLOCKS} floor, in `eth_getLogs` chunks sized by
376
+ * {@link determineBlockSkipInternal}) to reconstruct the candidate set of
377
+ * every token ever enabled.
378
+ * 2. Re-read `whitelistedTokens(token)` for each candidate — batched via
379
+ * Multicall3 where verified, else per-call — and keep only those the
380
+ * mapping currently returns `true` for. This step makes later disables (and
381
+ * disable-then-re-enable) correct without replaying `TokenDisabled`, and is
382
+ * the fail-closed source of truth: a token surfaces only on a definite
383
+ * on-chain `true`.
384
+ *
385
+ * The resolved list is cached per chain for 5 minutes — the allowlist changes
386
+ * only via an admin `enableToken`/`disableToken` transaction, so a short TTL
387
+ * keeps the (multi-RPC) scan off the hot path without going stale for long.
388
+ *
389
+ * @param chainId - EVM chain ID. Chains without a {@link SWAP_ROUTER_ADDRESSES}
390
+ * entry resolve to `[]` with no RPC.
391
+ * @param options - `rpcUrl` (required) must point at `chainId`'s network;
392
+ * `fromBlock` overrides the default deploy-block scan floor (e.g. to widen a
393
+ * scan on a chain missing from {@link SWAP_ROUTER_DEPLOY_BLOCKS}).
394
+ * @returns Checksummed addresses of the currently-whitelisted tokens, deduped.
395
+ * Empty when no router is deployed or none are enabled. Callers still filter
396
+ * out a given vault's natively-accepted assets (those deposit without a swap).
397
+ * @throws UpshiftValidationError when `rpcUrl` is missing/empty.
398
+ * @throws UpshiftSDKError when an `eth_getLogs` chunk fails — surfaced (not
399
+ * swallowed) so a partial scan never masquerades as a complete allowlist.
400
+ * @worstCaseRpcCalls 1 `eth_blockNumber` + ⌈(head − deploy block) ÷ window⌉
401
+ * `eth_getLogs` chunks + 1 Multicall3 `eth_call`, where `window` is
402
+ * {@link determineBlockSkipInternal} (10k blocks on mainnet, 1k on
403
+ * HyperEVM). The chunk count grows with the router's on-chain age (on
404
+ * mainnet roughly one more chunk every ~1.4 days since the deploy block,
405
+ * already in the tens), not with candidate count. Chunks run at most 8 at a
406
+ * time, so a cold scan never opens more than 8 concurrent requests.
407
+ * @example
408
+ * ```ts
409
+ * const tokens = await getSwapRouterWhitelistedTokens(1, {
410
+ * rpcUrl: 'https://eth-mainnet.example/v2/KEY',
411
+ * });
412
+ * // ['0xA0b8…', '0xdAC1…', '0xC02a…', '0x2260…'] (USDC, USDT, WETH, WBTC)
413
+ * ```
414
+ */
415
+ async function getSwapRouterWhitelistedTokens(chainId, options) {
416
+ const router = getSwapRouterAddress(chainId);
417
+ if (!router)
418
+ return [];
419
+ const cacheKey = `swap-router-whitelisted-tokens-${chainId}-${router.toLowerCase()}`;
420
+ const cached = await (0, cache_1.getSafeCache)(cacheKey);
421
+ if (cached)
422
+ return cached;
423
+ const provider = (0, web3_1.createProvider)(options.rpcUrl, chainId);
424
+ const contract = (0, web3_1.createContract)({
425
+ address: router,
426
+ provider,
427
+ abi: abis_1.ABI_SWAP_ROUTER,
428
+ });
429
+ if (!contract)
430
+ return [];
431
+ // Stage 1 — reconstruct the candidate set from TokenEnabled logs, scanning
432
+ // the router's lifetime in chunks to respect per-request eth_getLogs limits.
433
+ const currentBlock = await provider.getBlockNumber();
434
+ const fromBlock = Math.max(0, options.fromBlock ?? swap_router_1.SWAP_ROUTER_DEPLOY_BLOCKS[chainId] ?? 0);
435
+ const blockSkip = (0, web3_1.determineBlockSkipInternal)(chainId);
436
+ const ranges = [];
437
+ for (let end = currentBlock; end >= fromBlock; end -= blockSkip + 1) {
438
+ ranges.push({ from: Math.max(end - blockSkip, fromBlock), to: end });
439
+ }
440
+ // Bounded fan-out (see SWAP_ROUTER_LOG_SCAN_CONCURRENCY). Each chunk is
441
+ // settled individually so the result shape matches `Promise.allSettled`;
442
+ // once one chunk has failed the remaining chunks are skipped rather than
443
+ // spent, since the scan is thrown away below anyway.
444
+ let scanFailure;
445
+ const settled = await (0, concurrency_1.mapWithConcurrency)(ranges, SWAP_ROUTER_LOG_SCAN_CONCURRENCY, async (r) => {
446
+ if (scanFailure)
447
+ return scanFailure;
448
+ const [result] = await Promise.allSettled([
449
+ contract.queryFilter('TokenEnabled', BigInt(r.from), BigInt(r.to)),
450
+ ]);
451
+ if (result.status === 'rejected')
452
+ scanFailure = result;
453
+ return result;
454
+ });
455
+ const failed = settled.find((s) => s.status === 'rejected');
456
+ if (failed) {
457
+ const reason = failed.reason instanceof Error
458
+ ? failed.reason.message
459
+ : String(failed.reason);
460
+ throw new errors_1.UpshiftSDKError('NETWORK_ERROR', `getSwapRouterWhitelistedTokens: TokenEnabled log scan failed on chain ${chainId}: ${reason}`);
461
+ }
462
+ const candidates = new Set();
463
+ for (const s of settled) {
464
+ if (s.status !== 'fulfilled')
465
+ continue;
466
+ for (const log of s.value) {
467
+ const raw = log.args?.tokenAddr;
468
+ if (typeof raw === 'string' && (0, ethers_1.isAddress)(raw)) {
469
+ candidates.add((0, ethers_1.getAddress)(raw));
470
+ }
471
+ }
472
+ }
473
+ if (candidates.size === 0) {
474
+ cache_1.CACHE.set(cacheKey, [], { ttl: SWAP_ROUTER_WHITELIST_TTL_MS });
475
+ return [];
476
+ }
477
+ // Stage 2 — keep only tokens the mapping currently reports as whitelisted.
478
+ const list = [...candidates];
479
+ let enabled;
480
+ if ((0, multicall_1.isMulticall3Supported)(chainId)) {
481
+ const calls = list.map((token) => ({
482
+ target: router,
483
+ abi: abis_1.ABI_SWAP_ROUTER,
484
+ functionName: 'whitelistedTokens',
485
+ args: [token],
486
+ }));
487
+ const results = await (0, multicall_1.multicall3Aggregate)(provider, chainId, calls);
488
+ enabled = list.filter((_, i) => results[i]?.success && results[i]?.value === true);
489
+ }
490
+ else {
491
+ const bools = await Promise.all(list.map(async (token) => {
492
+ try {
493
+ return (await contract.whitelistedTokens(token));
494
+ }
495
+ catch (e) {
496
+ logger_1.Logger.log.warn('getSwapRouterWhitelistedTokens', `whitelistedTokens(${token}) read failed — omitting`, e);
497
+ return false;
498
+ }
499
+ }));
500
+ enabled = list.filter((_, i) => bools[i] === true);
501
+ }
502
+ cache_1.CACHE.set(cacheKey, enabled, { ttl: SWAP_ROUTER_WHITELIST_TTL_MS });
503
+ return enabled;
504
+ }
505
+ /**
506
+ * Resolve the vaults that offer the any-token `SwapRouter` deposit surface
507
+ * (swap tokens) on a chain: every vault the Upshift API marks `swaps_enabled`,
508
+ * on a chain with a SwapRouter.
509
+ *
510
+ * SwapRouter v2 has no on-chain vault registry, so the backend `swaps_enabled`
511
+ * flag is the source of truth. It fails closed: a vault without the flag, or
512
+ * with it `false`, is excluded. It only gates swap tokens — a normal deposit
513
+ * of an asset the vault accepts routes through the router whatever the flag
514
+ * (see {@link getDepositRoute}).
515
+ *
516
+ * App-level policy (e.g. excluding vaults with their own OVault deposit flow)
517
+ * remains the caller's responsibility.
518
+ *
519
+ * @param chainId - EVM chain ID. Chains without a {@link SWAP_ROUTER_ADDRESSES}
520
+ * entry resolve to `[]` with no request.
521
+ * @param _options - Kept for compatibility; `rpcUrl` and `fromBlock` are no
522
+ * longer read.
523
+ * @returns Checksummed addresses of the chain's `swaps_enabled` vaults. Empty
524
+ * when no router is deployed or no vault has the flag.
525
+ * @throws When the Upshift API vault-list request fails.
526
+ * @worstCaseRpcCalls 0 — one Upshift API request (the vault list, cached for
527
+ * 15 minutes), no RPC.
528
+ * @example
529
+ * ```ts
530
+ * const vaults = await getSwapRouterEligibleVaults(1);
531
+ * // ['0x74aD…718b', '0xE9B7…9D32']
532
+ * ```
533
+ */
534
+ async function getSwapRouterEligibleVaults(chainId, _options) {
535
+ if (!getSwapRouterAddress(chainId))
536
+ return [];
537
+ const vaults = await (0, fetcher_1.fetchTokenizedVaults)(undefined, undefined, false, false);
538
+ return vaults
539
+ .filter((v) => v.chain === chainId && v.swaps_enabled === true && (0, ethers_1.isAddress)(v.address))
540
+ .map((v) => (0, ethers_1.getAddress)(v.address));
541
+ }
542
+ //# sourceMappingURL=swap-router.js.map
@@ -0,0 +1,24 @@
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, Stellar, or a
17
+ * Sui Vault object ID — `0x` + 64 hex chars).
18
+ * @returns The vault version slug, or `undefined` for empty/invalid input.
19
+ */
20
+ export declare function getVaultVersion(vault: string): IVaultVersion | undefined;
21
+ export declare function getVaultVersionV2(vault: (Pick<ITokenizedVault, 'address'> & {
22
+ chain_type?: string;
23
+ internal_type?: string;
24
+ }) | undefined | null): IVaultVersion | undefined;
@@ -0,0 +1,83 @@
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, Stellar, or a
32
+ * Sui Vault object ID — `0x` + 64 hex chars).
33
+ * @returns The vault version slug, or `undefined` for empty/invalid input.
34
+ */
35
+ function getVaultVersion(vault) {
36
+ if (!vault)
37
+ return;
38
+ const chainType = getAddressChainType(vault);
39
+ if (chainType === 'stellar')
40
+ return 'stellar-0';
41
+ if (chainType === 'solana')
42
+ return 'sol-0';
43
+ if (chainType === 'sui')
44
+ return 'sui-0';
45
+ if (!(0, ethers_1.isAddress)(vault))
46
+ return;
47
+ if (vaults_1.OLD_LENDING_POOLS.includes((0, ethers_1.getAddress)(vault))) {
48
+ return 'evm-0';
49
+ }
50
+ else if (vaults_1.MULTI_ASSET_VAULTS.includes((0, ethers_1.getAddress)(vault))) {
51
+ return 'evm-2';
52
+ }
53
+ else {
54
+ return 'evm-1';
55
+ }
56
+ }
57
+ function getVaultVersionV2(vault) {
58
+ if (!vault)
59
+ return;
60
+ const chainType = getAddressChainType(vault.address);
61
+ if (vault.chain_type === 'stellar' || chainType === 'stellar')
62
+ return 'stellar-0';
63
+ if (vault.chain_type === 'solana' || chainType === 'solana')
64
+ return 'sol-0';
65
+ if (vault.chain_type === 'sui' || chainType === 'sui')
66
+ return 'sui-0';
67
+ if (!(0, ethers_1.isAddress)(vault.address))
68
+ return;
69
+ if (vaults_1.OLD_LENDING_POOLS.includes((0, ethers_1.getAddress)(vault.address))) {
70
+ return 'evm-0';
71
+ }
72
+ else if (vault.internal_type === 'multiAssetVault' ||
73
+ // Checksum-normalize before the lookup: the list holds checksummed
74
+ // addresses, and the backend / callers may supply lowercase. `isAddress`
75
+ // above already guarantees `getAddress` cannot throw here.
76
+ vaults_1.MULTI_ASSET_VAULTS.includes((0, ethers_1.getAddress)(vault.address))) {
77
+ return 'evm-2';
78
+ }
79
+ else {
80
+ return 'evm-1';
81
+ }
82
+ }
83
+ //# sourceMappingURL=vault-version.js.map