@eth-optimism/actions-sdk 0.2.0 → 0.3.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 (271) hide show
  1. package/dist/__mocks__/MockAssets.d.ts.map +1 -1
  2. package/dist/__mocks__/MockAssets.js +2 -0
  3. package/dist/__mocks__/MockAssets.js.map +1 -1
  4. package/dist/__tests__/actions.test.js +0 -4
  5. package/dist/__tests__/actions.test.js.map +1 -1
  6. package/dist/actions.d.ts +20 -1
  7. package/dist/actions.d.ts.map +1 -1
  8. package/dist/actions.js +37 -13
  9. package/dist/actions.js.map +1 -1
  10. package/dist/constants/assets.d.ts +4 -0
  11. package/dist/constants/assets.d.ts.map +1 -1
  12. package/dist/constants/assets.js +15 -0
  13. package/dist/constants/assets.js.map +1 -1
  14. package/dist/constants/contracts.d.ts +4 -0
  15. package/dist/constants/contracts.d.ts.map +1 -0
  16. package/dist/constants/contracts.js +3 -0
  17. package/dist/constants/contracts.js.map +1 -0
  18. package/dist/index.d.ts +4 -3
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +3 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/lend/core/LendProvider.d.ts +0 -6
  23. package/dist/lend/core/LendProvider.d.ts.map +1 -1
  24. package/dist/lend/core/LendProvider.js +6 -15
  25. package/dist/lend/core/LendProvider.js.map +1 -1
  26. package/dist/lend/core/__tests__/LendProvider.test.js +2 -4
  27. package/dist/lend/core/__tests__/LendProvider.test.js.map +1 -1
  28. package/dist/lend/providers/morpho/__tests__/sdk.test.js +3 -2
  29. package/dist/lend/providers/morpho/__tests__/sdk.test.js.map +1 -1
  30. package/dist/lend/providers/morpho/api.d.ts +4 -0
  31. package/dist/lend/providers/morpho/api.d.ts.map +1 -1
  32. package/dist/lend/providers/morpho/api.js.map +1 -1
  33. package/dist/lend/providers/morpho/sdk.d.ts.map +1 -1
  34. package/dist/lend/providers/morpho/sdk.js +10 -1
  35. package/dist/lend/providers/morpho/sdk.js.map +1 -1
  36. package/dist/supported/tokens.d.ts.map +1 -1
  37. package/dist/supported/tokens.js +9 -2
  38. package/dist/supported/tokens.js.map +1 -1
  39. package/dist/swap/__mocks__/MockSwapProvider.d.ts +38 -0
  40. package/dist/swap/__mocks__/MockSwapProvider.d.ts.map +1 -0
  41. package/dist/swap/__mocks__/MockSwapProvider.js +138 -0
  42. package/dist/swap/__mocks__/MockSwapProvider.js.map +1 -0
  43. package/dist/swap/core/SwapProvider.d.ts +56 -0
  44. package/dist/swap/core/SwapProvider.d.ts.map +1 -0
  45. package/dist/swap/core/SwapProvider.js +177 -0
  46. package/dist/swap/core/SwapProvider.js.map +1 -0
  47. package/dist/swap/core/__tests__/SwapProvider.test.d.ts +2 -0
  48. package/dist/swap/core/__tests__/SwapProvider.test.d.ts.map +1 -0
  49. package/dist/swap/core/__tests__/SwapProvider.test.js +329 -0
  50. package/dist/swap/core/__tests__/SwapProvider.test.js.map +1 -0
  51. package/dist/swap/index.d.ts +7 -0
  52. package/dist/swap/index.d.ts.map +1 -0
  53. package/dist/swap/index.js +8 -0
  54. package/dist/swap/index.js.map +1 -0
  55. package/dist/swap/namespaces/ActionsSwapNamespace.d.ts +8 -0
  56. package/dist/swap/namespaces/ActionsSwapNamespace.d.ts.map +1 -0
  57. package/dist/swap/namespaces/ActionsSwapNamespace.js +8 -0
  58. package/dist/swap/namespaces/ActionsSwapNamespace.js.map +1 -0
  59. package/dist/swap/namespaces/BaseSwapNamespace.d.ts +33 -0
  60. package/dist/swap/namespaces/BaseSwapNamespace.d.ts.map +1 -0
  61. package/dist/swap/namespaces/BaseSwapNamespace.js +58 -0
  62. package/dist/swap/namespaces/BaseSwapNamespace.js.map +1 -0
  63. package/dist/swap/namespaces/WalletSwapNamespace.d.ts +22 -0
  64. package/dist/swap/namespaces/WalletSwapNamespace.d.ts.map +1 -0
  65. package/dist/swap/namespaces/WalletSwapNamespace.js +60 -0
  66. package/dist/swap/namespaces/WalletSwapNamespace.js.map +1 -0
  67. package/dist/swap/namespaces/__tests__/BaseSwapNamespace.spec.d.ts +2 -0
  68. package/dist/swap/namespaces/__tests__/BaseSwapNamespace.spec.d.ts.map +1 -0
  69. package/dist/swap/namespaces/__tests__/BaseSwapNamespace.spec.js +106 -0
  70. package/dist/swap/namespaces/__tests__/BaseSwapNamespace.spec.js.map +1 -0
  71. package/dist/swap/namespaces/__tests__/WalletSwapNamespace.spec.d.ts +2 -0
  72. package/dist/swap/namespaces/__tests__/WalletSwapNamespace.spec.d.ts.map +1 -0
  73. package/dist/swap/namespaces/__tests__/WalletSwapNamespace.spec.js +132 -0
  74. package/dist/swap/namespaces/__tests__/WalletSwapNamespace.spec.js.map +1 -0
  75. package/dist/swap/providers/uniswap/UniswapSwapProvider.d.ts +68 -0
  76. package/dist/swap/providers/uniswap/UniswapSwapProvider.d.ts.map +1 -0
  77. package/dist/swap/providers/uniswap/UniswapSwapProvider.js +206 -0
  78. package/dist/swap/providers/uniswap/UniswapSwapProvider.js.map +1 -0
  79. package/dist/swap/providers/uniswap/__tests__/UniswapSwapProvider.test.d.ts +2 -0
  80. package/dist/swap/providers/uniswap/__tests__/UniswapSwapProvider.test.d.ts.map +1 -0
  81. package/dist/swap/providers/uniswap/__tests__/UniswapSwapProvider.test.js +257 -0
  82. package/dist/swap/providers/uniswap/__tests__/UniswapSwapProvider.test.js.map +1 -0
  83. package/dist/swap/providers/uniswap/__tests__/sdk.test.d.ts +2 -0
  84. package/dist/swap/providers/uniswap/__tests__/sdk.test.d.ts.map +1 -0
  85. package/dist/swap/providers/uniswap/__tests__/sdk.test.js +312 -0
  86. package/dist/swap/providers/uniswap/__tests__/sdk.test.js.map +1 -0
  87. package/dist/swap/providers/uniswap/abis.d.ts +227 -0
  88. package/dist/swap/providers/uniswap/abis.d.ts.map +1 -0
  89. package/dist/swap/providers/uniswap/abis.js +138 -0
  90. package/dist/swap/providers/uniswap/abis.js.map +1 -0
  91. package/dist/swap/providers/uniswap/addresses.d.ts +21 -0
  92. package/dist/swap/providers/uniswap/addresses.d.ts.map +1 -0
  93. package/dist/swap/providers/uniswap/addresses.js +81 -0
  94. package/dist/swap/providers/uniswap/addresses.js.map +1 -0
  95. package/dist/swap/providers/uniswap/encoding.d.ts +77 -0
  96. package/dist/swap/providers/uniswap/encoding.d.ts.map +1 -0
  97. package/dist/swap/providers/uniswap/encoding.js +233 -0
  98. package/dist/swap/providers/uniswap/encoding.js.map +1 -0
  99. package/dist/swap/providers/uniswap/types.d.ts +20 -0
  100. package/dist/swap/providers/uniswap/types.d.ts.map +1 -0
  101. package/dist/swap/providers/uniswap/types.js +2 -0
  102. package/dist/swap/providers/uniswap/types.js.map +1 -0
  103. package/dist/types/actions.d.ts +19 -5
  104. package/dist/types/actions.d.ts.map +1 -1
  105. package/dist/types/index.d.ts +2 -0
  106. package/dist/types/index.d.ts.map +1 -1
  107. package/dist/types/index.js +2 -0
  108. package/dist/types/index.js.map +1 -1
  109. package/dist/types/lend/base.d.ts +3 -13
  110. package/dist/types/lend/base.d.ts.map +1 -1
  111. package/dist/types/lend/base.js.map +1 -1
  112. package/dist/types/swap/base.d.ts +238 -0
  113. package/dist/types/swap/base.d.ts.map +1 -0
  114. package/dist/types/swap/base.js +4 -0
  115. package/dist/types/swap/base.js.map +1 -0
  116. package/dist/types/swap/index.d.ts +2 -0
  117. package/dist/types/swap/index.d.ts.map +1 -0
  118. package/dist/types/swap/index.js +2 -0
  119. package/dist/types/swap/index.js.map +1 -0
  120. package/dist/types/transaction.d.ts +14 -0
  121. package/dist/types/transaction.d.ts.map +1 -0
  122. package/dist/types/transaction.js +2 -0
  123. package/dist/types/transaction.js.map +1 -0
  124. package/dist/utils/assets.d.ts +4 -5
  125. package/dist/utils/assets.d.ts.map +1 -1
  126. package/dist/utils/assets.js +4 -11
  127. package/dist/utils/assets.js.map +1 -1
  128. package/dist/utils/assets.test.js +13 -1
  129. package/dist/utils/assets.test.js.map +1 -1
  130. package/dist/utils/permit2.d.ts +46 -0
  131. package/dist/utils/permit2.d.ts.map +1 -0
  132. package/dist/utils/permit2.js +100 -0
  133. package/dist/utils/permit2.js.map +1 -0
  134. package/dist/utils/permit2.test.d.ts +2 -0
  135. package/dist/utils/permit2.test.d.ts.map +1 -0
  136. package/dist/utils/permit2.test.js +110 -0
  137. package/dist/utils/permit2.test.js.map +1 -0
  138. package/dist/utils/validation.d.ts +12 -0
  139. package/dist/utils/validation.d.ts.map +1 -0
  140. package/dist/utils/validation.js +44 -0
  141. package/dist/utils/validation.js.map +1 -0
  142. package/dist/wallet/core/providers/hosted/abstract/HostedWalletProvider.d.ts +7 -1
  143. package/dist/wallet/core/providers/hosted/abstract/HostedWalletProvider.d.ts.map +1 -1
  144. package/dist/wallet/core/providers/hosted/abstract/HostedWalletProvider.js +2 -1
  145. package/dist/wallet/core/providers/hosted/abstract/HostedWalletProvider.js.map +1 -1
  146. package/dist/wallet/core/providers/hosted/types/index.d.ts +5 -1
  147. package/dist/wallet/core/providers/hosted/types/index.d.ts.map +1 -1
  148. package/dist/wallet/core/providers/smart/default/DefaultSmartWalletProvider.d.ts +7 -1
  149. package/dist/wallet/core/providers/smart/default/DefaultSmartWalletProvider.d.ts.map +1 -1
  150. package/dist/wallet/core/providers/smart/default/DefaultSmartWalletProvider.js +5 -1
  151. package/dist/wallet/core/providers/smart/default/DefaultSmartWalletProvider.js.map +1 -1
  152. package/dist/wallet/core/providers/smart/default/__tests__/DefaultSmartWalletProvider.spec.js +2 -2
  153. package/dist/wallet/core/providers/smart/default/__tests__/DefaultSmartWalletProvider.spec.js.map +1 -1
  154. package/dist/wallet/core/wallets/abstract/Wallet.d.ts +13 -2
  155. package/dist/wallet/core/wallets/abstract/Wallet.d.ts.map +1 -1
  156. package/dist/wallet/core/wallets/abstract/Wallet.js +7 -1
  157. package/dist/wallet/core/wallets/abstract/Wallet.js.map +1 -1
  158. package/dist/wallet/core/wallets/smart/default/DefaultSmartWallet.d.ts +7 -2
  159. package/dist/wallet/core/wallets/smart/default/DefaultSmartWallet.d.ts.map +1 -1
  160. package/dist/wallet/core/wallets/smart/default/DefaultSmartWallet.js +6 -5
  161. package/dist/wallet/core/wallets/smart/default/DefaultSmartWallet.js.map +1 -1
  162. package/dist/wallet/node/providers/hosted/privy/PrivyHostedWalletProvider.d.ts +6 -1
  163. package/dist/wallet/node/providers/hosted/privy/PrivyHostedWalletProvider.d.ts.map +1 -1
  164. package/dist/wallet/node/providers/hosted/privy/PrivyHostedWalletProvider.js +3 -1
  165. package/dist/wallet/node/providers/hosted/privy/PrivyHostedWalletProvider.js.map +1 -1
  166. package/dist/wallet/node/providers/hosted/registry/NodeHostedWalletProviderRegistry.d.ts.map +1 -1
  167. package/dist/wallet/node/providers/hosted/registry/NodeHostedWalletProviderRegistry.js +4 -3
  168. package/dist/wallet/node/providers/hosted/registry/NodeHostedWalletProviderRegistry.js.map +1 -1
  169. package/dist/wallet/node/providers/hosted/turnkey/TurnkeyHostedWalletProvider.d.ts +5 -1
  170. package/dist/wallet/node/providers/hosted/turnkey/TurnkeyHostedWalletProvider.d.ts.map +1 -1
  171. package/dist/wallet/node/providers/hosted/turnkey/TurnkeyHostedWalletProvider.js +4 -2
  172. package/dist/wallet/node/providers/hosted/turnkey/TurnkeyHostedWalletProvider.js.map +1 -1
  173. package/dist/wallet/node/wallets/hosted/privy/PrivyWallet.d.ts +6 -1
  174. package/dist/wallet/node/wallets/hosted/privy/PrivyWallet.d.ts.map +1 -1
  175. package/dist/wallet/node/wallets/hosted/privy/PrivyWallet.js +4 -3
  176. package/dist/wallet/node/wallets/hosted/privy/PrivyWallet.js.map +1 -1
  177. package/dist/wallet/node/wallets/hosted/turnkey/TurnkeyWallet.d.ts +5 -1
  178. package/dist/wallet/node/wallets/hosted/turnkey/TurnkeyWallet.d.ts.map +1 -1
  179. package/dist/wallet/node/wallets/hosted/turnkey/TurnkeyWallet.js +2 -2
  180. package/dist/wallet/node/wallets/hosted/turnkey/TurnkeyWallet.js.map +1 -1
  181. package/dist/wallet/react/providers/hosted/dynamic/DynamicHostedWalletProvider.d.ts +7 -1
  182. package/dist/wallet/react/providers/hosted/dynamic/DynamicHostedWalletProvider.d.ts.map +1 -1
  183. package/dist/wallet/react/providers/hosted/dynamic/DynamicHostedWalletProvider.js +6 -2
  184. package/dist/wallet/react/providers/hosted/dynamic/DynamicHostedWalletProvider.js.map +1 -1
  185. package/dist/wallet/react/providers/hosted/dynamic/__tests__/DynamicHostedWalletProvider.spec.js +1 -0
  186. package/dist/wallet/react/providers/hosted/dynamic/__tests__/DynamicHostedWalletProvider.spec.js.map +1 -1
  187. package/dist/wallet/react/providers/hosted/privy/PrivyHostedWalletProvider.d.ts +6 -1
  188. package/dist/wallet/react/providers/hosted/privy/PrivyHostedWalletProvider.d.ts.map +1 -1
  189. package/dist/wallet/react/providers/hosted/privy/PrivyHostedWalletProvider.js +5 -2
  190. package/dist/wallet/react/providers/hosted/privy/PrivyHostedWalletProvider.js.map +1 -1
  191. package/dist/wallet/react/providers/hosted/privy/__tests__/PrivyHostedWalletProvider.spec.js +1 -0
  192. package/dist/wallet/react/providers/hosted/privy/__tests__/PrivyHostedWalletProvider.spec.js.map +1 -1
  193. package/dist/wallet/react/providers/hosted/turnkey/TurnkeyHostedWalletProvider.d.ts +6 -3
  194. package/dist/wallet/react/providers/hosted/turnkey/TurnkeyHostedWalletProvider.d.ts.map +1 -1
  195. package/dist/wallet/react/providers/hosted/turnkey/TurnkeyHostedWalletProvider.js +5 -4
  196. package/dist/wallet/react/providers/hosted/turnkey/TurnkeyHostedWalletProvider.js.map +1 -1
  197. package/dist/wallet/react/providers/registry/ReactHostedWalletProviderRegistry.d.ts.map +1 -1
  198. package/dist/wallet/react/providers/registry/ReactHostedWalletProviderRegistry.js +6 -6
  199. package/dist/wallet/react/providers/registry/ReactHostedWalletProviderRegistry.js.map +1 -1
  200. package/dist/wallet/react/wallets/hosted/dynamic/DynamicWallet.d.ts +7 -1
  201. package/dist/wallet/react/wallets/hosted/dynamic/DynamicWallet.d.ts.map +1 -1
  202. package/dist/wallet/react/wallets/hosted/dynamic/DynamicWallet.js +5 -3
  203. package/dist/wallet/react/wallets/hosted/dynamic/DynamicWallet.js.map +1 -1
  204. package/dist/wallet/react/wallets/hosted/privy/PrivyWallet.d.ts +5 -1
  205. package/dist/wallet/react/wallets/hosted/privy/PrivyWallet.d.ts.map +1 -1
  206. package/dist/wallet/react/wallets/hosted/privy/PrivyWallet.js +3 -3
  207. package/dist/wallet/react/wallets/hosted/privy/PrivyWallet.js.map +1 -1
  208. package/dist/wallet/react/wallets/hosted/turnkey/TurnkeyWallet.d.ts +5 -1
  209. package/dist/wallet/react/wallets/hosted/turnkey/TurnkeyWallet.d.ts.map +1 -1
  210. package/dist/wallet/react/wallets/hosted/turnkey/TurnkeyWallet.js +2 -2
  211. package/dist/wallet/react/wallets/hosted/turnkey/TurnkeyWallet.js.map +1 -1
  212. package/package.json +2 -2
  213. package/src/__mocks__/MockAssets.ts +2 -0
  214. package/src/__tests__/actions.test.ts +0 -4
  215. package/src/actions.ts +57 -19
  216. package/src/constants/assets.ts +16 -0
  217. package/src/constants/contracts.ts +5 -0
  218. package/src/index.ts +30 -2
  219. package/src/lend/core/LendProvider.ts +6 -18
  220. package/src/lend/core/__tests__/LendProvider.test.ts +2 -5
  221. package/src/lend/providers/morpho/__tests__/sdk.test.ts +3 -2
  222. package/src/lend/providers/morpho/api.ts +4 -0
  223. package/src/lend/providers/morpho/sdk.ts +10 -1
  224. package/src/supported/tokens.ts +16 -2
  225. package/src/swap/__mocks__/MockSwapProvider.ts +216 -0
  226. package/src/swap/core/SwapProvider.ts +319 -0
  227. package/src/swap/core/__tests__/SwapProvider.test.ts +478 -0
  228. package/src/swap/index.ts +14 -0
  229. package/src/swap/namespaces/ActionsSwapNamespace.ts +7 -0
  230. package/src/swap/namespaces/BaseSwapNamespace.ts +77 -0
  231. package/src/swap/namespaces/WalletSwapNamespace.ts +82 -0
  232. package/src/swap/namespaces/__tests__/BaseSwapNamespace.spec.ts +138 -0
  233. package/src/swap/namespaces/__tests__/WalletSwapNamespace.spec.ts +162 -0
  234. package/src/swap/providers/uniswap/UniswapSwapProvider.ts +304 -0
  235. package/src/swap/providers/uniswap/__tests__/UniswapSwapProvider.test.ts +299 -0
  236. package/src/swap/providers/uniswap/__tests__/sdk.test.ts +370 -0
  237. package/src/swap/providers/uniswap/abis.ts +144 -0
  238. package/src/swap/providers/uniswap/addresses.ts +108 -0
  239. package/src/swap/providers/uniswap/encoding.ts +406 -0
  240. package/src/swap/providers/uniswap/types.ts +24 -0
  241. package/src/types/actions.ts +22 -6
  242. package/src/types/index.ts +2 -0
  243. package/src/types/lend/base.ts +4 -14
  244. package/src/types/swap/base.ts +259 -0
  245. package/src/types/swap/index.ts +1 -0
  246. package/src/types/transaction.ts +14 -0
  247. package/src/utils/assets.test.ts +16 -1
  248. package/src/utils/assets.ts +13 -10
  249. package/src/utils/permit2.test.ts +142 -0
  250. package/src/utils/permit2.ts +144 -0
  251. package/src/utils/validation.ts +76 -0
  252. package/src/wallet/core/providers/hosted/abstract/HostedWalletProvider.ts +9 -1
  253. package/src/wallet/core/providers/hosted/types/index.ts +5 -1
  254. package/src/wallet/core/providers/smart/default/DefaultSmartWalletProvider.ts +13 -1
  255. package/src/wallet/core/providers/smart/default/__tests__/DefaultSmartWalletProvider.spec.ts +2 -0
  256. package/src/wallet/core/wallets/abstract/Wallet.ts +18 -2
  257. package/src/wallet/core/wallets/smart/default/DefaultSmartWallet.ts +14 -5
  258. package/src/wallet/node/providers/hosted/privy/PrivyHostedWalletProvider.ts +13 -2
  259. package/src/wallet/node/providers/hosted/registry/NodeHostedWalletProviderRegistry.ts +10 -2
  260. package/src/wallet/node/providers/hosted/turnkey/TurnkeyHostedWalletProvider.ts +8 -2
  261. package/src/wallet/node/wallets/hosted/privy/PrivyWallet.ts +11 -2
  262. package/src/wallet/node/wallets/hosted/turnkey/TurnkeyWallet.ts +10 -2
  263. package/src/wallet/react/providers/hosted/dynamic/DynamicHostedWalletProvider.ts +10 -2
  264. package/src/wallet/react/providers/hosted/dynamic/__tests__/DynamicHostedWalletProvider.spec.ts +1 -0
  265. package/src/wallet/react/providers/hosted/privy/PrivyHostedWalletProvider.ts +9 -2
  266. package/src/wallet/react/providers/hosted/privy/__tests__/PrivyHostedWalletProvider.spec.ts +1 -0
  267. package/src/wallet/react/providers/hosted/turnkey/TurnkeyHostedWalletProvider.ts +9 -4
  268. package/src/wallet/react/providers/registry/ReactHostedWalletProviderRegistry.ts +18 -6
  269. package/src/wallet/react/wallets/hosted/dynamic/DynamicWallet.ts +12 -2
  270. package/src/wallet/react/wallets/hosted/privy/PrivyWallet.ts +10 -2
  271. package/src/wallet/react/wallets/hosted/turnkey/TurnkeyWallet.ts +10 -2
