@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.
- package/dist/__mocks__/MockAssets.d.ts.map +1 -1
- package/dist/__mocks__/MockAssets.js +2 -0
- package/dist/__mocks__/MockAssets.js.map +1 -1
- package/dist/__tests__/actions.test.js +0 -4
- package/dist/__tests__/actions.test.js.map +1 -1
- package/dist/actions.d.ts +20 -1
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +37 -13
- package/dist/actions.js.map +1 -1
- package/dist/constants/assets.d.ts +4 -0
- package/dist/constants/assets.d.ts.map +1 -1
- package/dist/constants/assets.js +15 -0
- package/dist/constants/assets.js.map +1 -1
- package/dist/constants/contracts.d.ts +4 -0
- package/dist/constants/contracts.d.ts.map +1 -0
- package/dist/constants/contracts.js +3 -0
- package/dist/constants/contracts.js.map +1 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/lend/core/LendProvider.d.ts +0 -6
- package/dist/lend/core/LendProvider.d.ts.map +1 -1
- package/dist/lend/core/LendProvider.js +6 -15
- package/dist/lend/core/LendProvider.js.map +1 -1
- package/dist/lend/core/__tests__/LendProvider.test.js +2 -4
- package/dist/lend/core/__tests__/LendProvider.test.js.map +1 -1
- package/dist/lend/providers/morpho/__tests__/sdk.test.js +3 -2
- package/dist/lend/providers/morpho/__tests__/sdk.test.js.map +1 -1
- package/dist/lend/providers/morpho/api.d.ts +4 -0
- package/dist/lend/providers/morpho/api.d.ts.map +1 -1
- package/dist/lend/providers/morpho/api.js.map +1 -1
- package/dist/lend/providers/morpho/sdk.d.ts.map +1 -1
- package/dist/lend/providers/morpho/sdk.js +10 -1
- package/dist/lend/providers/morpho/sdk.js.map +1 -1
- package/dist/supported/tokens.d.ts.map +1 -1
- package/dist/supported/tokens.js +9 -2
- package/dist/supported/tokens.js.map +1 -1
- package/dist/swap/__mocks__/MockSwapProvider.d.ts +38 -0
- package/dist/swap/__mocks__/MockSwapProvider.d.ts.map +1 -0
- package/dist/swap/__mocks__/MockSwapProvider.js +138 -0
- package/dist/swap/__mocks__/MockSwapProvider.js.map +1 -0
- package/dist/swap/core/SwapProvider.d.ts +56 -0
- package/dist/swap/core/SwapProvider.d.ts.map +1 -0
- package/dist/swap/core/SwapProvider.js +177 -0
- package/dist/swap/core/SwapProvider.js.map +1 -0
- package/dist/swap/core/__tests__/SwapProvider.test.d.ts +2 -0
- package/dist/swap/core/__tests__/SwapProvider.test.d.ts.map +1 -0
- package/dist/swap/core/__tests__/SwapProvider.test.js +329 -0
- package/dist/swap/core/__tests__/SwapProvider.test.js.map +1 -0
- package/dist/swap/index.d.ts +7 -0
- package/dist/swap/index.d.ts.map +1 -0
- package/dist/swap/index.js +8 -0
- package/dist/swap/index.js.map +1 -0
- package/dist/swap/namespaces/ActionsSwapNamespace.d.ts +8 -0
- package/dist/swap/namespaces/ActionsSwapNamespace.d.ts.map +1 -0
- package/dist/swap/namespaces/ActionsSwapNamespace.js +8 -0
- package/dist/swap/namespaces/ActionsSwapNamespace.js.map +1 -0
- package/dist/swap/namespaces/BaseSwapNamespace.d.ts +33 -0
- package/dist/swap/namespaces/BaseSwapNamespace.d.ts.map +1 -0
- package/dist/swap/namespaces/BaseSwapNamespace.js +58 -0
- package/dist/swap/namespaces/BaseSwapNamespace.js.map +1 -0
- package/dist/swap/namespaces/WalletSwapNamespace.d.ts +22 -0
- package/dist/swap/namespaces/WalletSwapNamespace.d.ts.map +1 -0
- package/dist/swap/namespaces/WalletSwapNamespace.js +60 -0
- package/dist/swap/namespaces/WalletSwapNamespace.js.map +1 -0
- package/dist/swap/namespaces/__tests__/BaseSwapNamespace.spec.d.ts +2 -0
- package/dist/swap/namespaces/__tests__/BaseSwapNamespace.spec.d.ts.map +1 -0
- package/dist/swap/namespaces/__tests__/BaseSwapNamespace.spec.js +106 -0
- package/dist/swap/namespaces/__tests__/BaseSwapNamespace.spec.js.map +1 -0
- package/dist/swap/namespaces/__tests__/WalletSwapNamespace.spec.d.ts +2 -0
- package/dist/swap/namespaces/__tests__/WalletSwapNamespace.spec.d.ts.map +1 -0
- package/dist/swap/namespaces/__tests__/WalletSwapNamespace.spec.js +132 -0
- package/dist/swap/namespaces/__tests__/WalletSwapNamespace.spec.js.map +1 -0
- package/dist/swap/providers/uniswap/UniswapSwapProvider.d.ts +68 -0
- package/dist/swap/providers/uniswap/UniswapSwapProvider.d.ts.map +1 -0
- package/dist/swap/providers/uniswap/UniswapSwapProvider.js +206 -0
- package/dist/swap/providers/uniswap/UniswapSwapProvider.js.map +1 -0
- package/dist/swap/providers/uniswap/__tests__/UniswapSwapProvider.test.d.ts +2 -0
- package/dist/swap/providers/uniswap/__tests__/UniswapSwapProvider.test.d.ts.map +1 -0
- package/dist/swap/providers/uniswap/__tests__/UniswapSwapProvider.test.js +257 -0
- package/dist/swap/providers/uniswap/__tests__/UniswapSwapProvider.test.js.map +1 -0
- package/dist/swap/providers/uniswap/__tests__/sdk.test.d.ts +2 -0
- package/dist/swap/providers/uniswap/__tests__/sdk.test.d.ts.map +1 -0
- package/dist/swap/providers/uniswap/__tests__/sdk.test.js +312 -0
- package/dist/swap/providers/uniswap/__tests__/sdk.test.js.map +1 -0
- package/dist/swap/providers/uniswap/abis.d.ts +227 -0
- package/dist/swap/providers/uniswap/abis.d.ts.map +1 -0
- package/dist/swap/providers/uniswap/abis.js +138 -0
- package/dist/swap/providers/uniswap/abis.js.map +1 -0
- package/dist/swap/providers/uniswap/addresses.d.ts +21 -0
- package/dist/swap/providers/uniswap/addresses.d.ts.map +1 -0
- package/dist/swap/providers/uniswap/addresses.js +81 -0
- package/dist/swap/providers/uniswap/addresses.js.map +1 -0
- package/dist/swap/providers/uniswap/encoding.d.ts +77 -0
- package/dist/swap/providers/uniswap/encoding.d.ts.map +1 -0
- package/dist/swap/providers/uniswap/encoding.js +233 -0
- package/dist/swap/providers/uniswap/encoding.js.map +1 -0
- package/dist/swap/providers/uniswap/types.d.ts +20 -0
- package/dist/swap/providers/uniswap/types.d.ts.map +1 -0
- package/dist/swap/providers/uniswap/types.js +2 -0
- package/dist/swap/providers/uniswap/types.js.map +1 -0
- package/dist/types/actions.d.ts +19 -5
- package/dist/types/actions.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/lend/base.d.ts +3 -13
- package/dist/types/lend/base.d.ts.map +1 -1
- package/dist/types/lend/base.js.map +1 -1
- package/dist/types/swap/base.d.ts +238 -0
- package/dist/types/swap/base.d.ts.map +1 -0
- package/dist/types/swap/base.js +4 -0
- package/dist/types/swap/base.js.map +1 -0
- package/dist/types/swap/index.d.ts +2 -0
- package/dist/types/swap/index.d.ts.map +1 -0
- package/dist/types/swap/index.js +2 -0
- package/dist/types/swap/index.js.map +1 -0
- package/dist/types/transaction.d.ts +14 -0
- package/dist/types/transaction.d.ts.map +1 -0
- package/dist/types/transaction.js +2 -0
- package/dist/types/transaction.js.map +1 -0
- package/dist/utils/assets.d.ts +4 -5
- package/dist/utils/assets.d.ts.map +1 -1
- package/dist/utils/assets.js +4 -11
- package/dist/utils/assets.js.map +1 -1
- package/dist/utils/assets.test.js +13 -1
- package/dist/utils/assets.test.js.map +1 -1
- package/dist/utils/permit2.d.ts +46 -0
- package/dist/utils/permit2.d.ts.map +1 -0
- package/dist/utils/permit2.js +100 -0
- package/dist/utils/permit2.js.map +1 -0
- package/dist/utils/permit2.test.d.ts +2 -0
- package/dist/utils/permit2.test.d.ts.map +1 -0
- package/dist/utils/permit2.test.js +110 -0
- package/dist/utils/permit2.test.js.map +1 -0
- package/dist/utils/validation.d.ts +12 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +44 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/wallet/core/providers/hosted/abstract/HostedWalletProvider.d.ts +7 -1
- package/dist/wallet/core/providers/hosted/abstract/HostedWalletProvider.d.ts.map +1 -1
- package/dist/wallet/core/providers/hosted/abstract/HostedWalletProvider.js +2 -1
- package/dist/wallet/core/providers/hosted/abstract/HostedWalletProvider.js.map +1 -1
- package/dist/wallet/core/providers/hosted/types/index.d.ts +5 -1
- package/dist/wallet/core/providers/hosted/types/index.d.ts.map +1 -1
- package/dist/wallet/core/providers/smart/default/DefaultSmartWalletProvider.d.ts +7 -1
- package/dist/wallet/core/providers/smart/default/DefaultSmartWalletProvider.d.ts.map +1 -1
- package/dist/wallet/core/providers/smart/default/DefaultSmartWalletProvider.js +5 -1
- package/dist/wallet/core/providers/smart/default/DefaultSmartWalletProvider.js.map +1 -1
- package/dist/wallet/core/providers/smart/default/__tests__/DefaultSmartWalletProvider.spec.js +2 -2
- package/dist/wallet/core/providers/smart/default/__tests__/DefaultSmartWalletProvider.spec.js.map +1 -1
- package/dist/wallet/core/wallets/abstract/Wallet.d.ts +13 -2
- package/dist/wallet/core/wallets/abstract/Wallet.d.ts.map +1 -1
- package/dist/wallet/core/wallets/abstract/Wallet.js +7 -1
- package/dist/wallet/core/wallets/abstract/Wallet.js.map +1 -1
- package/dist/wallet/core/wallets/smart/default/DefaultSmartWallet.d.ts +7 -2
- package/dist/wallet/core/wallets/smart/default/DefaultSmartWallet.d.ts.map +1 -1
- package/dist/wallet/core/wallets/smart/default/DefaultSmartWallet.js +6 -5
- package/dist/wallet/core/wallets/smart/default/DefaultSmartWallet.js.map +1 -1
- package/dist/wallet/node/providers/hosted/privy/PrivyHostedWalletProvider.d.ts +6 -1
- package/dist/wallet/node/providers/hosted/privy/PrivyHostedWalletProvider.d.ts.map +1 -1
- package/dist/wallet/node/providers/hosted/privy/PrivyHostedWalletProvider.js +3 -1
- package/dist/wallet/node/providers/hosted/privy/PrivyHostedWalletProvider.js.map +1 -1
- package/dist/wallet/node/providers/hosted/registry/NodeHostedWalletProviderRegistry.d.ts.map +1 -1
- package/dist/wallet/node/providers/hosted/registry/NodeHostedWalletProviderRegistry.js +4 -3
- package/dist/wallet/node/providers/hosted/registry/NodeHostedWalletProviderRegistry.js.map +1 -1
- package/dist/wallet/node/providers/hosted/turnkey/TurnkeyHostedWalletProvider.d.ts +5 -1
- package/dist/wallet/node/providers/hosted/turnkey/TurnkeyHostedWalletProvider.d.ts.map +1 -1
- package/dist/wallet/node/providers/hosted/turnkey/TurnkeyHostedWalletProvider.js +4 -2
- package/dist/wallet/node/providers/hosted/turnkey/TurnkeyHostedWalletProvider.js.map +1 -1
- package/dist/wallet/node/wallets/hosted/privy/PrivyWallet.d.ts +6 -1
- package/dist/wallet/node/wallets/hosted/privy/PrivyWallet.d.ts.map +1 -1
- package/dist/wallet/node/wallets/hosted/privy/PrivyWallet.js +4 -3
- package/dist/wallet/node/wallets/hosted/privy/PrivyWallet.js.map +1 -1
- package/dist/wallet/node/wallets/hosted/turnkey/TurnkeyWallet.d.ts +5 -1
- package/dist/wallet/node/wallets/hosted/turnkey/TurnkeyWallet.d.ts.map +1 -1
- package/dist/wallet/node/wallets/hosted/turnkey/TurnkeyWallet.js +2 -2
- package/dist/wallet/node/wallets/hosted/turnkey/TurnkeyWallet.js.map +1 -1
- package/dist/wallet/react/providers/hosted/dynamic/DynamicHostedWalletProvider.d.ts +7 -1
- package/dist/wallet/react/providers/hosted/dynamic/DynamicHostedWalletProvider.d.ts.map +1 -1
- package/dist/wallet/react/providers/hosted/dynamic/DynamicHostedWalletProvider.js +6 -2
- package/dist/wallet/react/providers/hosted/dynamic/DynamicHostedWalletProvider.js.map +1 -1
- package/dist/wallet/react/providers/hosted/dynamic/__tests__/DynamicHostedWalletProvider.spec.js +1 -0
- package/dist/wallet/react/providers/hosted/dynamic/__tests__/DynamicHostedWalletProvider.spec.js.map +1 -1
- package/dist/wallet/react/providers/hosted/privy/PrivyHostedWalletProvider.d.ts +6 -1
- package/dist/wallet/react/providers/hosted/privy/PrivyHostedWalletProvider.d.ts.map +1 -1
- package/dist/wallet/react/providers/hosted/privy/PrivyHostedWalletProvider.js +5 -2
- package/dist/wallet/react/providers/hosted/privy/PrivyHostedWalletProvider.js.map +1 -1
- package/dist/wallet/react/providers/hosted/privy/__tests__/PrivyHostedWalletProvider.spec.js +1 -0
- package/dist/wallet/react/providers/hosted/privy/__tests__/PrivyHostedWalletProvider.spec.js.map +1 -1
- package/dist/wallet/react/providers/hosted/turnkey/TurnkeyHostedWalletProvider.d.ts +6 -3
- package/dist/wallet/react/providers/hosted/turnkey/TurnkeyHostedWalletProvider.d.ts.map +1 -1
- package/dist/wallet/react/providers/hosted/turnkey/TurnkeyHostedWalletProvider.js +5 -4
- package/dist/wallet/react/providers/hosted/turnkey/TurnkeyHostedWalletProvider.js.map +1 -1
- package/dist/wallet/react/providers/registry/ReactHostedWalletProviderRegistry.d.ts.map +1 -1
- package/dist/wallet/react/providers/registry/ReactHostedWalletProviderRegistry.js +6 -6
- package/dist/wallet/react/providers/registry/ReactHostedWalletProviderRegistry.js.map +1 -1
- package/dist/wallet/react/wallets/hosted/dynamic/DynamicWallet.d.ts +7 -1
- package/dist/wallet/react/wallets/hosted/dynamic/DynamicWallet.d.ts.map +1 -1
- package/dist/wallet/react/wallets/hosted/dynamic/DynamicWallet.js +5 -3
- package/dist/wallet/react/wallets/hosted/dynamic/DynamicWallet.js.map +1 -1
- package/dist/wallet/react/wallets/hosted/privy/PrivyWallet.d.ts +5 -1
- package/dist/wallet/react/wallets/hosted/privy/PrivyWallet.d.ts.map +1 -1
- package/dist/wallet/react/wallets/hosted/privy/PrivyWallet.js +3 -3
- package/dist/wallet/react/wallets/hosted/privy/PrivyWallet.js.map +1 -1
- package/dist/wallet/react/wallets/hosted/turnkey/TurnkeyWallet.d.ts +5 -1
- package/dist/wallet/react/wallets/hosted/turnkey/TurnkeyWallet.d.ts.map +1 -1
- package/dist/wallet/react/wallets/hosted/turnkey/TurnkeyWallet.js +2 -2
- package/dist/wallet/react/wallets/hosted/turnkey/TurnkeyWallet.js.map +1 -1
- package/package.json +2 -2
- package/src/__mocks__/MockAssets.ts +2 -0
- package/src/__tests__/actions.test.ts +0 -4
- package/src/actions.ts +57 -19
- package/src/constants/assets.ts +16 -0
- package/src/constants/contracts.ts +5 -0
- package/src/index.ts +30 -2
- package/src/lend/core/LendProvider.ts +6 -18
- package/src/lend/core/__tests__/LendProvider.test.ts +2 -5
- package/src/lend/providers/morpho/__tests__/sdk.test.ts +3 -2
- package/src/lend/providers/morpho/api.ts +4 -0
- package/src/lend/providers/morpho/sdk.ts +10 -1
- package/src/supported/tokens.ts +16 -2
- package/src/swap/__mocks__/MockSwapProvider.ts +216 -0
- package/src/swap/core/SwapProvider.ts +319 -0
- package/src/swap/core/__tests__/SwapProvider.test.ts +478 -0
- package/src/swap/index.ts +14 -0
- package/src/swap/namespaces/ActionsSwapNamespace.ts +7 -0
- package/src/swap/namespaces/BaseSwapNamespace.ts +77 -0
- package/src/swap/namespaces/WalletSwapNamespace.ts +82 -0
- package/src/swap/namespaces/__tests__/BaseSwapNamespace.spec.ts +138 -0
- package/src/swap/namespaces/__tests__/WalletSwapNamespace.spec.ts +162 -0
- package/src/swap/providers/uniswap/UniswapSwapProvider.ts +304 -0
- package/src/swap/providers/uniswap/__tests__/UniswapSwapProvider.test.ts +299 -0
- package/src/swap/providers/uniswap/__tests__/sdk.test.ts +370 -0
- package/src/swap/providers/uniswap/abis.ts +144 -0
- package/src/swap/providers/uniswap/addresses.ts +108 -0
- package/src/swap/providers/uniswap/encoding.ts +406 -0
- package/src/swap/providers/uniswap/types.ts +24 -0
- package/src/types/actions.ts +22 -6
- package/src/types/index.ts +2 -0
- package/src/types/lend/base.ts +4 -14
- package/src/types/swap/base.ts +259 -0
- package/src/types/swap/index.ts +1 -0
- package/src/types/transaction.ts +14 -0
- package/src/utils/assets.test.ts +16 -1
- package/src/utils/assets.ts +13 -10
- package/src/utils/permit2.test.ts +142 -0
- package/src/utils/permit2.ts +144 -0
- package/src/utils/validation.ts +76 -0
- package/src/wallet/core/providers/hosted/abstract/HostedWalletProvider.ts +9 -1
- package/src/wallet/core/providers/hosted/types/index.ts +5 -1
- package/src/wallet/core/providers/smart/default/DefaultSmartWalletProvider.ts +13 -1
- package/src/wallet/core/providers/smart/default/__tests__/DefaultSmartWalletProvider.spec.ts +2 -0
- package/src/wallet/core/wallets/abstract/Wallet.ts +18 -2
- package/src/wallet/core/wallets/smart/default/DefaultSmartWallet.ts +14 -5
- package/src/wallet/node/providers/hosted/privy/PrivyHostedWalletProvider.ts +13 -2
- package/src/wallet/node/providers/hosted/registry/NodeHostedWalletProviderRegistry.ts +10 -2
- package/src/wallet/node/providers/hosted/turnkey/TurnkeyHostedWalletProvider.ts +8 -2
- package/src/wallet/node/wallets/hosted/privy/PrivyWallet.ts +11 -2
- package/src/wallet/node/wallets/hosted/turnkey/TurnkeyWallet.ts +10 -2
- package/src/wallet/react/providers/hosted/dynamic/DynamicHostedWalletProvider.ts +10 -2
- package/src/wallet/react/providers/hosted/dynamic/__tests__/DynamicHostedWalletProvider.spec.ts +1 -0
- package/src/wallet/react/providers/hosted/privy/PrivyHostedWalletProvider.ts +9 -2
- package/src/wallet/react/providers/hosted/privy/__tests__/PrivyHostedWalletProvider.spec.ts +1 -0
- package/src/wallet/react/providers/hosted/turnkey/TurnkeyHostedWalletProvider.ts +9 -4
- package/src/wallet/react/providers/registry/ReactHostedWalletProviderRegistry.ts +18 -6
- package/src/wallet/react/wallets/hosted/dynamic/DynamicWallet.ts +12 -2
- package/src/wallet/react/wallets/hosted/privy/PrivyWallet.ts +10 -2
- package/src/wallet/react/wallets/hosted/turnkey/TurnkeyWallet.ts +10 -2
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
import type { Address } from 'viem'
|
|
2
|
+
import { describe, expect, it } from 'vitest'
|
|
3
|
+
|
|
4
|
+
import type { SupportedChainId } from '@/constants/supportedChains.js'
|
|
5
|
+
import { MockSwapProvider } from '@/swap/__mocks__/MockSwapProvider.js'
|
|
6
|
+
import type { Asset } from '@/types/asset.js'
|
|
7
|
+
import type { SwapMarketConfig } from '@/types/swap/index.js'
|
|
8
|
+
|
|
9
|
+
// Test assets
|
|
10
|
+
const MockUSDC: Asset = {
|
|
11
|
+
type: 'erc20',
|
|
12
|
+
address: { 84532: '0x1111111111111111111111111111111111111111' as Address },
|
|
13
|
+
metadata: { name: 'USD Coin', symbol: 'USDC', decimals: 6 },
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const MockWETH: Asset = {
|
|
17
|
+
type: 'erc20',
|
|
18
|
+
address: { 84532: '0x2222222222222222222222222222222222222222' as Address },
|
|
19
|
+
metadata: { name: 'Wrapped Ether', symbol: 'WETH', decimals: 18 },
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const MockOP: Asset = {
|
|
23
|
+
type: 'erc20',
|
|
24
|
+
address: { 84532: '0x3333333333333333333333333333333333333333' as Address },
|
|
25
|
+
metadata: { name: 'Optimism', symbol: 'OP', decimals: 18 },
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
describe('SwapProvider', () => {
|
|
29
|
+
describe('constructor and configuration', () => {
|
|
30
|
+
it('should initialize with default config', () => {
|
|
31
|
+
const provider = new MockSwapProvider()
|
|
32
|
+
expect(provider).toBeDefined()
|
|
33
|
+
expect(provider.supportedChainIds()).toContain(84532)
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it('should use default slippage when not configured', () => {
|
|
37
|
+
const provider = new MockSwapProvider()
|
|
38
|
+
expect(provider.defaultSlippage).toBe(0.005)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it('should use config slippage when provided', () => {
|
|
42
|
+
const provider = new MockSwapProvider({ defaultSlippage: 0.01 })
|
|
43
|
+
expect(provider.defaultSlippage).toBe(0.01)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it('should store market allowlist when provided', () => {
|
|
47
|
+
const config: SwapMarketConfig = {
|
|
48
|
+
assets: [MockUSDC, MockWETH],
|
|
49
|
+
chainId: 84532 as SupportedChainId,
|
|
50
|
+
}
|
|
51
|
+
const provider = new MockSwapProvider({ marketAllowlist: [config] })
|
|
52
|
+
expect(provider.config.marketAllowlist).toEqual([config])
|
|
53
|
+
})
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
describe('execute()', () => {
|
|
57
|
+
it('should throw if neither amountIn nor amountOut provided', async () => {
|
|
58
|
+
const provider = new MockSwapProvider()
|
|
59
|
+
await expect(
|
|
60
|
+
provider.execute({
|
|
61
|
+
assetIn: MockUSDC,
|
|
62
|
+
assetOut: MockWETH,
|
|
63
|
+
chainId: 84532 as SupportedChainId,
|
|
64
|
+
walletAddress: '0x1234' as Address,
|
|
65
|
+
}),
|
|
66
|
+
).rejects.toThrow('Either amountIn or amountOut must be provided')
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
it('should throw if chain not supported', async () => {
|
|
70
|
+
const provider = new MockSwapProvider()
|
|
71
|
+
await expect(
|
|
72
|
+
provider.execute({
|
|
73
|
+
amountIn: 100,
|
|
74
|
+
assetIn: MockUSDC,
|
|
75
|
+
assetOut: MockWETH,
|
|
76
|
+
chainId: 999 as SupportedChainId,
|
|
77
|
+
walletAddress: '0x1234' as Address,
|
|
78
|
+
}),
|
|
79
|
+
).rejects.toThrow('Chain 999 is not supported')
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it('should throw if asset not supported on chain', async () => {
|
|
83
|
+
const unsupportedAsset: Asset = {
|
|
84
|
+
type: 'erc20',
|
|
85
|
+
address: { 1: '0x1111' as Address }, // Only on mainnet
|
|
86
|
+
metadata: { name: 'Test', symbol: 'TEST', decimals: 18 },
|
|
87
|
+
}
|
|
88
|
+
const provider = new MockSwapProvider()
|
|
89
|
+
await expect(
|
|
90
|
+
provider.execute({
|
|
91
|
+
amountIn: 100,
|
|
92
|
+
assetIn: unsupportedAsset,
|
|
93
|
+
assetOut: MockWETH,
|
|
94
|
+
chainId: 84532 as SupportedChainId,
|
|
95
|
+
walletAddress: '0x1234' as Address,
|
|
96
|
+
}),
|
|
97
|
+
).rejects.toThrow('not supported on chain')
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
it('should use param slippage over config default', async () => {
|
|
101
|
+
const provider = new MockSwapProvider({ defaultSlippage: 0.01 })
|
|
102
|
+
const result = await provider.execute({
|
|
103
|
+
amountIn: 100,
|
|
104
|
+
assetIn: MockUSDC,
|
|
105
|
+
assetOut: MockWETH,
|
|
106
|
+
chainId: 84532 as SupportedChainId,
|
|
107
|
+
walletAddress: '0x1234' as Address,
|
|
108
|
+
slippage: 0.02,
|
|
109
|
+
})
|
|
110
|
+
expect(result).toBeDefined()
|
|
111
|
+
// Slippage is passed to internal params
|
|
112
|
+
expect(provider.mockExecute).toHaveBeenCalledWith(
|
|
113
|
+
expect.objectContaining({ slippage: 0.02 }),
|
|
114
|
+
)
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
it('should use default deadline when not specified', async () => {
|
|
118
|
+
const provider = new MockSwapProvider()
|
|
119
|
+
const beforeTime = Math.floor(Date.now() / 1000)
|
|
120
|
+
await provider.execute({
|
|
121
|
+
amountIn: 100,
|
|
122
|
+
assetIn: MockUSDC,
|
|
123
|
+
assetOut: MockWETH,
|
|
124
|
+
chainId: 84532 as SupportedChainId,
|
|
125
|
+
walletAddress: '0x1234' as Address,
|
|
126
|
+
})
|
|
127
|
+
const afterTime = Math.floor(Date.now() / 1000) + 60
|
|
128
|
+
|
|
129
|
+
expect(provider.mockExecute).toHaveBeenCalledWith(
|
|
130
|
+
expect.objectContaining({
|
|
131
|
+
deadline: expect.any(Number),
|
|
132
|
+
}),
|
|
133
|
+
)
|
|
134
|
+
const call = provider.mockExecute.mock.calls[0][0]
|
|
135
|
+
expect(call.deadline).toBeGreaterThanOrEqual(beforeTime + 60)
|
|
136
|
+
expect(call.deadline).toBeLessThanOrEqual(afterTime)
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
it('should convert human-readable amounts to wei', async () => {
|
|
140
|
+
const provider = new MockSwapProvider()
|
|
141
|
+
await provider.execute({
|
|
142
|
+
amountIn: 100,
|
|
143
|
+
assetIn: MockUSDC, // 6 decimals
|
|
144
|
+
assetOut: MockWETH,
|
|
145
|
+
chainId: 84532 as SupportedChainId,
|
|
146
|
+
walletAddress: '0x1234' as Address,
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
expect(provider.mockExecute).toHaveBeenCalledWith(
|
|
150
|
+
expect.objectContaining({
|
|
151
|
+
amountInWei: 100000000n, // 100 * 10^6
|
|
152
|
+
}),
|
|
153
|
+
)
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
it('should return swap transaction', async () => {
|
|
157
|
+
const provider = new MockSwapProvider()
|
|
158
|
+
const result = await provider.execute({
|
|
159
|
+
amountIn: 100,
|
|
160
|
+
assetIn: MockUSDC,
|
|
161
|
+
assetOut: MockWETH,
|
|
162
|
+
chainId: 84532 as SupportedChainId,
|
|
163
|
+
walletAddress: '0x1234' as Address,
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
expect(result.amountIn).toBeDefined()
|
|
167
|
+
expect(result.amountOut).toBeDefined()
|
|
168
|
+
expect(result.transactionData.swap).toBeDefined()
|
|
169
|
+
})
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
describe('getPrice()', () => {
|
|
173
|
+
it('should throw if chain not supported', async () => {
|
|
174
|
+
const provider = new MockSwapProvider()
|
|
175
|
+
await expect(
|
|
176
|
+
provider.getPrice({
|
|
177
|
+
assetIn: MockUSDC,
|
|
178
|
+
assetOut: MockWETH,
|
|
179
|
+
chainId: 999 as SupportedChainId,
|
|
180
|
+
}),
|
|
181
|
+
).rejects.toThrow('Chain 999 is not supported')
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
it('should return price quote', async () => {
|
|
185
|
+
const provider = new MockSwapProvider()
|
|
186
|
+
const price = await provider.getPrice({
|
|
187
|
+
assetIn: MockUSDC,
|
|
188
|
+
assetOut: MockWETH,
|
|
189
|
+
amountIn: 100,
|
|
190
|
+
chainId: 84532 as SupportedChainId,
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
expect(price.price).toBeDefined()
|
|
194
|
+
expect(price.amountIn).toBeDefined()
|
|
195
|
+
expect(price.amountOut).toBeDefined()
|
|
196
|
+
expect(price.route).toBeDefined()
|
|
197
|
+
})
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
describe('getMarket()', () => {
|
|
201
|
+
it('should throw if chain not supported', async () => {
|
|
202
|
+
const provider = new MockSwapProvider()
|
|
203
|
+
await expect(
|
|
204
|
+
provider.getMarket({
|
|
205
|
+
poolId: '0xpool1',
|
|
206
|
+
chainId: 999 as SupportedChainId,
|
|
207
|
+
}),
|
|
208
|
+
).rejects.toThrow('Chain 999 is not supported')
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
it('should return market info', async () => {
|
|
212
|
+
const provider = new MockSwapProvider()
|
|
213
|
+
const market = await provider.getMarket({
|
|
214
|
+
poolId: '0xpool1',
|
|
215
|
+
chainId: 84532 as SupportedChainId,
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
expect(market.marketId.poolId).toBe('0xpool1')
|
|
219
|
+
expect(market.assets).toHaveLength(2)
|
|
220
|
+
expect(market.provider).toBe('uniswap')
|
|
221
|
+
})
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
describe('getMarkets()', () => {
|
|
225
|
+
it('should return markets array', async () => {
|
|
226
|
+
const provider = new MockSwapProvider()
|
|
227
|
+
const markets = await provider.getMarkets()
|
|
228
|
+
|
|
229
|
+
expect(Array.isArray(markets)).toBe(true)
|
|
230
|
+
expect(markets.length).toBeGreaterThan(0)
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
it('should validate chainId if provided', async () => {
|
|
234
|
+
const provider = new MockSwapProvider()
|
|
235
|
+
await expect(
|
|
236
|
+
provider.getMarkets({ chainId: 999 as SupportedChainId }),
|
|
237
|
+
).rejects.toThrow('Chain 999 is not supported')
|
|
238
|
+
})
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
describe('supportedChainIds()', () => {
|
|
242
|
+
it('should return array of supported chain IDs', () => {
|
|
243
|
+
const provider = new MockSwapProvider()
|
|
244
|
+
const chainIds = provider.supportedChainIds()
|
|
245
|
+
|
|
246
|
+
expect(Array.isArray(chainIds)).toBe(true)
|
|
247
|
+
expect(chainIds).toContain(84532)
|
|
248
|
+
})
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
describe('isChainSupported()', () => {
|
|
252
|
+
it('should return true for supported chain', () => {
|
|
253
|
+
const provider = new MockSwapProvider()
|
|
254
|
+
expect(provider.isChainSupported(84532 as SupportedChainId)).toBe(true)
|
|
255
|
+
})
|
|
256
|
+
|
|
257
|
+
it('should return false for unsupported chain', () => {
|
|
258
|
+
const provider = new MockSwapProvider()
|
|
259
|
+
expect(provider.isChainSupported(999 as SupportedChainId)).toBe(false)
|
|
260
|
+
})
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
describe('validateMarketAllowed()', () => {
|
|
264
|
+
it('should allow any pair when no allowlist configured', () => {
|
|
265
|
+
const provider = new MockSwapProvider()
|
|
266
|
+
expect(() =>
|
|
267
|
+
provider.testValidateMarketAllowed(
|
|
268
|
+
MockUSDC,
|
|
269
|
+
MockWETH,
|
|
270
|
+
84532 as SupportedChainId,
|
|
271
|
+
),
|
|
272
|
+
).not.toThrow()
|
|
273
|
+
})
|
|
274
|
+
|
|
275
|
+
it('should allow pairs in allowlist', () => {
|
|
276
|
+
const config: SwapMarketConfig = {
|
|
277
|
+
assets: [MockUSDC, MockWETH],
|
|
278
|
+
chainId: 84532 as SupportedChainId,
|
|
279
|
+
}
|
|
280
|
+
const provider = new MockSwapProvider({ marketAllowlist: [config] })
|
|
281
|
+
expect(() =>
|
|
282
|
+
provider.testValidateMarketAllowed(
|
|
283
|
+
MockUSDC,
|
|
284
|
+
MockWETH,
|
|
285
|
+
84532 as SupportedChainId,
|
|
286
|
+
),
|
|
287
|
+
).not.toThrow()
|
|
288
|
+
})
|
|
289
|
+
|
|
290
|
+
it('should reject pairs not in allowlist', () => {
|
|
291
|
+
const config: SwapMarketConfig = {
|
|
292
|
+
assets: [MockUSDC, MockWETH],
|
|
293
|
+
chainId: 84532 as SupportedChainId,
|
|
294
|
+
}
|
|
295
|
+
const provider = new MockSwapProvider({ marketAllowlist: [config] })
|
|
296
|
+
expect(() =>
|
|
297
|
+
provider.testValidateMarketAllowed(
|
|
298
|
+
MockUSDC,
|
|
299
|
+
MockOP,
|
|
300
|
+
84532 as SupportedChainId,
|
|
301
|
+
),
|
|
302
|
+
).toThrow('not in the allowlist')
|
|
303
|
+
})
|
|
304
|
+
|
|
305
|
+
it('should match pairs regardless of order', () => {
|
|
306
|
+
const config: SwapMarketConfig = {
|
|
307
|
+
assets: [MockUSDC, MockWETH],
|
|
308
|
+
chainId: 84532 as SupportedChainId,
|
|
309
|
+
}
|
|
310
|
+
const provider = new MockSwapProvider({ marketAllowlist: [config] })
|
|
311
|
+
// Reversed order should still match
|
|
312
|
+
expect(() =>
|
|
313
|
+
provider.testValidateMarketAllowed(
|
|
314
|
+
MockWETH,
|
|
315
|
+
MockUSDC,
|
|
316
|
+
84532 as SupportedChainId,
|
|
317
|
+
),
|
|
318
|
+
).not.toThrow()
|
|
319
|
+
})
|
|
320
|
+
|
|
321
|
+
it('should reject blocklisted pairs', () => {
|
|
322
|
+
const config: SwapMarketConfig = {
|
|
323
|
+
assets: [MockUSDC, MockOP],
|
|
324
|
+
chainId: 84532 as SupportedChainId,
|
|
325
|
+
}
|
|
326
|
+
const provider = new MockSwapProvider({ marketBlocklist: [config] })
|
|
327
|
+
expect(() =>
|
|
328
|
+
provider.testValidateMarketAllowed(
|
|
329
|
+
MockUSDC,
|
|
330
|
+
MockOP,
|
|
331
|
+
84532 as SupportedChainId,
|
|
332
|
+
),
|
|
333
|
+
).toThrow('is blocked')
|
|
334
|
+
})
|
|
335
|
+
|
|
336
|
+
it('should check blocklist before allowlist', () => {
|
|
337
|
+
const allowConfig: SwapMarketConfig = {
|
|
338
|
+
assets: [MockUSDC, MockWETH],
|
|
339
|
+
chainId: 84532 as SupportedChainId,
|
|
340
|
+
}
|
|
341
|
+
const blockConfig: SwapMarketConfig = {
|
|
342
|
+
assets: [MockUSDC, MockWETH],
|
|
343
|
+
chainId: 84532 as SupportedChainId,
|
|
344
|
+
}
|
|
345
|
+
const provider = new MockSwapProvider({
|
|
346
|
+
marketAllowlist: [allowConfig],
|
|
347
|
+
marketBlocklist: [blockConfig],
|
|
348
|
+
})
|
|
349
|
+
// Blocklist takes precedence
|
|
350
|
+
expect(() =>
|
|
351
|
+
provider.testValidateMarketAllowed(
|
|
352
|
+
MockUSDC,
|
|
353
|
+
MockWETH,
|
|
354
|
+
84532 as SupportedChainId,
|
|
355
|
+
),
|
|
356
|
+
).toThrow('is blocked')
|
|
357
|
+
})
|
|
358
|
+
|
|
359
|
+
it('should expand multi-asset filter to all pairs', () => {
|
|
360
|
+
const config: SwapMarketConfig = {
|
|
361
|
+
assets: [MockUSDC, MockWETH, MockOP],
|
|
362
|
+
chainId: 84532 as SupportedChainId,
|
|
363
|
+
}
|
|
364
|
+
const provider = new MockSwapProvider({ marketAllowlist: [config] })
|
|
365
|
+
|
|
366
|
+
// All 3 pairs should be allowed: USDC/WETH, USDC/OP, WETH/OP
|
|
367
|
+
expect(() =>
|
|
368
|
+
provider.testValidateMarketAllowed(
|
|
369
|
+
MockUSDC,
|
|
370
|
+
MockWETH,
|
|
371
|
+
84532 as SupportedChainId,
|
|
372
|
+
),
|
|
373
|
+
).not.toThrow()
|
|
374
|
+
expect(() =>
|
|
375
|
+
provider.testValidateMarketAllowed(
|
|
376
|
+
MockUSDC,
|
|
377
|
+
MockOP,
|
|
378
|
+
84532 as SupportedChainId,
|
|
379
|
+
),
|
|
380
|
+
).not.toThrow()
|
|
381
|
+
expect(() =>
|
|
382
|
+
provider.testValidateMarketAllowed(
|
|
383
|
+
MockWETH,
|
|
384
|
+
MockOP,
|
|
385
|
+
84532 as SupportedChainId,
|
|
386
|
+
),
|
|
387
|
+
).not.toThrow()
|
|
388
|
+
})
|
|
389
|
+
|
|
390
|
+
it('should match any chain when filter has no chainId', () => {
|
|
391
|
+
// Assets with addresses on both chains
|
|
392
|
+
const multiChainUSDC: Asset = {
|
|
393
|
+
...MockUSDC,
|
|
394
|
+
address: {
|
|
395
|
+
84532: '0x1111111111111111111111111111111111111111' as Address,
|
|
396
|
+
10: '0x1111111111111111111111111111111111111112' as Address,
|
|
397
|
+
},
|
|
398
|
+
}
|
|
399
|
+
const multiChainWETH: Asset = {
|
|
400
|
+
...MockWETH,
|
|
401
|
+
address: {
|
|
402
|
+
84532: '0x2222222222222222222222222222222222222222' as Address,
|
|
403
|
+
10: '0x2222222222222222222222222222222222222223' as Address,
|
|
404
|
+
},
|
|
405
|
+
}
|
|
406
|
+
const config: SwapMarketConfig = {
|
|
407
|
+
assets: [multiChainUSDC, multiChainWETH],
|
|
408
|
+
}
|
|
409
|
+
const provider = new MockSwapProvider(
|
|
410
|
+
{ marketAllowlist: [config] },
|
|
411
|
+
{
|
|
412
|
+
supportedChains: [84532 as SupportedChainId, 10 as SupportedChainId],
|
|
413
|
+
},
|
|
414
|
+
)
|
|
415
|
+
|
|
416
|
+
// Should match on any supported chain
|
|
417
|
+
expect(() =>
|
|
418
|
+
provider.testValidateMarketAllowed(
|
|
419
|
+
multiChainUSDC,
|
|
420
|
+
multiChainWETH,
|
|
421
|
+
84532 as SupportedChainId,
|
|
422
|
+
),
|
|
423
|
+
).not.toThrow()
|
|
424
|
+
expect(() =>
|
|
425
|
+
provider.testValidateMarketAllowed(
|
|
426
|
+
multiChainUSDC,
|
|
427
|
+
multiChainWETH,
|
|
428
|
+
10 as SupportedChainId,
|
|
429
|
+
),
|
|
430
|
+
).not.toThrow()
|
|
431
|
+
})
|
|
432
|
+
|
|
433
|
+
it('should scope filter to specific chainId when provided', () => {
|
|
434
|
+
const multiChainUSDC: Asset = {
|
|
435
|
+
...MockUSDC,
|
|
436
|
+
address: {
|
|
437
|
+
84532: '0x1111111111111111111111111111111111111111' as Address,
|
|
438
|
+
10: '0x1111111111111111111111111111111111111112' as Address,
|
|
439
|
+
},
|
|
440
|
+
}
|
|
441
|
+
const multiChainWETH: Asset = {
|
|
442
|
+
...MockWETH,
|
|
443
|
+
address: {
|
|
444
|
+
84532: '0x2222222222222222222222222222222222222222' as Address,
|
|
445
|
+
10: '0x2222222222222222222222222222222222222223' as Address,
|
|
446
|
+
},
|
|
447
|
+
}
|
|
448
|
+
const config: SwapMarketConfig = {
|
|
449
|
+
assets: [multiChainUSDC, multiChainWETH],
|
|
450
|
+
chainId: 84532 as SupportedChainId,
|
|
451
|
+
}
|
|
452
|
+
const provider = new MockSwapProvider(
|
|
453
|
+
{ marketAllowlist: [config] },
|
|
454
|
+
{
|
|
455
|
+
supportedChains: [84532 as SupportedChainId, 10 as SupportedChainId],
|
|
456
|
+
},
|
|
457
|
+
)
|
|
458
|
+
|
|
459
|
+
// Should match on 84532
|
|
460
|
+
expect(() =>
|
|
461
|
+
provider.testValidateMarketAllowed(
|
|
462
|
+
multiChainUSDC,
|
|
463
|
+
multiChainWETH,
|
|
464
|
+
84532 as SupportedChainId,
|
|
465
|
+
),
|
|
466
|
+
).not.toThrow()
|
|
467
|
+
|
|
468
|
+
// Should NOT match on chain 10
|
|
469
|
+
expect(() =>
|
|
470
|
+
provider.testValidateMarketAllowed(
|
|
471
|
+
multiChainUSDC,
|
|
472
|
+
multiChainWETH,
|
|
473
|
+
10 as SupportedChainId,
|
|
474
|
+
),
|
|
475
|
+
).toThrow('not in the allowlist')
|
|
476
|
+
})
|
|
477
|
+
})
|
|
478
|
+
})
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Core
|
|
2
|
+
export { SwapProvider } from '@/swap/core/SwapProvider.js'
|
|
3
|
+
|
|
4
|
+
// Namespaces
|
|
5
|
+
export { ActionsSwapNamespace } from '@/swap/namespaces/ActionsSwapNamespace.js'
|
|
6
|
+
export { BaseSwapNamespace } from '@/swap/namespaces/BaseSwapNamespace.js'
|
|
7
|
+
export { WalletSwapNamespace } from '@/swap/namespaces/WalletSwapNamespace.js'
|
|
8
|
+
|
|
9
|
+
// Providers
|
|
10
|
+
export type {
|
|
11
|
+
UniswapMarketConfig,
|
|
12
|
+
UniswapSwapProviderConfig,
|
|
13
|
+
} from '@/swap/providers/uniswap/types.js'
|
|
14
|
+
export { UniswapSwapProvider } from '@/swap/providers/uniswap/UniswapSwapProvider.js'
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { BaseSwapNamespace } from '@/swap/namespaces/BaseSwapNamespace.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Actions swap namespace (read-only, no wallet required)
|
|
5
|
+
* @description Provides price(), getMarket(), and getMarkets() for read-only access without a wallet
|
|
6
|
+
*/
|
|
7
|
+
export class ActionsSwapNamespace extends BaseSwapNamespace {}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { SupportedChainId } from '@/constants/supportedChains.js'
|
|
2
|
+
import type { SwapProvider } from '@/swap/core/SwapProvider.js'
|
|
3
|
+
import type {
|
|
4
|
+
GetSwapMarketParams,
|
|
5
|
+
GetSwapMarketsParams,
|
|
6
|
+
SwapMarket,
|
|
7
|
+
SwapPrice,
|
|
8
|
+
SwapPriceParams,
|
|
9
|
+
SwapProviderConfig,
|
|
10
|
+
SwapProviders,
|
|
11
|
+
} from '@/types/swap/index.js'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Base swap namespace with shared read-only operations
|
|
15
|
+
*/
|
|
16
|
+
export abstract class BaseSwapNamespace {
|
|
17
|
+
constructor(protected readonly providers: SwapProviders) {}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Get price quote for a swap
|
|
21
|
+
*/
|
|
22
|
+
async price(params: SwapPriceParams): Promise<SwapPrice> {
|
|
23
|
+
const provider = this.getProvider()
|
|
24
|
+
return provider.getPrice(params)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Get a specific swap market
|
|
29
|
+
* @param params - Market identifier
|
|
30
|
+
* @returns Market information
|
|
31
|
+
*/
|
|
32
|
+
async getMarket(params: GetSwapMarketParams): Promise<SwapMarket> {
|
|
33
|
+
const provider = this.getProvider()
|
|
34
|
+
return provider.getMarket(params)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Get available swap markets across all providers
|
|
39
|
+
* @param params - Optional filtering by chainId or asset
|
|
40
|
+
* @returns Promise resolving to array of markets from all providers
|
|
41
|
+
*/
|
|
42
|
+
async getMarkets(params: GetSwapMarketsParams = {}): Promise<SwapMarket[]> {
|
|
43
|
+
const results = await Promise.all(
|
|
44
|
+
this.getAllProviders().map((p) => p.getMarkets(params)),
|
|
45
|
+
)
|
|
46
|
+
return results.flat()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Get all supported chain IDs across all providers
|
|
51
|
+
*/
|
|
52
|
+
supportedChainIds(): SupportedChainId[] {
|
|
53
|
+
const chainIds = new Set<SupportedChainId>()
|
|
54
|
+
for (const provider of this.getAllProviders()) {
|
|
55
|
+
for (const chainId of provider.supportedChainIds()) {
|
|
56
|
+
chainIds.add(chainId)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return Array.from(chainIds)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// SwapProviders keys are optional (uniswap?, aerodrome?, etc.) so filter out unconfigured ones
|
|
63
|
+
protected getAllProviders(): Array<SwapProvider<SwapProviderConfig>> {
|
|
64
|
+
return Object.values(this.providers).filter(
|
|
65
|
+
(p): p is SwapProvider<SwapProviderConfig> => p !== undefined,
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Future: resolve the best provider for given params (e.g. best price across Uniswap, Aerodrome, etc.)
|
|
70
|
+
protected getProvider(): SwapProvider<SwapProviderConfig> {
|
|
71
|
+
const provider = this.providers.uniswap
|
|
72
|
+
if (!provider) {
|
|
73
|
+
throw new Error('No swap provider configured')
|
|
74
|
+
}
|
|
75
|
+
return provider
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { SupportedChainId } from '@/constants/supportedChains.js'
|
|
2
|
+
import { BaseSwapNamespace } from '@/swap/namespaces/BaseSwapNamespace.js'
|
|
3
|
+
import type {
|
|
4
|
+
SwapProviders,
|
|
5
|
+
SwapReceipt,
|
|
6
|
+
SwapTransaction,
|
|
7
|
+
WalletSwapParams,
|
|
8
|
+
} from '@/types/swap/index.js'
|
|
9
|
+
import type { Wallet } from '@/wallet/core/wallets/abstract/Wallet.js'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Wallet swap namespace (full operations with signing)
|
|
13
|
+
* @description Provides execute() for swapping tokens
|
|
14
|
+
*/
|
|
15
|
+
export class WalletSwapNamespace extends BaseSwapNamespace {
|
|
16
|
+
constructor(
|
|
17
|
+
providers: SwapProviders,
|
|
18
|
+
private readonly wallet: Wallet,
|
|
19
|
+
) {
|
|
20
|
+
super(providers)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Execute a token swap
|
|
25
|
+
* @param params - Swap parameters including chainId
|
|
26
|
+
* @returns Swap receipt with transaction details
|
|
27
|
+
*/
|
|
28
|
+
async execute(params: WalletSwapParams): Promise<SwapReceipt> {
|
|
29
|
+
const provider = this.getProvider()
|
|
30
|
+
|
|
31
|
+
// Build swap transaction
|
|
32
|
+
const swapTx = await provider.execute({
|
|
33
|
+
...params,
|
|
34
|
+
walletAddress: this.wallet.address,
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
// Execute transaction(s)
|
|
38
|
+
const receipt = await this.executeTransaction(swapTx, params.chainId)
|
|
39
|
+
|
|
40
|
+
return {
|
|
41
|
+
receipt,
|
|
42
|
+
amountIn: swapTx.amountIn,
|
|
43
|
+
amountOut: swapTx.amountOut,
|
|
44
|
+
amountInWei: swapTx.amountInWei,
|
|
45
|
+
amountOutWei: swapTx.amountOutWei,
|
|
46
|
+
assetIn: swapTx.assetIn,
|
|
47
|
+
assetOut: swapTx.assetOut,
|
|
48
|
+
price: swapTx.price,
|
|
49
|
+
priceImpact: swapTx.priceImpact,
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Execute swap transaction with approval batching
|
|
55
|
+
*/
|
|
56
|
+
private async executeTransaction(
|
|
57
|
+
swapTx: SwapTransaction,
|
|
58
|
+
chainId: SupportedChainId,
|
|
59
|
+
): Promise<SwapReceipt['receipt']> {
|
|
60
|
+
const { transactionData } = swapTx
|
|
61
|
+
const txs = []
|
|
62
|
+
|
|
63
|
+
// Add token approval if needed
|
|
64
|
+
if (transactionData.tokenApproval) {
|
|
65
|
+
txs.push(transactionData.tokenApproval)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Add Permit2 approval if needed
|
|
69
|
+
if (transactionData.permit2Approval) {
|
|
70
|
+
txs.push(transactionData.permit2Approval)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Add main swap transaction
|
|
74
|
+
txs.push(transactionData.swap)
|
|
75
|
+
|
|
76
|
+
// Execute as batch if multiple transactions, otherwise single
|
|
77
|
+
if (txs.length > 1) {
|
|
78
|
+
return this.wallet.sendBatch(txs, chainId)
|
|
79
|
+
}
|
|
80
|
+
return this.wallet.send(transactionData.swap, chainId)
|
|
81
|
+
}
|
|
82
|
+
}
|