diff --git a/cspell.json b/cspell.json index 26f6bec83b73..b37b5e1b9979 100644 --- a/cspell.json +++ b/cspell.json @@ -214,6 +214,8 @@ "sint", "solana", "sollet", + "spiritswap", + "spookyswap", "steelblue", "steganographic", "steganography", diff --git a/packages/mask/src/plugins/Trader/apis/trader/index.ts b/packages/mask/src/plugins/Trader/apis/trader/index.ts index 3e562ea63401..147fb14d350f 100644 --- a/packages/mask/src/plugins/Trader/apis/trader/index.ts +++ b/packages/mask/src/plugins/Trader/apis/trader/index.ts @@ -47,7 +47,7 @@ export async function getAvailableTraderProviders(chainId: ChainId) { case NetworkType.Celo: return [TradeProvider.SUSHISWAP] case NetworkType.Fantom: - return [TradeProvider.SUSHISWAP] + return [TradeProvider.SUSHISWAP, TradeProvider.SPOOKYSWAP, TradeProvider.SPIRITSWAP] case NetworkType.Aurora: return [TradeProvider.DODO, TradeProvider.WANNASWAP, TradeProvider.TRISOLARIS] case NetworkType.Boba: diff --git a/packages/mask/src/plugins/Trader/constants/index.ts b/packages/mask/src/plugins/Trader/constants/index.ts index 7cde5749d988..7962795af3f4 100644 --- a/packages/mask/src/plugins/Trader/constants/index.ts +++ b/packages/mask/src/plugins/Trader/constants/index.ts @@ -13,4 +13,6 @@ export * from './traderjoe' export * from './pangolindex' export * from './wannaswap' export * from './trisolaris' +export * from './spiritswap' +export * from './spookyswap' export type { ERC20TokenCustomizedBase, ERC20AgainstToken } from './types' diff --git a/packages/mask/src/plugins/Trader/constants/spiritswap.ts b/packages/mask/src/plugins/Trader/constants/spiritswap.ts new file mode 100644 index 000000000000..e5fb03a17424 --- /dev/null +++ b/packages/mask/src/plugins/Trader/constants/spiritswap.ts @@ -0,0 +1,13 @@ +import { ChainId, DAI, USDC, fUSDT, WBTC, WNATIVE, WNATIVE_ONLY, SPIRIT } from '@masknet/web3-shared-evm' +import type { ERC20AgainstToken, ERC20TokenCustomizedBase } from './types' + +/** + * Some tokens can only be swapped via certain pairs, + * so we override the list of bases that are considered for these tokens. + */ +export const SPIRITSWAP_CUSTOM_BASES: ERC20TokenCustomizedBase = {} + +export const SPIRITSWAP_BASE_AGAINST_TOKENS: ERC20AgainstToken = { + ...WNATIVE_ONLY, + [ChainId.Fantom]: [WNATIVE, DAI, USDC, fUSDT, WBTC, SPIRIT].map((x) => x[ChainId.Fantom]), +} diff --git a/packages/mask/src/plugins/Trader/constants/spookyswap.ts b/packages/mask/src/plugins/Trader/constants/spookyswap.ts new file mode 100644 index 000000000000..376610f4c961 --- /dev/null +++ b/packages/mask/src/plugins/Trader/constants/spookyswap.ts @@ -0,0 +1,13 @@ +import { ChainId, DAI, USDC, fUSDT, WBTC, WNATIVE, WNATIVE_ONLY, BOO } from '@masknet/web3-shared-evm' +import type { ERC20AgainstToken, ERC20TokenCustomizedBase } from './types' + +/** + * Some tokens can only be swapped via certain pairs, + * so we override the list of bases that are considered for these tokens. + */ +export const SPOOKYSWAP_CUSTOM_BASES: ERC20TokenCustomizedBase = {} + +export const SPOOKYSWAP_BASE_AGAINST_TOKENS: ERC20AgainstToken = { + ...WNATIVE_ONLY, + [ChainId.Fantom]: [WNATIVE, DAI, USDC, fUSDT, WBTC, BOO].map((x) => x[ChainId.Fantom]), +} diff --git a/packages/mask/src/plugins/Trader/pipes.ts b/packages/mask/src/plugins/Trader/pipes.ts index c5fa9424b3c1..5b0395c4d4c7 100644 --- a/packages/mask/src/plugins/Trader/pipes.ts +++ b/packages/mask/src/plugins/Trader/pipes.ts @@ -40,6 +40,8 @@ export const resolveTradeProviderName = createLookupTableResolver { throw new Error(`Unknown provider type: ${tradeProvider}`) diff --git a/packages/mask/src/plugins/Trader/trader/useAllTradeComputed.ts b/packages/mask/src/plugins/Trader/trader/useAllTradeComputed.ts index 95d3c4d7ea1f..44df70e6499b 100644 --- a/packages/mask/src/plugins/Trader/trader/useAllTradeComputed.ts +++ b/packages/mask/src/plugins/Trader/trader/useAllTradeComputed.ts @@ -198,6 +198,20 @@ export function useAllTradeComputed( traderEstimateGas: wannaSwapEstimateGas, } = useUniswapV2Like(tradeProviders, TradeProvider.WANNASWAP, inputAmount_, inputToken, outputToken) + // SpiritSwap + const { + trader_: spiritswap_, + trader: spiritswap, + traderEstimateGas: spiritswapEstimateGas, + } = useUniswapV2Like(tradeProviders, TradeProvider.SPIRITSWAP, inputAmount_, inputToken, outputToken) + + // Spookyswap + const { + trader_: spookyswap_, + trader: spookyswap, + traderEstimateGas: spookyswapEstimateGas, + } = useUniswapV2Like(tradeProviders, TradeProvider.SPOOKYSWAP, inputAmount_, inputToken, outputToken) + const allTradeResult = [ { provider: TradeProvider.UNISWAP_V2, ...uniswapV2_, value: uniswapV2, gas: uniswapV2EstimateGas }, { provider: TradeProvider.SUSHISWAP, ...sushiSwap_, value: sushiSwap, gas: sushiSwapEstimateGas }, @@ -214,6 +228,8 @@ export function useAllTradeComputed( { provider: TradeProvider.OPENOCEAN, ...openocean_, value: openocean, gas: openoceanSwapEstimateGas }, { provider: TradeProvider.WANNASWAP, ...wannaswap_, value: wannaswap, gas: wannaSwapEstimateGas }, { provider: TradeProvider.TRISOLARIS, ...trisolaris_, value: trisolaris, gas: trisolarisEstimateGas }, + { provider: TradeProvider.SPIRITSWAP, ...spiritswap_, value: spiritswap, gas: spiritswapEstimateGas }, + { provider: TradeProvider.SPOOKYSWAP, ...spookyswap_, value: spookyswap, gas: spookyswapEstimateGas }, ] return nativeToken_.value diff --git a/packages/mask/src/plugins/Trader/trader/useGetTradeContext.ts b/packages/mask/src/plugins/Trader/trader/useGetTradeContext.ts index 77533cc926e2..354320431d30 100644 --- a/packages/mask/src/plugins/Trader/trader/useGetTradeContext.ts +++ b/packages/mask/src/plugins/Trader/trader/useGetTradeContext.ts @@ -21,6 +21,10 @@ import { WANNASWAP_CUSTOM_BASES, TRISOLARIS_BASE_AGAINST_TOKENS, TRISOLARIS_CUSTOM_BASES, + SPIRITSWAP_BASE_AGAINST_TOKENS, + SPIRITSWAP_CUSTOM_BASES, + SPOOKYSWAP_BASE_AGAINST_TOKENS, + SPOOKYSWAP_CUSTOM_BASES, } from '../constants' import { unreachable } from '@dimensiondev/kit' import { TargetChainIdContext } from './useTargetChainIdContext' @@ -150,6 +154,30 @@ export function useGetTradeContext(tradeProvider?: TradeProvider) { ADDITIONAL_TOKENS: {}, CUSTOM_TOKENS: TRISOLARIS_CUSTOM_BASES, } + case TradeProvider.SPOOKYSWAP: + return { + TYPE: tradeProvider, + IS_UNISWAP_V2_LIKE: true, + GRAPH_API: DEX_TRADE.SPOOKYSWAP_THEGRAPH, + INIT_CODE_HASH: DEX_TRADE.SPOOKYSWAP_INIT_CODE_HASH, + ROUTER_CONTRACT_ADDRESS: DEX_TRADE.SPOOKYSWAP_ROUTER_ADDRESS, + FACTORY_CONTRACT_ADDRESS: DEX_TRADE.SPOOKYSWAP_FACTORY_ADDRESS, + AGAINST_TOKENS: SPOOKYSWAP_BASE_AGAINST_TOKENS, + ADDITIONAL_TOKENS: {}, + CUSTOM_TOKENS: SPOOKYSWAP_CUSTOM_BASES, + } + case TradeProvider.SPIRITSWAP: + return { + TYPE: tradeProvider, + IS_UNISWAP_V2_LIKE: true, + GRAPH_API: DEX_TRADE.SPIRITSWAP_THEGRAPH, + INIT_CODE_HASH: DEX_TRADE.SPIRITSWAP_INIT_CODE_HASH, + ROUTER_CONTRACT_ADDRESS: DEX_TRADE.SPIRITSWAP_ROUTER_ADDRESS, + FACTORY_CONTRACT_ADDRESS: DEX_TRADE.SPIRITSWAP_FACTORY_ADDRESS, + AGAINST_TOKENS: SPIRITSWAP_BASE_AGAINST_TOKENS, + ADDITIONAL_TOKENS: {}, + CUSTOM_TOKENS: SPIRITSWAP_CUSTOM_BASES, + } case TradeProvider.ZRX: return { TYPE: tradeProvider, diff --git a/packages/mask/src/plugins/Trader/trader/useTradeCallback.ts b/packages/mask/src/plugins/Trader/trader/useTradeCallback.ts index c678a4013af9..cf77f9328c95 100644 --- a/packages/mask/src/plugins/Trader/trader/useTradeCallback.ts +++ b/packages/mask/src/plugins/Trader/trader/useTradeCallback.ts @@ -114,6 +114,10 @@ export function useTradeCallback( return uniswapV2Like case TradeProvider.OPENOCEAN: return openocean + case TradeProvider.SPIRITSWAP: + return uniswapV2Like + case TradeProvider.SPOOKYSWAP: + return uniswapV2Like default: if (provider) unreachable(provider) return [] diff --git a/packages/mask/src/plugins/Trader/trader/useTradeContext.ts b/packages/mask/src/plugins/Trader/trader/useTradeContext.ts index 3db649333430..f93e310ed953 100644 --- a/packages/mask/src/plugins/Trader/trader/useTradeContext.ts +++ b/packages/mask/src/plugins/Trader/trader/useTradeContext.ts @@ -21,6 +21,10 @@ import { WANNASWAP_CUSTOM_BASES, TRISOLARIS_CUSTOM_BASES, TRISOLARIS_BASE_AGAINST_TOKENS, + SPOOKYSWAP_CUSTOM_BASES, + SPOOKYSWAP_BASE_AGAINST_TOKENS, + SPIRITSWAP_CUSTOM_BASES, + SPIRITSWAP_BASE_AGAINST_TOKENS, } from '../constants' import type { TradeContext as TradeContext_ } from '../types' import { TargetChainIdContext } from './useTargetChainIdContext' @@ -171,6 +175,30 @@ export function useTradeContext(tradeProvider: TradeProvider) { ADDITIONAL_TOKENS: {}, CUSTOM_TOKENS: PANGOLIN_CUSTOM_BASES, } + case TradeProvider.SPIRITSWAP: + return { + TYPE: tradeProvider, + IS_UNISWAP_V2_LIKE: true, + GRAPH_API: DEX_TRADE.SPIRITSWAP_THEGRAPH, + INIT_CODE_HASH: DEX_TRADE.SPIRITSWAP_INIT_CODE_HASH, + ROUTER_CONTRACT_ADDRESS: DEX_TRADE.SPIRITSWAP_ROUTER_ADDRESS, + FACTORY_CONTRACT_ADDRESS: DEX_TRADE.SPIRITSWAP_FACTORY_ADDRESS, + AGAINST_TOKENS: SPIRITSWAP_BASE_AGAINST_TOKENS, + ADDITIONAL_TOKENS: {}, + CUSTOM_TOKENS: SPIRITSWAP_CUSTOM_BASES, + } + case TradeProvider.SPOOKYSWAP: + return { + TYPE: tradeProvider, + IS_UNISWAP_V2_LIKE: true, + GRAPH_API: DEX_TRADE.SPOOKYSWAP_THEGRAPH, + INIT_CODE_HASH: DEX_TRADE.SPOOKYSWAP_INIT_CODE_HASH, + ROUTER_CONTRACT_ADDRESS: DEX_TRADE.SPOOKYSWAP_ROUTER_ADDRESS, + FACTORY_CONTRACT_ADDRESS: DEX_TRADE.SPOOKYSWAP_FACTORY_ADDRESS, + AGAINST_TOKENS: SPOOKYSWAP_BASE_AGAINST_TOKENS, + ADDITIONAL_TOKENS: {}, + CUSTOM_TOKENS: SPOOKYSWAP_CUSTOM_BASES, + } case TradeProvider.OPENOCEAN: return { TYPE: tradeProvider, diff --git a/packages/mask/src/plugins/Trader/types/trader.ts b/packages/mask/src/plugins/Trader/types/trader.ts index fb0d655737ee..2cdf434a8a27 100644 --- a/packages/mask/src/plugins/Trader/types/trader.ts +++ b/packages/mask/src/plugins/Trader/types/trader.ts @@ -75,6 +75,8 @@ export enum ZrxTradePool { PangolinDex = 'PangolinDex', Trisolaris = 'Trisolaris', WannaSwap = 'WannaSwap', + SpiritSwap = 'SpiritSwap', + SpookySwap = 'SpookySwap', } export interface TradeComputed { diff --git a/packages/public-api/src/web.ts b/packages/public-api/src/web.ts index fb4d55ad81ed..31d55234289e 100644 --- a/packages/public-api/src/web.ts +++ b/packages/public-api/src/web.ts @@ -216,6 +216,8 @@ export enum TradeProvider { TRISOLARIS = 12, TRADERJOE = 13, PANGOLIN = 14, + SPIRITSWAP = 15, + SPOOKYSWAP = 16, } /** Supported language settings */ export enum LanguageOptions { diff --git a/packages/web3-constants/evm/token.json b/packages/web3-constants/evm/token.json index f6fe2360d0d4..5c302b73b8cb 100644 --- a/packages/web3-constants/evm/token.json +++ b/packages/web3-constants/evm/token.json @@ -899,6 +899,46 @@ "Aurora": "", "Aurora_Testnet": "" }, + "SPIRIT_ADDRESS": { + "Mainnet": "", + "Ropsten": "", + "Rinkeby": "", + "Kovan": "", + "Gorli": "", + "BSC": "", + "BSCT": "", + "Matic": "", + "Mumbai": "", + "Arbitrum": "", + "Arbitrum_Rinkeby": "", + "xDai": "", + "Avalanche": "", + "Avalanche_Fuji": "", + "Celo": "", + "Fantom": "0x5cc61a78f164885776aa610fb0fe1257df78e59b", + "Aurora": "", + "Aurora_Testnet": "" + }, + "BOO_ADDRESS": { + "Mainnet": "0x55af5865807b196bd0197e0902746f31fbccfa58", + "Ropsten": "", + "Rinkeby": "", + "Kovan": "", + "Gorli": "", + "BSC": "", + "BSCT": "", + "Matic": "", + "Mumbai": "", + "Arbitrum": "", + "Arbitrum_Rinkeby": "", + "xDai": "", + "Avalanche": "0xbd83010eb60f12112908774998f65761cf9f6f9a", + "Avalanche_Fuji": "", + "Celo": "", + "Fantom": "0x841fad6eae12c286d1fd18d1d525dffa75c7effe", + "Aurora": "", + "Aurora_Testnet": "" + }, "ETHER_ADDRESS": { "Mainnet": "", "Ropsten": "", diff --git a/packages/web3-constants/evm/trader.json b/packages/web3-constants/evm/trader.json index b656354c3839..ee610efcc764 100644 --- a/packages/web3-constants/evm/trader.json +++ b/packages/web3-constants/evm/trader.json @@ -1018,5 +1018,165 @@ "Fantom": "", "Aurora": "0x754e1d90e536e4c1df81b7f030f47b4ca80c87120e145c294f098c83a6cb5ace", "Aurora_Testnet": "" + }, + "SPIRITSWAP_ROUTER_ADDRESS": { + "Mainnet": "", + "Ropsten": "", + "Rinkeby": "", + "Kovan": "", + "Gorli": "", + "BSC": "", + "BSCT": "", + "Matic": "", + "Mumbai": "", + "Arbitrum": "", + "Arbitrum_Rinkeby": "", + "xDai": "", + "Avalanche": "", + "Avalanche_Fuji": "", + "Celo": "", + "Fantom": "0x16327e3fbdaca3bcf7e38f5af2599d2ddc33ae52", + "Aurora": "", + "Aurora_Testnet": "" + }, + "SPIRITSWAP_FACTORY_ADDRESS": { + "Mainnet": "", + "Ropsten": "", + "Rinkeby": "", + "Kovan": "", + "Gorli": "", + "BSC": "", + "BSCT": "", + "Matic": "", + "Mumbai": "", + "Arbitrum": "", + "Arbitrum_Rinkeby": "", + "xDai": "", + "Avalanche": "", + "Avalanche_Fuji": "", + "Celo": "", + "Fantom": "0xEF45d134b73241eDa7703fa787148D9C9F4950b0", + "Aurora": "", + "Aurora_Testnet": "" + }, + "SPIRITSWAP_THEGRAPH": { + "Mainnet": "", + "Ropsten": "", + "Rinkeby": "", + "Kovan": "", + "Gorli": "", + "BSC": "", + "BSCT": "", + "Matic": "", + "Mumbai": "", + "Arbitrum": "", + "Arbitrum_Rinkeby": "", + "xDai": "", + "Avalanche": "", + "Avalanche_Fuji": "", + "Celo": "", + "Fantom": "", + "Aurora": "", + "Aurora_Testnet": "" + }, + "SPIRITSWAP_INIT_CODE_HASH": { + "Mainnet": "", + "Ropsten": "", + "Rinkeby": "", + "Kovan": "", + "Gorli": "", + "BSC": "", + "BSCT": "", + "Matic": "0x4a697f690d1f46e0f1a897a8662acae31ced3039b00c052392ed0bc179f9f28c", + "Mumbai": "", + "Arbitrum": "", + "Arbitrum_Rinkeby": "", + "xDai": "", + "Avalanche": "", + "Avalanche_Fuji": "", + "Celo": "", + "Fantom": "0xe242e798f6cee26a9cb0bbf24653bf066e5356ffeac160907fe2cc108e238617", + "Aurora": "", + "Aurora_Testnet": "" + }, + "SPOOKYSWAP_ROUTER_ADDRESS": { + "Mainnet": "0xf491e7b69e4244ad4002bc14e878a34207e38c29", + "Ropsten": "", + "Rinkeby": "", + "Kovan": "", + "Gorli": "", + "BSC": "", + "BSCT": "", + "Matic": "", + "Mumbai": "", + "Arbitrum": "", + "Arbitrum_Rinkeby": "", + "xDai": "", + "Avalanche": "0xf491e7b69e4244ad4002bc14e878a34207e38c29", + "Avalanche_Fuji": "", + "Celo": "", + "Fantom": "0xf491e7b69e4244ad4002bc14e878a34207e38c29", + "Aurora": "", + "Aurora_Testnet": "" + }, + "SPOOKYSWAP_FACTORY_ADDRESS": { + "Mainnet": "0x152ee697f2e276fa89e96742e9bb9ab1f2e61be3", + "Ropsten": "", + "Rinkeby": "", + "Kovan": "", + "Gorli": "", + "BSC": "", + "BSCT": "", + "Matic": "", + "Mumbai": "", + "Arbitrum": "", + "Arbitrum_Rinkeby": "", + "xDai": "", + "Avalanche": "0x152ee697f2e276fa89e96742e9bb9ab1f2e61be3", + "Avalanche_Fuji": "", + "Celo": "", + "Fantom": "0x152ee697f2e276fa89e96742e9bb9ab1f2e61be3", + "Aurora": "", + "Aurora_Testnet": "" + }, + "SPOOKYSWAP_THEGRAPH": { + "Mainnet": "", + "Ropsten": "", + "Rinkeby": "", + "Kovan": "", + "Gorli": "", + "BSC": "", + "BSCT": "", + "Matic": "", + "Mumbai": "", + "Arbitrum": "", + "Arbitrum_Rinkeby": "", + "xDai": "", + "Avalanche": "", + "Avalanche_Fuji": "", + "Celo": "", + "Fantom": "", + "Aurora": "", + "Aurora_Testnet": "" + }, + "SPOOKYSWAP_INIT_CODE_HASH": { + "Mainnet": "0xcdf2deca40a0bd56de8e3ce5c7df6727e5b1bf2ac96f283fa9c4b3e6b42ea9d2", + "Ropsten": "", + "Rinkeby": "", + "Kovan": "", + "Gorli": "", + "BSC": "", + "BSCT": "", + "Matic": "", + "Mumbai": "", + "Arbitrum": "", + "Arbitrum_Rinkeby": "", + "xDai": "", + "Avalanche": "0xcdf2deca40a0bd56de8e3ce5c7df6727e5b1bf2ac96f283fa9c4b3e6b42ea9d2", + "Avalanche_Fuji": "", + "Celo": "", + "Fantom": "0xcdf2deca40a0bd56de8e3ce5c7df6727e5b1bf2ac96f283fa9c4b3e6b42ea9d2", + "Aurora": "", + "Aurora_Testnet": "" } } diff --git a/packages/web3-shared/evm/constants/tokens.ts b/packages/web3-shared/evm/constants/tokens.ts index 486f30fea1ca..63ca8e55e192 100644 --- a/packages/web3-shared/evm/constants/tokens.ts +++ b/packages/web3-shared/evm/constants/tokens.ts @@ -50,6 +50,8 @@ export const CUSD = createERC20Tokens('cUSD_ADDRESS', 'Celo Dollar', 'cUSD', 18) export const CEUR = createERC20Tokens('cEUR_ADDRESS', 'Celo Euro', 'cEUR', 18) export const JOE = createERC20Tokens('JOE_ADDRESS', 'JoeToken', 'JOE', 18) export const PNG = createERC20Tokens('PNG_ADDRESS', 'Pangolin', 'PNG', 18) +export const SPIRIT = createERC20Tokens('SPIRIT_ADDRESS', 'SpiritSwap Token', 'SPIRIT', 18) +export const BOO = createERC20Tokens('BOO_ADDRESS', 'SpookyToken', 'BOO', 18) export const WNATIVE = createERC20Tokens( 'WNATIVE_ADDRESS',