@@ -21,6 +21,7 @@ import type {
21
21
  TransactionData,
22
22
  } from '@/types/lend/index.js'
23
23
  import { validateMarketAsset } from '@/utils/markets.js'
24
+ import { validateChainSupported } from '@/utils/validation.js'
24
25
 
25
26
  /**
26
27
  * Lending provider abstract class
@@ -77,7 +78,7 @@ export abstract class LendProvider<
77
78
  throw new Error('walletAddress is required')
78
79
  }
79
80
 
80
- this.validateProviderSupported(params.marketId.chainId)
81
+ validateChainSupported(params.marketId.chainId, this.SUPPORTED_CHAIN_IDS)
81
82
  this.validateConfigSupported(params.marketId)
82
83
 
83
84
  // Convert human-readable amount to wei using the asset's decimals
@@ -105,7 +106,7 @@ export abstract class LendProvider<
105
106
  chainId: params.chainId,
106
107
  }
107
108
 
108
- this.validateProviderSupported(params.chainId)
109
+ validateChainSupported(params.chainId, this.SUPPORTED_CHAIN_IDS)
109
110
  this.validateConfigSupported(marketId)
110
111
  return this._getMarket(marketId)
111
112
  }
@@ -117,7 +118,7 @@ export abstract class LendProvider<
117
118
  */
