@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
@@ -0,0 +1,299 @@
1
+ import type { Address, PublicClient } from 'viem'
2
+ import { baseSepolia } from 'viem/chains'
3
+ import { describe, expect, it, vi } from 'vitest'
4
+
5
+ import { MockWETHAsset } from '@/__mocks__/MockAssets.js'
6
+ import type { SupportedChainId } from '@/constants/supportedChains.js'
7
+ import type { ChainManager } from '@/services/ChainManager.js'
8
+ import type { Asset } from '@/types/asset.js'
9
+
10
+ import type { UniswapSwapProviderConfig } from '../types.js'
11
+ import { UniswapSwapProvider } from '../UniswapSwapProvider.js'
12
+
13
+ const CHAIN_ID = baseSepolia.id as SupportedChainId
14
+
15
+ const USDC: Asset = {
16
+ type: 'erc20',
17
+ address: {
18
+ [CHAIN_ID]: '0x1111111111111111111111111111111111111111' as Address,
19
+ },
20
+ metadata: { name: 'USD Coin', symbol: 'USDC', decimals: 6 },
21
+ }
22
+
23
+ const OP: Asset = {
24
+ type: 'erc20',
25
+ address: {
26
+ [CHAIN_ID]: '0x3333333333333333333333333333333333333333' as Address,
27
+ },
28
+ metadata: { name: 'Optimism', symbol: 'OP', decimals: 18 },
29
+ }
30
+
31
+ function createMockChainManager(): ChainManager {
32
+ const mockPublicClient = {
33
+ simulateContract: vi.fn().mockResolvedValue({
34
+ result: [500000000000000000n, 150000n],
35
+ }),
36
+ readContract: vi
37
+ .fn()
38
+ .mockImplementation(
39
+ ({ functionName, args }: { functionName: string; args: unknown[] }) => {
40
+ if (functionName === 'extsload')
41
+ return Promise.resolve(
42
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
43
+ )
44
+ // Permit2 allowance: 3 args (owner, token, spender)
45
+ if (args?.length === 3) return Promise.resolve([0n, 0, 0])
46
+ // ERC20 allowance: 2 args (owner, spender)
47
+ return Promise.resolve(0n)
48
+ },
49
+ ),
50
+ } as unknown as PublicClient
51
+
52
+ return {
53
+ getPublicClient: vi.fn().mockReturnValue(mockPublicClient),
54
+ getSupportedChains: vi.fn().mockReturnValue([CHAIN_ID]),
55
+ } as unknown as ChainManager
56
+ }
57
+
58
+ function createProvider(
59
+ configOverrides?: Partial<UniswapSwapProviderConfig>,
60
+ ): UniswapSwapProvider {
61
+ const config: UniswapSwapProviderConfig = {
62
+ defaultSlippage: 0.005,
63
+ marketAllowlist: [
64
+ { assets: [USDC, OP], fee: 100, tickSpacing: 2, chainId: CHAIN_ID },
65
+ ],
66
+ ...configOverrides,
67
+ }
68
+ return new UniswapSwapProvider(config, createMockChainManager())
69
+ }
70
+
71
+ describe('UniswapSwapProvider', () => {
72
+ describe('supportedChainIds', () => {
73
+ it('returns Base Sepolia', () => {
74
+ const provider = createProvider()
75
+ expect(provider.supportedChainIds()).toContain(CHAIN_ID)
76
+ })
77
+ })
78
+
79
+ describe('execute', () => {
80
+ it('returns swap transaction with approval data', async () => {
81
+ const provider = createProvider()
82
+ const result = await provider.execute({
83
+ amountIn: 100,
84
+ assetIn: USDC,
85
+ assetOut: OP,
86
+ chainId: CHAIN_ID,
87
+ walletAddress: '0xwallet' as Address,
88
+ })
89
+
90
+ expect(result.transactionData.swap).toBeDefined()
91
+ expect(result.transactionData.swap.to).toBeDefined()
92
+ expect(result.transactionData.swap.data).toMatch(/^0x/)
93
+ expect(result.amountIn).toBeDefined()
94
+ expect(result.amountOut).toBeDefined()
95
+ expect(result.price).toBeDefined()
96
+ })
97
+
98
+ it('includes token approval when allowance is insufficient', async () => {
99
+ const provider = createProvider()
100
+ const result = await provider.execute({
101
+ amountIn: 100,
102
+ assetIn: USDC,
103
+ assetOut: OP,
104
+ chainId: CHAIN_ID,
105
+ walletAddress: '0xwallet' as Address,
106
+ })
107
+
108
+ // Mock readContract returns 0n (no allowance), so approvals should be needed
109
+ expect(result.transactionData.tokenApproval).toBeDefined()
110
+ expect(result.transactionData.permit2Approval).toBeDefined()
111
+ })
112
+
113
+ it('throws without fee/tickSpacing in market filter', async () => {
114
+ const provider = createProvider({
115
+ marketAllowlist: [{ assets: [USDC, OP], chainId: CHAIN_ID }],
116
+ })
117
+
118
+ await expect(
119
+ provider.execute({
120
+ amountIn: 100,
121
+ assetIn: USDC,
122
+ assetOut: OP,
123
+ chainId: CHAIN_ID,
124
+ walletAddress: '0xwallet' as Address,
125
+ }),
126
+ ).rejects.toThrow('fee and tickSpacing must be configured')
127
+ })
128
+ })
129
+
130
+ describe('getPrice', () => {
131
+ it('returns price quote', async () => {
132
+ const provider = createProvider()
133
+ const price = await provider.getPrice({
134
+ assetIn: USDC,
135
+ assetOut: OP,
136
+ amountIn: 100,
137
+ chainId: CHAIN_ID,
138
+ })
139
+
140
+ expect(price.price).toBeDefined()
141
+ expect(price.amountIn).toBeDefined()
142
+ expect(price.amountOut).toBeDefined()
143
+ expect(price.route.path).toEqual([USDC, OP])
144
+ })
145
+
146
+ it('defaults to 1 unit when no amount specified', async () => {
147
+ const provider = createProvider()
148
+ const price = await provider.getPrice({
149
+ assetIn: USDC,
150
+ assetOut: OP,
151
+ chainId: CHAIN_ID,
152
+ })
153
+
154
+ // 1 USDC = 1000000 (6 decimals)
155
+ expect(price.amountInWei).toBe(1000000n)
156
+ })
157
+ })
158
+
159
+ describe('getMarkets', () => {
160
+ it('returns markets from allowlist config', async () => {
161
+ const provider = createProvider()
162
+ const markets = await provider.getMarkets({})
163
+ expect(markets).toHaveLength(1)
164
+ expect(markets[0].assets).toEqual([USDC, OP])
165
+ expect(markets[0].fee).toBe(100)
166
+ expect(markets[0].provider).toBe('uniswap')
167
+ expect(markets[0].marketId.poolId).toMatch(/^0x/)
168
+ expect(markets[0].marketId.chainId).toBe(CHAIN_ID)
169
+ })
170
+
171
+ it('returns empty when no allowlist configured', async () => {
172
+ const provider = createProvider({ marketAllowlist: [] })
173
+ const markets = await provider.getMarkets({})
174
+ expect(markets).toEqual([])
175
+ })
176
+
177
+ it('expands multi-asset filter into all pairs', async () => {
178
+ const provider = createProvider({
179
+ marketAllowlist: [
180
+ {
181
+ assets: [USDC, OP, MockWETHAsset],
182
+ fee: 100,
183
+ tickSpacing: 2,
184
+ chainId: CHAIN_ID,
185
+ },
186
+ ],
187
+ })
188
+ const markets = await provider.getMarkets({})
189
+ // 3 assets → 3 pairs: USDC/OP, USDC/WETH, OP/WETH
190
+ expect(markets).toHaveLength(3)
191
+ })
192
+
193
+ it('filters by asset', async () => {
194
+ const provider = createProvider({
195
+ marketAllowlist: [
196
+ {
197
+ assets: [USDC, OP, MockWETHAsset],
198
+ fee: 100,
199
+ tickSpacing: 2,
200
+ chainId: CHAIN_ID,
201
+ },
202
+ ],
203
+ })
204
+ const markets = await provider.getMarkets({ asset: USDC })
205
+ // Only pairs containing USDC: USDC/OP, USDC/WETH
206
+ expect(markets).toHaveLength(2)
207
+ for (const market of markets) {
208
+ expect(market.assets).toContain(USDC)
209
+ }
210
+ })
211
+
212
+ it('skips filters without fee/tickSpacing', async () => {
213
+ const provider = createProvider({
214
+ marketAllowlist: [
215
+ { assets: [USDC, OP], chainId: CHAIN_ID },
216
+ {
217
+ assets: [USDC, MockWETHAsset],
218
+ fee: 500,
219
+ tickSpacing: 10,
220
+ chainId: CHAIN_ID,
221
+ },
222
+ ],
223
+ })
224
+ const markets = await provider.getMarkets({})
225
+ // Only the second filter has fee+tickSpacing
226
+ expect(markets).toHaveLength(1)
227
+ expect(markets[0].assets).toEqual([USDC, MockWETHAsset])
228
+ })
229
+
230
+ it('skips assets without address on target chain', async () => {
231
+ const noChainAsset: Asset = {
232
+ type: 'erc20',
233
+ address: { 1: '0x5555555555555555555555555555555555555555' as Address },
234
+ metadata: { name: 'No Chain', symbol: 'NC', decimals: 18 },
235
+ }
236
+ const provider = createProvider({
237
+ marketAllowlist: [
238
+ {
239
+ assets: [USDC, noChainAsset],
240
+ fee: 100,
241
+ tickSpacing: 2,
242
+ chainId: CHAIN_ID,
243
+ },
244
+ ],
245
+ })
246
+ const markets = await provider.getMarkets({})
247
+ expect(markets).toEqual([])
248
+ })
249
+
250
+ it('produces deterministic poolIds', async () => {
251
+ const provider = createProvider()
252
+ const first = await provider.getMarkets({})
253
+ const second = await provider.getMarkets({})
254
+ expect(first[0].marketId.poolId).toBe(second[0].marketId.poolId)
255
+ })
256
+ })
257
+
258
+ describe('getMarket', () => {
259
+ it('finds market by poolId', async () => {
260
+ const provider = createProvider()
261
+ const markets = await provider.getMarkets({})
262
+ const market = await provider.getMarket({
263
+ poolId: markets[0].marketId.poolId,
264
+ chainId: CHAIN_ID,
265
+ })
266
+ expect(market.fee).toBe(100)
267
+ expect(market.assets).toEqual([USDC, OP])
268
+ })
269
+
270
+ it('throws for unknown poolId', async () => {
271
+ const provider = createProvider()
272
+ await expect(
273
+ provider.getMarket({ poolId: '0xunknown', chainId: CHAIN_ID }),
274
+ ).rejects.toThrow('not found')
275
+ })
276
+
277
+ it('finds correct market in multi-asset filter', async () => {
278
+ const provider = createProvider({
279
+ marketAllowlist: [
280
+ {
281
+ assets: [USDC, OP, MockWETHAsset],
282
+ fee: 100,
283
+ tickSpacing: 2,
284
+ chainId: CHAIN_ID,
285
+ },
286
+ ],
287
+ })
288
+ const markets = await provider.getMarkets({})
289
+ // Look up each market by its poolId
290
+ for (const expected of markets) {
291
+ const found = await provider.getMarket({
292
+ poolId: expected.marketId.poolId,
293
+ chainId: CHAIN_ID,
294
+ })
295
+ expect(found.marketId.poolId).toBe(expected.marketId.poolId)
296
+ }
297
+ })
298
+ })
299
+ })
@@ -0,0 +1,370 @@
1
+ import { type Address, type PublicClient, zeroAddress } from 'viem'
2
+ import { describe, expect, it, vi } from 'vitest'
3
+
4
+ import type { SupportedChainId } from '@/constants/supportedChains.js'
5
+ import type { Asset } from '@/types/asset.js'
6
+
7
+ import {
8
+ calculatePriceImpact,
9
+ encodeUniversalRouterSwap,
10
+ getQuote,
11
+ } from '../encoding.js'
12
+
13
+ const USDC: Asset = {
14
+ type: 'erc20',
15
+ address: { 84532: '0x1111111111111111111111111111111111111111' as Address },
16
+ metadata: { name: 'USD Coin', symbol: 'USDC', decimals: 6 },
17
+ }
18
+
19
+ const WETH: Asset = {
20
+ type: 'erc20',
21
+ address: { 84532: '0x2222222222222222222222222222222222222222' as Address },
22
+ metadata: { name: 'Wrapped Ether', symbol: 'WETH', decimals: 18 },
23
+ }
24
+
25
+ const ETH: Asset = {
26
+ type: 'native',
27
+ address: { 84532: 'native' },
28
+ metadata: { name: 'Ethereum', symbol: 'ETH', decimals: 18 },
29
+ }
30
+
31
+ const QUOTER = '0x4a6513c898fe1b2d0e78d3b0e0a4a151589b1cba' as Address
32
+ const POOL_MANAGER = '0x05E73354cFDd6745C338b50BcFDfA3Aa6fA03408' as Address
33
+ const CHAIN_ID = 84532 as SupportedChainId
34
+ const FEE = 100
35
+ const TICK_SPACING = 2
36
+
37
+ // Mock sqrtPriceX96 for a ~2000 USDC/WETH pool
38
+ // sqrtPriceX96 = sqrt(price) * 2^96, where price = WETH/USDC adjusted for decimals
39
+ // For 1 WETH = 2000 USDC: price(token0→token1) depends on sort order
40
+ const MOCK_SQRT_PRICE =
41
+ '0x0000000000000000000000000000000000000000000000010000000000000000' as `0x${string}`
42
+
43
+ function createMockPublicClient(
44
+ amountResult: bigint,
45
+ gasEstimate = 150000n,
46
+ ): PublicClient {
47
+ return {
48
+ simulateContract: vi.fn().mockResolvedValue({
49
+ result: [amountResult, gasEstimate],
50
+ }),
51
+ readContract: vi.fn().mockResolvedValue(MOCK_SQRT_PRICE),
52
+ } as unknown as PublicClient
53
+ }
54
+
55
+ describe('getQuote', () => {
56
+ it('returns quote for exact-in swap', async () => {
57
+ const publicClient = createMockPublicClient(500000000000000000n) // 0.5 WETH
58
+ const quote = await getQuote({
59
+ assetIn: USDC,
60
+ assetOut: WETH,
61
+ amountInWei: 100000000n, // 100 USDC
62
+ chainId: CHAIN_ID,
63
+ publicClient,
64
+ quoterAddress: QUOTER,
65
+ poolManagerAddress: POOL_MANAGER,
66
+ fee: FEE,
67
+ tickSpacing: TICK_SPACING,
68
+ })
69
+
70
+ expect(quote.amountIn).toBe(100)
71
+ expect(quote.amountOut).toBe(0.5)
72
+ expect(quote.amountInWei).toBe(100000000n)
73
+ expect(quote.amountOutWei).toBe(500000000000000000n)
74
+ expect(quote.price).toBeDefined()
75
+ expect(quote.priceInverse).toBeDefined()
76
+ expect(typeof quote.priceImpact).toBe('number')
77
+ expect(quote.priceImpact).toBeGreaterThanOrEqual(0)
78
+ expect(quote.route.path).toEqual([USDC, WETH])
79
+ expect(quote.route.pools).toHaveLength(1)
80
+ expect(quote.gasEstimate).toBe(150000n)
81
+
82
+ expect(publicClient.simulateContract).toHaveBeenCalledWith(
83
+ expect.objectContaining({
84
+ functionName: 'quoteExactInputSingle',
85
+ }),
86
+ )
87
+ // Should also read sqrtPriceX96 via extsload
88
+ expect(publicClient.readContract).toHaveBeenCalledWith(
89
+ expect.objectContaining({
90
+ address: POOL_MANAGER,
91
+ functionName: 'extsload',
92
+ }),
93
+ )
94
+ })
95
+
96
+ it('returns quote for exact-out swap', async () => {
97
+ const publicClient = createMockPublicClient(100000000n) // 100 USDC needed
98
+ const quote = await getQuote({
99
+ assetIn: USDC,
100
+ assetOut: WETH,
101
+ amountOutWei: 500000000000000000n, // 0.5 WETH
102
+ chainId: CHAIN_ID,
103
+ publicClient,
104
+ quoterAddress: QUOTER,
105
+ poolManagerAddress: POOL_MANAGER,
106
+ fee: FEE,
107
+ tickSpacing: TICK_SPACING,
108
+ })
109
+
110
+ expect(quote.amountInWei).toBe(100000000n)
111
+ expect(quote.amountOutWei).toBe(500000000000000000n)
112
+
113
+ expect(publicClient.simulateContract).toHaveBeenCalledWith(
114
+ expect.objectContaining({
115
+ functionName: 'quoteExactOutputSingle',
116
+ }),
117
+ )
118
+ })
119
+
120
+ it('sorts currency0/currency1 correctly', async () => {
121
+ const publicClient = createMockPublicClient(100000000n)
122
+ await getQuote({
123
+ assetIn: WETH, // higher address
124
+ assetOut: USDC, // lower address
125
+ amountInWei: 1000000000000000000n,
126
+ chainId: CHAIN_ID,
127
+ publicClient,
128
+ quoterAddress: QUOTER,
129
+ poolManagerAddress: POOL_MANAGER,
130
+ fee: FEE,
131
+ tickSpacing: TICK_SPACING,
132
+ })
133
+
134
+ const call = vi.mocked(publicClient.simulateContract).mock.calls[0][0]
135
+ const args = (call as any).args[0]
136
+ // currency0 should be the lower address
137
+ expect(
138
+ args.poolKey.currency0.toLowerCase() <
139
+ args.poolKey.currency1.toLowerCase(),
140
+ ).toBe(true)
141
+ })
142
+
143
+ it('uses address(0) for native ETH in pool key', async () => {
144
+ const publicClient = createMockPublicClient(100000000n)
145
+ await getQuote({
146
+ assetIn: ETH,
147
+ assetOut: USDC,
148
+ amountInWei: 1000000000000000000n,
149
+ chainId: CHAIN_ID,
150
+ publicClient,
151
+ quoterAddress: QUOTER,
152
+ poolManagerAddress: POOL_MANAGER,
153
+ fee: FEE,
154
+ tickSpacing: TICK_SPACING,
155
+ })
156
+
157
+ const call = vi.mocked(publicClient.simulateContract).mock.calls[0][0]
158
+ const args = (call as any).args[0]
159
+ // Native ETH should be address(0), sorted as currency0 (lowest possible address)
160
+ expect(args.poolKey.currency0).toBe(zeroAddress)
161
+ })
162
+
163
+ it('uses address(0) for native ETH as output', async () => {
164
+ const publicClient = createMockPublicClient(1000000000000000000n)
165
+ await getQuote({
166
+ assetIn: USDC,
167
+ assetOut: ETH,
168
+ amountInWei: 100000000n,
169
+ chainId: CHAIN_ID,
170
+ publicClient,
171
+ quoterAddress: QUOTER,
172
+ poolManagerAddress: POOL_MANAGER,
173
+ fee: FEE,
174
+ tickSpacing: TICK_SPACING,
175
+ })
176
+
177
+ const call = vi.mocked(publicClient.simulateContract).mock.calls[0][0]
178
+ const args = (call as any).args[0]
179
+ // Native ETH should be address(0) regardless of swap direction
180
+ expect(args.poolKey.currency0).toBe(zeroAddress)
181
+ })
182
+ })
183
+
184
+ describe('calculatePriceImpact', () => {
185
+ // sqrtPriceX96 for a pool where 1 USDC-wei buys 5e9 WETH-wei
186
+ // (100 USDC → 0.5 WETH at mid-price)
187
+ // Computed as: sqrt(5e9) * 2^96 ≈ 70711 * 2^96
188
+ const MID_SQRT_PRICE = 5602302599546145575577086272208896n
189
+
190
+ it('returns 0 when sqrtPriceX96 is 0', () => {
191
+ const impact = calculatePriceImpact({
192
+ sqrtPriceX96: 0n,
193
+ amountIn: 100000000n,
194
+ amountOut: 500000000000000000n,
195
+ zeroForOne: true,
196
+ })
197
+ expect(impact).toBe(0)
198
+ })
199
+
200
+ it('returns ~0 for a trade at mid-price', () => {
201
+ // 100 USDC → ~0.5 WETH, which matches the mid-price
202
+ const impact = calculatePriceImpact({
203
+ sqrtPriceX96: MID_SQRT_PRICE,
204
+ amountIn: 100000000n,
205
+ amountOut: 500000000000000000n,
206
+ zeroForOne: true,
207
+ })
208
+
209
+ // Very small due to integer sqrt rounding, but near 0
210
+ expect(impact).toBeLessThan(0.001)
211
+ })
212
+
213
+ it('returns positive impact when execution is worse than mid-price', () => {
214
+ // Mid-price says we should get ~0.5 WETH, but we only get 0.4 WETH
215
+ const impact = calculatePriceImpact({
216
+ sqrtPriceX96: MID_SQRT_PRICE,
217
+ amountIn: 100000000n,
218
+ amountOut: 400000000000000000n, // 0.4 WETH instead of ~0.5
219
+ zeroForOne: true,
220
+ })
221
+
222
+ // ~20% price impact
223
+ expect(impact).toBeGreaterThan(0.15)
224
+ expect(impact).toBeLessThan(0.25)
225
+ })
226
+
227
+ it('clamps negative impact to 0', () => {
228
+ // Execution was better than mid-price (got more than expected)
229
+ const impact = calculatePriceImpact({
230
+ sqrtPriceX96: MID_SQRT_PRICE,
231
+ amountIn: 100000000n,
232
+ amountOut: 600000000000000000n, // 0.6 WETH — better than ~0.5 mid
233
+ zeroForOne: true,
234
+ })
235
+
236
+ expect(impact).toBe(0)
237
+ })
238
+
239
+ it('works for oneForZero direction', () => {
240
+ // Selling WETH for USDC (oneForZero)
241
+ // At mid-price: 0.5 WETH should get ~100 USDC-wei worth
242
+ // But we only get 90 USDC → some impact
243
+ const impact = calculatePriceImpact({
244
+ sqrtPriceX96: MID_SQRT_PRICE,
245
+ amountIn: 500000000000000000n, // 0.5 WETH
246
+ amountOut: 90000000n, // 90 USDC (less than ~100)
247
+ zeroForOne: false,
248
+ })
249
+
250
+ expect(impact).toBeGreaterThan(0.05)
251
+ expect(impact).toBeLessThan(0.15)
252
+ })
253
+ })
254
+
255
+ describe('encodeUniversalRouterSwap', () => {
256
+ const baseQuote = {
257
+ price: '0.005',
258
+ priceInverse: '200',
259
+ amountIn: 100,
260
+ amountOut: 0.5,
261
+ amountInWei: 100000000n,
262
+ amountOutWei: 500000000000000000n,
263
+ priceImpact: 0.001,
264
+ route: { path: [USDC, WETH], pools: [] },
265
+ gasEstimate: 150000n,
266
+ }
267
+
268
+ it('encodes exact-in swap calldata', () => {
269
+ const calldata = encodeUniversalRouterSwap({
270
+ amountInWei: 100000000n,
271
+ assetIn: USDC,
272
+ assetOut: WETH,
273
+ slippage: 0.005,
274
+ deadline: 1700000000,
275
+ recipient: '0xrecipient' as Address,
276
+ chainId: CHAIN_ID,
277
+ quote: baseQuote,
278
+ universalRouterAddress: '0xrouter' as Address,
279
+ fee: FEE,
280
+ tickSpacing: TICK_SPACING,
281
+ })
282
+
283
+ expect(calldata).toMatch(/^0x/)
284
+ expect(calldata.length).toBeGreaterThan(10)
285
+ })
286
+
287
+ it('encodes exact-out swap calldata', () => {
288
+ const calldata = encodeUniversalRouterSwap({
289
+ amountOutWei: 500000000000000000n,
290
+ assetIn: USDC,
291
+ assetOut: WETH,
292
+ slippage: 0.005,
293
+ deadline: 1700000000,
294
+ recipient: '0xrecipient' as Address,
295
+ chainId: CHAIN_ID,
296
+ quote: baseQuote,
297
+ universalRouterAddress: '0xrouter' as Address,
298
+ fee: FEE,
299
+ tickSpacing: TICK_SPACING,
300
+ })
301
+
302
+ expect(calldata).toMatch(/^0x/)
303
+ expect(calldata.length).toBeGreaterThan(10)
304
+ })
305
+
306
+ it('produces different calldata for exact-in vs exact-out', () => {
307
+ const exactIn = encodeUniversalRouterSwap({
308
+ amountInWei: 100000000n,
309
+ assetIn: USDC,
310
+ assetOut: WETH,
311
+ slippage: 0.005,
312
+ deadline: 1700000000,
313
+ recipient: '0xrecipient' as Address,
314
+ chainId: CHAIN_ID,
315
+ quote: baseQuote,
316
+ universalRouterAddress: '0xrouter' as Address,
317
+ fee: FEE,
318
+ tickSpacing: TICK_SPACING,
319
+ })
320
+
321
+ const exactOut = encodeUniversalRouterSwap({
322
+ amountOutWei: 500000000000000000n,
323
+ assetIn: USDC,
324
+ assetOut: WETH,
325
+ slippage: 0.005,
326
+ deadline: 1700000000,
327
+ recipient: '0xrecipient' as Address,
328
+ chainId: CHAIN_ID,
329
+ quote: baseQuote,
330
+ universalRouterAddress: '0xrouter' as Address,
331
+ fee: FEE,
332
+ tickSpacing: TICK_SPACING,
333
+ })
334
+
335
+ expect(exactIn).not.toBe(exactOut)
336
+ })
337
+
338
+ it('applies slippage to minimum output for exact-in', () => {
339
+ const noSlippage = encodeUniversalRouterSwap({
340
+ amountInWei: 100000000n,
341
+ assetIn: USDC,
342
+ assetOut: WETH,
343
+ slippage: 0,
344
+ deadline: 1700000000,
345
+ recipient: '0xrecipient' as Address,
346
+ chainId: CHAIN_ID,
347
+ quote: baseQuote,
348
+ universalRouterAddress: '0xrouter' as Address,
349
+ fee: FEE,
350
+ tickSpacing: TICK_SPACING,
351
+ })
352
+
353
+ const withSlippage = encodeUniversalRouterSwap({
354
+ amountInWei: 100000000n,
355
+ assetIn: USDC,
356
+ assetOut: WETH,
357
+ slippage: 0.05, // 5%
358
+ deadline: 1700000000,
359
+ recipient: '0xrecipient' as Address,
360
+ chainId: CHAIN_ID,
361
+ quote: baseQuote,
362
+ universalRouterAddress: '0xrouter' as Address,
363
+ fee: FEE,
364
+ tickSpacing: TICK_SPACING,
365
+ })
366
+
367
+ // Different slippage should produce different calldata
368
+ expect(noSlippage).not.toBe(withSlippage)
369
+ })
370
+ })