118
119
  async getMarkets(params: GetLendMarketsParams = {}): Promise<LendMarket[]> {
119
120
  if (params.chainId !== undefined)
120
- this.validateProviderSupported(params.chainId)
121
+ validateChainSupported(params.chainId, this.SUPPORTED_CHAIN_IDS)
121
122
 
122
123
  const filteredMarkets = this.filterMarketConfigs(
123
124
  params.chainId,
@@ -156,7 +157,7 @@ export abstract class LendProvider<
156
157
  )
157
158
  }
158
159
 
159
- this.validateProviderSupported(marketId.chainId)
160
+ validateChainSupported(marketId.chainId, this.SUPPORTED_CHAIN_IDS)
160
161
  this.validateConfigSupported(marketId)
161
162
 
162
163
  return this._getPosition({ marketId, walletAddress })
@@ -176,7 +177,7 @@ export abstract class LendProvider<
176
177
  throw new Error('walletAddress is required')
177
178
  }
178
179
 
179
- this.validateProviderSupported(params.marketId.chainId)
180
+ validateChainSupported(params.marketId.chainId, this.SUPPORTED_CHAIN_IDS)
180
181
  this.validateConfigSupported(params.marketId)
181
182
 
182
183
  const market = await this.getMarket({
@@ -217,19 +218,6 @@ export abstract class LendProvider<
217
218
  return this.SUPPORTED_CHAIN_IDS.includes(chainId)
218
219
  }
219
220
 
220
- /**
221
- * Validate that a chainId is supported for lending operations
222
- * @param chainId - Chain ID to validate
223
- * @throws Error if chain is not supported
224
- */
225
- protected validateProviderSupported(chainId: number): void {
226
- if (!this.isChainSupported(chainId)) {
227
- throw new Error(
228
- `Chain ${chainId} is not supported. Supported chains: ${this.SUPPORTED_CHAIN_IDS.join(', ')}`,
229
- )
230
- }
231
- }
232
-
233
221
  /**
234
222
  * Validate that a market is in the config's market allowlist
235
223
  * @param marketId - Market identifier containing address and chainId
@@ -4,13 +4,10 @@ import { describe, expect, it } from 'vitest'
4
4
  import { MockUSDCAsset } from '@/__mocks__/MockAssets.js'
5
5
  import { MockLendProvider } from '@/lend/__mocks__/MockLendProvider.js'
6
6
  import type { LendMarketConfig, LendMarketId } from '@/types/lend/index.js'
7
+ import { validateChainSupported } from '@/utils/validation.js'
7
8
 
8
9
  // Test helper class that exposes protected validation methods as public
9
10
  class TestLendProvider extends MockLendProvider {
10
- public validateProviderSupported(chainId: number): void {
11
- return super.validateProviderSupported(chainId)
12
- }
13
-
14
11
  public validateConfigSupported(marketId: LendMarketId): void {
15
12
  return super.validateConfigSupported(marketId)
16
13
  }
@@ -186,7 +183,7 @@ describe('LendProvider', () => {
186
183
  const provider = new TestLendProvider()
187
184
 
188
185
  expect(() => {
189
- provider.validateProviderSupported(999)
186
+ validateChainSupported(999, provider.supportedChainIds())
190
187
  }).toThrow('Chain 999 is not supported')
191
188
  })
192
189
 
@@ -160,11 +160,12 @@ describe('Vault Utilities', () => {
160
160
  const result = calculateRewardsBreakdown(apiVault)
161
161
 
162
162
  expect(result).toEqual({
163
+ eth: 0,
164
+ weth: 0,
163
165
  usdc: 0,
164
166
  usdc_demo: 0,
167
+ op_demo: 0,
165
168
  morpho: 0,
166
- eth: 0,
167
- weth: 0,
168
169
  other: 0,
169
170
  totalRewards: 0,
170
171
  })
@@ -3,7 +3,11 @@ import type { Address } from 'viem'
3
3
  const MORPHO_API_ENDPOINT = 'https://api.morpho.org/graphql'
4
4
 
5
5
  export interface RewardsBreakdown {
6
+ eth: number
7
+ weth: number
6
8
  usdc: number
9
+ usdc_demo: number
10
+ op_demo: number
7
11
  morpho: number
8
12
  other: number
9
13
  totalRewards: number
@@ -345,7 +345,16 @@ export async function getVault(params: GetVaultParams): Promise<LendMarket> {
345
345
  params.marketId.address,
346
346
  ).catch((error) => {
347
347
  console.error('Failed to fetch rewards data:', error)
348
- return { usdc: 0, morpho: 0, other: 0, totalRewards: 0 }
348
+ return {
349
+ eth: 0,
350
+ weth: 0,
351
+ usdc: 0,
352
+ usdc_demo: 0,
353
+ op_demo: 0,
354
+ morpho: 0,
355
+ other: 0,
356
+ totalRewards: 0,
357
+ }
349
358
  })
350
359
 
351
360
  const apyBreakdown = calculateApyBreakdown(vault, rewardsBreakdown)
@@ -1,10 +1,24 @@
1
1
  import type { Address } from 'viem'
2
2
 
3
- import { ETH, MORPHO, USDC, USDC_DEMO, WETH } from '@/constants/assets.js'
3
+ import {
4
+ ETH,
5
+ MORPHO,
6
+ OP_DEMO,
7
+ USDC,
8
+ USDC_DEMO,
9
+ WETH,
10
+ } from '@/constants/assets.js'
4
11
  import type { SupportedChainId } from '@/constants/supportedChains.js'
5
12
  import type { Asset } from '@/types/asset.js'
6
13
 
7
- export const SUPPORTED_TOKENS: Asset[] = [ETH, WETH, USDC, USDC_DEMO, MORPHO]
14
+ export const SUPPORTED_TOKENS: Asset[] = [
15
+ ETH,
16
+ WETH,
17
+ USDC,
18
+ USDC_DEMO,
19
+ OP_DEMO,
20
+ MORPHO,
21
+ ]
8
22
 
9
23
  /**
10
24
  * Get token by address and chain ID
@@ -0,0 +1,216 @@
1
+ import type { Address } from 'viem'
2
+ import { type MockedFunction, vi } from 'vitest'
3
+
4
+ import type { SupportedChainId } from '@/constants/supportedChains.js'
5
+ import { MockChainManager } from '@/services/__mocks__/MockChainManager.js'
6
+ import type { ChainManager } from '@/services/ChainManager.js'
7
+ import { SwapProvider } from '@/swap/core/SwapProvider.js'
8
+ import type {
9
+ GetSwapMarketParams,
10
+ GetSwapMarketsParams,
11
+ ResolvedSwapParams,
12
+ SwapMarket,
13
+ SwapPrice,
14
+ SwapPriceParams,
15
+ SwapProviderConfig,
16
+ SwapTransaction,
17
+ } from '@/types/swap/index.js'
18
+
19
+ export interface MockSwapProviderConfig {
20
+ supportedChains: SupportedChainId[]
21
+ defaultPrice: string
22
+ defaultPriceImpact: number
23
+ }
24
+
25
+ /**
26
+ * Mock Swap Provider for testing
27
+ */
28
+ export class MockSwapProvider extends SwapProvider<SwapProviderConfig> {
29
+ public mockExecute: MockedFunction<
30
+ (params: ResolvedSwapParams) => Promise<SwapTransaction>
31
+ >
32
+ public mockGetPrice: MockedFunction<
33
+ (params: SwapPriceParams) => Promise<SwapPrice>
34
+ >
35
+ public mockGetMarket: MockedFunction<
36
+ (params: GetSwapMarketParams) => Promise<SwapMarket>
37
+ >
38
+ public mockGetMarkets: MockedFunction<
39
+ (params: GetSwapMarketsParams) => Promise<SwapMarket[]>
40
+ >
41
+
42
+ private _supportedChains: SupportedChainId[]
43
+ private mockProviderConfig: MockSwapProviderConfig
44
+
45
+ constructor(
46
+ config?: SwapProviderConfig,
47
+ mockConfig?: Partial<MockSwapProviderConfig>,
48
+ chainManager?: ChainManager,
49
+ ) {
50
+ super(
51
+ config || {},
52
+ chainManager || (new MockChainManager() as unknown as ChainManager),
53
+ )
54
+
55
+ this._supportedChains = mockConfig?.supportedChains ?? [
56
+ 84532 as SupportedChainId,
57
+ ]
58
+ this.mockProviderConfig = {
59
+ supportedChains: this._supportedChains,
60
+ defaultPrice: mockConfig?.defaultPrice ?? '1.5',
61
+ defaultPriceImpact: mockConfig?.defaultPriceImpact ?? 0.001,
62
+ }
63
+
64
+ // Create mocked functions
65
+ this.mockExecute = vi
66
+ .fn()
67
+ .mockImplementation(this.createMockSwapTransaction.bind(this))
68
+ this.mockGetPrice = vi
69
+ .fn()
70
+ .mockImplementation(this.createMockPrice.bind(this))
71
+ this.mockGetMarket = vi
72
+ .fn()
73
+ .mockImplementation(this.createMockMarket.bind(this))
74
+ this.mockGetMarkets = vi
75
+ .fn()
76
+ .mockImplementation(this.createMockMarkets.bind(this))
77
+ }
78
+
79
+ supportedChainIds(): SupportedChainId[] {
80
+ return this._supportedChains
81
+ }
82
+
83
+ reset(): void {
84
+ vi.clearAllMocks()
85
+ }
86
+
87
+ // Expose protected methods for testing
88
+ public testValidateMarketAllowed(
89
+ assetIn: any,
90
+ assetOut: any,
91
+ chainId: SupportedChainId,
92
+ ): void {
93
+ return this.validateMarketAllowed(assetIn, assetOut, chainId)
94
+ }
95
+
96
+ protected async _execute(
97
+ params: ResolvedSwapParams,
98
+ ): Promise<SwapTransaction> {
99
+ return this.mockExecute(params)
100
+ }
101
+
102
+ protected async _getPrice(params: SwapPriceParams): Promise<SwapPrice> {
103
+ return this.mockGetPrice(params)
104
+ }
105
+
106
+ protected async _getMarket(params: GetSwapMarketParams): Promise<SwapMarket> {
107
+ return this.mockGetMarket(params)
108
+ }
109
+
110
+ protected async _getMarkets(
111
+ params: GetSwapMarketsParams,
112
+ ): Promise<SwapMarket[]> {
113
+ return this.mockGetMarkets(params)
114
+ }
115
+
116
+ private createMockSwapTransaction(
117
+ params: ResolvedSwapParams,
118
+ ): SwapTransaction {
119
+ const amountIn = params.amountInWei ?? 1000000n
120
+ const amountOut = 1500000000000000000n
121
+
122
+ return {
123
+ amountIn: 1.0,
124
+ amountOut: 1.5,
125
+ amountInWei: amountIn,
126
+ amountOutWei: amountOut,
127
+ assetIn: params.assetIn,
128
+ assetOut: params.assetOut,
129
+ price: this.mockProviderConfig.defaultPrice,
130
+ priceImpact: this.mockProviderConfig.defaultPriceImpact,
131
+ transactionData: {
132
+ swap: {
133
+ to: '0x492e6456d9528771018deb9e87ef7750ef184104' as Address,
134
+ data: '0x1234' as `0x${string}`,
135
+ value: 0n,
136
+ },
137
+ },
138
+ }
139
+ }
140
+
141
+ private createMockPrice(params: SwapPriceParams): SwapPrice {
142
+ const amountIn =
143
+ params.amountIn !== undefined
144
+ ? BigInt(
145
+ Math.floor(
146
+ params.amountIn * 10 ** params.assetIn.metadata.decimals,
147
+ ),
148
+ )
149
+ : BigInt(10 ** params.assetIn.metadata.decimals)
150
+
151
+ const amountOut = (amountIn * 15n) / 10n
152
+
153
+ return {
154
+ price: this.mockProviderConfig.defaultPrice,
155
+ priceInverse: '0.666666',
156
+ amountIn: 1.0,
157
+ amountOut: 1.5,
158
+ amountInWei: amountIn,
159
+ amountOutWei: amountOut,
160
+ priceImpact: this.mockProviderConfig.defaultPriceImpact,
161
+ route: {
162
+ path: [params.assetIn, params.assetOut!],
163
+ pools: [
164
+ {
165
+ address: '0x1234' as Address,
166
+ fee: 500,
167
+ version: 'v4',
168
+ },
169
+ ],
170
+ },
171
+ gasEstimate: 150000n,
172
+ }
173
+ }
174
+
175
+ private createMockMarket(params: GetSwapMarketParams): SwapMarket {
176
+ return {
177
+ marketId: {
178
+ poolId: params.poolId,
179
+ chainId: params.chainId,
180
+ },
181
+ assets: [
182
+ {
183
+ type: 'erc20',
184
+ address: { [params.chainId]: '0x1111' as Address },
185
+ metadata: { name: 'USDC', symbol: 'USDC', decimals: 6 },
186
+ },
187
+ {
188
+ type: 'erc20',
189
+ address: { [params.chainId]: '0x2222' as Address },
190
+ metadata: { name: 'WETH', symbol: 'WETH', decimals: 18 },
191
+ },
192
+ ],
193
+ fee: 500,
194
+ provider: 'uniswap',
195
+ }
196
+ }
197
+
198
+ private createMockMarkets(_params: GetSwapMarketsParams): SwapMarket[] {
199
+ return [
200
+ this.createMockMarket({
201
+ poolId: '0xpool1',
202
+ chainId: 84532 as SupportedChainId,
203
+ }),
204
+ ]
205
+ }
206
+ }
207
+
208
+ /**
209
+ * Create a mock swap provider
210
+ */
211
+ export function createMockSwapProvider(
212
+ config?: SwapProviderConfig,
213
+ mockConfig?: Partial<MockSwapProviderConfig>,
214
+ ): MockSwapProvider {
215
+ return new MockSwapProvider(config, mockConfig)
216
+ }
@@ -0,0 +1,319 @@
1
+ import type { Address } from 'viem'
2
+
3
+ import type { SupportedChainId } from '@/constants/supportedChains.js'
4
+ import type { ChainManager } from '@/services/ChainManager.js'
5
+ import type { Asset } from '@/types/asset.js'
6
+ import type {
7
+ GetSwapMarketParams,
8
+ GetSwapMarketsParams,
9
+ ResolvedSwapParams,
10
+ SwapExecuteParams,
11
+ SwapMarket,
12
+ SwapMarketConfig,
13
+ SwapPrice,
14
+ SwapPriceParams,
15
+ SwapProviderConfig,
16
+ SwapTransaction,
17
+ } from '@/types/swap/index.js'
18
+ import type { TransactionData } from '@/types/transaction.js'
19
+ import {
20
+ getAssetAddress,
21
+ isNativeAsset,
22
+ parseAssetAmount,
23
+ } from '@/utils/assets.js'
24
+ import {
25
+ buildPermit2ApprovalTx,
26
+ buildTokenApprovalTx,
27
+ checkPermit2Allowance,
28
+ checkTokenAllowance,
29
+ } from '@/utils/permit2.js'
30
+ import {
31
+ validateAmountPositiveIfExists,
32
+ validateAmountProvided,
33
+ validateAssetOnChain,
34
+ validateChainSupported,
35
+ validateNotBothAmounts,
36
+ validateNotSameAsset,
37
+ validateNotZeroAddress,
38
+ validateSlippage,
39
+ } from '@/utils/validation.js'
40
+
41
+ const DEFAULT_SLIPPAGE = 0.005
42
+ const DEFAULT_DEADLINE_OFFSET = 60
43
+ const DEFAULT_MAX_SLIPPAGE = 0.5
44
+
45
+ /**
46
+ * Abstract base class for swap providers.
47
+ * Public methods handle validation and conversion,
48
+ * protected abstract methods implement provider-specific logic.
49
+ */
50
+ export abstract class SwapProvider<
51
+ TConfig extends SwapProviderConfig = SwapProviderConfig,
52
+ > {
53
+ protected readonly _config: TConfig
54
+ protected readonly chainManager: ChainManager
55
+
56
+ constructor(config: TConfig, chainManager: ChainManager) {
57
+ this._config = config
58
+ this.chainManager = chainManager
59
+ }
60
+
61
+ get config(): TConfig {
62
+ return this._config
63
+ }
64
+
65
+ get defaultSlippage(): number {
66
+ return this._config.defaultSlippage ?? DEFAULT_SLIPPAGE
67
+ }
68
+
69
+ /**
70
+ * Execute a token swap
71
+ * @param params - Swap parameters including assets, amounts, and chain
72
+ * @returns Swap transaction data ready for execution
73
+ */
74
+ async execute(params: SwapExecuteParams): Promise<SwapTransaction> {
75
+ this.executeValidations(params)
76
+ const resolvedParams = this.resolveParams(params)
77
+ validateSlippage(
78
+ resolvedParams.slippage,
79
+ this._config.maxSlippage ?? DEFAULT_MAX_SLIPPAGE,
80
+ )
81
+ return this._execute(resolvedParams)
82
+ }
83
+
84
+ /** Get price quote for a swap */
85
+ async getPrice(params: SwapPriceParams): Promise<SwapPrice> {
86
+ validateChainSupported(params.chainId, this.supportedChainIds())
87
+ return this._getPrice(params)
88
+ }
89
+
90
+ /** Get a specific swap market by ID */
91
+ async getMarket(params: GetSwapMarketParams): Promise<SwapMarket> {
92
+ validateChainSupported(params.chainId, this.supportedChainIds())
93
+ return this._getMarket(params)
94
+ }
95
+
96
+ /** Get available swap markets, optionally filtered by chainId or asset */
97
+ async getMarkets(params: GetSwapMarketsParams = {}): Promise<SwapMarket[]> {
98
+ if (params.chainId) {
99
+ validateChainSupported(params.chainId, this.supportedChainIds())
100
+ }
101
+ return this._getMarkets(params)
102
+ }
103
+
104
+ isChainSupported(chainId: SupportedChainId): boolean {
105
+ return this.supportedChainIds().includes(chainId)
106
+ }
107
+
108
+ // ─────────────────────────────────────────────────────────────────────────────
109
+ // Protected helpers
110
+ // ─────────────────────────────────────────────────────────────────────────────
111
+
112
+ protected validateMarketAllowed(
113
+ assetIn: Asset,
114
+ assetOut: Asset,
115
+ chainId: SupportedChainId,
116
+ ): void {
117
+ const { marketBlocklist, marketAllowlist } = this._config
118
+
119
+ if (marketBlocklist?.length) {
120
+ const isBlocked = this.findMatchingConfig(
121
+ assetIn,
122
+ assetOut,
123
+ chainId,
124
+ marketBlocklist,
125
+ )
126
+ if (isBlocked) {
127
+ throw new Error(
128
+ `Pair ${assetIn.metadata.symbol}/${assetOut.metadata.symbol} is blocked on chain ${chainId}`,
129
+ )
130
+ }
131
+ }
132
+
133
+ if (marketAllowlist?.length) {
134
+ const isAllowed = this.findMatchingConfig(
135
+ assetIn,
136
+ assetOut,
137
+ chainId,
138
+ marketAllowlist,
139
+ )
140
+ if (!isAllowed) {
141
+ throw new Error(
142
+ `Pair ${assetIn.metadata.symbol}/${assetOut.metadata.symbol} is not in the allowlist for chain ${chainId}`,
143
+ )
144
+ }
145
+ }
146
+ }
147
+
148
+ protected resolveMarketConfig(
149
+ assetIn: Asset,
150
+ assetOut: Asset,
151
+ chainId: SupportedChainId,
152
+ ): SwapMarketConfig | undefined {
153
+ const { marketAllowlist } = this._config
154
+ if (!marketAllowlist?.length) {
155
+ throw new Error(
156
+ 'No markets configured. Provide a marketAllowlist in swap provider config.',
157
+ )
158
+ }
159
+ return this.findMatchingConfig(assetIn, assetOut, chainId, marketAllowlist)
160
+ }
161
+
162
+ /**
163
+ * Build Permit2 approval transactions for an ERC20 swap input.
164
+ * Skipped for native assets. Checks both ERC20→Permit2 and Permit2→spender allowances in parallel.
165
+ * @param params - Resolved swap params (wallet address, asset info, chain)
166
+ * @param requiredAmount - Amount in wei that must be approved
167
+ * @param permit2Address - Permit2 contract address
168
+ * @param permit2Spender - The router/contract that Permit2 should approve (e.g. Universal Router)
169
+ * @param permit2ExpirySeconds - Optional custom expiry for the Permit2 approval
170
+ */
171
+ protected async buildPermit2Approvals(
172
+ params: ResolvedSwapParams,
173
+ requiredAmount: bigint,
174
+ permit2Address: Address,
175
+ permit2Spender: Address,
176
+ permit2ExpirySeconds?: number,
177
+ ): Promise<{
178
+ tokenApproval: TransactionData | undefined
179
+ permit2Approval: TransactionData | undefined
180
+ }> {
181
+ if (isNativeAsset(params.assetIn)) {
182
+ return { tokenApproval: undefined, permit2Approval: undefined }
183
+ }
184
+
185
+ const publicClient = this.chainManager.getPublicClient(params.chainId)
186
+ const token = getAssetAddress(params.assetIn, params.chainId)
187
+
188
+ const [tokenAllowance, permit2Allowance] = await Promise.all([
189
+ checkTokenAllowance({
190
+ publicClient,
191
+ token,
192
+ owner: params.walletAddress,
193
+ spender: permit2Address,
194
+ }),
195
+ checkPermit2Allowance({
196
+ publicClient,
197
+ permit2Address,
198
+ owner: params.walletAddress,
199
+ token,
200
+ spender: permit2Spender,
201
+ }),
202
+ ])
203
+
204
+ const tokenApproval =
205
+ tokenAllowance < requiredAmount
206
+ ? buildTokenApprovalTx(token, permit2Address)
207
+ : undefined
208
+
209
+ // Permit2 expiration is in Unix seconds (matching EVM block.timestamp)
210
+ const permit2Expired =
211
+ permit2Allowance.expiration < Math.floor(Date.now() / 1000)
212
+ const permit2Approval =
213
+ permit2Allowance.amount < requiredAmount || permit2Expired
214
+ ? buildPermit2ApprovalTx({
215
+ permit2Address,
216
+ token,
217
+ spender: permit2Spender,
218
+ amount: requiredAmount,
219
+ expirySeconds: permit2ExpirySeconds,
220
+ })
221
+ : undefined
222
+
223
+ return { tokenApproval, permit2Approval }
224
+ }
225
+
226
+ // ─────────────────────────────────────────────────────────────────────────────
227
+ // Private helpers
228
+ // ─────────────────────────────────────────────────────────────────────────────
229
+
230
+ private executeValidations(params: SwapExecuteParams): void {
231
+ validateAmountProvided(params.amountIn, params.amountOut)
232
+ validateAmountPositiveIfExists(params.amountIn)
233
+ validateAmountPositiveIfExists(params.amountOut)
234
+ validateNotBothAmounts(params.amountIn, params.amountOut)
235
+ validateNotSameAsset(params.assetIn, params.assetOut)
236
+ validateNotZeroAddress(params.walletAddress, 'walletAddress')
237
+ if (params.recipient) {
238
+ validateNotZeroAddress(params.recipient, 'recipient')
239
+ }
240
+ validateChainSupported(params.chainId, this.supportedChainIds())
241
+ this.validateMarketAllowed(params.assetIn, params.assetOut, params.chainId)
242
+ validateAssetOnChain(params.assetIn, params.chainId)
243
+ validateAssetOnChain(params.assetOut, params.chainId)
244
+ }
245
+
246
+ private resolveParams(params: SwapExecuteParams): ResolvedSwapParams {
247
+ return {
248
+ amountInWei: parseAssetAmount(params.assetIn, params.amountIn),
249
+ amountOutWei: parseAssetAmount(params.assetOut, params.amountOut),
250
+ assetIn: params.assetIn,
251
+ assetOut: params.assetOut,
252
+ slippage: params.slippage ?? this.defaultSlippage,
253
+ deadline:
254
+ params.deadline ??
255
+ Math.floor(Date.now() / 1000) + DEFAULT_DEADLINE_OFFSET,
256
+ // Send output tokens to specified recipient, or back to the initiating wallet
257
+ recipient: params.recipient ?? params.walletAddress,
258
+ walletAddress: params.walletAddress,
259
+ chainId: params.chainId,
260
+ }
261
+ }
262
+
263
+ private findMatchingConfig(
264
+ assetIn: Asset,
265
+ assetOut: Asset,
266
+ chainId: SupportedChainId,
267
+ list: SwapMarketConfig[],
268
+ ): SwapMarketConfig | undefined {
269
+ const addressIn = assetIn.address[chainId]
270
+ const addressOut = assetOut.address[chainId]
271
+ if (!addressIn || !addressOut) return undefined
272
+
273
+ return list.find((config) => {
274
+ if (config.chainId !== undefined && config.chainId !== chainId)
275
+ return false
276
+ return this.containsPairByAddress(
277
+ addressIn,
278
+ addressOut,
279
+ chainId,
280
+ config.assets,
281
+ )
282
+ })
283
+ }
284
+
285
+ private containsPairByAddress(
286
+ addressIn: string,
287
+ addressOut: string,
288
+ chainId: SupportedChainId,
289
+ assets: Asset[],
290
+ ): boolean {
291
+ const addresses = assets
292
+ .map((a) => a.address[chainId]?.toLowerCase())
293
+ .filter(Boolean)
294
+ return (
295
+ addresses.includes(addressIn.toLowerCase()) &&
296
+ addresses.includes(addressOut.toLowerCase())
297
+ )
298
+ }
299
+
300
+ // ─────────────────────────────────────────────────────────────────────────────
301
+ // Abstract methods (implement in provider)
302
+ // ─────────────────────────────────────────────────────────────────────────────
303
+
304
+ abstract supportedChainIds(): SupportedChainId[]
305
+
306
+ protected abstract _execute(
307
+ params: ResolvedSwapParams,
308
+ ): Promise<SwapTransaction>
309
+
310
+ protected abstract _getPrice(params: SwapPriceParams): Promise<SwapPrice>
311
+
312
+ protected abstract _getMarket(
313
+ params: GetSwapMarketParams,
314
+ ): Promise<SwapMarket>
315
+
316
+ protected abstract _getMarkets(
317
+ params: GetSwapMarketsParams,
318
+ ): Promise<SwapMarket[]>
319
+ }