diff --git a/packages/dashboard/src/pages/Labs/components/SwapSettingDialog.tsx b/packages/dashboard/src/pages/Labs/components/SwapSettingDialog.tsx index 3f76640639a4..15ece37dd2ce 100644 --- a/packages/dashboard/src/pages/Labs/components/SwapSettingDialog.tsx +++ b/packages/dashboard/src/pages/Labs/components/SwapSettingDialog.tsx @@ -17,7 +17,7 @@ export interface SettingDialogProps { } export default function SwapSettingDialog({ open, onClose }: SettingDialogProps) { const ethOptions = [ - { label: 'UniSwap V2', value: TradeProvider.UNISWAP }, + { label: 'UniSwap V2', value: TradeProvider.UNISWAP_V2 }, { label: 'SushiSwap', value: TradeProvider.SUSHISWAP }, { label: 'SashimiSwap', value: TradeProvider.SASHIMISWAP }, { label: 'Ox', value: TradeProvider.ZRX }, diff --git a/packages/maskbook/package.json b/packages/maskbook/package.json index a6e8316be9f3..87235575011b 100644 --- a/packages/maskbook/package.json +++ b/packages/maskbook/package.json @@ -53,8 +53,11 @@ "@types/tiny-secp256k1": "^1.0.0", "@types/use-subscription": "^1.0.0", "@types/uuid": "^8.3.1", - "@uniswap/sdk-core": "^3.0.0", - "@uniswap/v2-sdk": "^3.0.0", + "@uniswap/sdk-core": "^3.0.1", + "@uniswap/v2-core": "1.0.0", + "@uniswap/v2-sdk": "3.0.0-alpha.2", + "@uniswap/v3-core": "1.0.0", + "@uniswap/v3-sdk": "^3.3.2", "@walletconnect/client": "^1.2.2", "anchorme": "^2.1.2", "arweave": "^1.10.13", @@ -76,7 +79,7 @@ "https-browserify": "^1.0.0", "immer": "^9.0.5", "isomorphic-dompurify": "^0.13.0", - "jsbi": "^3.1.5", + "jsbi": "3.1.4", "json-stable-stringify": "^1.0.1", "json2csv": "^5.0.6", "jsonwebtoken": "^8.5.1", diff --git a/packages/maskbook/src/_locales/en/messages.json b/packages/maskbook/src/_locales/en/messages.json index 3d5d2ccfdd9d..99b6aab03c78 100644 --- a/packages/maskbook/src/_locales/en/messages.json +++ b/packages/maskbook/src/_locales/en/messages.json @@ -487,6 +487,7 @@ "plugin_trader_settings_trade_provider_primary": "Choose Exchange Network", "plugin_trader_settings_trade_provider_secondary": "Swap cryptocurrencies on different exchange networks.", "plugin_trader_slipage_tolerance": "Slippage Tolerance:", + "plugin_trader_single_hop_only": "Single Hop Only:", "plugin_trader_swap_settings": "Swap Settings", "plugin_poll_display_name": "Plugin: Poll", "plugin_poll_question_hint": "Ask a question…", diff --git a/packages/maskbook/src/_locales/ja/messages.json b/packages/maskbook/src/_locales/ja/messages.json index 3c974ec8b2a0..1bfa0803a9b7 100644 --- a/packages/maskbook/src/_locales/ja/messages.json +++ b/packages/maskbook/src/_locales/ja/messages.json @@ -487,6 +487,7 @@ "plugin_trader_settings_trade_provider_primary": "交換するネットワークを選択", "plugin_trader_settings_trade_provider_secondary": "その他の取引所で暗号通貨をスワップする", "plugin_trader_slipage_tolerance": "スリッページの許容範囲:", + "plugin_trader_single_hop_only": "", "plugin_trader_swap_settings": "スワップの設定", "plugin_poll_display_name": "プラグイン: 投票", "plugin_poll_question_hint": "質問を入力してください...", diff --git a/packages/maskbook/src/_locales/ko/messages.json b/packages/maskbook/src/_locales/ko/messages.json index abc1eac688fd..9333be9e41b0 100644 --- a/packages/maskbook/src/_locales/ko/messages.json +++ b/packages/maskbook/src/_locales/ko/messages.json @@ -487,6 +487,7 @@ "plugin_trader_settings_trade_provider_primary": "교환 네트워크 선택", "plugin_trader_settings_trade_provider_secondary": "서로 다른 교환 네트워크에서 암호화폐 교환하기", "plugin_trader_slipage_tolerance": "슬리피지 톨러런스:", + "plugin_trader_single_hop_only": "", "plugin_trader_swap_settings": "스왑 설정", "plugin_poll_display_name": "플러그인: 투표", "plugin_poll_question_hint": "질문하기", diff --git a/packages/maskbook/src/_locales/zh/messages.json b/packages/maskbook/src/_locales/zh/messages.json index dcb10566985b..0c04cd217139 100644 --- a/packages/maskbook/src/_locales/zh/messages.json +++ b/packages/maskbook/src/_locales/zh/messages.json @@ -487,6 +487,7 @@ "plugin_trader_settings_trade_provider_primary": "選擇交易所網絡", "plugin_trader_settings_trade_provider_secondary": "在不同的交換網絡上交換加密貨幣。", "plugin_trader_slipage_tolerance": "滑動容許值:", + "plugin_trader_single_hop_only": "", "plugin_trader_swap_settings": "交換設定", "plugin_poll_display_name": "插件:投票", "plugin_poll_question_hint": "提出一個問題…", diff --git a/packages/maskbook/src/extension/background-script/EthereumServices/network.ts b/packages/maskbook/src/extension/background-script/EthereumServices/network.ts index 104dced6b8fc..4ec973f8c8b4 100644 --- a/packages/maskbook/src/extension/background-script/EthereumServices/network.ts +++ b/packages/maskbook/src/extension/background-script/EthereumServices/network.ts @@ -70,6 +70,16 @@ export async function getTransactionCount(address: string, overrides?: SendOverr return Number.parseInt(count, 16) } +export async function call(config: TransactionConfig, overrides?: SendOverrides) { + return request( + { + method: EthereumMethodType.ETH_CALL, + params: [config, 'latest'], + }, + overrides, + ) +} + export async function estimateGas(config: TransactionConfig, overrides?: SendOverrides) { const gas = await request( { @@ -139,6 +149,16 @@ export async function signTransaction(config: TransactionConfig, overrides?: Sen ) } +export async function sendTransaction(config: TransactionConfig, overrides?: SendOverrides) { + return request( + { + method: EthereumMethodType.ETH_SEND_TRANSACTION, + params: [config], + }, + overrides, + ) +} + export async function getPastLogs(config: PastLogsOptions, overrides?: SendOverrides) { return new Promise((resolve, reject) => request( diff --git a/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/SettingsDialog.tsx b/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/SettingsDialog.tsx index c90d216e32d7..4745f0ee5cfc 100644 --- a/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/SettingsDialog.tsx +++ b/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/SettingsDialog.tsx @@ -19,11 +19,11 @@ import { TradeProvider, ZrxTradePool } from '../../types' import { SelectPoolPanel } from './SelectPoolPanel' import { SlippageSlider } from './SlippageSlider' import { - currentSlippageTolerance, + currentSlippageSettings, currentTradeProviderSettings, getCurrentTradeProviderGeneralSettings, } from '../../settings' -import { SLIPPAGE_TOLERANCE_DEFAULT } from '../../constants' +import { SLIPPAGE_DEFAULT } from '../../constants' import { InjectedDialog } from '../../../../components/shared/InjectedDialog' import { PluginTraderMessages } from '../../messages' import stringify from 'json-stable-stringify' @@ -57,7 +57,7 @@ export function SettingsDialog(props: SettingsDialogProps) { const classes = useStylesExtends(useStyles(), props) const provider = useValueRef(currentTradeProviderSettings) - const slippage = useValueRef(currentSlippageTolerance) + const slippage = useValueRef(currentSlippageSettings) const { pools } = useTradeProviderSettings(provider) //#region remote controlled dialog @@ -65,8 +65,8 @@ export function SettingsDialog(props: SettingsDialogProps) { //#endregion const onReset = useCallback(() => { - currentTradeProviderSettings.value = TradeProvider.UNISWAP - currentSlippageTolerance.value = SLIPPAGE_TOLERANCE_DEFAULT + currentTradeProviderSettings.value = TradeProvider.UNISWAP_V2 + currentSlippageSettings.value = SLIPPAGE_DEFAULT if (provider === TradeProvider.ZRX) getCurrentTradeProviderGeneralSettings(provider).value = stringify({ pools: getEnumAsArray(ZrxTradePool).map((x) => x.value), @@ -90,7 +90,23 @@ export function SettingsDialog(props: SettingsDialogProps) { { - currentSlippageTolerance.value = tolerance + currentSlippageSettings.value = tolerance + }} + /> + + + + + + {t('plugin_trader_single_hop_only')} + + {slippage / 100}% + + + { + currentSlippageSettings.value = tolerance }} /> diff --git a/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/SlippageSlider.tsx b/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/SlippageSlider.tsx index f6ffc3bb3c29..370975eaceff 100644 --- a/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/SlippageSlider.tsx +++ b/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/SlippageSlider.tsx @@ -1,6 +1,6 @@ import { Slider } from '@material-ui/core' import { formatPercentage } from '@masknet/web3-shared' -import { SLIPPAGE_TOLERANCE_DEFAULT, SLIPPAGE_TOLERANCE_MAX, SLIPPAGE_TOLERANCE_MIN } from '../../constants' +import { SLIPPAGE_DEFAULT, SLIPPAGE_MAX, SLIPPAGE_MIN } from '../../constants' import { toBips } from '../../helpers' export interface SlippageSliderProps { @@ -9,14 +9,14 @@ export interface SlippageSliderProps { } export function SlippageSlider(props: SlippageSliderProps) { - const { value = SLIPPAGE_TOLERANCE_DEFAULT, onChange } = props + const { value = SLIPPAGE_DEFAULT, onChange } = props return ( formatPercentage(toBips(v))} step={10} - min={SLIPPAGE_TOLERANCE_MIN} - max={SLIPPAGE_TOLERANCE_MAX} + min={SLIPPAGE_MIN} + max={SLIPPAGE_MAX} onChange={(_, value: number | number[]) => onChange(value as number)} /> ) diff --git a/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/TradeForm.tsx b/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/TradeForm.tsx index a4441616bcc9..a35647ada557 100644 --- a/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/TradeForm.tsx +++ b/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/TradeForm.tsx @@ -12,7 +12,7 @@ import { TokenAmountPanel } from '../../../../web3/UI/TokenAmountPanel' import { useI18N } from '../../../../utils' import { useRemoteControlledDialog, useStylesExtends } from '@masknet/shared' import { EthereumTokenType, formatPercentage, FungibleTokenDetailed, isLessThan, pow10 } from '@masknet/web3-shared' -import { currentSlippageTolerance } from '../../settings' +import { currentSlippageSettings } from '../../settings' import { PluginTraderMessages } from '../../messages' import { isNativeTokenWrapper, toBips } from '../../helpers' import { resolveUniswapWarningLevel } from '../../pipes' @@ -219,8 +219,7 @@ export function TradeForm(props: TradeFormProps) {
- {t('plugin_trader_slipage_tolerance')}{' '} - {formatPercentage(toBips(currentSlippageTolerance.value))} + {t('plugin_trader_slipage_tolerance')} {formatPercentage(toBips(currentSlippageSettings.value))} diff --git a/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/TradeProviderIcon.tsx b/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/TradeProviderIcon.tsx index 7715b3827ca7..3c5fe02ba2ac 100644 --- a/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/TradeProviderIcon.tsx +++ b/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/TradeProviderIcon.tsx @@ -26,7 +26,9 @@ export interface TradeProviderIconProps { export function TradeProviderIcon(props: TradeProviderIconProps) { const classes = useStyles() switch (props.provider) { - case TradeProvider.UNISWAP: + case TradeProvider.UNISWAP_V2: + return + case TradeProvider.UNISWAP_V3: return case TradeProvider.ZRX: return diff --git a/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/TradeSummary.tsx b/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/TradeSummary.tsx index 5d1777f9e786..07ec6aaaac0c 100644 --- a/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/TradeSummary.tsx +++ b/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/TradeSummary.tsx @@ -222,7 +222,7 @@ export function TradeSummary(props: TradeSummaryProps) { {[ ...records, - ...(context?.IS_UNISWAP_LIKE ? uniswapRecords : []), + ...(context?.IS_UNISWAP_V2_LIKE || context?.IS_UNISWAP_V3_LIKE ? uniswapRecords : []), ...(provider === TradeProvider.BALANCER ? balancerRecords : []), ...(provider === TradeProvider.ZRX ? zrxRecords : []), ].map((record) => diff --git a/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/Trader.tsx b/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/Trader.tsx index a00eefcdafc8..44321358085e 100644 --- a/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/Trader.tsx +++ b/packages/maskbook/src/plugins/Trader/SNSAdaptor/trader/Trader.tsx @@ -3,7 +3,6 @@ import { useAsyncRetry, useTimeoutFn } from 'react-use' import { makeStyles } from '@material-ui/core' import type { Trade } from '@uniswap/v2-sdk' import type { Currency, TradeType } from '@uniswap/sdk-core' - import { ChainId, createERC20Token, @@ -71,7 +70,7 @@ export function Trader(props: TraderProps) { const classes = useStylesExtends(useStyles(), props) const context = useContext(TradeContext) - const provider = context?.TYPE ?? TradeProvider.UNISWAP + const provider = context?.TYPE ?? TradeProvider.UNISWAP_V2 //#region trade state const { @@ -313,7 +312,7 @@ export function Trader(props: TraderProps) { inputToken={inputToken} outputToken={outputToken} /> - {context?.IS_UNISWAP_LIKE ? ( + {context?.IS_UNISWAP_V2_LIKE ? ( ) : null} {[TradeProvider.BALANCER].includes(provider) ? ( @@ -322,7 +321,7 @@ export function Trader(props: TraderProps) { trade={tradeComputed as TradeComputed} /> ) : null} - {context?.IS_UNISWAP_LIKE ? ( + {context?.IS_UNISWAP_V2_LIKE ? ( >} provider={provider} diff --git a/packages/maskbook/src/plugins/Trader/SNSAdaptor/trending/CoinMarketTable.tsx b/packages/maskbook/src/plugins/Trader/SNSAdaptor/trending/CoinMarketTable.tsx index c53a638aa8c5..ac42438df554 100644 --- a/packages/maskbook/src/plugins/Trader/SNSAdaptor/trending/CoinMarketTable.tsx +++ b/packages/maskbook/src/plugins/Trader/SNSAdaptor/trending/CoinMarketTable.tsx @@ -81,11 +81,11 @@ export function CoinMarketTable(props: CoinMarketTableProps) { {dataProvider !== DataProvider.UNISWAP_INFO ? ( - + ) : null} - + {dataProvider !== DataProvider.UNISWAP_INFO ? ( <> diff --git a/packages/maskbook/src/plugins/Trader/apis/balancer/index.ts b/packages/maskbook/src/plugins/Trader/apis/balancer/index.ts index 19114f814a8a..52dc58cf6042 100644 --- a/packages/maskbook/src/plugins/Trader/apis/balancer/index.ts +++ b/packages/maskbook/src/plugins/Trader/apis/balancer/index.ts @@ -66,7 +66,7 @@ export async function getSwaps(tokenIn: string, tokenOut: string, swapType: BALA // compose routes // learn more: https://github.com/balancer-labs/balancer-frontend/blob/develop/src/components/swap/Routing.vue - const totalSwapAmount = swaps.reduce((total, rawHops) => total.plus(rawHops[0].swapAmount || '0'), ZERO) + const totalSwapAmount = swaps.reduce((total, rawHops) => total.plus(first(rawHops)?.swapAmount || '0'), ZERO) const pools = sor.onChainCache.pools const routes = swaps.map((rawHops) => { diff --git a/packages/maskbook/src/plugins/Trader/apis/trader/index.ts b/packages/maskbook/src/plugins/Trader/apis/trader/index.ts index 4f031dbd90fa..b78bd01bc7ef 100644 --- a/packages/maskbook/src/plugins/Trader/apis/trader/index.ts +++ b/packages/maskbook/src/plugins/Trader/apis/trader/index.ts @@ -9,7 +9,8 @@ export async function getAvailableTraderProviders(type?: TagType, keyword?: stri switch (networkType) { case NetworkType.Ethereum: return [ - TradeProvider.UNISWAP, + TradeProvider.UNISWAP_V2, + TradeProvider.UNISWAP_V3, TradeProvider.SUSHISWAP, TradeProvider.SASHIMISWAP, TradeProvider.ZRX, diff --git a/packages/maskbook/src/plugins/Trader/constants/trader.ts b/packages/maskbook/src/plugins/Trader/constants/trader.ts index 652623426b0a..0586607cf3be 100644 --- a/packages/maskbook/src/plugins/Trader/constants/trader.ts +++ b/packages/maskbook/src/plugins/Trader/constants/trader.ts @@ -64,11 +64,12 @@ export const WETH_ONLY: ERC20AgainstToken = { export const BIPS_BASE = new BigNumber(10000) export const ONE_BIPS = ONE.dividedBy(BIPS_BASE) -export const SLIPPAGE_TOLERANCE_MIN = 10 // bips -export const SLIPPAGE_TOLERANCE_DEFAULT = 50 // bips -export const SLIPPAGE_TOLERANCE_MAX = 500 // bips +export const SLIPPAGE_MIN = 10 // bips +export const SLIPPAGE_DEFAULT = 50 // bips +export const SLIPPAGE_MAX = 500 // bips -export const DEFAULT_TRANSACTION_DEADLINE = 20 /* minutes */ * 60 /* seconds */ +export const DEFAULT_TRANSACTION_DEADLINE = 30 /* minutes */ * 60 /* seconds */ +export const L2_TRANSACTION_DEADLINE = 60 /* minutes */ * 5 /* seconds */ export const PRICE_IMPACT_LOW = 100 // 1% export const PRICE_IMPACT_MEDIUM = 300 // 3% diff --git a/packages/maskbook/src/plugins/Trader/constants/uniswap.ts b/packages/maskbook/src/plugins/Trader/constants/uniswap.ts index 49203a6bf4f4..50812ebc7e10 100644 --- a/packages/maskbook/src/plugins/Trader/constants/uniswap.ts +++ b/packages/maskbook/src/plugins/Trader/constants/uniswap.ts @@ -1,6 +1,5 @@ import { ChainId } from '@masknet/web3-shared' import { Percent } from '@uniswap/sdk-core' -import { INIT_CODE_HASH } from '@uniswap/v2-sdk' import JSBI from 'jsbi' import { AMPL, DAI, MSKA, MSKB, MSKC, USDC, USDT, WBTC, WETH, WETH_ONLY } from './trader' import type { ERC20AgainstToken, ERC20TokenCustomizedBase } from './types' @@ -21,10 +20,6 @@ export const UNISWAP_BASE_AGAINST_TOKENS: ERC20AgainstToken = { [ChainId.Rinkeby]: [WETH, MSKA, MSKB, MSKC].map((x) => x[ChainId.Rinkeby]), } -export const THEGRAPH_UNISWAP_V2 = 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v2' - -export const UNISWAP_INIT_CODE_HASH = INIT_CODE_HASH - export const MAX_HOP = 3 // used to ensure the user doesn't send so much ETH so they end up with <.01 diff --git a/packages/maskbook/src/plugins/Trader/contracts/pancakeswap/useRouterV2Contract.ts b/packages/maskbook/src/plugins/Trader/contracts/pancakeswap/useRouterV2Contract.ts deleted file mode 100644 index 32bc6db8acad..000000000000 --- a/packages/maskbook/src/plugins/Trader/contracts/pancakeswap/useRouterV2Contract.ts +++ /dev/null @@ -1,9 +0,0 @@ -import RouterV2ABI from '@masknet/web3-contracts/abis/RouterV2.json' -import type { RouterV2 } from '@masknet/web3-contracts/types/RouterV2' -import { useContract, useTraderConstants } from '@masknet/web3-shared' -import type { AbiItem } from 'web3-utils' - -export function useRouterV2Contract() { - const { PANCAKESWAP_ROUTER_ADDRESS } = useTraderConstants() - return useContract(PANCAKESWAP_ROUTER_ADDRESS, RouterV2ABI as AbiItem[]) -} diff --git a/packages/maskbook/src/plugins/Trader/contracts/quickswap/useRouterV2Contract.ts b/packages/maskbook/src/plugins/Trader/contracts/quickswap/useRouterV2Contract.ts deleted file mode 100644 index 1ffc4c34a941..000000000000 --- a/packages/maskbook/src/plugins/Trader/contracts/quickswap/useRouterV2Contract.ts +++ /dev/null @@ -1,9 +0,0 @@ -import RouterV2ABI from '@masknet/web3-contracts/abis/RouterV2.json' -import type { RouterV2 } from '@masknet/web3-contracts/types/RouterV2' -import { useContract, useTraderConstants } from '@masknet/web3-shared' -import type { AbiItem } from 'web3-utils' - -export function useRouterV2Contract() { - const { QUICKSWAP_ROUTER_ADDRESS } = useTraderConstants() - return useContract(QUICKSWAP_ROUTER_ADDRESS, RouterV2ABI as AbiItem[]) -} diff --git a/packages/maskbook/src/plugins/Trader/contracts/sashimiswap/useRouterV2Contract.ts b/packages/maskbook/src/plugins/Trader/contracts/sashimiswap/useRouterV2Contract.ts deleted file mode 100644 index 32f68fd595f6..000000000000 --- a/packages/maskbook/src/plugins/Trader/contracts/sashimiswap/useRouterV2Contract.ts +++ /dev/null @@ -1,9 +0,0 @@ -import RouterV2ABI from '@masknet/web3-contracts/abis/RouterV2.json' -import type { RouterV2 } from '@masknet/web3-contracts/types/RouterV2' -import { useContract, useTraderConstants } from '@masknet/web3-shared' -import type { AbiItem } from 'web3-utils' - -export function useRouterV2Contract() { - const { SASHIMISWAP_ROUTER_ADDRESS } = useTraderConstants() - return useContract(SASHIMISWAP_ROUTER_ADDRESS, RouterV2ABI as AbiItem[]) -} diff --git a/packages/maskbook/src/plugins/Trader/contracts/sushiswap/useRouterV2Contract.ts b/packages/maskbook/src/plugins/Trader/contracts/sushiswap/useRouterV2Contract.ts deleted file mode 100644 index f25b37b1fd83..000000000000 --- a/packages/maskbook/src/plugins/Trader/contracts/sushiswap/useRouterV2Contract.ts +++ /dev/null @@ -1,9 +0,0 @@ -import RouterV2ABI from '@masknet/web3-contracts/abis/RouterV2.json' -import type { RouterV2 } from '@masknet/web3-contracts/types/RouterV2' -import { useContract, useTraderConstants } from '@masknet/web3-shared' -import type { AbiItem } from 'web3-utils' - -export function useRouterV2Contract() { - const { SUSHISWAP_ROUTER_ADDRESS } = useTraderConstants() - return useContract(SUSHISWAP_ROUTER_ADDRESS, RouterV2ABI as AbiItem[]) -} diff --git a/packages/maskbook/src/plugins/Trader/contracts/uniswap/usePoolContract.ts b/packages/maskbook/src/plugins/Trader/contracts/uniswap/usePoolContract.ts new file mode 100644 index 000000000000..68dec3e7cc43 --- /dev/null +++ b/packages/maskbook/src/plugins/Trader/contracts/uniswap/usePoolContract.ts @@ -0,0 +1,12 @@ +import PoolStateV3ABI from '@masknet/web3-contracts/abis/PoolStateV3.json' +import type { PoolStateV3 } from '@masknet/web3-contracts/types/PoolStateV3' +import { useContract, useContracts } from '@masknet/web3-shared' +import type { AbiItem } from 'web3-utils' + +export function usePoolContract(address: string) { + return useContract(address, PoolStateV3ABI as AbiItem[]) +} + +export function usePoolContracts(listOfAddress: string[]) { + return useContracts(listOfAddress, PoolStateV3ABI as AbiItem[]) +} diff --git a/packages/maskbook/src/plugins/Trader/contracts/uniswap/useQuoterContract.ts b/packages/maskbook/src/plugins/Trader/contracts/uniswap/useQuoterContract.ts new file mode 100644 index 000000000000..4e0e8102e588 --- /dev/null +++ b/packages/maskbook/src/plugins/Trader/contracts/uniswap/useQuoterContract.ts @@ -0,0 +1,9 @@ +import QuoterABI from '@masknet/web3-contracts/abis/Quoter.json' +import type { Quoter } from '@masknet/web3-contracts/types/Quoter' +import { useContract, useTraderConstants } from '@masknet/web3-shared' +import type { AbiItem } from 'web3-utils' + +export function useQuoterContract() { + const { UNISWAP_V3_QUOTER_ADDRESS } = useTraderConstants() + return useContract(UNISWAP_V3_QUOTER_ADDRESS, QuoterABI as AbiItem[]) +} diff --git a/packages/maskbook/src/plugins/Trader/contracts/uniswap/useRouterV2Contract.ts b/packages/maskbook/src/plugins/Trader/contracts/uniswap/useRouterV2Contract.ts index beb55b8c8d41..03bf3be4b50b 100644 --- a/packages/maskbook/src/plugins/Trader/contracts/uniswap/useRouterV2Contract.ts +++ b/packages/maskbook/src/plugins/Trader/contracts/uniswap/useRouterV2Contract.ts @@ -1,9 +1,8 @@ import RouterV2ABI from '@masknet/web3-contracts/abis/RouterV2.json' import type { RouterV2 } from '@masknet/web3-contracts/types/RouterV2' -import { useContract, useTraderConstants } from '@masknet/web3-shared' +import { useContract } from '@masknet/web3-shared' import type { AbiItem } from 'web3-utils' -export function useRouterV2Contract() { - const { UNISWAP_ROUTER_ADDRESS } = useTraderConstants() - return useContract(UNISWAP_ROUTER_ADDRESS, RouterV2ABI as AbiItem[]) +export function useRouterV2Contract(address?: string) { + return useContract(address, RouterV2ABI as AbiItem[]) } diff --git a/packages/maskbook/src/plugins/Trader/contracts/uniswap/useSwapRouterContract.ts b/packages/maskbook/src/plugins/Trader/contracts/uniswap/useSwapRouterContract.ts new file mode 100644 index 000000000000..747ae1ceaf2e --- /dev/null +++ b/packages/maskbook/src/plugins/Trader/contracts/uniswap/useSwapRouterContract.ts @@ -0,0 +1,8 @@ +import SwapRouterABI from '@masknet/web3-contracts/abis/SwapRouter.json' +import type { SwapRouter } from '@masknet/web3-contracts/types/SwapRouter' +import { useContract } from '@masknet/web3-shared' +import type { AbiItem } from 'web3-utils' + +export function useSwapRouterContract(address?: string) { + return useContract(address, SwapRouterABI as AbiItem[]) +} diff --git a/packages/maskbook/src/plugins/Trader/helpers/uniswap.ts b/packages/maskbook/src/plugins/Trader/helpers/uniswap.ts index 4abbd7fc59a4..c9faac14b325 100644 --- a/packages/maskbook/src/plugins/Trader/helpers/uniswap.ts +++ b/packages/maskbook/src/plugins/Trader/helpers/uniswap.ts @@ -1,4 +1,5 @@ import JSBI from 'jsbi' +import { memoize } from 'lodash-es' import BigNumber from 'bignumber.js' import { Currency, Token, CurrencyAmount, TradeType, Percent, Price, Ether } from '@uniswap/sdk-core' import type { Trade } from '@uniswap/v2-sdk' @@ -12,6 +13,44 @@ import { } from '@masknet/web3-shared' import { ONE_HUNDRED_PERCENT, WETH, ZERO_PERCENT } from '../constants' +export function swapErrorToUserReadableMessage(error: any): string { + let reason: string | undefined + while (Boolean(error)) { + reason = error.reason ?? error.message ?? reason + error = error.error ?? error.data?.originalError + } + + if (reason?.startsWith('execution reverted: ')) reason = reason.substr('execution reverted: '.length) + + switch (reason) { + case 'UniswapV2Router: EXPIRED': + return `The transaction could not be sent because the deadline has passed. Please check that your transaction deadline is not too low.` + case 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT': + case 'UniswapV2Router: EXCESSIVE_INPUT_AMOUNT': + return `This transaction will not succeed either due to price movement or fee on transfer. Try increasing your slippage tolerance.` + case 'TransferHelper: TRANSFER_FROM_FAILED': + return `The input token cannot be transferred. There may be an issue with the input token.` + case 'UniswapV2: TRANSFER_FAILED': + return `The output token cannot be transferred. There may be an issue with the output token.` + case 'UniswapV2: K': + return `The Uniswap invariant x*y=k was not satisfied by the swap. This usually means one of the tokens you are swapping incorporates custom behavior on transfer.` + case 'Too little received': + case 'Too much requested': + case 'STF': + return `This transaction will not succeed due to price movement. Try increasing your slippage tolerance. Note: fee on transfer and rebase tokens are incompatible with Uniswap V3.` + case 'TF': + return `The output token cannot be transferred. There may be an issue with the output token. Note: fee on transfer and rebase tokens are incompatible with Uniswap V3.` + default: + if (reason?.includes('undefined is not an object')) { + console.error(error, reason) + return `An error occurred when trying to execute this swap. You may need to increase your slippage tolerance. If that does not work, there may be an incompatibility with the token you are trading. Note: fee on transfer and rebase tokens are incompatible with Uniswap V3.` + } + return `Unknown error${ + reason ? `: "${reason}"` : '' + }. Try increasing your slippage tolerance. Note: fee on transfer and rebase tokens are incompatible with Uniswap V3.` + } +} + export function toUniswapChainId(chainId: ChainId) { return chainId as number } @@ -103,7 +142,7 @@ export function isTradeBetter( export class ExtendedEther extends Ether { public get wrapped(): Token { - if (this.chainId in WETH) return toUniswapToken(this.chainId, WETH[this.chainId as ChainId]) + if (this.chainId in WETH) return ExtendedEther.wrapEther(this.chainId) throw new Error('Unsupported chain ID') } @@ -112,4 +151,6 @@ export class ExtendedEther extends Ether { public static onChain(chainId: number): ExtendedEther { return this._cachedEther[chainId] ?? (this._cachedEther[chainId] = new ExtendedEther(chainId)) } + + public static wrapEther = memoize((chainId: ChainId) => toUniswapToken(chainId, WETH[chainId])) } diff --git a/packages/maskbook/src/plugins/Trader/pipes.ts b/packages/maskbook/src/plugins/Trader/pipes.ts index 2db5cefae1cb..c3476c945479 100644 --- a/packages/maskbook/src/plugins/Trader/pipes.ts +++ b/packages/maskbook/src/plugins/Trader/pipes.ts @@ -50,8 +50,10 @@ export function resolveDataProviderLink(dataProvider: DataProvider) { export function resolveTradeProviderName(tradeProvider: TradeProvider) { switch (tradeProvider) { - case TradeProvider.UNISWAP: + case TradeProvider.UNISWAP_V2: return 'Uniswap V2' + case TradeProvider.UNISWAP_V3: + return 'Uniswap V3' case TradeProvider.ZRX: return '0x' case TradeProvider.SUSHISWAP: @@ -73,7 +75,9 @@ export function resolveTradeProviderName(tradeProvider: TradeProvider) { export function resolveTradeProviderLink(tradeProvider: TradeProvider) { switch (tradeProvider) { - case TradeProvider.UNISWAP: + case TradeProvider.UNISWAP_V2: + return 'https://uniswap.org/' + case TradeProvider.UNISWAP_V3: return 'https://uniswap.org/' case TradeProvider.ZRX: return 'https://0x.org/' @@ -96,8 +100,10 @@ export function resolveTradeProviderLink(tradeProvider: TradeProvider) { export function resolveTradePairLink(tradeProvider: TradeProvider, address: string, networkType: NetworkType) { switch (tradeProvider) { - case TradeProvider.UNISWAP: + case TradeProvider.UNISWAP_V2: return `https://v2.info.uniswap.org/pair/${address}` + case TradeProvider.UNISWAP_V3: + return `https://info.uniswap.org/pair/${address}` case TradeProvider.ZRX: return '' case TradeProvider.DODO: { diff --git a/packages/maskbook/src/plugins/Trader/services.ts b/packages/maskbook/src/plugins/Trader/services.ts index 820348aef45b..a2fe980a03c2 100644 --- a/packages/maskbook/src/plugins/Trader/services.ts +++ b/packages/maskbook/src/plugins/Trader/services.ts @@ -30,7 +30,7 @@ currentChainIdSettings.addListener((chainId: ChainId) => { currentDataProviderSettings.value = DataProvider.COIN_GECKO break case NetworkType.Arbitrum: - currentTradeProviderSettings.value = TradeProvider.UNISWAP + currentTradeProviderSettings.value = TradeProvider.UNISWAP_V2 if (currentDataProviderSettings.value === DataProvider.UNISWAP_INFO) currentDataProviderSettings.value = DataProvider.COIN_MARKET_CAP break diff --git a/packages/maskbook/src/plugins/Trader/settings.ts b/packages/maskbook/src/plugins/Trader/settings.ts index 749a1f9bda3e..1c5bfebc4c29 100644 --- a/packages/maskbook/src/plugins/Trader/settings.ts +++ b/packages/maskbook/src/plugins/Trader/settings.ts @@ -2,21 +2,28 @@ import { getEnumAsArray, unreachable } from '@dimensiondev/kit' import stringify from 'json-stable-stringify' import { createGlobalSettings, createInternalSettings } from '../../settings/createSettings' import { i18n } from '../../utils/i18n-next' -import { PLUGIN_IDENTIFIER, SLIPPAGE_TOLERANCE_DEFAULT } from './constants' +import { PLUGIN_IDENTIFIER, SLIPPAGE_DEFAULT } from './constants' import { ZrxTradePool } from './types' import { DataProvider, TradeProvider } from '@masknet/public-api' /** * The slippage tolerance of trader */ -export const currentSlippageTolerance = createGlobalSettings( +export const currentSlippageSettings = createGlobalSettings( `${PLUGIN_IDENTIFIER}+slippageTolerance`, - SLIPPAGE_TOLERANCE_DEFAULT, + SLIPPAGE_DEFAULT, { primary: () => '', }, ) +/** + * Single Hop + */ +export const currentSingleHopOnlySettings = createGlobalSettings(`${PLUGIN_IDENTIFIER}+singleHopOnly`, false, { + primary: () => '', +}) + /** * The default data provider */ @@ -34,7 +41,7 @@ export const currentDataProviderSettings = createGlobalSettings( */ export const currentTradeProviderSettings = createGlobalSettings( `${PLUGIN_IDENTIFIER}+tradeProvider`, - TradeProvider.UNISWAP, + TradeProvider.UNISWAP_V2, { primary: () => i18n.t('plugin_trader_settings_trade_provider_primary'), secondary: () => i18n.t('plugin_trader_settings_trade_provider_secondary'), @@ -43,7 +50,7 @@ export const currentTradeProviderSettings = createGlobalSettings( export const ethereumNetworkTradeProviderSettings = createGlobalSettings( `${PLUGIN_IDENTIFIER}+eth+tradeProvider`, - TradeProvider.UNISWAP, + TradeProvider.UNISWAP_V2, { primary: () => '' }, ) @@ -64,7 +71,8 @@ export interface TradeProviderSettings { pools: ZrxTradePool[] } -const uniswapSettings = createInternalSettings(`${PLUGIN_IDENTIFIER}+tradeProvider+uniswap`, '') +const uniswapV2Settings = createInternalSettings(`${PLUGIN_IDENTIFIER}+tradeProvider+uniswap+v2`, '') +const uniswapV3Settings = createInternalSettings(`${PLUGIN_IDENTIFIER}+tradeProvider+uniswap+v3`, '') const zrxSettings = createInternalSettings( `${PLUGIN_IDENTIFIER}+tradeProvider+zrx`, stringify({ @@ -83,8 +91,10 @@ const dodoSettings = createInternalSettings(`${PLUGIN_IDENTIFIER}+tradeP */ export function getCurrentTradeProviderGeneralSettings(tradeProvider: TradeProvider) { switch (tradeProvider) { - case TradeProvider.UNISWAP: - return uniswapSettings + case TradeProvider.UNISWAP_V2: + return uniswapV2Settings + case TradeProvider.UNISWAP_V3: + return uniswapV3Settings case TradeProvider.ZRX: return zrxSettings case TradeProvider.SUSHISWAP: diff --git a/packages/maskbook/src/plugins/Trader/trader/0x/useSlippageTolerance.ts b/packages/maskbook/src/plugins/Trader/trader/0x/useSlippageTolerance.ts index 7ed6d99ecca0..b78798ce50dd 100644 --- a/packages/maskbook/src/plugins/Trader/trader/0x/useSlippageTolerance.ts +++ b/packages/maskbook/src/plugins/Trader/trader/0x/useSlippageTolerance.ts @@ -1,9 +1,9 @@ import { clamp } from 'lodash-es' import { useValueRef } from '@masknet/shared' -import { SLIPPAGE_TOLERANCE_MAX, SLIPPAGE_TOLERANCE_MIN } from '../../constants' -import { currentSlippageTolerance } from '../../settings' +import { SLIPPAGE_MAX, SLIPPAGE_MIN } from '../../constants' +import { currentSlippageSettings } from '../../settings' export function useSlippageTolerance() { - const slippage_ = useValueRef(currentSlippageTolerance) - return clamp(slippage_, SLIPPAGE_TOLERANCE_MIN, SLIPPAGE_TOLERANCE_MAX) + const slippage_ = useValueRef(currentSlippageSettings) + return clamp(slippage_, SLIPPAGE_MIN, SLIPPAGE_MAX) } diff --git a/packages/maskbook/src/plugins/Trader/trader/balancer/useTradeAmount.ts b/packages/maskbook/src/plugins/Trader/trader/balancer/useTradeAmount.ts index 6cb74fb696b8..47113bd0b835 100644 --- a/packages/maskbook/src/plugins/Trader/trader/balancer/useTradeAmount.ts +++ b/packages/maskbook/src/plugins/Trader/trader/balancer/useTradeAmount.ts @@ -1,13 +1,10 @@ import { ZERO } from '@masknet/web3-shared' import BigNumber from 'bignumber.js' import { useMemo } from 'react' -import { ONE_BIPS, SLIPPAGE_TOLERANCE_DEFAULT } from '../../constants' +import { ONE_BIPS, SLIPPAGE_DEFAULT } from '../../constants' import { SwapResponse, TradeComputed, TradeStrategy } from '../../types' -export function useTradeAmount( - trade: TradeComputed | null, - allowedSlippage = SLIPPAGE_TOLERANCE_DEFAULT, -) { +export function useTradeAmount(trade: TradeComputed | null, allowedSlippage = SLIPPAGE_DEFAULT) { return useMemo(() => { if (!trade) return ZERO return trade.strategy === TradeStrategy.ExactIn diff --git a/packages/maskbook/src/plugins/Trader/trader/balancer/useTradeCallback.ts b/packages/maskbook/src/plugins/Trader/trader/balancer/useTradeCallback.ts index b427ae81e502..1d229e0a4a8e 100644 --- a/packages/maskbook/src/plugins/Trader/trader/balancer/useTradeCallback.ts +++ b/packages/maskbook/src/plugins/Trader/trader/balancer/useTradeCallback.ts @@ -12,14 +12,14 @@ import { useTraderConstants, } from '@masknet/web3-shared' import { useCallback, useState } from 'react' -import { SLIPPAGE_TOLERANCE_DEFAULT } from '../../constants' +import { SLIPPAGE_DEFAULT } from '../../constants' import { SwapResponse, TradeComputed, TradeStrategy } from '../../types' import { useTradeAmount } from './useTradeAmount' export function useTradeCallback( trade: TradeComputed | null, exchangeProxyContract: ExchangeProxy | null, - allowedSlippage = SLIPPAGE_TOLERANCE_DEFAULT, + allowedSlippage = SLIPPAGE_DEFAULT, ) { const nonce = useNonce() const gasPrice = useGasPrice() diff --git a/packages/maskbook/src/plugins/Trader/trader/dodo/useSlippageTolerance.ts b/packages/maskbook/src/plugins/Trader/trader/dodo/useSlippageTolerance.ts index 7ed6d99ecca0..b78798ce50dd 100644 --- a/packages/maskbook/src/plugins/Trader/trader/dodo/useSlippageTolerance.ts +++ b/packages/maskbook/src/plugins/Trader/trader/dodo/useSlippageTolerance.ts @@ -1,9 +1,9 @@ import { clamp } from 'lodash-es' import { useValueRef } from '@masknet/shared' -import { SLIPPAGE_TOLERANCE_MAX, SLIPPAGE_TOLERANCE_MIN } from '../../constants' -import { currentSlippageTolerance } from '../../settings' +import { SLIPPAGE_MAX, SLIPPAGE_MIN } from '../../constants' +import { currentSlippageSettings } from '../../settings' export function useSlippageTolerance() { - const slippage_ = useValueRef(currentSlippageTolerance) - return clamp(slippage_, SLIPPAGE_TOLERANCE_MIN, SLIPPAGE_TOLERANCE_MAX) + const slippage_ = useValueRef(currentSlippageSettings) + return clamp(slippage_, SLIPPAGE_MIN, SLIPPAGE_MAX) } diff --git a/packages/maskbook/src/plugins/Trader/trader/uniswap/useAllCommonPairs.ts b/packages/maskbook/src/plugins/Trader/trader/uniswap/useAllCommonPairs.ts index 267b3597bb53..beb47d325cc6 100644 --- a/packages/maskbook/src/plugins/Trader/trader/uniswap/useAllCommonPairs.ts +++ b/packages/maskbook/src/plugins/Trader/trader/uniswap/useAllCommonPairs.ts @@ -20,49 +20,47 @@ export function useAllCurrencyCombinations(currencyA?: Currency, currencyB?: Cur const additionalA = tokenA ? context?.ADDITIONAL_TOKENS[chainId]?.[tokenA.address] ?? [] : [] const additionalB = tokenB ? context?.ADDITIONAL_TOKENS[chainId]?.[tokenB.address] ?? [] : [] return [...common, ...additionalA, ...additionalB].map((x) => toUniswapToken(chainId, x)) - }, [chainId, chainIdValid, tokenA, tokenB]) + }, [chainId, chainIdValid, tokenA?.address, tokenB?.address]) const basePairs: [Token, Token][] = useMemo( () => flatMap(bases, (base): [Token, Token][] => bases.map((otherBase) => [base, otherBase])), [bases], ) - return useMemo( - () => - tokenA && tokenB - ? [ - // the direct pair - [tokenA, tokenB], - // token A against all bases - ...bases.map((base): [Token, Token] => [tokenA, base]), - // token B against all bases - ...bases.map((base): [Token, Token] => [tokenB, base]), - // each base against all bases - ...basePairs, - ] - .filter((tokens): tokens is [Token, Token] => Boolean(tokens[0] && tokens[1])) - .filter(([t0, t1]) => t0.address !== t1.address) - .filter(([tokenA, tokenB]) => { - if (!chainIdValid) return true - const customBases = context?.CUSTOM_TOKENS?.[chainId] + return useMemo(() => { + if (!tokenA || !tokenB) return [] - const customBasesA: Token[] | undefined = customBases?.[tokenA.address]?.map((x) => - toUniswapToken(chainId, x), - ) - const customBasesB: Token[] | undefined = customBases?.[tokenB.address]?.map((x) => - toUniswapToken(chainId, x), - ) + return [ + // the direct pair + [tokenA, tokenB], + // token A against all bases + ...bases.map((base): [Token, Token] => [tokenA, base]), + // token B against all bases + ...bases.map((base): [Token, Token] => [tokenB, base]), + // each base against all bases + ...basePairs, + ] + .filter((tokens): tokens is [Token, Token] => Boolean(tokens[0] && tokens[1])) + .filter(([t0, t1]) => t0.address !== t1.address) + .filter(([tokenA, tokenB]) => { + if (!chainIdValid) return true + const customBases = context?.CUSTOM_TOKENS?.[chainId] - if (!customBasesA && !customBasesB) return true + const customBasesA: Token[] | undefined = customBases?.[tokenA.address]?.map((x) => + toUniswapToken(chainId, x), + ) + const customBasesB: Token[] | undefined = customBases?.[tokenB.address]?.map((x) => + toUniswapToken(chainId, x), + ) - if (customBasesA && !customBasesA.find((base) => tokenB.equals(base))) return false - if (customBasesB && !customBasesB.find((base) => tokenA.equals(base))) return false + if (!customBasesA && !customBasesB) return true - return true - }) - : [], - [tokenA, tokenB, bases, basePairs, chainId, chainIdValid], - ) + if (customBasesA && !customBasesA.find((base) => tokenB.equals(base))) return false + if (customBasesB && !customBasesB.find((base) => tokenA.equals(base))) return false + + return true + }) + }, [tokenA?.address, tokenB?.address, bases, basePairs, chainId, chainIdValid]) } export function useAllCommonPairs(currencyA?: Currency, currencyB?: Currency) { diff --git a/packages/maskbook/src/plugins/Trader/trader/uniswap/useAllV3Routes.ts b/packages/maskbook/src/plugins/Trader/trader/uniswap/useAllV3Routes.ts new file mode 100644 index 000000000000..3b106a2d3007 --- /dev/null +++ b/packages/maskbook/src/plugins/Trader/trader/uniswap/useAllV3Routes.ts @@ -0,0 +1,73 @@ +import { useMemo } from 'react' +import type { Currency } from '@uniswap/sdk-core' +import { Pool, Route } from '@uniswap/v3-sdk' +import { useChainId } from '@masknet/web3-shared' +import { useV3SwapPools } from './useV3SwapPools' +import { useSingleHopOnly } from './useSingleHopOnly' + +function computeAllRoutes( + currencyIn: Currency, + currencyOut: Currency, + pools: Pool[], + chainId: number, + currentPath: Pool[] = [], + allPaths: Route[] = [], + startCurrencyIn: Currency = currencyIn, + maxHops = 2, +): Route[] { + const tokenIn = currencyIn?.wrapped + const tokenOut = currencyOut?.wrapped + if (!tokenIn || !tokenOut) throw new Error('Missing tokenIn/tokenOut') + + for (const pool of pools) { + if (currentPath.includes(pool) || !pool.involvesToken(tokenIn)) continue + + const outputToken = pool.token0.equals(tokenIn) ? pool.token1 : pool.token0 + if (outputToken.equals(tokenOut)) { + allPaths.push(new Route([...currentPath, pool], startCurrencyIn, currencyOut)) + } else if (maxHops > 1) { + computeAllRoutes( + outputToken, + currencyOut, + pools, + chainId, + [...currentPath, pool], + allPaths, + startCurrencyIn, + maxHops - 1, + ) + } + } + + return allPaths +} + +/** + * Returns all the routes from an input currency to an output currency + * @param currencyIn the input currency + * @param currencyOut the output currency + */ +export function useAllV3Routes( + currencyIn?: Currency, + currencyOut?: Currency, +): { loading: boolean; routes: Route[] } { + const chainId = useChainId() + const { pools, loading: poolsLoading } = useV3SwapPools(currencyIn, currencyOut) + const singleHopOnly = useSingleHopOnly() + + return useMemo(() => { + if (poolsLoading || !chainId || !pools || !currencyIn || !currencyOut) return { loading: true, routes: [] } + + const routes = computeAllRoutes( + currencyIn, + currencyOut, + pools, + chainId, + [], + [], + currencyIn, + singleHopOnly ? 1 : 2, + ) + return { loading: false, routes } + }, [chainId, currencyIn?.wrapped.address, currencyOut?.wrapped.address, pools, poolsLoading, singleHopOnly]) +} diff --git a/packages/maskbook/src/plugins/Trader/trader/uniswap/usePools.ts b/packages/maskbook/src/plugins/Trader/trader/uniswap/usePools.ts new file mode 100644 index 000000000000..5dcee3d9c89b --- /dev/null +++ b/packages/maskbook/src/plugins/Trader/trader/uniswap/usePools.ts @@ -0,0 +1,105 @@ +import { useContext, useMemo } from 'react' +import { useAsyncRetry } from 'react-use' +import BigNumber from 'bignumber.js' +import { computePoolAddress, Pool, FeeAmount } from '@uniswap/v3-sdk' +import type { Token, Currency } from '@uniswap/sdk-core' +import { MulticalStateType, useChainId, useMutlipleContractSingleData } from '@masknet/web3-shared' +import { usePoolContracts } from '../../contracts/uniswap/usePoolContract' +import { TradeContext } from '../useTradeContext' + +export enum PoolState { + LOADING = 0, + NOT_EXISTS = 1, + EXISTS = 2, + INVALID = 3, +} + +export function usePools( + poolKeys: [Currency | undefined, Currency | undefined, FeeAmount | undefined][], +): [PoolState, Pool | null][] { + const chainId = useChainId() + const context = useContext(TradeContext) + + const transformed: ([Token, Token, FeeAmount] | null)[] = useMemo(() => { + return poolKeys.map(([currencyA, currencyB, feeAmount]) => { + if (!chainId || !currencyA || !currencyB || !feeAmount) return null + + const tokenA = currencyA?.wrapped + const tokenB = currencyB?.wrapped + if (!tokenA || !tokenB || tokenA.equals(tokenB)) return null + const [token0, token1] = tokenA.sortsBefore(tokenB) ? [tokenA, tokenB] : [tokenB, tokenA] + return [token0, token1, feeAmount] + }) + }, [chainId, poolKeys]) + + const poolAddresses = useMemo(() => { + return transformed.map((value) => { + if (!context?.IS_UNISWAP_V3_LIKE) return '' + if (!context?.FACTORY_CONTRACT_ADDRESS || !value) return '' + return computePoolAddress({ + factoryAddress: context.FACTORY_CONTRACT_ADDRESS, + tokenA: value[0], + tokenB: value[1], + fee: value[2], + }) + }) + }, [chainId, transformed, context?.FACTORY_CONTRACT_ADDRESS]) + + const poolContracts = usePoolContracts(poolAddresses) + + const [slot0s, slot0sCalls, slot0sState, slot0sCallback] = useMutlipleContractSingleData( + poolContracts, + Array.from<'slot0'>({ length: poolContracts.length }).fill('slot0'), + [], + ) + const [liquidities, liquiditiesCalls, liquiditiesState, liquiditiesCallback] = useMutlipleContractSingleData( + poolContracts, + Array.from<'liquidity'>({ length: poolContracts.length }).fill('liquidity'), + [], + ) + + useAsyncRetry(() => slot0sCallback(slot0sCalls), [slot0sCallback, slot0sCalls]) + useAsyncRetry(() => liquiditiesCallback(liquiditiesCalls), [liquiditiesCallback, liquiditiesCalls]) + + return useMemo(() => { + return poolKeys.map((_key, index) => { + const [token0, token1, fee] = transformed[index] ?? [] + if (!token0 || !token1 || !fee) return [PoolState.INVALID, null] + + const { value: slot0, error: slot0Error } = slot0s[index] ?? {} + const { value: liquidity, error: liquidityError } = liquidities[index] ?? {} + const slot0Loading = slot0sState.type === MulticalStateType.PENDING + const liquiditiesLoading = liquiditiesState.type === MulticalStateType.PENDING + + if (slot0Error || liquidityError) return [PoolState.INVALID, null] + if (slot0Loading || liquiditiesLoading) return [PoolState.LOADING, null] + + if (!slot0 || !liquidity) return [PoolState.NOT_EXISTS, null] + + if (new BigNumber(slot0.sqrtPriceX96 ?? '0').isZero()) return [PoolState.NOT_EXISTS, null] + + try { + return [ + PoolState.EXISTS, + new Pool(token0, token1, fee, slot0.sqrtPriceX96, liquidity[0], Number.parseInt(slot0.tick, 10)), + ] + } catch (error) { + console.error('Error when constructing the pool', error) + return [PoolState.NOT_EXISTS, null] + } + }) + }, [slot0s, liquidities, slot0sState.type, liquiditiesState.type, poolKeys, transformed]) +} + +export function usePool( + currencyA: Currency | undefined, + currencyB: Currency | undefined, + feeAmount: FeeAmount | undefined, +): [PoolState, Pool | null] { + const poolKeys: [Currency | undefined, Currency | undefined, FeeAmount | undefined][] = useMemo( + () => [[currencyA, currencyB, feeAmount]], + [currencyA, currencyB, feeAmount], + ) + + return usePools(poolKeys)[0] +} diff --git a/packages/maskbook/src/plugins/Trader/trader/uniswap/useSingleHopOnly.ts b/packages/maskbook/src/plugins/Trader/trader/uniswap/useSingleHopOnly.ts new file mode 100644 index 000000000000..1c67c18b0854 --- /dev/null +++ b/packages/maskbook/src/plugins/Trader/trader/uniswap/useSingleHopOnly.ts @@ -0,0 +1,7 @@ +import { useValueRef } from '@masknet/shared' +import { currentSingleHopOnlySettings } from '../../settings' + +export function useSingleHopOnly() { + const singleHopOnly = useValueRef(currentSingleHopOnlySettings) + return singleHopOnly +} diff --git a/packages/maskbook/src/plugins/Trader/trader/uniswap/useSlippageTolerance.ts b/packages/maskbook/src/plugins/Trader/trader/uniswap/useSlippageTolerance.ts index 7d4ecaad48a5..2be3cc903d8c 100644 --- a/packages/maskbook/src/plugins/Trader/trader/uniswap/useSlippageTolerance.ts +++ b/packages/maskbook/src/plugins/Trader/trader/uniswap/useSlippageTolerance.ts @@ -1,11 +1,11 @@ import { clamp } from 'lodash-es' import { useValueRef } from '@masknet/shared' -import { SLIPPAGE_TOLERANCE_MAX, SLIPPAGE_TOLERANCE_MIN } from '../../constants' +import { SLIPPAGE_MAX, SLIPPAGE_MIN } from '../../constants' import { toUniswapPercent } from '../../helpers' -import { currentSlippageTolerance } from '../../settings' +import { currentSlippageSettings } from '../../settings' export function useSlippageTolerance() { - const slippage_ = useValueRef(currentSlippageTolerance) - const slippage = clamp(slippage_, SLIPPAGE_TOLERANCE_MIN, SLIPPAGE_TOLERANCE_MAX) + const slippage_ = useValueRef(currentSlippageSettings) + const slippage = clamp(slippage_, SLIPPAGE_MIN, SLIPPAGE_MAX) return toUniswapPercent(slippage, 10000) } diff --git a/packages/maskbook/src/plugins/Trader/trader/uniswap/useTrade.ts b/packages/maskbook/src/plugins/Trader/trader/uniswap/useTrade.ts index 9909abd7e2fe..547cd25618cf 100644 --- a/packages/maskbook/src/plugins/Trader/trader/uniswap/useTrade.ts +++ b/packages/maskbook/src/plugins/Trader/trader/uniswap/useTrade.ts @@ -1,9 +1,10 @@ import { isZero, useChainId, FungibleTokenDetailed } from '@masknet/web3-shared' -import { toUniswapCurrencyAmount, toUniswapCurrency } from '../../helpers' import { TradeStrategy } from '../../types' -import { useV2BestTradeExactIn, useV2BestTradeExactOut } from './useV2Trade' +import { toUniswapCurrencyAmount, toUniswapCurrency } from '../../helpers' +import { useV2BestTradeExactIn, useV2BestTradeExactOut } from './useV2BestTrade' +import { useV3BestTradeExactIn, useV3BestTradeExactOut } from './useV3BestTrade' -export function useTrade( +function useTrade( strategy: TradeStrategy = TradeStrategy.ExactIn, inputAmount: string, outputAmount: string, @@ -12,6 +13,12 @@ export function useTrade( ) { const isExactIn = strategy === TradeStrategy.ExactIn const isTradable = !isZero(inputAmount) || !isZero(outputAmount) + const isNotAvailable = + !isTradable || + !inputToken || + !outputToken || + (inputAmount === '0' && isExactIn) || + (outputAmount === '0' && !isExactIn) const chainId = useChainId() const inputCurrency = toUniswapCurrency(chainId, inputToken) @@ -21,31 +28,81 @@ export function useTrade( isExactIn ? inputToken : outputToken, isExactIn ? inputAmount : outputAmount, ) - - const { value: bestTradeExactIn, ...asyncResultExactIn } = useV2BestTradeExactIn( - isExactIn ? tradeAmount : undefined, - outputCurrency, - ) - const { value: bestTradeExactOut, ...asyncResultExactOut } = useV2BestTradeExactOut( + return { + isNotAvailable, + isExactIn, + tradeAmount, inputCurrency, - !isExactIn ? tradeAmount : undefined, + outputCurrency, + } +} + +export function useV2Trade( + strategy: TradeStrategy = TradeStrategy.ExactIn, + inputAmount: string, + outputAmount: string, + inputToken?: FungibleTokenDetailed, + outputToken?: FungibleTokenDetailed, +) { + const { isNotAvailable, isExactIn, tradeAmount, inputCurrency, outputCurrency } = useTrade( + strategy, + inputAmount, + outputAmount, + inputToken, + outputToken, ) - if ( - !isTradable || - !inputToken || - !outputToken || - (inputAmount === '0' && isExactIn) || - (outputAmount === '0' && !isExactIn) + //#region v2 + const v2BestTradeExactIn = useV2BestTradeExactIn(isExactIn ? tradeAmount : undefined, outputCurrency) + const v2BestTradeExactOut = useV2BestTradeExactOut(inputCurrency, !isExactIn ? tradeAmount : undefined) + //#endregion + + const v2Trade = isExactIn ? v2BestTradeExactIn : v2BestTradeExactOut + + if (isNotAvailable) + return { + ...v2Trade, + error: undefined, + loading: false, + value: null, + } + return { + ...v2Trade, + value: v2Trade.value, + } +} + +export function useV3Trade( + strategy: TradeStrategy = TradeStrategy.ExactIn, + inputAmount: string, + outputAmount: string, + inputToken?: FungibleTokenDetailed, + outputToken?: FungibleTokenDetailed, +) { + const { isNotAvailable, isExactIn, tradeAmount, inputCurrency, outputCurrency } = useTrade( + strategy, + inputAmount, + outputAmount, + inputToken, + outputToken, ) + + //#region v2 + const v3BestTradeExactIn = useV3BestTradeExactIn(isExactIn ? tradeAmount : undefined, outputCurrency) + const v3BestTradeExactOut = useV3BestTradeExactOut(inputCurrency, !isExactIn ? tradeAmount : undefined) + //#endregion + + const v3Trade = isExactIn ? v3BestTradeExactIn : v3BestTradeExactOut + + if (isNotAvailable) return { - ...(isExactIn ? asyncResultExactIn : asyncResultExactOut), + ...v3Trade, error: undefined, loading: false, value: null, } return { - ...(isExactIn ? asyncResultExactIn : asyncResultExactOut), - value: isExactIn ? bestTradeExactIn : bestTradeExactOut, + ...v3Trade, + value: v3Trade.value ?? null, } } diff --git a/packages/maskbook/src/plugins/Trader/trader/uniswap/useTradeBreakdown.ts b/packages/maskbook/src/plugins/Trader/trader/uniswap/useTradeBreakdown.ts new file mode 100644 index 000000000000..38f9a7e1f34f --- /dev/null +++ b/packages/maskbook/src/plugins/Trader/trader/uniswap/useTradeBreakdown.ts @@ -0,0 +1,63 @@ +import { useMemo } from 'react' +import JSBI from 'jsbi' +import { Trade as V2Trade } from '@uniswap/v2-sdk' +import { Percent, Fraction, CurrencyAmount, Currency } from '@uniswap/sdk-core' +import type { Trade } from '../../types' + +const BASE_FEE = new Percent(JSBI.BigInt(30), JSBI.BigInt(10000)) +const ONE_HUNDRED_PERCENT = new Percent(JSBI.BigInt(10000), JSBI.BigInt(10000)) +const INPUT_FRACTION_AFTER_FEE = ONE_HUNDRED_PERCENT.subtract(BASE_FEE) + +// computes realized lp fee as a percent +function computeRealizedLPFeePercent(trade: Trade): Percent { + if (trade instanceof V2Trade) { + // for each hop in our trade, take away the x*y=k price impact from 0.3% fees + // e.g. for 3 tokens/2 hops: 1 - ((1 - .03) * (1-.03)) + const percent = ONE_HUNDRED_PERCENT.subtract( + trade.route.pairs.reduce( + (currentFee: Percent): Percent => currentFee.multiply(INPUT_FRACTION_AFTER_FEE), + ONE_HUNDRED_PERCENT, + ), + ) + return new Percent(percent.numerator, percent.denominator) + } else { + const percent = ONE_HUNDRED_PERCENT.subtract( + trade.route.pools.reduce( + (currentFee: Percent, pool): Percent => + currentFee.multiply(ONE_HUNDRED_PERCENT.subtract(new Fraction(pool.fee, 1_000_000))), + ONE_HUNDRED_PERCENT, + ), + ) + return new Percent(percent.numerator, percent.denominator) + } +} + +// computes price breakdown for the trade +function computeRealizedLPFeeAmount(trade?: Trade | null): CurrencyAmount | undefined { + if (trade) { + const realizedLPFee = computeRealizedLPFeePercent(trade) + + // the amount of the input that accrues to LPs + return CurrencyAmount.fromRawAmount( + trade.inputAmount.currency, + trade.inputAmount.multiply(realizedLPFee).quotient, + ) + } + return undefined +} + +export function useTradeBreakdown(trade: Trade | null) { + return useMemo(() => { + if (!trade) return null + const realizedLPFeePercent = computeRealizedLPFeePercent(trade) + const realizedLPFeeAmount = computeRealizedLPFeeAmount(trade) + return { + realizedLPFeePercent, + realizedLPFeeAmount, + + // different ver of @uniswap/sdk-core were userd by @uniswap/v2-sdk and @uniswap/v3-sdk + realizedLPFee: trade.inputAmount.multiply(realizedLPFeePercent) as CurrencyAmount, + priceImpact: trade.priceImpact.subtract(realizedLPFeePercent) as Percent, + } + }, [trade]) +} diff --git a/packages/maskbook/src/plugins/Trader/trader/uniswap/useTradeCallback.ts b/packages/maskbook/src/plugins/Trader/trader/uniswap/useTradeCallback.ts index fcf70b8baf14..52b085ba78f6 100644 --- a/packages/maskbook/src/plugins/Trader/trader/uniswap/useTradeCallback.ts +++ b/packages/maskbook/src/plugins/Trader/trader/uniswap/useTradeCallback.ts @@ -1,37 +1,42 @@ import { useCallback, useState } from 'react' -import type { Currency, TradeType } from '@uniswap/sdk-core' -import type { SwapParameters, Trade } from '@uniswap/v2-sdk' -import type { RouterV2 } from '@masknet/web3-contracts/types/RouterV2' -import { TransactionState, TransactionStateType, TransactionEventType, useAccount } from '@masknet/web3-shared' +import BigNumber from 'bignumber.js' +import type { SwapParameters } from '@uniswap/v2-sdk' +import { TransactionState, TransactionStateType, useAccount } from '@masknet/web3-shared' import { useSwapParameters as useTradeParameters } from './useTradeParameters' -import { SLIPPAGE_TOLERANCE_DEFAULT, DEFAULT_TRANSACTION_DEADLINE } from '../../constants' -import type { TradeComputed } from '../../types' +import { SLIPPAGE_DEFAULT } from '../../constants' +import type { SwapCall, Trade, TradeComputed } from '../../types' +import Services from '../../../../extension/service' +import { swapErrorToUserReadableMessage } from '../../helpers' -interface SuccessfulCall { +interface FailedCall { parameters: SwapParameters - gasEstimated: number + error: Error } -interface FailedCall { - parameters: SwapParameters +interface SwapCallEstimate { + call: SwapCall +} + +interface SuccessfulCall extends SwapCallEstimate { + call: SwapCall + gasEstimate: BigNumber +} + +interface FailedCall extends SwapCallEstimate { + call: SwapCall error: Error } -export function useTradeCallback( - trade: TradeComputed> | null, - routerV2Contract: RouterV2 | null, - allowedSlippage = SLIPPAGE_TOLERANCE_DEFAULT, - ddl = DEFAULT_TRANSACTION_DEADLINE, -) { +export function useTradeCallback(trade: TradeComputed | null, allowedSlippage = SLIPPAGE_DEFAULT) { const account = useAccount() - const tradeParameters = useTradeParameters(trade, allowedSlippage, ddl) + const tradeParameters = useTradeParameters(trade, allowedSlippage) const [tradeState, setTradeState] = useState({ type: TransactionStateType.UNKNOWN, }) const tradeCallback = useCallback(async () => { - if (!routerV2Contract) { + if (!tradeParameters.length) { setTradeState({ type: TransactionStateType.UNKNOWN, }) @@ -44,98 +49,111 @@ export function useTradeCallback( }) // step 1: estimate each trade parameter - const estimatedCalls = await Promise.all( + const estimatedCalls: SwapCallEstimate[] = await Promise.all( tradeParameters.map(async (x) => { - const { methodName, args, value } = x - const config = !value || /^0x0*$/.test(value) ? {} : { value } - - // @ts-ignore - const tx = routerV2Contract.methods[methodName as keyof typeof routerV2Contract.methods](...args) + const { address, calldata, value } = x + const config = { + from: account, + to: address, + data: calldata, + ...(!value || /^0x0*$/.test(value) ? {} : { value }), + } - return tx - .estimateGas({ - from: account, - to: routerV2Contract.options.address, - ...config, + return Services.Ethereum.estimateGas(config) + .then((gasEstimate) => { + return { + call: x, + gasEstimate: new BigNumber(gasEstimate), + } }) - .then( - (gasEstimated) => - ({ - parameters: x, - gasEstimated, - } as SuccessfulCall), - ) - .catch(() => { - return tx - .call({ - from: account, - to: routerV2Contract.options.address, - ...config, + .catch((error) => { + return Services.Ethereum.call(config) + .then(() => { + return { + call: x, + error: new Error('Gas estimate failed.'), + } + }) + .catch((error) => { + return { + call: x, + error: new Error(swapErrorToUserReadableMessage(error)), + } }) - .then( - () => - ({ - parameters: x, - error: new Error('Unexpected issue with estimating the gas. Please try again.'), - } as FailedCall), - ) - .catch( - (error) => - ({ - parameters: x, - error, - } as FailedCall), - ) }) }), ) - // step 2: validate estimation - const successfulCall = estimatedCalls.find( - (x, i, list): x is SuccessfulCall => - ('gasEstimated' in x && i === list.length - 1) || (list[i + 1] && 'gasEstimated' in list[i + 1]), + // a successful estimation is a bignumber gas estimate and the next call is also a bignumber gas estimate + let bestCallOption: SuccessfulCall | SwapCallEstimate | undefined = estimatedCalls.find( + (el, ix, list): el is SuccessfulCall => + 'gasEstimate' in el && (ix === list.length - 1 || 'gasEstimate' in list[ix + 1]), ) - if (!successfulCall) { - const failedCalls = estimatedCalls.filter((x): x is FailedCall => 'error' in x) - setTradeState({ - type: TransactionStateType.FAILED, - error: - failedCalls.length > 0 ? failedCalls[failedCalls.length - 1].error : new Error('Unexpected error'), - }) - return + + // check if any calls errored with a recognizable error + if (!bestCallOption) { + const errorCalls = estimatedCalls.filter((call): call is FailedCall => 'error' in call) + if (errorCalls.length > 0) { + setTradeState({ + type: TransactionStateType.FAILED, + error: errorCalls[errorCalls.length - 1].error, + }) + return + } + const firstNoErrorCall = estimatedCalls.find((call): call is SwapCallEstimate => !('error' in call)) + if (!firstNoErrorCall) { + setTradeState({ + type: TransactionStateType.FAILED, + error: new Error('Unexpected error. Could not estimate gas for the swap.'), + }) + return + } + bestCallOption = firstNoErrorCall } - // send transaction and wait for hash - return new Promise((resolve, reject) => { + return new Promise(async (resolve, reject) => { + if (!bestCallOption) { + setTradeState({ + type: TransactionStateType.FAILED, + error: new Error('Bad call options.'), + }) + return + } + const { - gasEstimated, - parameters: { methodName, args, value }, - } = successfulCall - const config = !value || /^0x0*$/.test(value) ? {} : { value } - - // @ts-ignore - routerV2Contract.methods[methodName as keyof typeof routerV2Contract.methods](...args) - .send({ - ...config, + call: { address, calldata, value }, + } = bestCallOption + + try { + const hash = await Services.Ethereum.sendTransaction({ from: account, - gas: gasEstimated, + to: address, + data: calldata, + ...('gasEstimate' in bestCallOption ? { gas: bestCallOption.gasEstimate.toFixed() } : {}), + ...(!value || /^0x0*$/.test(value) ? {} : { value }), + }) + setTradeState({ + type: TransactionStateType.HASH, + hash, }) - .on(TransactionEventType.TRANSACTION_HASH, (hash) => { + resolve(hash) + } catch (error) { + if (error?.code) { + const error_ = new Error('Transaction rejected.') setTradeState({ - type: TransactionStateType.HASH, - hash, + type: TransactionStateType.FAILED, + error: error_, }) - resolve(hash) - }) - .on(TransactionEventType.ERROR, (error) => { + reject(error_) + } else { setTradeState({ type: TransactionStateType.FAILED, - error, + error: new Error(`Swap failed: ${swapErrorToUserReadableMessage(error)}`), }) - reject(error) - }) + } + } }) - }, [account, tradeParameters, routerV2Contract]) + }, [account, tradeParameters]) const resetCallback = useCallback(() => { setTradeState({ diff --git a/packages/maskbook/src/plugins/Trader/trader/uniswap/useV2TradeComputed.ts b/packages/maskbook/src/plugins/Trader/trader/uniswap/useTradeComputed.ts similarity index 69% rename from packages/maskbook/src/plugins/Trader/trader/uniswap/useV2TradeComputed.ts rename to packages/maskbook/src/plugins/Trader/trader/uniswap/useTradeComputed.ts index 96f8b15a70bf..61f2a74958e0 100644 --- a/packages/maskbook/src/plugins/Trader/trader/uniswap/useV2TradeComputed.ts +++ b/packages/maskbook/src/plugins/Trader/trader/uniswap/useTradeComputed.ts @@ -1,18 +1,18 @@ import { ZERO, FungibleTokenDetailed } from '@masknet/web3-shared' -import type { Trade } from '@uniswap/v2-sdk' -import { Currency, TradeType } from '@uniswap/sdk-core' +import { Trade as V2Trade } from '@uniswap/v2-sdk' +import { TradeType } from '@uniswap/sdk-core' import { uniswapCurrencyAmountTo, uniswapPercentTo, uniswapPriceTo, uniswapTokenTo } from '../../helpers' -import { TradeComputed, TradeStrategy } from '../../types' +import { Trade, TradeComputed, TradeStrategy } from '../../types' import { useSlippageTolerance } from './useSlippageTolerance' -import { useV2TradeBreakdown } from './useV2TradeBreakdown' +import { useTradeBreakdown } from './useTradeBreakdown' -export function useV2TradeComputed( - trade: Trade | null, +export function useTradeComputed( + trade: Trade | null, inputToken?: FungibleTokenDetailed, outputToken?: FungibleTokenDetailed, -): TradeComputed> | null { +): TradeComputed | null { const slippage = useSlippageTolerance() - const breakdown = useV2TradeBreakdown(trade) + const breakdown = useTradeBreakdown(trade) if (!trade) return null @@ -22,9 +22,10 @@ export function useV2TradeComputed( outputToken, inputAmount: uniswapCurrencyAmountTo(trade.inputAmount), outputAmount: uniswapCurrencyAmountTo(trade.outputAmount), + // @ts-ignore executionPrice: uniswapPriceTo(trade.executionPrice), priceImpact: uniswapPercentTo(breakdown?.priceImpact ?? trade.priceImpact), - path: trade.route.path.map((x) => [uniswapTokenTo(x)]), + path: trade instanceof V2Trade ? trade.route.path.map((x) => [uniswapTokenTo(x)]) : [], maximumSold: uniswapCurrencyAmountTo(trade.maximumAmountIn(slippage)), minimumReceived: uniswapCurrencyAmountTo(trade.minimumAmountOut(slippage)), fee: breakdown?.realizedLPFee ? uniswapCurrencyAmountTo(breakdown.realizedLPFee) : ZERO, diff --git a/packages/maskbook/src/plugins/Trader/trader/uniswap/useTradeParameters.ts b/packages/maskbook/src/plugins/Trader/trader/uniswap/useTradeParameters.ts index 103afaa30ccd..f1cf439111f0 100644 --- a/packages/maskbook/src/plugins/Trader/trader/uniswap/useTradeParameters.ts +++ b/packages/maskbook/src/plugins/Trader/trader/uniswap/useTradeParameters.ts @@ -1,10 +1,15 @@ -import { useMemo } from 'react' +import { useContext, useMemo } from 'react' import JSBI from 'jsbi' -import { Percent, TradeType, Currency } from '@uniswap/sdk-core' -import { Router, Trade } from '@uniswap/v2-sdk' -import { SLIPPAGE_TOLERANCE_DEFAULT, DEFAULT_TRANSACTION_DEADLINE } from '../../constants' +import { Percent, TradeType } from '@uniswap/sdk-core' +import { Router, Trade as V2Trade } from '@uniswap/v2-sdk' +import { SLIPPAGE_DEFAULT } from '../../constants' import { useAccount } from '@masknet/web3-shared' -import type { TradeComputed } from '../../types' +import type { SwapCall, Trade, TradeComputed } from '../../types' +import { SwapRouter } from '@uniswap/v3-sdk' +import { useRouterV2Contract } from '../../contracts/uniswap/useRouterV2Contract' +import { useSwapRouterContract } from '../../contracts/uniswap/useSwapRouterContract' +import { TradeContext } from '../useTradeContext' +import { useTransactionDeadline } from './useTransactionDeadline' const UNISWAP_BIPS_BASE = JSBI.BigInt(10_000) @@ -15,32 +20,64 @@ const UNISWAP_BIPS_BASE = JSBI.BigInt(10_000) * @param deadline the deadline for the trade */ export function useSwapParameters( - trade: TradeComputed> | null, // trade to execute, required - allowedSlippage: number = SLIPPAGE_TOLERANCE_DEFAULT, // in bips - deadline: number = DEFAULT_TRANSACTION_DEADLINE, // in seconds from now + trade: TradeComputed | null, // trade to execute, required + allowedSlippage: number = SLIPPAGE_DEFAULT, // in bips ) { const account = useAccount() - return useMemo(() => { - if (!trade?.trade_ || !account) return [] + const context = useContext(TradeContext) + const deadline = useTransactionDeadline() + const routerV2Contract = useRouterV2Contract(context?.ROUTER_CONTRACT_ADDRESS) + const swapRouterContract = useSwapRouterContract(context?.ROUTER_CONTRACT_ADDRESS) + + return useMemo(() => { + if (!account || !trade?.trade_ || !deadline) return [] + const { trade_ } = trade const allowedSlippage_ = new Percent(JSBI.BigInt(allowedSlippage), UNISWAP_BIPS_BASE) - const parameters = [ - Router.swapCallParameters(trade_, { - feeOnTransfer: false, - allowedSlippage: allowedSlippage_, - recipient: account, - ttl: deadline, - }), - ] - if (trade_.tradeType === TradeType.EXACT_INPUT) - parameters.push( + + if (trade_ instanceof V2Trade) { + if (!routerV2Contract) return [] + const parameters = [ Router.swapCallParameters(trade_, { - feeOnTransfer: true, + feeOnTransfer: false, allowedSlippage: allowedSlippage_, recipient: account, - ttl: deadline, + ttl: deadline.toNumber(), }), - ) - return parameters - }, [account, allowedSlippage, deadline, trade]) + ] + if (trade_.tradeType === TradeType.EXACT_INPUT) + parameters.push( + Router.swapCallParameters(trade_, { + feeOnTransfer: true, + allowedSlippage: allowedSlippage_, + recipient: account, + ttl: deadline.toNumber(), + }), + ) + return parameters.map(({ methodName, args, value }) => { + return { + address: routerV2Contract.options.address, + calldata: routerV2Contract.methods[methodName as keyof typeof routerV2Contract.methods]( + // @ts-ignore + ...args, + ).encodeABI(), + value, + } + }) + } else { + if (!swapRouterContract) return [] + const { value, calldata } = SwapRouter.swapCallParameters(trade_, { + recipient: account, + slippageTolerance: allowedSlippage_, + deadline: deadline.toString(), + }) + return [ + { + address: swapRouterContract.options.address, + calldata, + value, + }, + ] + } + }, [account, allowedSlippage, deadline, trade, routerV2Contract, swapRouterContract]) } diff --git a/packages/maskbook/src/plugins/Trader/trader/uniswap/useTransactionDeadline.ts b/packages/maskbook/src/plugins/Trader/trader/uniswap/useTransactionDeadline.ts new file mode 100644 index 000000000000..dda40415dad0 --- /dev/null +++ b/packages/maskbook/src/plugins/Trader/trader/uniswap/useTransactionDeadline.ts @@ -0,0 +1,15 @@ +import { ChainId, useChainId, useCurrentBlockTimestamp } from '@masknet/web3-shared' +import BigNumber from 'bignumber.js' +import { useMemo } from 'react' +import { DEFAULT_TRANSACTION_DEADLINE, L2_TRANSACTION_DEADLINE } from '../../constants' + +export function useTransactionDeadline() { + const chainId = useChainId() + const { value: timestamp } = useCurrentBlockTimestamp() + + return useMemo(() => { + if (!timestamp) return + const timestamp_ = new BigNumber(timestamp ?? '0') + return timestamp_.plus(ChainId.Mainnet === chainId ? DEFAULT_TRANSACTION_DEADLINE : L2_TRANSACTION_DEADLINE) + }, [chainId, timestamp]) +} diff --git a/packages/maskbook/src/plugins/Trader/trader/uniswap/useV2Trade.ts b/packages/maskbook/src/plugins/Trader/trader/uniswap/useV2BestTrade.ts similarity index 92% rename from packages/maskbook/src/plugins/Trader/trader/uniswap/useV2Trade.ts rename to packages/maskbook/src/plugins/Trader/trader/uniswap/useV2BestTrade.ts index 04722b3d6452..277606a88284 100644 --- a/packages/maskbook/src/plugins/Trader/trader/uniswap/useV2Trade.ts +++ b/packages/maskbook/src/plugins/Trader/trader/uniswap/useV2BestTrade.ts @@ -42,7 +42,9 @@ export function useV2BestTradeExactIn( return { ...asyncResult, - value: bestTrade, + + // override the trade type from @uniswap/v2-sdk + value: bestTrade as Trade | null, } } @@ -82,6 +84,8 @@ export function useV2BestTradeExactOut( return { ...asyncResult, - value: bestTrade, + + // override the trade type from @uniswap/v2-sdk + value: bestTrade as Trade | null, } } diff --git a/packages/maskbook/src/plugins/Trader/trader/uniswap/useV2TradeBreakdown.ts b/packages/maskbook/src/plugins/Trader/trader/uniswap/useV2TradeBreakdown.ts deleted file mode 100644 index 526a750971ab..000000000000 --- a/packages/maskbook/src/plugins/Trader/trader/uniswap/useV2TradeBreakdown.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { useMemo } from 'react' -import JSBI from 'jsbi' -import type { Trade } from '@uniswap/v2-sdk' -import { Percent, CurrencyAmount, Currency, TradeType } from '@uniswap/sdk-core' - -const BASE_FEE = new Percent(JSBI.BigInt(30), JSBI.BigInt(10000)) -const ONE_HUNDRED_PERCENT = new Percent(JSBI.BigInt(10000), JSBI.BigInt(10000)) -const INPUT_FRACTION_AFTER_FEE = ONE_HUNDRED_PERCENT.subtract(BASE_FEE) - -// computes realized lp fee as a percent -function computeRealizedLPFeePercent(trade: Trade): Percent { - // for each hop in our trade, take away the x*y=k price impact from 0.3% fees - // e.g. for 3 tokens/2 hops: 1 - ((1 - .03) * (1-.03)) - const percent = ONE_HUNDRED_PERCENT.subtract( - trade.route.pairs.reduce( - (currentFee: Percent): Percent => currentFee.multiply(INPUT_FRACTION_AFTER_FEE), - ONE_HUNDRED_PERCENT, - ), - ) - return new Percent(percent.numerator, percent.denominator) -} - -// computes price breakdown for the trade -function computeRealizedLPFeeAmount( - trade?: Trade | null, -): CurrencyAmount | undefined { - if (trade) { - const realizedLPFee = computeRealizedLPFeePercent(trade) - - // the amount of the input that accrues to LPs - return CurrencyAmount.fromRawAmount( - trade.inputAmount.currency, - trade.inputAmount.multiply(realizedLPFee).quotient, - ) - } - return undefined -} - -export function useV2TradeBreakdown(trade: Trade | null) { - return useMemo(() => { - if (!trade) return null - const realizedLPFeePercent = computeRealizedLPFeePercent(trade) - const realizedLPFeeAmount = computeRealizedLPFeeAmount(trade) - return { - realizedLPFeePercent, - realizedLPFeeAmount, - realizedLPFee: trade.inputAmount.multiply(realizedLPFeePercent), - priceImpact: trade.priceImpact.subtract(realizedLPFeePercent), - } - }, [trade]) -} diff --git a/packages/maskbook/src/plugins/Trader/trader/uniswap/useV3BestTrade.ts b/packages/maskbook/src/plugins/Trader/trader/uniswap/useV3BestTrade.ts new file mode 100644 index 000000000000..0899a610a9f9 --- /dev/null +++ b/packages/maskbook/src/plugins/Trader/trader/uniswap/useV3BestTrade.ts @@ -0,0 +1,210 @@ +import { useMemo } from 'react' +import { useAsyncRetry } from 'react-use' +import type { AsyncStateRetry } from 'react-use/lib/useAsyncRetry' +import BigNumber from 'bignumber.js' +import { Currency, CurrencyAmount, TradeType } from '@uniswap/sdk-core' +import { encodeRouteToPath, Route, Trade } from '@uniswap/v3-sdk' +import { useQuoterContract } from '../../contracts/uniswap/useQuoterContract' +import { useAllV3Routes } from './useAllV3Routes' +import { MulticalStateType, useSingleContractMultipleData } from '@masknet/web3-shared' + +export enum V3TradeState { + LOADING = 0, + INVALID = 1, + NO_ROUTE_FOUND = 2, + VALID = 3, + SYNCING = 4, +} + +/** + * Returns the best v3 trade for a desired exact input swap + * @param amountIn the amount to swap in + * @param currencyOut the desired output currency + */ +export function useV3BestTradeExactIn( + amountIn?: CurrencyAmount, + currencyOut?: Currency, +): AsyncStateRetry | null> { + const quoterContract = useQuoterContract() + const { routes, loading: routesLoading } = useAllV3Routes(amountIn?.currency, currencyOut) + const quoteExactInInputs = useMemo(() => { + return routes.map( + (route) => + [encodeRouteToPath(route, false), amountIn ? `0x${amountIn.quotient.toString(16)}` : undefined] as [ + string, + string, + ], + ) + }, [amountIn, routes]) + + const [quotesResults, quotesCalls, quotesState, quotesCallback] = useSingleContractMultipleData( + quoterContract, + Array.from<'quoteExactInput'>({ length: quoteExactInInputs.length }).fill('quoteExactInput'), + quoteExactInInputs, + ) + const asyncResult = useAsyncRetry( + () => quotesCallback(quotesCalls), + [quoterContract, quotesCalls.map((x) => x.join()).join()], + ) + const asyncBestTrade = useMemo(() => { + if (!amountIn || !currencyOut) { + return { + value: undefined, + loading: false, + error: new Error('Invalid trade info.'), + } + } + if (routesLoading || quotesState.type === MulticalStateType.PENDING) { + return { + value: undefined, + loading: true, + error: undefined, + } + } + + const { bestRoute, amountOut } = quotesResults.reduce( + (currentBest: { bestRoute: Route | null; amountOut: string | null }, { value }, i) => { + if (!value) return currentBest + + if (currentBest.amountOut === null) { + return { + bestRoute: routes[i], + amountOut: value, + } + } else if (new BigNumber(currentBest.amountOut).lt(value)) { + return { + bestRoute: routes[i], + amountOut: value, + } + } + + return currentBest + }, + { + bestRoute: null, + amountOut: null, + }, + ) + + if (!bestRoute || !amountOut) { + return { + value: undefined, + loading: false, + error: new Error('No route found.'), + } + } + + return { + value: Trade.createUncheckedTrade({ + route: bestRoute, + tradeType: TradeType.EXACT_INPUT, + inputAmount: amountIn, + outputAmount: CurrencyAmount.fromRawAmount(currencyOut, amountOut), + }), + loading: false, + error: undefined, + } + }, [amountIn, currencyOut, quotesResults, routes, routesLoading]) + + return { + ...asyncBestTrade, + retry: asyncResult.retry, + } +} + +/** + * Returns the best v3 trade for a desired exact output swap + * @param currencyIn the desired input currency + * @param amountOut the amount to swap out + */ +export function useV3BestTradeExactOut( + currencyIn?: Currency, + amountOut?: CurrencyAmount, +): AsyncStateRetry | null> { + const { routes, loading: routesLoading } = useAllV3Routes(currencyIn, amountOut?.currency) + const quoterContract = useQuoterContract() + const quoteExactOutInputs = useMemo(() => { + return routes.map( + (route) => + [encodeRouteToPath(route, true), amountOut ? `0x${amountOut.quotient.toString(16)}` : undefined] as [ + string, + string, + ], + ) + }, [amountOut, routes]) + + const [quotesResults, quotesCalls, quotesState, quotesCallback] = useSingleContractMultipleData( + quoterContract, + Array.from<'quoteExactOutput'>({ length: quoteExactOutInputs.length }).fill('quoteExactOutput'), + quoteExactOutInputs, + ) + const asyncResult = useAsyncRetry( + () => quotesCallback(quotesCalls), + [quotesCallback, quotesCalls.map((x) => x.join()).join()], + ) + const asyncBestTrade = useMemo(() => { + if (!amountOut || !currencyIn || quotesResults.some(({ error }) => !!error)) { + return { + value: undefined, + loading: false, + error: new Error('Invalid trade info.'), + } + } + + if (routesLoading || quotesState.type === MulticalStateType.PENDING) { + return { + value: undefined, + loading: true, + error: undefined, + } + } + + const { bestRoute, amountIn } = quotesResults.reduce( + (currentBest: { bestRoute: Route | null; amountIn: string | null }, { value }, i) => { + if (!value) return currentBest + + if (currentBest.amountIn === null) { + return { + bestRoute: routes[i], + amountIn: value, + } + } else if (new BigNumber(currentBest.amountIn).gt(value)) { + return { + bestRoute: routes[i], + amountIn: value, + } + } + + return currentBest + }, + { + bestRoute: null, + amountIn: null, + }, + ) + + if (!bestRoute || !amountIn) { + return { + value: undefined, + loading: false, + error: new Error('No route found.'), + } + } + + return { + value: Trade.createUncheckedTrade({ + route: bestRoute, + tradeType: TradeType.EXACT_OUTPUT, + inputAmount: CurrencyAmount.fromRawAmount(currencyIn, amountIn), + outputAmount: amountOut, + }), + loading: false, + error: undefined, + } + }, [amountOut, currencyIn, quotesResults, routes, routesLoading]) + + return { + ...asyncBestTrade, + retry: asyncResult.retry, + } +} diff --git a/packages/maskbook/src/plugins/Trader/trader/uniswap/useV3SwapPools.ts b/packages/maskbook/src/plugins/Trader/trader/uniswap/useV3SwapPools.ts new file mode 100644 index 000000000000..5c01b77930a4 --- /dev/null +++ b/packages/maskbook/src/plugins/Trader/trader/uniswap/useV3SwapPools.ts @@ -0,0 +1,44 @@ +import type { Currency, Token } from '@uniswap/sdk-core' +import { FeeAmount, Pool } from '@uniswap/v3-sdk' +import { useMemo } from 'react' +import { useAllCurrencyCombinations } from './useAllCommonPairs' +import { PoolState, usePools } from './usePools' + +/** + * Returns all the existing pools that should be considered for swapping between an input currency and an output currency + * @param currencyIn the input currency + * @param currencyOut the output currency + */ +export function useV3SwapPools( + currencyIn?: Currency, + currencyOut?: Currency, +): { + pools: Pool[] + loading: boolean +} { + const allCurrencyCombinations = useAllCurrencyCombinations(currencyIn, currencyOut) + + const allCurrencyCombinationsWithAllFees: [Token, Token, FeeAmount][] = useMemo( + () => + allCurrencyCombinations.reduce<[Token, Token, FeeAmount][]>((list, [tokenA, tokenB]) => { + return list.concat([ + [tokenA, tokenB, FeeAmount.LOW], + [tokenA, tokenB, FeeAmount.MEDIUM], + [tokenA, tokenB, FeeAmount.HIGH], + ]) + }, []), + [allCurrencyCombinations], + ) + const pools = usePools(allCurrencyCombinationsWithAllFees) + + return useMemo(() => { + return { + pools: pools + .filter((tuple): tuple is [PoolState.EXISTS, Pool] => { + return tuple[0] === PoolState.EXISTS && tuple[1] !== null + }) + .map(([, pool]) => pool), + loading: pools.some(([state]) => state === PoolState.LOADING), + } + }, [pools]) +} diff --git a/packages/maskbook/src/plugins/Trader/trader/useTradeCallback.ts b/packages/maskbook/src/plugins/Trader/trader/useTradeCallback.ts index e11c22251b11..e9db5cc4c429 100644 --- a/packages/maskbook/src/plugins/Trader/trader/useTradeCallback.ts +++ b/packages/maskbook/src/plugins/Trader/trader/useTradeCallback.ts @@ -1,39 +1,33 @@ import { useContext } from 'react' -import type { Trade } from '@uniswap/v2-sdk' +import type { Trade as V2Trade } from '@uniswap/v2-sdk' +import type { Trade as V3Trade } from '@uniswap/v3-sdk' import type { Currency, TradeType } from '@uniswap/sdk-core' import { unreachable } from '@dimensiondev/kit' -import { SwapQuoteResponse, SwapResponse, SwapRouteSuccessResponse, TradeComputed, TradeProvider } from '../types' +import { TradeProvider } from '@masknet/public-api' +import type { SwapQuoteResponse, SwapResponse, SwapRouteSuccessResponse, TradeComputed } from '../types' import { useTradeCallback as useNativeTokenWrapperCallback } from './native/useTradeCallback' import { useTradeCallback as useZrxCallback } from './0x/useTradeCallback' import { useTradeCallback as useUniswapCallback } from './uniswap/useTradeCallback' import { useTradeCallback as useBalancerCallback } from './balancer/useTradeCallback' import { useTradeCallback as useDODOCallback } from './dodo/useTradeCallback' -import { useRouterV2Contract as useUniswapRouterV2Contract } from '../contracts/uniswap/useRouterV2Contract' -import { useRouterV2Contract as useSushiSwapRouterV2Contract } from '../contracts/sushiswap/useRouterV2Contract' -import { useRouterV2Contract as useSashimiSwapRouterV2Contract } from '../contracts/sashimiswap/useRouterV2Contract' -import { useRouterV2Contract as useQuickSwapRouterV2Contract } from '../contracts/quickswap/useRouterV2Contract' -import { useRouterV2Contract as usePancakeSwapRouterV2Contract } from '../contracts/pancakeswap/useRouterV2Contract' import { useExchangeProxyContract } from '../contracts/balancer/useExchangeProxyContract' import type { NativeTokenWrapper } from './native/useTradeComputed' import { isNativeTokenWrapper } from '../helpers' import { TradeContext } from './useTradeContext' export function useTradeCallback(provider: TradeProvider, tradeComputed: TradeComputed | null) { - const uniswapRouterV2Contract = useUniswapRouterV2Contract() - const sushiswapRouterV2Contract = useSushiSwapRouterV2Contract() - const sashimiswapRouterV2Contract = useSashimiSwapRouterV2Contract() - const quickswapRouterV2Contract = useQuickSwapRouterV2Contract() - const pancakeswapRouterV2Contract = usePancakeSwapRouterV2Contract() - const exchangeProxyContract = useExchangeProxyContract() - // trade conetxt const context = useContext(TradeContext) // create trade computed const isNativeTokenWrapper_ = isNativeTokenWrapper(tradeComputed) - const tradeComputedForUniswapLike = - context?.IS_UNISWAP_LIKE && !isNativeTokenWrapper_ - ? (tradeComputed as TradeComputed>) + const tradeComputedForUniswapV2Like = + context?.IS_UNISWAP_V2_LIKE && !isNativeTokenWrapper_ + ? (tradeComputed as TradeComputed>) + : null + const tradeComputedForUniswapV3Like = + context?.IS_UNISWAP_V3_LIKE && !isNativeTokenWrapper_ + ? (tradeComputed as TradeComputed>) : null const tradeComputedForZRX = !isNativeTokenWrapper_ ? (tradeComputed as TradeComputed) : null const tradeComputedForBalancer = !isNativeTokenWrapper_ ? (tradeComputed as TradeComputed) : null @@ -41,34 +35,39 @@ export function useTradeCallback(provider: TradeProvider, tradeComputed: TradeCo ? (tradeComputed as TradeComputed) : null - const uniswap = useUniswapCallback(tradeComputedForUniswapLike, uniswapRouterV2Contract) - const sushiswap = useUniswapCallback(tradeComputedForUniswapLike, sushiswapRouterV2Contract) - const sashimiswap = useUniswapCallback(tradeComputedForUniswapLike, sashimiswapRouterV2Contract) - const quickswap = useUniswapCallback(tradeComputedForUniswapLike, quickswapRouterV2Contract) - const pancakeswap = useUniswapCallback(tradeComputedForUniswapLike, pancakeswapRouterV2Contract) + // uniswap like providers + const uniswapV2Like = useUniswapCallback(tradeComputedForUniswapV2Like) + const uniswapV3Like = useUniswapCallback(tradeComputedForUniswapV3Like) + + // balancer + const exchangeProxyContract = useExchangeProxyContract() const balancer = useBalancerCallback( provider === TradeProvider.BALANCER ? tradeComputedForBalancer : null, exchangeProxyContract, ) + + // other providers const zrx = useZrxCallback(provider === TradeProvider.ZRX ? tradeComputedForZRX : null) const dodo = useDODOCallback(provider === TradeProvider.DODO ? tradeComputedForDODO : null) - const nativeTokenWrapper = useNativeTokenWrapperCallback(tradeComputed as TradeComputed) // the trade is an ETH-WETH pair + const nativeTokenWrapper = useNativeTokenWrapperCallback(tradeComputed as TradeComputed) if (isNativeTokenWrapper_) return nativeTokenWrapper // handle trades by various provider switch (provider) { - case TradeProvider.UNISWAP: - return uniswap + case TradeProvider.UNISWAP_V2: + return uniswapV2Like + case TradeProvider.UNISWAP_V3: + return uniswapV3Like case TradeProvider.SUSHISWAP: - return sushiswap + return uniswapV2Like case TradeProvider.SASHIMISWAP: - return sashimiswap + return uniswapV2Like case TradeProvider.QUICKSWAP: - return quickswap + return uniswapV2Like case TradeProvider.PANCAKESWAP: - return pancakeswap + return uniswapV2Like case TradeProvider.ZRX: return zrx case TradeProvider.BALANCER: diff --git a/packages/maskbook/src/plugins/Trader/trader/useTradeComputed.ts b/packages/maskbook/src/plugins/Trader/trader/useTradeComputed.ts index ad80cd07a8d8..bb5713493616 100644 --- a/packages/maskbook/src/plugins/Trader/trader/useTradeComputed.ts +++ b/packages/maskbook/src/plugins/Trader/trader/useTradeComputed.ts @@ -5,8 +5,8 @@ import { pow10 } from '@masknet/web3-shared' import { TradeProvider, TradeStrategy } from '../types' import { useTrade as useNativeTokenTrade } from './native/useTrade' import { useTradeComputed as useNativeTokenTradeComputed } from './native/useTradeComputed' -import { useTrade as useUniswapTrade } from './uniswap/useTrade' -import { useV2TradeComputed as useUniswapTradeComputed } from './uniswap/useV2TradeComputed' +import { useV2Trade as useUnswapV2Trade, useV3Trade as useUnswapV3Trade } from './uniswap/useTrade' +import { useTradeComputed as useUniswapTradeComputed } from './uniswap/useTradeComputed' import { useTradeComputed as useZrxTradeComputed } from './0x/useTradeComputed' import { useTradeComputed as useBalancerTradeComputed } from './balancer/useTradeComputed' import { useTradeComputed as useDODOTradeComputed } from './dodo/useTradeComputed' @@ -43,15 +43,25 @@ export function useTradeComputed( outputToken, ) - // uniswap like providers - const uniswap_ = useUniswapTrade( + // uniswap-v2 like providers + const uniswapV2_ = useUnswapV2Trade( strategy, - context?.IS_UNISWAP_LIKE ? inputAmount_ : '0', - context?.IS_UNISWAP_LIKE ? outputAmount_ : '0', + context?.IS_UNISWAP_V2_LIKE ? inputAmount_ : '0', + context?.IS_UNISWAP_V2_LIKE ? outputAmount_ : '0', inputToken, outputToken, ) - const uniswap = useUniswapTradeComputed(uniswap_.value, inputToken, outputToken) + const uniswapV2 = useUniswapTradeComputed(uniswapV2_.value, inputToken, outputToken) + + // uniswap-v3 like providers + const uniswapV3_ = useUnswapV3Trade( + strategy, + context?.IS_UNISWAP_V3_LIKE ? inputAmount_ : '0', + context?.IS_UNISWAP_V3_LIKE ? outputAmount_ : '0', + inputToken, + outputToken, + ) + const uniswapV3 = useUniswapTradeComputed(uniswapV3_.value, inputToken, outputToken) // zrx const zrx_ = useZrxTrade( @@ -97,14 +107,19 @@ export function useTradeComputed( } switch (provider) { - case TradeProvider.UNISWAP: + case TradeProvider.UNISWAP_V2: case TradeProvider.SUSHISWAP: case TradeProvider.SASHIMISWAP: case TradeProvider.QUICKSWAP: case TradeProvider.PANCAKESWAP: return { - ...uniswap_, - value: uniswap, + ...uniswapV2_, + value: uniswapV2, + } + case TradeProvider.UNISWAP_V3: + return { + ...uniswapV3_, + value: uniswapV3, } case TradeProvider.ZRX: return { diff --git a/packages/maskbook/src/plugins/Trader/trader/useTradeContext.ts b/packages/maskbook/src/plugins/Trader/trader/useTradeContext.ts index 257194216406..93d74ced1d97 100644 --- a/packages/maskbook/src/plugins/Trader/trader/useTradeContext.ts +++ b/packages/maskbook/src/plugins/Trader/trader/useTradeContext.ts @@ -21,14 +21,26 @@ export function useTradeContext(tradeProvider: TradeProvider) { const chainId = useChainId() return useMemo(() => { switch (tradeProvider) { - case TradeProvider.UNISWAP: + case TradeProvider.UNISWAP_V2: return { TYPE: tradeProvider, - IS_UNISWAP_LIKE: true, - GRAPH_API: getTraderConstants(chainId).UNISWAP_THEGRAPH, - INIT_CODE_HASH: getTraderConstants(chainId).UNISWAP_INIT_CODE_HASH, - ROUTER_CONTRACT_ADDRESS: getTraderConstants(chainId).UNISWAP_ROUTER_ADDRESS, - FACTORY_CONTRACT_ADDRESS: getTraderConstants(chainId).UNISWAP_FACTORY_ADDRESS, + IS_UNISWAP_V2_LIKE: true, + GRAPH_API: getTraderConstants(chainId).UNISWAP_V2_THEGRAPH, + INIT_CODE_HASH: getTraderConstants(chainId).UNISWAP_V2_INIT_CODE_HASH, + ROUTER_CONTRACT_ADDRESS: getTraderConstants(chainId).UNISWAP_V2_ROUTER_ADDRESS, + FACTORY_CONTRACT_ADDRESS: getTraderConstants(chainId).UNISWAP_V2_FACTORY_ADDRESS, + AGAINST_TOKENS: UNISWAP_BASE_AGAINST_TOKENS, + ADDITIONAL_TOKENS: {}, + CUSTOM_TOKENS: UNISWAP_CUSTOM_BASES, + } + case TradeProvider.UNISWAP_V3: + return { + TYPE: tradeProvider, + IS_UNISWAP_V3_LIKE: true, + GRAPH_API: getTraderConstants(chainId).UNISWAP_V2_THEGRAPH, + INIT_CODE_HASH: getTraderConstants(chainId).UNISWAP_V2_INIT_CODE_HASH, + ROUTER_CONTRACT_ADDRESS: getTraderConstants(chainId).UNISWAP_SWAP_ROUTER_ADDRESS, + FACTORY_CONTRACT_ADDRESS: getTraderConstants(chainId).UNISWAP_V3_FACTORY_ADDRESS, AGAINST_TOKENS: UNISWAP_BASE_AGAINST_TOKENS, ADDITIONAL_TOKENS: {}, CUSTOM_TOKENS: UNISWAP_CUSTOM_BASES, @@ -36,7 +48,7 @@ export function useTradeContext(tradeProvider: TradeProvider) { case TradeProvider.SUSHISWAP: return { TYPE: tradeProvider, - IS_UNISWAP_LIKE: true, + IS_UNISWAP_V2_LIKE: true, GRAPH_API: getTraderConstants(chainId).SUSHISWAP_THEGRAPH, INIT_CODE_HASH: getTraderConstants(chainId).SUSHISWAP_INIT_CODE_HASH, ROUTER_CONTRACT_ADDRESS: getTraderConstants(chainId).SUSHISWAP_ROUTER_ADDRESS, @@ -48,7 +60,7 @@ export function useTradeContext(tradeProvider: TradeProvider) { case TradeProvider.SASHIMISWAP: return { TYPE: tradeProvider, - IS_UNISWAP_LIKE: true, + IS_UNISWAP_V2_LIKE: true, GRAPH_API: getTraderConstants(chainId).SASHIMISWAP_THEGRAPH, INIT_CODE_HASH: getTraderConstants(chainId).SASHIMISWAP_INIT_CODE_HASH, ROUTER_CONTRACT_ADDRESS: getTraderConstants(chainId).SASHIMISWAP_ROUTER_ADDRESS, @@ -60,7 +72,7 @@ export function useTradeContext(tradeProvider: TradeProvider) { case TradeProvider.QUICKSWAP: return { TYPE: tradeProvider, - IS_UNISWAP_LIKE: true, + IS_UNISWAP_V2_LIKE: true, GRAPH_API: getTraderConstants(chainId).QUICKSWAP_THEGRAPH, INIT_CODE_HASH: getTraderConstants(chainId).QUICKSWAP_INIT_CODE_HASH, ROUTER_CONTRACT_ADDRESS: getTraderConstants(chainId).QUICKSWAP_ROUTER_ADDRESS, @@ -72,7 +84,7 @@ export function useTradeContext(tradeProvider: TradeProvider) { case TradeProvider.PANCAKESWAP: return { TYPE: tradeProvider, - IS_UNISWAP_LIKE: true, + IS_UNISWAP_V2_LIKE: true, GRAPH_API: getTraderConstants(chainId).PANCAKESWAP_THEGRAPH, INIT_CODE_HASH: getTraderConstants(chainId).PANCAKESWAP_INIT_CODE_HASH, ROUTER_CONTRACT_ADDRESS: getTraderConstants(chainId).PANCAKESWAP_ROUTER_ADDRESS, @@ -84,38 +96,16 @@ export function useTradeContext(tradeProvider: TradeProvider) { case TradeProvider.ZRX: return { TYPE: tradeProvider, - IS_UNISWAP_LIKE: false, - GRAPH_API: '', - INIT_CODE_HASH: '', - ROUTER_CONTRACT_ADDRESS: '', - FACTORY_CONTRACT_ADDRESS: '', - AGAINST_TOKENS: {}, - ADDITIONAL_TOKENS: {}, - CUSTOM_TOKENS: {}, } as TradeContext_ case TradeProvider.BALANCER: return { TYPE: tradeProvider, - IS_UNISWAP_LIKE: false, - GRAPH_API: '', - INIT_CODE_HASH: '', ROUTER_CONTRACT_ADDRESS: getTraderConstants(chainId).BALANCER_EXCHANGE_PROXY_ADDRESS, - FACTORY_CONTRACT_ADDRESS: '', - AGAINST_TOKENS: {}, - ADDITIONAL_TOKENS: {}, - CUSTOM_TOKENS: {}, } as TradeContext_ case TradeProvider.DODO: return { TYPE: tradeProvider, - IS_UNISWAP_LIKE: false, - GRAPH_API: '', - INIT_CODE_HASH: '', ROUTER_CONTRACT_ADDRESS: getTraderConstants(chainId).DODO_EXCHANGE_PROXY_ADDRESS, - FACTORY_CONTRACT_ADDRESS: '', - AGAINST_TOKENS: {}, - ADDITIONAL_TOKENS: {}, - CUSTOM_TOKENS: {}, } as TradeContext_ default: unreachable(tradeProvider) diff --git a/packages/maskbook/src/plugins/Trader/trader/useTradeStateComputed.ts b/packages/maskbook/src/plugins/Trader/trader/useTradeStateComputed.ts index 4981fa9aa64a..c9b4e9d9f54a 100644 --- a/packages/maskbook/src/plugins/Trader/trader/useTradeStateComputed.ts +++ b/packages/maskbook/src/plugins/Trader/trader/useTradeStateComputed.ts @@ -1,5 +1,5 @@ import { formatBalance } from '@masknet/web3-shared' -import { TradeProvider, TradeStrategy } from '../types' +import { TradeStrategy, TradeProvider } from '../types' import { useTradeComputed } from './useTradeComputed' import { useTradeState } from './useTradeState' diff --git a/packages/maskbook/src/plugins/Trader/trending/useCurrentTradeProvider.ts b/packages/maskbook/src/plugins/Trader/trending/useCurrentTradeProvider.ts index 10e944a9d720..cc7120d9bea6 100644 --- a/packages/maskbook/src/plugins/Trader/trending/useCurrentTradeProvider.ts +++ b/packages/maskbook/src/plugins/Trader/trending/useCurrentTradeProvider.ts @@ -16,7 +16,7 @@ export function useCurrentTradeProvider() { const polygonNetworkTradeProvider = useValueRef(polygonNetworkTradeProviderSettings) const binanceNetworkTradeProvider = useValueRef(binanceNetworkTradeProviderSettings) - if (!networkType) return TradeProvider.UNISWAP + if (!networkType) return TradeProvider.UNISWAP_V2 switch (networkType) { case NetworkType.Ethereum: return ethNetworkTradeProvider diff --git a/packages/maskbook/src/plugins/Trader/types/index.ts b/packages/maskbook/src/plugins/Trader/types/index.ts index e0c16723feeb..906809192291 100644 --- a/packages/maskbook/src/plugins/Trader/types/index.ts +++ b/packages/maskbook/src/plugins/Trader/types/index.ts @@ -1,5 +1,6 @@ export * from './0x' export * from './balancer' +export * from './uniswap' +export * from './dodo' export * from './trader' export * from './trending' -export * from './dodo' diff --git a/packages/maskbook/src/plugins/Trader/types/trader.ts b/packages/maskbook/src/plugins/Trader/types/trader.ts index 2344c9eb13ca..0652c33e3f44 100644 --- a/packages/maskbook/src/plugins/Trader/types/trader.ts +++ b/packages/maskbook/src/plugins/Trader/types/trader.ts @@ -77,7 +77,8 @@ export enum TokenPanelType { export interface TradeContext { TYPE: TradeProvider - IS_UNISWAP_LIKE: boolean + IS_UNISWAP_V2_LIKE?: boolean + IS_UNISWAP_V3_LIKE?: boolean GRAPH_API?: string INIT_CODE_HASH?: string ROUTER_CONTRACT_ADDRESS?: string diff --git a/packages/maskbook/src/plugins/Trader/types/uniswap.ts b/packages/maskbook/src/plugins/Trader/types/uniswap.ts new file mode 100644 index 000000000000..4b40ae6058bd --- /dev/null +++ b/packages/maskbook/src/plugins/Trader/types/uniswap.ts @@ -0,0 +1,11 @@ +import type { Trade as V2Trade } from '@uniswap/v2-sdk' +import type { Trade as V3Trade } from '@uniswap/v3-sdk' +import type { Currency, TradeType } from '@uniswap/sdk-core' + +export type Trade = V2Trade | V3Trade + +export interface SwapCall { + address: string + calldata: string + value: string +} diff --git a/packages/maskbook/src/plugins/VCent/icons/VCent.tsx b/packages/maskbook/src/plugins/VCent/icons/VCent.tsx index c54941a02168..fd80939733b8 100644 --- a/packages/maskbook/src/plugins/VCent/icons/VCent.tsx +++ b/packages/maskbook/src/plugins/VCent/icons/VCent.tsx @@ -8,35 +8,35 @@ export const VCentIconLight = createIcon( d="M60.710 10.487 C 60.138 10.663,59.549 10.927,59.402 11.074 C 59.010 11.466,58.070 11.825,56.806 12.065 C 55.738 12.268,54.833 12.688,54.833 12.981 C 54.833 13.057,54.327 13.447,53.708 13.846 C 52.567 14.581,49.335 17.743,49.334 18.125 C 49.334 18.240,49.260 18.333,49.170 18.333 C 49.080 18.333,48.960 18.519,48.903 18.746 C 48.846 18.973,48.522 19.409,48.184 19.714 C 47.644 20.203,47.533 20.441,47.274 21.677 C 46.802 23.933,46.327 25.335,45.878 25.804 C 45.717 25.972,45.667 27.230,45.667 31.111 C 45.667 36.726,45.629 36.936,44.533 37.352 C 44.267 37.454,38.999 37.511,30.588 37.504 C 20.691 37.496,16.921 37.545,16.513 37.687 C 15.852 37.918,14.061 39.699,13.756 40.429 C 13.638 40.710,13.310 41.205,13.027 41.528 L 12.511 42.114 12.496 53.849 C 12.488 60.303,12.485 65.965,12.490 66.432 C 12.498 67.084,12.595 67.392,12.907 67.756 C 13.131 68.016,13.450 68.493,13.616 68.814 C 13.907 69.379,15.287 70.825,15.542 70.831 C 15.610 70.832,15.667 70.927,15.668 71.042 C 15.672 71.758,15.333 71.748,39.103 71.794 C 59.045 71.833,61.646 71.809,61.831 71.586 C 61.947 71.447,62.095 71.333,62.162 71.333 C 62.374 71.333,64.271 69.437,64.580 68.917 C 64.743 68.642,65.045 68.229,65.251 68.000 C 65.819 67.368,65.844 66.791,65.846 54.336 C 65.848 42.122,65.835 41.844,65.226 41.112 C 65.010 40.853,64.833 40.591,64.833 40.529 C 64.831 40.348,63.698 39.167,63.526 39.167 C 63.439 39.167,63.144 38.911,62.870 38.600 C 62.030 37.643,61.852 37.599,58.417 37.504 C 53.764 37.376,54.106 37.959,54.196 30.299 C 54.267 24.272,54.261 24.304,55.500 23.103 C 55.867 22.748,56.167 22.366,56.167 22.256 C 56.167 21.992,56.940 21.331,57.716 20.932 C 58.055 20.757,58.333 20.551,58.333 20.474 C 58.333 19.536,59.789 19.167,63.489 19.167 C 67.252 19.167,67.736 19.270,68.541 20.247 C 68.798 20.558,69.175 20.866,69.379 20.930 C 69.980 21.118,70.518 21.618,70.858 22.306 C 71.033 22.659,71.362 23.048,71.588 23.169 C 71.815 23.290,72.000 23.474,72.000 23.578 C 72.000 23.682,72.092 23.859,72.204 23.971 C 72.690 24.457,72.839 26.133,72.923 32.083 C 73.008 38.081,73.009 38.083,73.391 38.425 C 73.602 38.612,73.918 39.069,74.095 39.440 C 74.542 40.377,74.912 40.500,77.275 40.500 C 79.513 40.500,79.933 40.388,80.422 39.657 C 80.603 39.388,80.805 39.167,80.873 39.167 C 81.429 39.165,81.547 37.932,81.523 32.417 C 81.495 26.331,81.366 25.093,80.660 24.167 C 80.192 23.554,80.066 23.167,79.842 21.667 C 79.676 20.547,79.385 19.882,78.823 19.333 C 78.588 19.104,78.257 18.694,78.087 18.421 C 77.376 17.285,74.840 14.741,73.615 13.937 C 73.082 13.588,72.427 13.088,72.159 12.826 C 71.661 12.339,70.767 12.003,69.965 12.001 C 69.451 12.000,67.957 11.449,67.333 11.031 C 66.199 10.271,62.427 9.961,60.710 10.487 M99.728 18.269 L 99.040 18.519 99.358 19.178 C 99.533 19.540,99.810 20.616,99.975 21.569 C 100.151 22.588,100.406 23.491,100.595 23.761 C 101.360 24.854,101.614 25.511,101.816 26.924 C 102.069 28.696,102.148 28.922,102.749 29.607 C 103.269 30.198,103.832 31.651,103.836 32.410 C 103.839 33.135,104.375 34.752,104.748 35.164 C 105.148 35.606,105.491 36.512,105.666 37.583 C 105.740 38.042,105.883 38.628,105.984 38.886 C 106.084 39.144,106.167 39.521,106.167 39.725 C 106.167 39.928,106.330 40.297,106.529 40.544 C 107.078 41.227,107.861 43.551,108.081 45.149 C 108.166 45.765,108.341 46.170,108.684 46.546 C 109.270 47.188,109.115 46.674,110.127 51.309 C 110.174 51.525,110.411 51.905,110.654 52.153 C 111.113 52.624,111.454 53.639,111.906 55.883 C 112.089 56.788,112.294 57.319,112.584 57.631 C 112.813 57.878,113.000 58.197,113.000 58.340 C 113.000 58.483,113.065 58.671,113.144 58.758 C 113.223 58.845,113.382 59.490,113.497 60.190 C 113.613 60.890,113.766 61.558,113.838 61.674 C 113.999 61.935,119.096 62.083,121.079 61.884 L 122.407 61.750 122.607 60.554 C 122.817 59.299,123.256 58.202,123.831 57.498 C 124.136 57.125,124.598 55.531,124.903 53.800 C 124.963 53.461,125.272 52.873,125.589 52.493 C 125.907 52.113,126.167 51.684,126.167 51.541 C 126.167 51.397,126.275 50.898,126.406 50.431 C 126.538 49.965,126.737 49.157,126.847 48.636 C 126.979 48.015,127.217 47.504,127.538 47.152 C 128.136 46.497,128.333 46.007,128.333 45.175 C 128.333 44.240,128.825 42.878,129.374 42.289 C 129.872 41.757,130.139 40.919,130.513 38.715 C 130.686 37.701,130.818 37.403,131.359 36.805 C 131.711 36.416,132.000 35.934,132.000 35.736 C 132.000 35.538,132.112 35.056,132.250 34.667 C 132.387 34.277,132.504 33.724,132.509 33.437 C 132.521 32.767,133.014 31.554,133.465 31.086 C 133.659 30.884,133.929 30.277,134.065 29.735 C 134.201 29.193,134.442 28.225,134.600 27.583 C 134.943 26.183,135.159 25.668,135.402 25.662 C 135.671 25.656,136.167 24.473,136.167 23.835 C 136.167 22.995,136.689 21.512,137.126 21.108 C 137.649 20.626,137.933 20.055,138.059 19.228 C 138.222 18.162,138.065 18.103,134.877 18.026 C 130.673 17.925,130.205 18.169,129.503 20.833 C 129.395 21.246,129.200 21.948,129.070 22.394 C 128.940 22.840,128.833 23.391,128.833 23.618 C 128.833 24.082,128.433 24.869,127.885 25.483 C 127.684 25.708,127.475 26.198,127.421 26.571 C 127.012 29.396,126.802 30.207,126.371 30.648 C 125.774 31.258,125.731 31.395,124.954 35.167 C 124.836 35.740,124.607 36.245,124.341 36.514 C 123.823 37.040,123.539 37.797,123.339 39.190 C 123.086 40.951,122.797 41.725,122.163 42.333 C 121.938 42.550,121.690 43.385,121.423 44.833 C 120.984 47.213,119.080 50.500,118.142 50.500 C 117.827 50.500,117.129 49.267,116.901 48.309 C 116.762 47.726,116.321 46.575,115.921 45.750 C 115.521 44.925,115.117 43.837,115.024 43.333 C 114.583 40.940,114.243 39.667,114.044 39.667 C 113.928 39.667,113.833 39.554,113.833 39.417 C 113.833 39.279,113.765 39.167,113.682 39.167 C 113.495 39.167,113.048 37.679,112.931 36.667 C 112.797 35.505,112.438 34.385,112.062 33.953 C 111.429 33.224,111.188 32.590,110.864 30.799 C 110.606 29.373,110.426 28.836,109.967 28.132 C 109.418 27.290,108.833 25.393,108.833 24.455 C 108.833 23.899,108.417 22.752,108.004 22.172 C 107.616 21.627,107.005 19.786,107.002 19.151 C 106.998 18.230,106.619 18.117,103.374 18.066 C 101.072 18.030,100.264 18.075,99.728 18.269 M177.333 18.141 C 176.921 18.206,176.490 18.317,176.375 18.389 C 176.025 18.609,176.075 61.383,176.426 61.674 C 176.834 62.013,182.786 62.006,183.002 61.667 C 183.101 61.513,183.174 54.350,183.194 43.000 C 183.240 16.303,183.277 18.571,182.792 18.310 C 182.362 18.079,178.497 17.959,177.333 18.141 M265.996 18.460 C 265.672 18.872,265.667 19.220,265.667 40.185 L 265.667 61.492 266.084 61.765 C 266.432 61.994,266.863 62.027,268.709 61.970 C 271.568 61.880,271.707 61.803,271.562 60.386 C 271.425 59.050,271.916 58.445,273.292 58.256 C 274.166 58.135,275.167 58.486,275.167 58.913 C 275.167 59.203,275.994 60.000,276.298 60.002 C 276.867 60.006,278.645 60.657,279.460 61.158 C 281.419 62.363,285.129 62.274,286.540 60.987 C 287.050 60.522,288.483 60.002,289.265 59.997 C 289.890 59.994,290.027 59.894,290.553 59.053 C 290.793 58.670,291.197 58.257,291.450 58.136 C 291.704 58.014,292.095 57.578,292.320 57.166 C 292.696 56.477,293.435 55.667,293.689 55.667 C 293.748 55.667,293.836 55.460,293.887 55.208 C 294.047 54.399,294.452 53.102,294.757 52.417 C 295.374 51.031,295.530 50.540,295.843 49.000 C 296.237 47.067,296.268 44.226,295.917 42.390 C 295.779 41.671,295.667 40.853,295.667 40.572 C 295.667 40.241,295.527 39.938,295.271 39.716 C 294.894 39.389,294.739 39.035,294.103 37.049 C 293.949 36.570,293.564 35.905,293.242 35.564 C 292.922 35.224,292.614 34.752,292.558 34.514 C 292.432 33.981,291.865 33.336,291.513 33.326 C 291.368 33.321,291.100 33.127,290.917 32.894 C 290.160 31.931,289.413 31.504,288.477 31.501 C 288.047 31.499,286.867 30.922,286.543 30.556 C 285.549 29.429,280.962 29.446,279.667 30.581 C 279.326 30.880,277.741 31.574,276.301 32.055 C 276.146 32.106,275.884 32.359,275.718 32.616 C 274.742 34.131,273.365 33.994,272.866 32.333 C 272.691 31.751,272.560 25.092,272.640 20.847 C 272.695 17.938,272.943 18.142,269.263 18.086 L 266.325 18.041 265.996 18.460 M305.919 18.115 C 305.553 18.157,305.160 18.270,305.044 18.366 C 304.876 18.505,304.833 22.940,304.833 40.098 L 304.833 61.655 305.202 61.852 C 305.716 62.127,311.505 61.925,311.696 61.626 C 311.769 61.511,311.833 53.542,311.839 43.917 C 311.855 18.112,311.861 18.626,311.572 18.336 C 311.321 18.083,307.495 17.934,305.919 18.115 M150.417 29.771 C 150.233 29.807,149.671 29.919,149.167 30.019 C 148.662 30.120,148.025 30.368,147.750 30.570 C 147.216 30.964,146.037 31.343,144.417 31.643 C 143.443 31.823,143.266 31.943,142.667 32.827 C 142.529 33.030,142.146 33.335,141.816 33.506 C 141.214 33.816,141.001 34.172,140.685 35.387 C 140.439 36.337,140.890 36.833,141.998 36.833 C 142.550 36.833,143.902 37.310,144.718 37.792 C 145.451 38.225,145.667 38.258,145.667 37.936 C 145.667 37.809,145.985 37.434,146.375 37.103 C 146.765 36.771,147.383 36.202,147.750 35.837 C 148.808 34.784,149.271 34.667,152.364 34.667 C 155.375 34.667,157.000 35.045,157.000 35.747 C 157.000 35.805,157.210 36.054,157.467 36.301 C 158.895 37.672,158.687 40.705,157.082 41.922 C 156.625 42.269,156.212 42.609,156.166 42.678 C 156.016 42.902,153.542 43.333,152.382 43.337 C 150.520 43.343,148.447 43.719,147.898 44.151 C 147.162 44.731,146.513 44.948,144.811 45.183 C 143.433 45.373,143.191 45.458,142.750 45.907 C 142.475 46.187,141.895 46.679,141.462 47.000 C 141.029 47.321,140.636 47.696,140.589 47.833 C 140.541 47.971,140.170 48.440,139.763 48.876 C 138.874 49.830,138.778 50.340,138.874 53.583 C 138.949 56.148,139.157 56.799,140.251 57.909 C 140.671 58.335,141.085 58.868,141.170 59.093 C 141.256 59.318,141.571 59.605,141.871 59.731 C 142.171 59.857,142.700 60.082,143.047 60.230 C 143.394 60.379,143.791 60.500,143.928 60.500 C 144.199 60.500,144.895 60.910,145.399 61.367 C 146.262 62.149,152.000 62.129,152.000 61.344 C 152.000 61.106,153.291 60.528,154.491 60.227 C 155.475 59.981,155.858 59.790,156.337 59.308 C 157.896 57.739,159.700 58.319,160.310 60.587 C 160.675 61.942,160.606 61.917,163.897 61.899 C 167.653 61.879,167.895 61.718,166.406 60.228 C 165.569 59.391,165.486 58.126,165.481 46.250 C 165.477 36.874,165.383 35.456,164.721 34.827 C 163.913 34.058,163.541 33.558,163.191 32.766 C 162.932 32.180,162.762 31.999,162.468 31.994 C 162.256 31.991,161.896 31.881,161.667 31.750 C 161.438 31.619,161.070 31.509,160.850 31.506 C 160.300 31.498,158.591 30.858,158.221 30.521 C 157.532 29.895,152.326 29.395,150.417 29.771 M193.782 29.959 L 193.314 30.250 193.387 41.667 C 193.469 54.583,193.548 55.828,194.331 56.539 C 194.607 56.790,194.833 57.071,194.833 57.164 C 194.833 57.257,194.891 57.333,194.960 57.333 C 195.030 57.333,195.162 57.480,195.252 57.658 C 196.033 59.201,196.206 59.443,196.704 59.685 C 197.811 60.225,198.519 60.500,198.801 60.500 C 198.960 60.500,199.352 60.711,199.670 60.969 C 201.228 62.228,204.546 62.345,206.862 61.221 C 207.625 60.851,208.737 60.410,209.333 60.242 C 209.929 60.075,210.829 59.673,211.333 59.350 C 211.838 59.027,212.475 58.676,212.750 58.570 C 213.025 58.465,213.363 58.330,213.501 58.270 C 213.654 58.204,214.000 58.366,214.388 58.686 L 215.023 59.210 214.970 60.388 C 214.898 61.975,215.004 62.029,217.917 61.889 C 219.108 61.831,220.233 61.731,220.417 61.665 C 220.870 61.503,221.279 50.640,220.897 48.906 C 220.555 47.359,220.627 41.818,221.001 40.833 C 221.250 40.177,221.259 39.958,221.076 39.083 C 220.923 38.356,220.912 37.861,221.035 37.268 C 221.130 36.814,221.149 36.112,221.079 35.684 C 221.009 35.262,220.942 34.092,220.928 33.083 C 220.901 31.046,220.749 30.167,220.424 30.167 C 220.305 30.167,220.114 30.054,220.000 29.917 C 219.678 29.529,215.833 29.561,214.992 29.958 C 214.196 30.334,214.198 30.313,214.201 40.464 L 214.204 48.178 213.776 49.798 C 213.541 50.688,213.258 52.008,213.147 52.730 L 212.946 54.043 211.996 54.780 C 211.474 55.185,210.957 55.682,210.847 55.883 C 210.163 57.134,203.962 57.577,202.874 56.453 C 202.677 56.250,202.107 55.649,201.607 55.119 L 200.698 54.154 200.589 52.452 C 200.529 51.516,200.504 46.137,200.532 40.500 C 200.577 31.562,200.551 30.218,200.333 30.000 C 199.928 29.595,194.423 29.561,193.782 29.959 M239.785 29.931 C 238.943 30.084,238.358 30.288,238.118 30.514 C 237.518 31.081,236.854 31.356,235.856 31.450 C 235.339 31.499,234.767 31.631,234.583 31.743 C 234.400 31.855,234.045 31.998,233.795 32.059 C 233.522 32.126,233.233 32.377,233.075 32.682 C 232.930 32.963,232.460 33.550,232.031 33.986 C 230.225 35.819,230.359 36.833,232.405 36.833 C 232.976 36.833,234.234 37.177,234.938 37.525 C 235.171 37.641,235.398 37.646,235.604 37.539 C 235.776 37.450,236.191 37.328,236.525 37.267 C 237.130 37.158,237.631 36.661,238.135 35.667 C 238.513 34.920,239.046 34.786,241.961 34.707 C 247.222 34.562,248.405 35.329,248.386 38.869 C 248.369 42.082,246.798 43.306,242.667 43.326 C 240.920 43.335,239.220 43.677,238.288 44.206 C 237.901 44.426,237.283 44.690,236.917 44.793 C 235.745 45.120,233.929 45.501,233.540 45.500 C 233.294 45.500,233.008 45.719,232.714 46.131 C 232.467 46.479,231.941 46.964,231.545 47.211 C 231.150 47.457,230.783 47.791,230.730 47.954 C 230.532 48.567,230.075 49.431,229.738 49.833 C 228.618 51.168,228.551 55.337,229.637 56.098 C 229.797 56.210,230.113 56.703,230.339 57.193 C 231.122 58.889,232.062 59.802,233.476 60.240 C 234.051 60.417,234.722 60.736,234.969 60.948 C 236.417 62.195,240.412 62.277,242.686 61.108 C 243.321 60.781,244.103 60.465,244.422 60.405 C 244.742 60.345,245.045 60.229,245.095 60.148 C 245.145 60.066,245.336 60.000,245.518 60.000 C 245.961 60.000,246.835 59.540,247.265 59.080 C 248.070 58.219,249.380 58.179,249.912 59.000 C 250.145 59.359,250.667 60.856,250.667 61.165 C 250.667 61.637,251.673 61.867,254.122 61.956 C 256.689 62.049,257.505 61.851,257.252 61.196 C 257.192 61.042,257.073 60.544,256.986 60.089 C 256.899 59.634,256.673 58.940,256.482 58.547 C 255.652 56.832,255.637 56.645,255.576 47.162 C 255.505 36.095,255.333 34.329,254.266 33.696 C 253.982 33.528,253.596 33.097,253.409 32.737 C 253.113 32.170,252.936 32.043,252.075 31.782 C 249.758 31.077,249.457 30.961,249.059 30.614 C 248.131 29.806,242.693 29.406,239.785 29.931 M331.083 29.990 C 329.881 30.279,328.989 30.601,328.837 30.802 C 328.655 31.043,327.684 31.500,327.355 31.500 C 326.776 31.500,325.784 32.049,325.078 32.760 C 324.709 33.133,324.091 33.615,323.705 33.832 C 323.319 34.049,322.965 34.346,322.919 34.493 C 322.757 35.002,321.692 36.531,321.182 36.986 C 320.770 37.354,320.621 37.685,320.416 38.680 C 319.965 40.877,319.818 41.408,319.588 41.665 C 318.686 42.675,318.457 48.010,319.265 49.201 C 319.532 49.595,319.799 50.179,319.858 50.500 C 319.918 50.821,320.051 51.571,320.155 52.167 C 320.432 53.750,320.785 54.718,321.297 55.298 C 322.185 56.304,322.353 56.530,322.608 57.064 C 322.752 57.367,323.192 57.802,323.608 58.054 C 324.016 58.300,324.476 58.722,324.630 58.990 C 324.837 59.351,325.172 59.567,325.914 59.818 C 327.590 60.385,328.065 60.578,328.500 60.868 C 330.476 62.187,336.530 62.322,339.093 61.105 C 340.103 60.626,341.205 60.284,342.931 59.915 C 343.122 59.874,343.559 59.576,343.901 59.254 C 344.244 58.931,344.552 58.667,344.587 58.667 C 344.621 58.667,344.860 58.471,345.116 58.231 C 345.373 57.991,345.733 57.737,345.917 57.666 C 346.215 57.550,346.197 57.522,345.750 57.408 C 345.475 57.338,345.100 57.189,344.917 57.077 C 344.733 56.964,344.149 56.825,343.618 56.767 C 342.563 56.652,341.246 56.113,341.102 55.738 C 340.967 55.386,340.382 55.449,339.781 55.881 C 337.530 57.499,329.766 57.459,329.248 55.828 C 329.199 55.674,328.899 55.408,328.580 55.236 C 328.261 55.065,328.000 54.829,328.000 54.712 C 328.000 54.595,327.926 54.500,327.837 54.500 C 327.747 54.500,327.624 54.294,327.564 54.042 C 327.425 53.460,327.022 52.702,326.568 52.167 C 326.096 51.611,325.754 49.886,326.042 49.516 C 326.338 49.137,326.843 48.775,327.330 48.594 C 327.562 48.507,331.986 48.395,337.203 48.344 C 348.042 48.236,347.172 48.384,347.208 46.651 C 347.286 42.864,346.763 39.216,346.016 38.348 C 345.430 37.666,345.260 37.326,344.999 36.311 C 344.870 35.808,344.668 35.468,344.420 35.335 C 344.211 35.223,343.817 34.816,343.545 34.430 C 343.273 34.044,342.774 33.598,342.437 33.437 C 342.099 33.277,341.656 32.889,341.453 32.575 C 341.250 32.261,340.990 32.003,340.875 32.002 C 340.760 32.001,340.667 31.932,340.667 31.849 C 340.667 31.766,340.273 31.644,339.792 31.579 C 338.765 31.440,337.782 31.083,337.085 30.597 C 335.771 29.682,333.371 29.439,331.083 29.990 M365.250 29.771 C 363.487 30.118,363.019 30.255,362.507 30.573 C 362.182 30.776,361.429 31.074,360.833 31.237 C 358.504 31.873,358.017 32.092,357.623 32.682 C 357.414 32.994,357.002 33.371,356.707 33.520 C 355.889 33.931,355.667 34.168,355.667 34.631 C 355.667 35.008,355.467 35.830,354.987 37.428 C 354.902 37.710,354.833 38.451,354.833 39.076 C 354.833 40.172,354.933 40.733,355.414 42.333 C 355.538 42.746,355.683 43.285,355.737 43.531 C 355.807 43.855,356.075 44.110,356.697 44.448 C 357.217 44.730,357.662 45.119,357.816 45.424 C 358.068 45.926,359.275 46.496,360.098 46.503 C 360.660 46.507,361.679 46.937,362.189 47.384 C 362.868 47.980,363.381 48.116,366.167 48.435 C 368.234 48.673,368.761 48.796,369.814 49.287 C 370.491 49.603,371.316 49.904,371.647 49.955 C 372.262 50.051,374.015 50.822,374.542 51.229 C 374.775 51.409,374.840 51.743,374.865 52.888 C 374.898 54.445,374.777 54.719,373.796 55.298 C 373.542 55.449,373.333 55.654,373.333 55.755 C 373.333 55.855,373.103 56.158,372.822 56.427 L 372.312 56.917 368.167 56.917 L 364.022 56.917 363.511 56.427 C 363.230 56.158,363.000 55.870,363.000 55.788 C 363.000 55.706,362.721 55.401,362.381 55.111 C 361.272 54.166,360.860 53.667,360.740 53.121 C 360.431 51.714,359.855 51.256,359.333 52.003 C 358.965 52.530,357.788 52.808,354.167 53.224 C 353.693 53.278,353.772 54.207,354.297 54.752 C 354.847 55.325,355.453 56.368,355.635 57.057 C 355.724 57.394,355.999 57.662,356.588 57.984 C 357.044 58.234,357.567 58.671,357.750 58.956 C 358.171 59.611,358.544 59.786,360.500 60.252 C 362.055 60.622,362.462 60.783,363.373 61.396 C 364.486 62.143,370.076 62.166,372.103 61.430 C 372.756 61.194,373.406 61.000,373.548 61.000 C 373.690 61.000,373.831 60.927,373.861 60.837 C 373.892 60.747,374.479 60.516,375.167 60.323 C 376.807 59.863,377.433 59.548,378.207 58.792 C 378.559 58.448,378.982 58.167,379.148 58.167 C 379.552 58.167,379.981 57.665,380.174 56.968 C 380.261 56.653,380.599 56.100,380.925 55.739 C 381.770 54.805,382.000 54.152,382.000 52.693 C 382.000 51.396,381.693 49.667,381.462 49.667 C 381.192 49.667,380.724 49.038,380.403 48.244 C 380.132 47.570,379.932 47.347,379.326 47.039 C 378.918 46.832,378.343 46.400,378.050 46.081 C 377.688 45.687,377.367 45.499,377.050 45.496 C 376.388 45.491,374.208 44.890,373.507 44.519 C 373.183 44.348,372.692 44.092,372.417 43.951 C 371.765 43.618,370.153 43.334,368.907 43.333 C 367.634 43.332,365.990 42.865,365.388 42.334 C 364.732 41.755,364.207 41.500,363.669 41.500 C 360.950 41.500,359.721 38.160,361.566 35.784 C 362.572 34.488,370.310 34.197,372.015 35.392 C 372.169 35.499,372.605 35.980,372.984 36.460 C 373.463 37.066,373.793 37.333,374.062 37.333 C 374.276 37.333,374.692 37.418,374.989 37.521 C 375.539 37.713,375.668 37.682,376.859 37.063 C 377.102 36.937,377.740 36.832,378.276 36.831 C 379.398 36.828,380.062 36.555,380.132 36.069 C 380.209 35.540,379.570 34.211,379.179 34.087 C 378.989 34.027,378.833 33.908,378.833 33.822 C 378.833 33.737,378.740 33.665,378.625 33.664 C 378.510 33.662,378.192 33.316,377.917 32.894 C 377.419 32.131,376.249 31.522,375.250 31.505 C 374.865 31.499,373.351 30.945,372.500 30.500 C 371.192 29.815,367.111 29.404,365.250 29.771 M284.223 35.014 C 284.575 35.134,285.107 35.517,285.406 35.866 C 285.704 36.215,286.012 36.500,286.089 36.500 C 286.311 36.500,287.000 37.204,287.000 37.432 C 287.000 37.703,287.783 39.259,288.058 39.535 C 288.671 40.150,288.805 40.651,289.009 43.083 C 289.241 45.844,289.027 50.649,288.653 51.100 C 288.263 51.569,287.816 52.411,287.201 53.833 C 286.935 54.447,286.411 55.000,286.095 55.000 C 285.879 55.000,285.333 55.593,285.333 55.828 C 285.333 56.430,284.501 56.802,282.884 56.923 C 279.118 57.206,276.667 56.746,276.667 55.756 C 276.667 55.656,276.330 55.427,275.918 55.246 C 275.220 54.939,274.333 53.679,274.333 52.995 C 274.333 52.906,274.258 52.833,274.167 52.833 C 272.943 52.833,272.556 49.937,272.862 43.083 C 273.015 39.671,273.188 38.667,273.624 38.667 C 273.739 38.667,273.833 38.592,273.833 38.500 C 273.833 38.408,273.934 38.333,274.058 38.333 C 274.182 38.333,274.415 38.039,274.577 37.680 C 274.868 37.036,276.221 35.500,276.497 35.500 C 276.575 35.500,276.664 35.439,276.694 35.364 C 276.973 34.683,282.498 34.426,284.223 35.014 M336.708 35.122 C 337.144 35.319,337.501 35.542,337.503 35.616 C 337.507 35.827,338.441 36.833,338.633 36.833 C 338.958 36.833,339.833 38.123,339.836 38.607 C 339.838 38.869,339.949 39.755,340.084 40.575 C 340.541 43.364,340.548 43.360,333.256 43.347 C 327.005 43.336,326.882 43.319,326.216 42.405 C 325.811 41.849,326.091 40.101,326.659 39.640 C 326.847 39.488,327.002 39.263,327.005 39.140 C 327.008 39.017,327.121 38.771,327.255 38.593 C 327.390 38.415,327.500 38.127,327.500 37.952 C 327.500 37.512,328.094 36.721,328.617 36.464 C 328.857 36.346,329.135 36.103,329.235 35.923 C 329.434 35.566,330.077 34.987,330.489 34.795 C 331.125 34.497,335.885 34.748,336.708 35.122 M157.821 47.013 L 158.333 47.526 158.331 50.054 C 158.328 53.193,158.250 53.425,156.666 55.003 C 154.653 57.009,154.910 56.917,151.333 56.917 C 146.650 56.917,145.581 55.919,146.010 51.946 C 146.279 49.446,146.658 49.015,149.167 48.348 C 149.946 48.140,150.771 47.846,151.000 47.694 C 152.803 46.498,156.897 46.089,157.821 47.013 M247.890 46.935 C 248.482 47.528,248.565 48.148,248.429 50.956 C 248.294 53.721,247.834 55.000,246.974 55.000 C 246.788 55.000,246.167 55.626,246.167 55.814 C 246.167 55.894,245.885 56.176,245.542 56.439 L 244.917 56.917 241.750 56.917 L 238.583 56.917 238.042 56.431 C 237.744 56.164,237.501 55.864,237.503 55.764 C 237.504 55.665,237.201 55.321,236.830 55.000 C 235.623 53.958,235.530 51.245,236.667 50.269 C 236.896 50.073,237.281 49.648,237.523 49.325 C 237.922 48.792,238.130 48.695,239.766 48.281 C 240.758 48.030,241.610 47.768,241.660 47.700 C 242.432 46.637,247.028 46.073,247.890 46.935 " stroke="none" fill="#0e0b10" - fill-rule="evenodd" + fillRule="evenodd" /> , '0 0 500 150', @@ -51,35 +51,35 @@ export const VCentIconDark = createIcon( d="M60.710 10.487 C 60.138 10.663,59.549 10.927,59.402 11.074 C 59.010 11.466,58.070 11.825,56.806 12.065 C 55.738 12.268,54.833 12.688,54.833 12.981 C 54.833 13.057,54.327 13.447,53.708 13.846 C 52.567 14.581,49.335 17.743,49.334 18.125 C 49.334 18.240,49.260 18.333,49.170 18.333 C 49.080 18.333,48.960 18.519,48.903 18.746 C 48.846 18.973,48.522 19.409,48.184 19.714 C 47.644 20.203,47.533 20.441,47.274 21.677 C 46.802 23.933,46.327 25.335,45.878 25.804 C 45.717 25.972,45.667 27.230,45.667 31.111 C 45.667 36.726,45.629 36.936,44.533 37.352 C 44.267 37.454,38.999 37.511,30.588 37.504 C 20.691 37.496,16.921 37.545,16.513 37.687 C 15.852 37.918,14.061 39.699,13.756 40.429 C 13.638 40.710,13.310 41.205,13.027 41.528 L 12.511 42.114 12.496 53.849 C 12.488 60.303,12.485 65.965,12.490 66.432 C 12.498 67.084,12.595 67.392,12.907 67.756 C 13.131 68.016,13.450 68.493,13.616 68.814 C 13.907 69.379,15.287 70.825,15.542 70.831 C 15.610 70.832,15.667 70.927,15.668 71.042 C 15.672 71.758,15.333 71.748,39.103 71.794 C 59.045 71.833,61.646 71.809,61.831 71.586 C 61.947 71.447,62.095 71.333,62.162 71.333 C 62.374 71.333,64.271 69.437,64.580 68.917 C 64.743 68.642,65.045 68.229,65.251 68.000 C 65.819 67.368,65.844 66.791,65.846 54.336 C 65.848 42.122,65.835 41.844,65.226 41.112 C 65.010 40.853,64.833 40.591,64.833 40.529 C 64.831 40.348,63.698 39.167,63.526 39.167 C 63.439 39.167,63.144 38.911,62.870 38.600 C 62.030 37.643,61.852 37.599,58.417 37.504 C 53.764 37.376,54.106 37.959,54.196 30.299 C 54.267 24.272,54.261 24.304,55.500 23.103 C 55.867 22.748,56.167 22.366,56.167 22.256 C 56.167 21.992,56.940 21.331,57.716 20.932 C 58.055 20.757,58.333 20.551,58.333 20.474 C 58.333 19.536,59.789 19.167,63.489 19.167 C 67.252 19.167,67.736 19.270,68.541 20.247 C 68.798 20.558,69.175 20.866,69.379 20.930 C 69.980 21.118,70.518 21.618,70.858 22.306 C 71.033 22.659,71.362 23.048,71.588 23.169 C 71.815 23.290,72.000 23.474,72.000 23.578 C 72.000 23.682,72.092 23.859,72.204 23.971 C 72.690 24.457,72.839 26.133,72.923 32.083 C 73.008 38.081,73.009 38.083,73.391 38.425 C 73.602 38.612,73.918 39.069,74.095 39.440 C 74.542 40.377,74.912 40.500,77.275 40.500 C 79.513 40.500,79.933 40.388,80.422 39.657 C 80.603 39.388,80.805 39.167,80.873 39.167 C 81.429 39.165,81.547 37.932,81.523 32.417 C 81.495 26.331,81.366 25.093,80.660 24.167 C 80.192 23.554,80.066 23.167,79.842 21.667 C 79.676 20.547,79.385 19.882,78.823 19.333 C 78.588 19.104,78.257 18.694,78.087 18.421 C 77.376 17.285,74.840 14.741,73.615 13.937 C 73.082 13.588,72.427 13.088,72.159 12.826 C 71.661 12.339,70.767 12.003,69.965 12.001 C 69.451 12.000,67.957 11.449,67.333 11.031 C 66.199 10.271,62.427 9.961,60.710 10.487 M99.728 18.269 L 99.040 18.519 99.358 19.178 C 99.533 19.540,99.810 20.616,99.975 21.569 C 100.151 22.588,100.406 23.491,100.595 23.761 C 101.360 24.854,101.614 25.511,101.816 26.924 C 102.069 28.696,102.148 28.922,102.749 29.607 C 103.269 30.198,103.832 31.651,103.836 32.410 C 103.839 33.135,104.375 34.752,104.748 35.164 C 105.148 35.606,105.491 36.512,105.666 37.583 C 105.740 38.042,105.883 38.628,105.984 38.886 C 106.084 39.144,106.167 39.521,106.167 39.725 C 106.167 39.928,106.330 40.297,106.529 40.544 C 107.078 41.227,107.861 43.551,108.081 45.149 C 108.166 45.765,108.341 46.170,108.684 46.546 C 109.270 47.188,109.115 46.674,110.127 51.309 C 110.174 51.525,110.411 51.905,110.654 52.153 C 111.113 52.624,111.454 53.639,111.906 55.883 C 112.089 56.788,112.294 57.319,112.584 57.631 C 112.813 57.878,113.000 58.197,113.000 58.340 C 113.000 58.483,113.065 58.671,113.144 58.758 C 113.223 58.845,113.382 59.490,113.497 60.190 C 113.613 60.890,113.766 61.558,113.838 61.674 C 113.999 61.935,119.096 62.083,121.079 61.884 L 122.407 61.750 122.607 60.554 C 122.817 59.299,123.256 58.202,123.831 57.498 C 124.136 57.125,124.598 55.531,124.903 53.800 C 124.963 53.461,125.272 52.873,125.589 52.493 C 125.907 52.113,126.167 51.684,126.167 51.541 C 126.167 51.397,126.275 50.898,126.406 50.431 C 126.538 49.965,126.737 49.157,126.847 48.636 C 126.979 48.015,127.217 47.504,127.538 47.152 C 128.136 46.497,128.333 46.007,128.333 45.175 C 128.333 44.240,128.825 42.878,129.374 42.289 C 129.872 41.757,130.139 40.919,130.513 38.715 C 130.686 37.701,130.818 37.403,131.359 36.805 C 131.711 36.416,132.000 35.934,132.000 35.736 C 132.000 35.538,132.112 35.056,132.250 34.667 C 132.387 34.277,132.504 33.724,132.509 33.437 C 132.521 32.767,133.014 31.554,133.465 31.086 C 133.659 30.884,133.929 30.277,134.065 29.735 C 134.201 29.193,134.442 28.225,134.600 27.583 C 134.943 26.183,135.159 25.668,135.402 25.662 C 135.671 25.656,136.167 24.473,136.167 23.835 C 136.167 22.995,136.689 21.512,137.126 21.108 C 137.649 20.626,137.933 20.055,138.059 19.228 C 138.222 18.162,138.065 18.103,134.877 18.026 C 130.673 17.925,130.205 18.169,129.503 20.833 C 129.395 21.246,129.200 21.948,129.070 22.394 C 128.940 22.840,128.833 23.391,128.833 23.618 C 128.833 24.082,128.433 24.869,127.885 25.483 C 127.684 25.708,127.475 26.198,127.421 26.571 C 127.012 29.396,126.802 30.207,126.371 30.648 C 125.774 31.258,125.731 31.395,124.954 35.167 C 124.836 35.740,124.607 36.245,124.341 36.514 C 123.823 37.040,123.539 37.797,123.339 39.190 C 123.086 40.951,122.797 41.725,122.163 42.333 C 121.938 42.550,121.690 43.385,121.423 44.833 C 120.984 47.213,119.080 50.500,118.142 50.500 C 117.827 50.500,117.129 49.267,116.901 48.309 C 116.762 47.726,116.321 46.575,115.921 45.750 C 115.521 44.925,115.117 43.837,115.024 43.333 C 114.583 40.940,114.243 39.667,114.044 39.667 C 113.928 39.667,113.833 39.554,113.833 39.417 C 113.833 39.279,113.765 39.167,113.682 39.167 C 113.495 39.167,113.048 37.679,112.931 36.667 C 112.797 35.505,112.438 34.385,112.062 33.953 C 111.429 33.224,111.188 32.590,110.864 30.799 C 110.606 29.373,110.426 28.836,109.967 28.132 C 109.418 27.290,108.833 25.393,108.833 24.455 C 108.833 23.899,108.417 22.752,108.004 22.172 C 107.616 21.627,107.005 19.786,107.002 19.151 C 106.998 18.230,106.619 18.117,103.374 18.066 C 101.072 18.030,100.264 18.075,99.728 18.269 M177.333 18.141 C 176.921 18.206,176.490 18.317,176.375 18.389 C 176.025 18.609,176.075 61.383,176.426 61.674 C 176.834 62.013,182.786 62.006,183.002 61.667 C 183.101 61.513,183.174 54.350,183.194 43.000 C 183.240 16.303,183.277 18.571,182.792 18.310 C 182.362 18.079,178.497 17.959,177.333 18.141 M265.996 18.460 C 265.672 18.872,265.667 19.220,265.667 40.185 L 265.667 61.492 266.084 61.765 C 266.432 61.994,266.863 62.027,268.709 61.970 C 271.568 61.880,271.707 61.803,271.562 60.386 C 271.425 59.050,271.916 58.445,273.292 58.256 C 274.166 58.135,275.167 58.486,275.167 58.913 C 275.167 59.203,275.994 60.000,276.298 60.002 C 276.867 60.006,278.645 60.657,279.460 61.158 C 281.419 62.363,285.129 62.274,286.540 60.987 C 287.050 60.522,288.483 60.002,289.265 59.997 C 289.890 59.994,290.027 59.894,290.553 59.053 C 290.793 58.670,291.197 58.257,291.450 58.136 C 291.704 58.014,292.095 57.578,292.320 57.166 C 292.696 56.477,293.435 55.667,293.689 55.667 C 293.748 55.667,293.836 55.460,293.887 55.208 C 294.047 54.399,294.452 53.102,294.757 52.417 C 295.374 51.031,295.530 50.540,295.843 49.000 C 296.237 47.067,296.268 44.226,295.917 42.390 C 295.779 41.671,295.667 40.853,295.667 40.572 C 295.667 40.241,295.527 39.938,295.271 39.716 C 294.894 39.389,294.739 39.035,294.103 37.049 C 293.949 36.570,293.564 35.905,293.242 35.564 C 292.922 35.224,292.614 34.752,292.558 34.514 C 292.432 33.981,291.865 33.336,291.513 33.326 C 291.368 33.321,291.100 33.127,290.917 32.894 C 290.160 31.931,289.413 31.504,288.477 31.501 C 288.047 31.499,286.867 30.922,286.543 30.556 C 285.549 29.429,280.962 29.446,279.667 30.581 C 279.326 30.880,277.741 31.574,276.301 32.055 C 276.146 32.106,275.884 32.359,275.718 32.616 C 274.742 34.131,273.365 33.994,272.866 32.333 C 272.691 31.751,272.560 25.092,272.640 20.847 C 272.695 17.938,272.943 18.142,269.263 18.086 L 266.325 18.041 265.996 18.460 M305.919 18.115 C 305.553 18.157,305.160 18.270,305.044 18.366 C 304.876 18.505,304.833 22.940,304.833 40.098 L 304.833 61.655 305.202 61.852 C 305.716 62.127,311.505 61.925,311.696 61.626 C 311.769 61.511,311.833 53.542,311.839 43.917 C 311.855 18.112,311.861 18.626,311.572 18.336 C 311.321 18.083,307.495 17.934,305.919 18.115 M150.417 29.771 C 150.233 29.807,149.671 29.919,149.167 30.019 C 148.662 30.120,148.025 30.368,147.750 30.570 C 147.216 30.964,146.037 31.343,144.417 31.643 C 143.443 31.823,143.266 31.943,142.667 32.827 C 142.529 33.030,142.146 33.335,141.816 33.506 C 141.214 33.816,141.001 34.172,140.685 35.387 C 140.439 36.337,140.890 36.833,141.998 36.833 C 142.550 36.833,143.902 37.310,144.718 37.792 C 145.451 38.225,145.667 38.258,145.667 37.936 C 145.667 37.809,145.985 37.434,146.375 37.103 C 146.765 36.771,147.383 36.202,147.750 35.837 C 148.808 34.784,149.271 34.667,152.364 34.667 C 155.375 34.667,157.000 35.045,157.000 35.747 C 157.000 35.805,157.210 36.054,157.467 36.301 C 158.895 37.672,158.687 40.705,157.082 41.922 C 156.625 42.269,156.212 42.609,156.166 42.678 C 156.016 42.902,153.542 43.333,152.382 43.337 C 150.520 43.343,148.447 43.719,147.898 44.151 C 147.162 44.731,146.513 44.948,144.811 45.183 C 143.433 45.373,143.191 45.458,142.750 45.907 C 142.475 46.187,141.895 46.679,141.462 47.000 C 141.029 47.321,140.636 47.696,140.589 47.833 C 140.541 47.971,140.170 48.440,139.763 48.876 C 138.874 49.830,138.778 50.340,138.874 53.583 C 138.949 56.148,139.157 56.799,140.251 57.909 C 140.671 58.335,141.085 58.868,141.170 59.093 C 141.256 59.318,141.571 59.605,141.871 59.731 C 142.171 59.857,142.700 60.082,143.047 60.230 C 143.394 60.379,143.791 60.500,143.928 60.500 C 144.199 60.500,144.895 60.910,145.399 61.367 C 146.262 62.149,152.000 62.129,152.000 61.344 C 152.000 61.106,153.291 60.528,154.491 60.227 C 155.475 59.981,155.858 59.790,156.337 59.308 C 157.896 57.739,159.700 58.319,160.310 60.587 C 160.675 61.942,160.606 61.917,163.897 61.899 C 167.653 61.879,167.895 61.718,166.406 60.228 C 165.569 59.391,165.486 58.126,165.481 46.250 C 165.477 36.874,165.383 35.456,164.721 34.827 C 163.913 34.058,163.541 33.558,163.191 32.766 C 162.932 32.180,162.762 31.999,162.468 31.994 C 162.256 31.991,161.896 31.881,161.667 31.750 C 161.438 31.619,161.070 31.509,160.850 31.506 C 160.300 31.498,158.591 30.858,158.221 30.521 C 157.532 29.895,152.326 29.395,150.417 29.771 M193.782 29.959 L 193.314 30.250 193.387 41.667 C 193.469 54.583,193.548 55.828,194.331 56.539 C 194.607 56.790,194.833 57.071,194.833 57.164 C 194.833 57.257,194.891 57.333,194.960 57.333 C 195.030 57.333,195.162 57.480,195.252 57.658 C 196.033 59.201,196.206 59.443,196.704 59.685 C 197.811 60.225,198.519 60.500,198.801 60.500 C 198.960 60.500,199.352 60.711,199.670 60.969 C 201.228 62.228,204.546 62.345,206.862 61.221 C 207.625 60.851,208.737 60.410,209.333 60.242 C 209.929 60.075,210.829 59.673,211.333 59.350 C 211.838 59.027,212.475 58.676,212.750 58.570 C 213.025 58.465,213.363 58.330,213.501 58.270 C 213.654 58.204,214.000 58.366,214.388 58.686 L 215.023 59.210 214.970 60.388 C 214.898 61.975,215.004 62.029,217.917 61.889 C 219.108 61.831,220.233 61.731,220.417 61.665 C 220.870 61.503,221.279 50.640,220.897 48.906 C 220.555 47.359,220.627 41.818,221.001 40.833 C 221.250 40.177,221.259 39.958,221.076 39.083 C 220.923 38.356,220.912 37.861,221.035 37.268 C 221.130 36.814,221.149 36.112,221.079 35.684 C 221.009 35.262,220.942 34.092,220.928 33.083 C 220.901 31.046,220.749 30.167,220.424 30.167 C 220.305 30.167,220.114 30.054,220.000 29.917 C 219.678 29.529,215.833 29.561,214.992 29.958 C 214.196 30.334,214.198 30.313,214.201 40.464 L 214.204 48.178 213.776 49.798 C 213.541 50.688,213.258 52.008,213.147 52.730 L 212.946 54.043 211.996 54.780 C 211.474 55.185,210.957 55.682,210.847 55.883 C 210.163 57.134,203.962 57.577,202.874 56.453 C 202.677 56.250,202.107 55.649,201.607 55.119 L 200.698 54.154 200.589 52.452 C 200.529 51.516,200.504 46.137,200.532 40.500 C 200.577 31.562,200.551 30.218,200.333 30.000 C 199.928 29.595,194.423 29.561,193.782 29.959 M239.785 29.931 C 238.943 30.084,238.358 30.288,238.118 30.514 C 237.518 31.081,236.854 31.356,235.856 31.450 C 235.339 31.499,234.767 31.631,234.583 31.743 C 234.400 31.855,234.045 31.998,233.795 32.059 C 233.522 32.126,233.233 32.377,233.075 32.682 C 232.930 32.963,232.460 33.550,232.031 33.986 C 230.225 35.819,230.359 36.833,232.405 36.833 C 232.976 36.833,234.234 37.177,234.938 37.525 C 235.171 37.641,235.398 37.646,235.604 37.539 C 235.776 37.450,236.191 37.328,236.525 37.267 C 237.130 37.158,237.631 36.661,238.135 35.667 C 238.513 34.920,239.046 34.786,241.961 34.707 C 247.222 34.562,248.405 35.329,248.386 38.869 C 248.369 42.082,246.798 43.306,242.667 43.326 C 240.920 43.335,239.220 43.677,238.288 44.206 C 237.901 44.426,237.283 44.690,236.917 44.793 C 235.745 45.120,233.929 45.501,233.540 45.500 C 233.294 45.500,233.008 45.719,232.714 46.131 C 232.467 46.479,231.941 46.964,231.545 47.211 C 231.150 47.457,230.783 47.791,230.730 47.954 C 230.532 48.567,230.075 49.431,229.738 49.833 C 228.618 51.168,228.551 55.337,229.637 56.098 C 229.797 56.210,230.113 56.703,230.339 57.193 C 231.122 58.889,232.062 59.802,233.476 60.240 C 234.051 60.417,234.722 60.736,234.969 60.948 C 236.417 62.195,240.412 62.277,242.686 61.108 C 243.321 60.781,244.103 60.465,244.422 60.405 C 244.742 60.345,245.045 60.229,245.095 60.148 C 245.145 60.066,245.336 60.000,245.518 60.000 C 245.961 60.000,246.835 59.540,247.265 59.080 C 248.070 58.219,249.380 58.179,249.912 59.000 C 250.145 59.359,250.667 60.856,250.667 61.165 C 250.667 61.637,251.673 61.867,254.122 61.956 C 256.689 62.049,257.505 61.851,257.252 61.196 C 257.192 61.042,257.073 60.544,256.986 60.089 C 256.899 59.634,256.673 58.940,256.482 58.547 C 255.652 56.832,255.637 56.645,255.576 47.162 C 255.505 36.095,255.333 34.329,254.266 33.696 C 253.982 33.528,253.596 33.097,253.409 32.737 C 253.113 32.170,252.936 32.043,252.075 31.782 C 249.758 31.077,249.457 30.961,249.059 30.614 C 248.131 29.806,242.693 29.406,239.785 29.931 M331.083 29.990 C 329.881 30.279,328.989 30.601,328.837 30.802 C 328.655 31.043,327.684 31.500,327.355 31.500 C 326.776 31.500,325.784 32.049,325.078 32.760 C 324.709 33.133,324.091 33.615,323.705 33.832 C 323.319 34.049,322.965 34.346,322.919 34.493 C 322.757 35.002,321.692 36.531,321.182 36.986 C 320.770 37.354,320.621 37.685,320.416 38.680 C 319.965 40.877,319.818 41.408,319.588 41.665 C 318.686 42.675,318.457 48.010,319.265 49.201 C 319.532 49.595,319.799 50.179,319.858 50.500 C 319.918 50.821,320.051 51.571,320.155 52.167 C 320.432 53.750,320.785 54.718,321.297 55.298 C 322.185 56.304,322.353 56.530,322.608 57.064 C 322.752 57.367,323.192 57.802,323.608 58.054 C 324.016 58.300,324.476 58.722,324.630 58.990 C 324.837 59.351,325.172 59.567,325.914 59.818 C 327.590 60.385,328.065 60.578,328.500 60.868 C 330.476 62.187,336.530 62.322,339.093 61.105 C 340.103 60.626,341.205 60.284,342.931 59.915 C 343.122 59.874,343.559 59.576,343.901 59.254 C 344.244 58.931,344.552 58.667,344.587 58.667 C 344.621 58.667,344.860 58.471,345.116 58.231 C 345.373 57.991,345.733 57.737,345.917 57.666 C 346.215 57.550,346.197 57.522,345.750 57.408 C 345.475 57.338,345.100 57.189,344.917 57.077 C 344.733 56.964,344.149 56.825,343.618 56.767 C 342.563 56.652,341.246 56.113,341.102 55.738 C 340.967 55.386,340.382 55.449,339.781 55.881 C 337.530 57.499,329.766 57.459,329.248 55.828 C 329.199 55.674,328.899 55.408,328.580 55.236 C 328.261 55.065,328.000 54.829,328.000 54.712 C 328.000 54.595,327.926 54.500,327.837 54.500 C 327.747 54.500,327.624 54.294,327.564 54.042 C 327.425 53.460,327.022 52.702,326.568 52.167 C 326.096 51.611,325.754 49.886,326.042 49.516 C 326.338 49.137,326.843 48.775,327.330 48.594 C 327.562 48.507,331.986 48.395,337.203 48.344 C 348.042 48.236,347.172 48.384,347.208 46.651 C 347.286 42.864,346.763 39.216,346.016 38.348 C 345.430 37.666,345.260 37.326,344.999 36.311 C 344.870 35.808,344.668 35.468,344.420 35.335 C 344.211 35.223,343.817 34.816,343.545 34.430 C 343.273 34.044,342.774 33.598,342.437 33.437 C 342.099 33.277,341.656 32.889,341.453 32.575 C 341.250 32.261,340.990 32.003,340.875 32.002 C 340.760 32.001,340.667 31.932,340.667 31.849 C 340.667 31.766,340.273 31.644,339.792 31.579 C 338.765 31.440,337.782 31.083,337.085 30.597 C 335.771 29.682,333.371 29.439,331.083 29.990 M365.250 29.771 C 363.487 30.118,363.019 30.255,362.507 30.573 C 362.182 30.776,361.429 31.074,360.833 31.237 C 358.504 31.873,358.017 32.092,357.623 32.682 C 357.414 32.994,357.002 33.371,356.707 33.520 C 355.889 33.931,355.667 34.168,355.667 34.631 C 355.667 35.008,355.467 35.830,354.987 37.428 C 354.902 37.710,354.833 38.451,354.833 39.076 C 354.833 40.172,354.933 40.733,355.414 42.333 C 355.538 42.746,355.683 43.285,355.737 43.531 C 355.807 43.855,356.075 44.110,356.697 44.448 C 357.217 44.730,357.662 45.119,357.816 45.424 C 358.068 45.926,359.275 46.496,360.098 46.503 C 360.660 46.507,361.679 46.937,362.189 47.384 C 362.868 47.980,363.381 48.116,366.167 48.435 C 368.234 48.673,368.761 48.796,369.814 49.287 C 370.491 49.603,371.316 49.904,371.647 49.955 C 372.262 50.051,374.015 50.822,374.542 51.229 C 374.775 51.409,374.840 51.743,374.865 52.888 C 374.898 54.445,374.777 54.719,373.796 55.298 C 373.542 55.449,373.333 55.654,373.333 55.755 C 373.333 55.855,373.103 56.158,372.822 56.427 L 372.312 56.917 368.167 56.917 L 364.022 56.917 363.511 56.427 C 363.230 56.158,363.000 55.870,363.000 55.788 C 363.000 55.706,362.721 55.401,362.381 55.111 C 361.272 54.166,360.860 53.667,360.740 53.121 C 360.431 51.714,359.855 51.256,359.333 52.003 C 358.965 52.530,357.788 52.808,354.167 53.224 C 353.693 53.278,353.772 54.207,354.297 54.752 C 354.847 55.325,355.453 56.368,355.635 57.057 C 355.724 57.394,355.999 57.662,356.588 57.984 C 357.044 58.234,357.567 58.671,357.750 58.956 C 358.171 59.611,358.544 59.786,360.500 60.252 C 362.055 60.622,362.462 60.783,363.373 61.396 C 364.486 62.143,370.076 62.166,372.103 61.430 C 372.756 61.194,373.406 61.000,373.548 61.000 C 373.690 61.000,373.831 60.927,373.861 60.837 C 373.892 60.747,374.479 60.516,375.167 60.323 C 376.807 59.863,377.433 59.548,378.207 58.792 C 378.559 58.448,378.982 58.167,379.148 58.167 C 379.552 58.167,379.981 57.665,380.174 56.968 C 380.261 56.653,380.599 56.100,380.925 55.739 C 381.770 54.805,382.000 54.152,382.000 52.693 C 382.000 51.396,381.693 49.667,381.462 49.667 C 381.192 49.667,380.724 49.038,380.403 48.244 C 380.132 47.570,379.932 47.347,379.326 47.039 C 378.918 46.832,378.343 46.400,378.050 46.081 C 377.688 45.687,377.367 45.499,377.050 45.496 C 376.388 45.491,374.208 44.890,373.507 44.519 C 373.183 44.348,372.692 44.092,372.417 43.951 C 371.765 43.618,370.153 43.334,368.907 43.333 C 367.634 43.332,365.990 42.865,365.388 42.334 C 364.732 41.755,364.207 41.500,363.669 41.500 C 360.950 41.500,359.721 38.160,361.566 35.784 C 362.572 34.488,370.310 34.197,372.015 35.392 C 372.169 35.499,372.605 35.980,372.984 36.460 C 373.463 37.066,373.793 37.333,374.062 37.333 C 374.276 37.333,374.692 37.418,374.989 37.521 C 375.539 37.713,375.668 37.682,376.859 37.063 C 377.102 36.937,377.740 36.832,378.276 36.831 C 379.398 36.828,380.062 36.555,380.132 36.069 C 380.209 35.540,379.570 34.211,379.179 34.087 C 378.989 34.027,378.833 33.908,378.833 33.822 C 378.833 33.737,378.740 33.665,378.625 33.664 C 378.510 33.662,378.192 33.316,377.917 32.894 C 377.419 32.131,376.249 31.522,375.250 31.505 C 374.865 31.499,373.351 30.945,372.500 30.500 C 371.192 29.815,367.111 29.404,365.250 29.771 M284.223 35.014 C 284.575 35.134,285.107 35.517,285.406 35.866 C 285.704 36.215,286.012 36.500,286.089 36.500 C 286.311 36.500,287.000 37.204,287.000 37.432 C 287.000 37.703,287.783 39.259,288.058 39.535 C 288.671 40.150,288.805 40.651,289.009 43.083 C 289.241 45.844,289.027 50.649,288.653 51.100 C 288.263 51.569,287.816 52.411,287.201 53.833 C 286.935 54.447,286.411 55.000,286.095 55.000 C 285.879 55.000,285.333 55.593,285.333 55.828 C 285.333 56.430,284.501 56.802,282.884 56.923 C 279.118 57.206,276.667 56.746,276.667 55.756 C 276.667 55.656,276.330 55.427,275.918 55.246 C 275.220 54.939,274.333 53.679,274.333 52.995 C 274.333 52.906,274.258 52.833,274.167 52.833 C 272.943 52.833,272.556 49.937,272.862 43.083 C 273.015 39.671,273.188 38.667,273.624 38.667 C 273.739 38.667,273.833 38.592,273.833 38.500 C 273.833 38.408,273.934 38.333,274.058 38.333 C 274.182 38.333,274.415 38.039,274.577 37.680 C 274.868 37.036,276.221 35.500,276.497 35.500 C 276.575 35.500,276.664 35.439,276.694 35.364 C 276.973 34.683,282.498 34.426,284.223 35.014 M336.708 35.122 C 337.144 35.319,337.501 35.542,337.503 35.616 C 337.507 35.827,338.441 36.833,338.633 36.833 C 338.958 36.833,339.833 38.123,339.836 38.607 C 339.838 38.869,339.949 39.755,340.084 40.575 C 340.541 43.364,340.548 43.360,333.256 43.347 C 327.005 43.336,326.882 43.319,326.216 42.405 C 325.811 41.849,326.091 40.101,326.659 39.640 C 326.847 39.488,327.002 39.263,327.005 39.140 C 327.008 39.017,327.121 38.771,327.255 38.593 C 327.390 38.415,327.500 38.127,327.500 37.952 C 327.500 37.512,328.094 36.721,328.617 36.464 C 328.857 36.346,329.135 36.103,329.235 35.923 C 329.434 35.566,330.077 34.987,330.489 34.795 C 331.125 34.497,335.885 34.748,336.708 35.122 M157.821 47.013 L 158.333 47.526 158.331 50.054 C 158.328 53.193,158.250 53.425,156.666 55.003 C 154.653 57.009,154.910 56.917,151.333 56.917 C 146.650 56.917,145.581 55.919,146.010 51.946 C 146.279 49.446,146.658 49.015,149.167 48.348 C 149.946 48.140,150.771 47.846,151.000 47.694 C 152.803 46.498,156.897 46.089,157.821 47.013 M247.890 46.935 C 248.482 47.528,248.565 48.148,248.429 50.956 C 248.294 53.721,247.834 55.000,246.974 55.000 C 246.788 55.000,246.167 55.626,246.167 55.814 C 246.167 55.894,245.885 56.176,245.542 56.439 L 244.917 56.917 241.750 56.917 L 238.583 56.917 238.042 56.431 C 237.744 56.164,237.501 55.864,237.503 55.764 C 237.504 55.665,237.201 55.321,236.830 55.000 C 235.623 53.958,235.530 51.245,236.667 50.269 C 236.896 50.073,237.281 49.648,237.523 49.325 C 237.922 48.792,238.130 48.695,239.766 48.281 C 240.758 48.030,241.610 47.768,241.660 47.700 C 242.432 46.637,247.028 46.073,247.890 46.935 " stroke="none" fill="#969595" - fill-rule="evenodd" + fillRule="evenodd" /> , '0 0 500 150', diff --git a/packages/maskbook/src/plugins/Wallet/SNSAdaptor/WalletConnectQRCodeDialog/Icons.tsx b/packages/maskbook/src/plugins/Wallet/SNSAdaptor/WalletConnectQRCodeDialog/Icons.tsx index 46d45ee2407f..e00e494142f9 100644 --- a/packages/maskbook/src/plugins/Wallet/SNSAdaptor/WalletConnectQRCodeDialog/Icons.tsx +++ b/packages/maskbook/src/plugins/Wallet/SNSAdaptor/WalletConnectQRCodeDialog/Icons.tsx @@ -24,8 +24,8 @@ export const IMTokenIcon: React.FC = (props) => ( /> - - + + @@ -56,8 +56,8 @@ export const RainbowIcon: React.FC = (props) => ( r="1" gradientTransform="matrix(35.56535 -34.37578 34.64161 35.84038 23.943 103.361)" gradientUnits="userSpaceOnUse"> - - + + = (props) => ( r="1" gradientTransform="rotate(-44.956 139.17 26.446) scale(69.6855 70.0822)" gradientUnits="userSpaceOnUse"> - - + + = (props) => ( r="1" gradientTransform="matrix(61.26799 -59.14432 59.4229 61.55657 22 106.063)" gradientUnits="userSpaceOnUse"> - - + + - - + + diff --git a/packages/maskbook/src/plugins/Wallet/services/cloud.ts b/packages/maskbook/src/plugins/Wallet/services/cloud.ts index 5501016a74d5..7471e81c4fbf 100644 --- a/packages/maskbook/src/plugins/Wallet/services/cloud.ts +++ b/packages/maskbook/src/plugins/Wallet/services/cloud.ts @@ -27,6 +27,6 @@ const sendRiskWarningConfirm = (address: string, pluginId?: string) => }) export const confirmRiskWarning = async (address: string, pluginId?: string) => { - const result = await sendRiskWarningConfirm(address, pluginId) - if (result.ok) await setRiskWarningConfirmed(address, true) + await setRiskWarningConfirmed(address, true) + await sendRiskWarningConfirm(address, pluginId) } diff --git a/packages/maskbook/src/resources/DODOIcon.tsx b/packages/maskbook/src/resources/DODOIcon.tsx index 6eb074380d33..3a64e0a1adce 100644 --- a/packages/maskbook/src/resources/DODOIcon.tsx +++ b/packages/maskbook/src/resources/DODOIcon.tsx @@ -4,11 +4,11 @@ const svg = ( - - + + - + + + feeGrowthGlobal1X128(): NonPayableTransactionObject + + liquidity(): NonPayableTransactionObject + + observations(index: number | string | BN): NonPayableTransactionObject<{ + blockTimestamp: string + tickCumulative: string + secondsPerLiquidityCumulativeX128: string + initialized: boolean + 0: string + 1: string + 2: string + 3: boolean + }> + + positions(key: string | number[]): NonPayableTransactionObject<{ + _liquidity: string + feeGrowthInside0LastX128: string + feeGrowthInside1LastX128: string + tokensOwed0: string + tokensOwed1: string + 0: string + 1: string + 2: string + 3: string + 4: string + }> + + protocolFees(): NonPayableTransactionObject<{ + token0: string + token1: string + 0: string + 1: string + }> + + slot0(): NonPayableTransactionObject<{ + sqrtPriceX96: string + tick: string + observationIndex: string + observationCardinality: string + observationCardinalityNext: string + feeProtocol: string + unlocked: boolean + 0: string + 1: string + 2: string + 3: string + 4: string + 5: string + 6: boolean + }> + + tickBitmap(wordPosition: number | string | BN): NonPayableTransactionObject + + ticks(tick: number | string | BN): NonPayableTransactionObject<{ + liquidityGross: string + liquidityNet: string + feeGrowthOutside0X128: string + feeGrowthOutside1X128: string + tickCumulativeOutside: string + secondsPerLiquidityOutsideX128: string + secondsOutside: string + initialized: boolean + 0: string + 1: string + 2: string + 3: string + 4: string + 5: string + 6: string + 7: boolean + }> + } + events: { + allEvents(options?: EventOptions, cb?: Callback): EventEmitter + } +} diff --git a/packages/web3-contracts/types/Quoter.d.ts b/packages/web3-contracts/types/Quoter.d.ts new file mode 100644 index 000000000000..70d43c348d8d --- /dev/null +++ b/packages/web3-contracts/types/Quoter.d.ts @@ -0,0 +1,61 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import BN from 'bn.js' +import { ContractOptions } from 'web3-eth-contract' +import { EventLog } from 'web3-core' +import { EventEmitter } from 'events' +import { + Callback, + PayableTransactionObject, + NonPayableTransactionObject, + BlockType, + ContractEventLog, + BaseContract, +} from './types' + +interface EventOptions { + filter?: object + fromBlock?: BlockType + topics?: string[] +} + +export interface Quoter extends BaseContract { + constructor(jsonInterface: any[], address?: string, options?: ContractOptions): Quoter + clone(): Quoter + methods: { + WETH9(): NonPayableTransactionObject + + factory(): NonPayableTransactionObject + + quoteExactInput(path: string | number[], amountIn: number | string | BN): NonPayableTransactionObject + + quoteExactInputSingle( + tokenIn: string, + tokenOut: string, + fee: number | string | BN, + amountIn: number | string | BN, + sqrtPriceLimitX96: number | string | BN, + ): NonPayableTransactionObject + + quoteExactOutput(path: string | number[], amountOut: number | string | BN): NonPayableTransactionObject + + quoteExactOutputSingle( + tokenIn: string, + tokenOut: string, + fee: number | string | BN, + amountOut: number | string | BN, + sqrtPriceLimitX96: number | string | BN, + ): NonPayableTransactionObject + + uniswapV3SwapCallback( + amount0Delta: number | string | BN, + amount1Delta: number | string | BN, + path: string | number[], + ): NonPayableTransactionObject + } + events: { + allEvents(options?: EventOptions, cb?: Callback): EventEmitter + } +} diff --git a/packages/web3-contracts/types/SwapRouter.d.ts b/packages/web3-contracts/types/SwapRouter.d.ts new file mode 100644 index 000000000000..84a37a65b5f2 --- /dev/null +++ b/packages/web3-contracts/types/SwapRouter.d.ts @@ -0,0 +1,138 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import BN from 'bn.js' +import { ContractOptions } from 'web3-eth-contract' +import { EventLog } from 'web3-core' +import { EventEmitter } from 'events' +import { + Callback, + PayableTransactionObject, + NonPayableTransactionObject, + BlockType, + ContractEventLog, + BaseContract, +} from './types' + +interface EventOptions { + filter?: object + fromBlock?: BlockType + topics?: string[] +} + +export interface SwapRouter extends BaseContract { + constructor(jsonInterface: any[], address?: string, options?: ContractOptions): SwapRouter + clone(): SwapRouter + methods: { + WETH9(): NonPayableTransactionObject + + exactInput( + params: [string | number[], string, number | string | BN, number | string | BN, number | string | BN], + ): PayableTransactionObject + + exactInputSingle( + params: [ + string, + string, + number | string | BN, + string, + number | string | BN, + number | string | BN, + number | string | BN, + number | string | BN, + ], + ): PayableTransactionObject + + exactOutput( + params: [string | number[], string, number | string | BN, number | string | BN, number | string | BN], + ): PayableTransactionObject + + exactOutputSingle( + params: [ + string, + string, + number | string | BN, + string, + number | string | BN, + number | string | BN, + number | string | BN, + number | string | BN, + ], + ): PayableTransactionObject + + factory(): NonPayableTransactionObject + + multicall(data: (string | number[])[]): PayableTransactionObject + + refundETH(): PayableTransactionObject + + selfPermit( + token: string, + value: number | string | BN, + deadline: number | string | BN, + v: number | string | BN, + r: string | number[], + s: string | number[], + ): PayableTransactionObject + + selfPermitAllowed( + token: string, + nonce: number | string | BN, + expiry: number | string | BN, + v: number | string | BN, + r: string | number[], + s: string | number[], + ): PayableTransactionObject + + selfPermitAllowedIfNecessary( + token: string, + nonce: number | string | BN, + expiry: number | string | BN, + v: number | string | BN, + r: string | number[], + s: string | number[], + ): PayableTransactionObject + + selfPermitIfNecessary( + token: string, + value: number | string | BN, + deadline: number | string | BN, + v: number | string | BN, + r: string | number[], + s: string | number[], + ): PayableTransactionObject + + sweepToken( + token: string, + amountMinimum: number | string | BN, + recipient: string, + ): PayableTransactionObject + + sweepTokenWithFee( + token: string, + amountMinimum: number | string | BN, + recipient: string, + feeBips: number | string | BN, + feeRecipient: string, + ): PayableTransactionObject + + uniswapV3SwapCallback( + amount0Delta: number | string | BN, + amount1Delta: number | string | BN, + _data: string | number[], + ): NonPayableTransactionObject + + unwrapWETH9(amountMinimum: number | string | BN, recipient: string): PayableTransactionObject + + unwrapWETH9WithFee( + amountMinimum: number | string | BN, + recipient: string, + feeBips: number | string | BN, + feeRecipient: string, + ): PayableTransactionObject + } + events: { + allEvents(options?: EventOptions, cb?: Callback): EventEmitter + } +} diff --git a/packages/web3-shared/src/hooks/index.ts b/packages/web3-shared/src/hooks/index.ts index 4c482e12865f..879af4e6adc7 100644 --- a/packages/web3-shared/src/hooks/index.ts +++ b/packages/web3-shared/src/hooks/index.ts @@ -5,6 +5,7 @@ export * from './useBlockNumber' export * from './useChainId' export * from './useChainDetailed' export * from './useContract' +export * from './useCurrentBlockTimestamp' export * from './useNonce' export * from './useGasPrice' export * from './useEtherPrice' diff --git a/packages/web3-shared/src/hooks/useCurrentBlockTimestamp.ts b/packages/web3-shared/src/hooks/useCurrentBlockTimestamp.ts new file mode 100644 index 000000000000..bd83124dc6cf --- /dev/null +++ b/packages/web3-shared/src/hooks/useCurrentBlockTimestamp.ts @@ -0,0 +1,7 @@ +import { useAsyncRetry } from 'react-use' +import { useMulticallContract } from '../contracts/useMulticallContract' + +export function useCurrentBlockTimestamp() { + const multicallContract = useMulticallContract() + return useAsyncRetry(async () => multicallContract?.methods.getCurrentBlockTimestamp().call(), [multicallContract]) +} diff --git a/packages/web3-shared/src/hooks/useMulticall.ts b/packages/web3-shared/src/hooks/useMulticall.ts index 30035e0a31ce..2bc14d5de045 100644 --- a/packages/web3-shared/src/hooks/useMulticall.ts +++ b/packages/web3-shared/src/hooks/useMulticall.ts @@ -94,7 +94,7 @@ export function useMutlicallStateDecoded< return { raw, error, value: null } } }) - }, [web3, contracts.map((x) => x.options.address).join(','), names.join(''), state]) + }, [web3, contracts.map((x) => x.options.address).join(), names.join(), state]) } //#endregion @@ -109,7 +109,7 @@ export function useSingleContractMultipleData x).join('')]) + }, [contract?.options.address, names.join(), callDatas.flatMap((x) => x).join()]) const [state, callback] = useMulticallCallback() const results = useMutlicallStateDecoded(Array.from({ length: calls.length }).fill(contract) as T[], names, state) return [results, calls, state, callback] as const @@ -126,7 +126,7 @@ export function useMutlipleContractSingleData x.options.address).join(''), names.join(''), callData.join('')], + [contracts.map((x) => x.options.address).join(), names.join(), callData.join()], ) const [state, callback] = useMulticallCallback() const results = useMutlicallStateDecoded(contracts, names, state) @@ -144,7 +144,7 @@ export function useMultipleContractMultipleData x.options.address).join(''), names.join(''), callDatas.flatMap((x) => x).join('')], + [contracts.map((x) => x.options.address).join(), names.join(), callDatas.flatMap((x) => x).join()], ) const [state, callback] = useMulticallCallback() const results = useMutlicallStateDecoded(contracts, names, state) diff --git a/packages/web3-shared/src/types/index.ts b/packages/web3-shared/src/types/index.ts index ae26a5ec1bc0..4ee4ec9f765a 100644 --- a/packages/web3-shared/src/types/index.ts +++ b/packages/web3-shared/src/types/index.ts @@ -203,6 +203,7 @@ export enum EthereumMethodType { ETH_GET_TRANSACTION_RECEIPT = 'eth_getTransactionReceipt', ETH_GET_TRANSACTION_COUNT = 'eth_getTransactionCount', ETH_ESTIMATE_GAS = 'eth_estimateGas', + ETH_CALL = 'eth_call', ETH_SIGN = 'eth_sign', ETH_SIGN_TRANSACTION = 'eth_signTransaction', ETH_GET_LOGS = 'eth_getLogs', diff --git a/patches/idb+5.0.8.patch b/patches/idb+5.0.8.patch index 98532f935ae8..2d2a4f0aae38 100644 --- a/patches/idb+5.0.8.patch +++ b/patches/idb+5.0.8.patch @@ -1,4 +1,4 @@ -# generated by patch-package 6.4.7 on 2021-05-27 12:59:06 +# generated by patch-package 6.4.7 on 2021-07-12 13:17:16 # # command: # npx patch-package idb @@ -7,7 +7,7 @@ # idb: 5.0.8 # diff --git a/node_modules/idb/build/cjs/entry.d.ts b/node_modules/idb/build/cjs/entry.d.ts -index 153848e..e41df5b 100644 +index 153848e..98a26e6 100644 --- a/node_modules/idb/build/cjs/entry.d.ts +++ b/node_modules/idb/build/cjs/entry.d.ts @@ -46,11 +46,10 @@ export interface DeleteDBCallbacks { @@ -21,13 +21,13 @@ index 153848e..e41df5b 100644 -} ? U : never; +declare type RemoveIndex = { + [P in keyof T as string extends P ? never : number extends P ? never : P]: T[P] -+} -+declare type KnownKeys = keyof RemoveIndex ++}; ++declare type KnownKeys = keyof RemoveIndex; declare type Omit = Pick>; export interface DBSchema { [s: string]: DBSchemaValue; diff --git a/node_modules/idb/build/esm/entry.d.ts b/node_modules/idb/build/esm/entry.d.ts -index 153848e..e41df5b 100644 +index 153848e..98a26e6 100644 --- a/node_modules/idb/build/esm/entry.d.ts +++ b/node_modules/idb/build/esm/entry.d.ts @@ -46,11 +46,10 @@ export interface DeleteDBCallbacks { @@ -41,8 +41,8 @@ index 153848e..e41df5b 100644 -} ? U : never; +declare type RemoveIndex = { + [P in keyof T as string extends P ? never : number extends P ? never : P]: T[P] -+} -+declare type KnownKeys = keyof RemoveIndex ++}; ++declare type KnownKeys = keyof RemoveIndex; declare type Omit = Pick>; export interface DBSchema { [s: string]: DBSchemaValue; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c7ddce0a3ac6..ad6ddf601642 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -268,8 +268,11 @@ importers: '@types/webpack-dev-server': ^3.11.5 '@typescript-eslint/eslint-plugin': ^4.28.4 '@typescript-eslint/parser': ^4.28.4 - '@uniswap/sdk-core': ^3.0.0 - '@uniswap/v2-sdk': ^3.0.0 + '@uniswap/sdk-core': ^3.0.1 + '@uniswap/v2-core': 1.0.0 + '@uniswap/v2-sdk': 3.0.0-alpha.2 + '@uniswap/v3-core': 1.0.0 + '@uniswap/v3-sdk': ^3.3.2 '@walletconnect/client': ^1.2.2 anchorme: ^2.1.2 arweave: ^1.10.13 @@ -307,7 +310,7 @@ importers: jest-junit: ^12.2.0 jest-puppeteer: ^5.0.4 jest-webextension-mock: ^3.7.17 - jsbi: ^3.1.5 + jsbi: 3.1.4 json-stable-stringify: ^1.0.1 json2csv: ^5.0.6 jsonwebtoken: ^8.5.1 @@ -416,8 +419,11 @@ importers: '@types/tiny-secp256k1': 1.0.0 '@types/use-subscription': 1.0.0 '@types/uuid': 8.3.1 - '@uniswap/sdk-core': 3.0.0 - '@uniswap/v2-sdk': 3.0.0 + '@uniswap/sdk-core': 3.0.1 + '@uniswap/v2-core': 1.0.0 + '@uniswap/v2-sdk': 3.0.0-alpha.2 + '@uniswap/v3-core': 1.0.0 + '@uniswap/v3-sdk': 3.3.2 '@walletconnect/client': 1.4.1 anchorme: 2.1.2 arweave: 1.10.16 @@ -439,7 +445,7 @@ importers: https-browserify: 1.0.0 immer: 9.0.5 isomorphic-dompurify: 0.13.0 - jsbi: 3.1.5 + jsbi: 3.1.4 json-stable-stringify: 1.0.1 json2csv: 5.0.6 jsonwebtoken: 8.5.1 @@ -454,14 +460,14 @@ importers: pvtsutils: 1.1.7 qrcode: 1.4.4 react-draggable: 4.4.3 - react-feather: 2.0.9_react@18.0.0-alpha-aecb3b6d1 - react-highlight-words: 0.17.0_react@18.0.0-alpha-aecb3b6d1 - react-middle-ellipsis: 1.2.1_f991c289939c8299bed5e4a6a5a79a62 - react-router: 5.2.0_react@18.0.0-alpha-aecb3b6d1 - react-router-dom: 5.2.0_react@18.0.0-alpha-aecb3b6d1 - react-use: 17.2.4_f991c289939c8299bed5e4a6a5a79a62 - react-virtualized-auto-sizer: 1.0.5_f991c289939c8299bed5e4a6a5a79a62 - react-window: 1.8.6_f991c289939c8299bed5e4a6a5a79a62 + react-feather: 2.0.9 + react-highlight-words: 0.17.0 + react-middle-ellipsis: 1.2.1 + react-router: 5.2.0 + react-router-dom: 5.2.0 + react-use: 17.2.4 + react-virtualized-auto-sizer: 1.0.5 + react-window: 1.8.6 remarkable: 2.0.1 scrypt-js: 3.0.1 socket.io-client: 2.4.0 @@ -471,7 +477,7 @@ importers: ts-results: 3.3.0 unstated-next: 1.1.0 urlcat: 2.0.4 - use-subscription: 1.5.1_react@18.0.0-alpha-aecb3b6d1 + use-subscription: 1.5.1 uuid: 8.3.2 wallet.ts: 1.0.1 web-ext-types: 3.2.1 @@ -486,11 +492,11 @@ importers: webextension-polyfill: 0.8.0 z-schema: 5.0.1 devDependencies: - '@dimensiondev/webextension-shim': 0.0.3-20210708053012-57a254d_typescript@4.3.5 + '@dimensiondev/webextension-shim': 0.0.3-20210708053012-57a254d '@pmmmwh/react-refresh-webpack-plugin': 0.5.0-rc.2_0cb17a392999b7da0b5f4263f37b1695 '@sinonjs/text-encoding': 0.7.1 '@swc/core': 1.2.66 - '@testing-library/react-hooks': 7.0.1_1959de3a9153879cff3acd96b46ed70f + '@testing-library/react-hooks': 7.0.1_react-test-renderer@17.0.2 '@types/enzyme': 3.10.9 '@types/enzyme-adapter-react-16': 1.0.6 '@types/expect-puppeteer': 4.4.6 @@ -501,19 +507,19 @@ importers: '@types/rimraf': 3.0.1 '@types/socket.io-client': 1.4.36 '@types/webpack-dev-server': 3.11.5 - '@typescript-eslint/eslint-plugin': 4.28.5_514553717ff968e20f6d1c6e521f8616 - '@typescript-eslint/parser': 4.28.5_eslint@7.31.0+typescript@4.3.5 + '@typescript-eslint/eslint-plugin': 4.28.5_@typescript-eslint+parser@4.28.5 + '@typescript-eslint/parser': 4.28.5 babel-loader: 8.2.2_webpack@5.46.0 chrome-launcher: 0.14.0 copy-webpack-plugin: 9.0.1_webpack@5.46.0 dotenv: 10.0.0 enzyme: 3.11.0 - enzyme-adapter-react-16: 1.15.6_f15f970d9b179e8975516dda0497bdea + enzyme-adapter-react-16: 1.15.6_enzyme@3.11.0 expect-puppeteer: 5.0.4 fake-indexeddb: 3.1.3 file-loader: 6.2.0_webpack@5.46.0 html-webpack-plugin: 5.3.2_webpack@5.46.0 - jest: 27.0.6_ts-node@10.1.0 + jest: 27.0.6 jest-environment-jsdom-fourteen: 1.0.1 jest-esm-transformer: 1.0.0 jest-junit: 12.2.0 @@ -522,12 +528,12 @@ importers: openzeppelin-solidity: 3.4.1 react-devtools-core: 4.14.0 react-refresh: 0.10.0 - react-test-renderer: 17.0.2_react@18.0.0-alpha-aecb3b6d1 + react-test-renderer: 17.0.2 rimraf: 3.0.2 source-map-loader: 3.0.0_webpack@5.46.0 swc-loader: 0.1.14_webpack@5.46.0 - ts-jest: 27.0.4_52cc4273aa16028085013af47e479e10 - type-coverage: 2.18.0_typescript@4.3.5 + ts-jest: 27.0.4_@types+jest@26.0.24+jest@27.0.6 + type-coverage: 2.18.0 webpack: 5.46.0_webpack-cli@4.7.2 webpack-cli: 4.7.2_d46d1c9a5e33a01c3500802a2e542ae0 webpack-dev-server: 3.11.2_webpack-cli@4.7.2+webpack@5.46.0 @@ -782,7 +788,7 @@ packages: bintrees: 1.0.2 bn.js: 4.12.0 compare-versions: 3.6.0 - ethereumjs-abi: 0.6.8 + ethereumjs-abi: 0.6.6 ethereumjs-blockstream: 2.0.7 ethereumjs-util: 5.2.1 find-versions: 2.0.0 @@ -3499,7 +3505,7 @@ packages: meow: 7.1.1 dev: false - /@dimensiondev/webextension-shim/0.0.3-20210708053012-57a254d_typescript@4.3.5: + /@dimensiondev/webextension-shim/0.0.3-20210708053012-57a254d: resolution: {integrity: sha512-0O0Nc3j2Vxo9Gfvgeq8pWuMHKMSU3tDjRnzE0U5oWvYoY+ZO61NniKp4xf/C+J6Py6lhQFutjd2tqlporqRwlw==, tarball: download/@dimensiondev/webextension-shim/0.0.3-20210708053012-57a254d/a2ee1bed40822a7f6b9c60ce4296930c9bab00828e82637aa56060498a135ac7} hasBin: true peerDependencies: @@ -3508,7 +3514,6 @@ packages: async-call-rpc: 4.2.1 buffer: 6.0.3 systemjs: 6.3.2 - typescript: 4.3.5 web-ext-types: 3.2.1 dev: true @@ -4264,7 +4269,7 @@ packages: slash: 3.0.0 dev: true - /@jest/core/27.0.6_ts-node@10.1.0: + /@jest/core/27.0.6: resolution: {integrity: sha512-SsYBm3yhqOn5ZLJCtccaBcvD/ccTLCeuDv8U41WJH/V1MW5eKUkeMHT9U+Pw/v1m1AIWlnIW/eM2XzQr0rEmow==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} peerDependencies: @@ -4285,7 +4290,7 @@ packages: exit: 0.1.2 graceful-fs: 4.2.6 jest-changed-files: 27.0.6 - jest-config: 27.0.6_ts-node@10.1.0 + jest-config: 27.0.6 jest-haste-map: 27.0.6 jest-message-util: 27.0.6 jest-regex-util: 27.0.6 @@ -5103,6 +5108,10 @@ packages: resolution: {integrity: sha512-cUriqMauq1ylzP2TxePNdPqkwI7Le3Annh4K9rrpvKfSBB/bdW+Iu1ihBaTIABTAAJ85LmKL5SSPPL9ry8d1gQ==} dev: false + /@openzeppelin/contracts/3.4.1-solc-0.7-2: + resolution: {integrity: sha512-tAG9LWg8+M2CMu7hIsqHPaTyG4uDzjr6mhvH96LvOpLZZj6tgzTluBt+LsCf1/QaYrlis6pITvpIaIhE+iZB+Q==} + dev: false + /@peculiar/asn1-schema/2.0.37: resolution: {integrity: sha512-f/dozij2XCZZ7ayOWI88TbHt/1rk3zJ91O/xTtDdc8SttyF6pleu4RYBuFohkobA5HJn+bEcY6Cvq4x9feXokQ==} dependencies: @@ -7010,7 +7019,7 @@ packages: defer-to-connect: 2.0.1 dev: true - /@testing-library/react-hooks/7.0.1_1959de3a9153879cff3acd96b46ed70f: + /@testing-library/react-hooks/7.0.1_react-test-renderer@17.0.2: resolution: {integrity: sha512-bpEQ2SHSBSzBmfJ437NmnP+oArQ7aVmmULiAp6Ag2rtyLBLPNFSMmgltUbFGmQOJdPWo4Ub31kpUC5T46zXNwQ==} engines: {node: '>=12'} peerDependencies: @@ -7027,10 +7036,8 @@ packages: '@types/react': 17.0.15 '@types/react-dom': 17.0.9 '@types/react-test-renderer': 17.0.1 - react: 18.0.0-alpha-aecb3b6d1 - react-dom: 18.0.0-alpha-aecb3b6d1_react@18.0.0-alpha-aecb3b6d1 - react-error-boundary: 3.1.3_react@18.0.0-alpha-aecb3b6d1 - react-test-renderer: 17.0.2_react@18.0.0-alpha-aecb3b6d1 + react-error-boundary: 3.1.3 + react-test-renderer: 17.0.2 dev: true /@tootallnate/once/1.1.2: @@ -7996,7 +8003,7 @@ packages: '@types/yargs-parser': 20.2.1 dev: true - /@typescript-eslint/eslint-plugin/4.28.5_514553717ff968e20f6d1c6e521f8616: + /@typescript-eslint/eslint-plugin/4.28.5_@typescript-eslint+parser@4.28.5: resolution: {integrity: sha512-m31cPEnbuCqXtEZQJOXAHsHvtoDi9OVaeL5wZnO2KZTnkvELk+u6J6jHg+NzvWQxk+87Zjbc4lJS4NHmgImz6Q==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -8007,21 +8014,19 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/experimental-utils': 4.28.5_eslint@7.31.0+typescript@4.3.5 - '@typescript-eslint/parser': 4.28.5_eslint@7.31.0+typescript@4.3.5 + '@typescript-eslint/experimental-utils': 4.28.5 + '@typescript-eslint/parser': 4.28.5 '@typescript-eslint/scope-manager': 4.28.5 debug: 4.3.2 - eslint: 7.31.0 functional-red-black-tree: 1.0.1 regexpp: 3.2.0 semver: 7.3.5 - tsutils: 3.21.0_typescript@4.3.5 - typescript: 4.3.5 + tsutils: 3.21.0 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/experimental-utils/4.28.5_eslint@7.31.0+typescript@4.3.5: + /@typescript-eslint/experimental-utils/4.28.5: resolution: {integrity: sha512-bGPLCOJAa+j49hsynTaAtQIWg6uZd8VLiPcyDe4QPULsvQwLHGLSGKKcBN8/lBxIX14F74UEMK2zNDI8r0okwA==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -8030,16 +8035,15 @@ packages: '@types/json-schema': 7.0.8 '@typescript-eslint/scope-manager': 4.28.5 '@typescript-eslint/types': 4.28.5 - '@typescript-eslint/typescript-estree': 4.28.5_typescript@4.3.5 - eslint: 7.31.0 + '@typescript-eslint/typescript-estree': 4.28.5 eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@7.31.0 + eslint-utils: 3.0.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/parser/4.28.5_eslint@7.31.0+typescript@4.3.5: + /@typescript-eslint/parser/4.28.5: resolution: {integrity: sha512-NPCOGhTnkXGMqTznqgVbA5LqVsnw+i3+XA1UKLnAb+MG1Y1rP4ZSK9GX0kJBmAZTMIktf+dTwXToT6kFwyimbw==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -8051,10 +8055,8 @@ packages: dependencies: '@typescript-eslint/scope-manager': 4.28.5 '@typescript-eslint/types': 4.28.5 - '@typescript-eslint/typescript-estree': 4.28.5_typescript@4.3.5 + '@typescript-eslint/typescript-estree': 4.28.5 debug: 4.3.2 - eslint: 7.31.0 - typescript: 4.3.5 transitivePeerDependencies: - supports-color dev: true @@ -8072,7 +8074,7 @@ packages: engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} dev: true - /@typescript-eslint/typescript-estree/4.28.5_typescript@4.3.5: + /@typescript-eslint/typescript-estree/4.28.5: resolution: {integrity: sha512-FzJUKsBX8poCCdve7iV7ShirP8V+ys2t1fvamVeD1rWpiAnIm550a+BX/fmTHrjEpQJ7ZAn+Z7ZZwJjytk9rZw==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -8087,8 +8089,7 @@ packages: globby: 11.0.4 is-glob: 4.0.1 semver: 7.3.5 - tsutils: 3.21.0_typescript@4.3.5 - typescript: 4.3.5 + tsutils: 3.21.0 transitivePeerDependencies: - supports-color dev: true @@ -8101,25 +8102,68 @@ packages: eslint-visitor-keys: 2.1.0 dev: true - /@uniswap/sdk-core/3.0.0: - resolution: {integrity: sha512-Yarx/5lqPZvAAzI7i+twK/IueJNl+OhqbeiiTuD4+g+NEVPCU+SMBvLFzf0/jAlM1WKz6K1psQLUDwdgAj8I3w==} + /@uniswap/lib/4.0.1-alpha: + resolution: {integrity: sha512-f6UIliwBbRsgVLxIaBANF6w09tYqc6Y/qXdsrbEmXHyFA7ILiKrIwRFXe1yOg8M3cksgVsO9N7yuL2DdCGQKBA==} + engines: {node: '>=10'} + dev: false + + /@uniswap/sdk-core/3.0.1: + resolution: {integrity: sha512-WbeDkhZ9myVR0VnHOdTrb8nHKKkqTFa5uE9RvUbG3eyDt2NWWDwhhqGHwAWJEHG405l30Fa1u3PogHDFsIOQlA==} engines: {node: '>=10'} dependencies: '@ethersproject/address': 5.4.0 big.js: 5.2.2 decimal.js-light: 2.5.1 - jsbi: 3.1.5 + jsbi: 3.1.4 tiny-invariant: 1.1.0 toformat: 2.0.0 dev: false - /@uniswap/v2-sdk/3.0.0: - resolution: {integrity: sha512-UyAZHCQaV/4XCsgR+o+daP0E6rLUOY0H2G10P1cxGI1c3uxZe3/mXIHq+kUkeW8kxHC0622TckFYWnkiWkjULg==} + /@uniswap/v2-core/1.0.0: + resolution: {integrity: sha512-BJiXrBGnN8mti7saW49MXwxDBRFiWemGetE58q8zgfnPPzQKq55ADltEILqOt6VFZ22kVeVKbF8gVd8aY3l7pA==} + engines: {node: '>=10'} + dev: false + + /@uniswap/v2-core/1.0.1: + resolution: {integrity: sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q==} + engines: {node: '>=10'} + dev: false + + /@uniswap/v2-sdk/3.0.0-alpha.2: + resolution: {integrity: sha512-LkGGZMdJueIIC3OBzgiBMV/1GdZgzTTf2qGEgBAxJUuCSFf5wZQgWNU4KOkoaBrl/FlEctAGSgGh3j3BhWKL5Q==} engines: {node: '>=10'} dependencies: '@ethersproject/address': 5.4.0 '@ethersproject/solidity': 5.4.0 - '@uniswap/sdk-core': 3.0.0 + '@uniswap/sdk-core': 3.0.1 + tiny-invariant: 1.1.0 + tiny-warning: 1.0.3 + dev: false + + /@uniswap/v3-core/1.0.0: + resolution: {integrity: sha512-kSC4djMGKMHj7sLMYVnn61k9nu+lHjMIxgg9CDQT+s2QYLoA56GbSK9Oxr+qJXzzygbkrmuY6cwgP6cW2JXPFA==} + engines: {node: '>=10'} + dev: false + + /@uniswap/v3-periphery/1.0.0: + resolution: {integrity: sha512-kRqUrjnyh+X1wJdSENPDFr9sjRVebv2KyLtfqDOPij0dXJ69GspFU2qrZXjouc6LYdkWG7x3fagiTlw0eGniYQ==} + engines: {node: '>=10'} + dependencies: + '@openzeppelin/contracts': 3.4.1-solc-0.7-2 + '@uniswap/lib': 4.0.1-alpha + '@uniswap/v2-core': 1.0.1 + '@uniswap/v3-core': 1.0.0 + base64-sol: 1.0.1 + dev: false + + /@uniswap/v3-sdk/3.3.2: + resolution: {integrity: sha512-oADWpKPkmtgnrBr8xUmLURZnH1wO2HFPoQw/K2gI2ZLjyR1xkAbZT6X+hjLaXCdOI+PN5WMZo3/OiPUJC2X1bA==} + engines: {node: '>=10'} + dependencies: + '@ethersproject/abi': 5.4.0 + '@ethersproject/solidity': 5.4.0 + '@uniswap/sdk-core': 3.0.1 + '@uniswap/v3-periphery': 1.0.0 tiny-invariant: 1.1.0 tiny-warning: 1.0.3 dev: false @@ -8642,7 +8686,7 @@ packages: symbol.prototype.description: 1.0.4 dev: true - /airbnb-prop-types/2.16.0_react@18.0.0-alpha-aecb3b6d1: + /airbnb-prop-types/2.16.0: resolution: {integrity: sha512-7WHOFolP/6cS96PhKNrslCLMYAI8yB1Pp6u6XmxozQOiZbsI5ycglZr5cHhBFfuRcQQjzCMith5ZPZdYiJCxUg==} peerDependencies: react: ^0.14 || ^15.0.0 || ^16.0.0-alpha @@ -8655,7 +8699,6 @@ packages: object.entries: 1.1.4 prop-types: 15.7.2 prop-types-exact: 1.2.0 - react: 18.0.0-alpha-aecb3b6d1 react-is: 16.13.1 dev: true @@ -10053,6 +10096,10 @@ packages: /base64-js/1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + /base64-sol/1.0.1: + resolution: {integrity: sha512-ld3cCNMeXt4uJXmLZBHFGMvVpK9KsLVEhPpFRXnvSVAqABKbuNZg/+dsq3NuM+wxFLb/UrVkz7m1ciWmkMfTbg==} + dev: false + /batch-processor/1.0.0: resolution: {integrity: sha1-dclcMrdI4IUNEMKxaPa9vpiRrOg=} dev: true @@ -10299,8 +10346,8 @@ packages: resolution: {integrity: sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==} hasBin: true dependencies: - caniuse-lite: 1.0.30001248 - electron-to-chromium: 1.3.792 + caniuse-lite: 1.0.30001251 + electron-to-chromium: 1.3.805 dev: false /browserslist/4.14.2: @@ -10629,6 +10676,11 @@ packages: /caniuse-lite/1.0.30001248: resolution: {integrity: sha512-NwlQbJkxUFJ8nMErnGtT0QTM2TJ33xgz4KXJSMIrjXIbDVdaYueGyjOrLKRtJC+rTiWfi6j5cnZN1NBiSBJGNw==} + dev: true + + /caniuse-lite/1.0.30001251: + resolution: {integrity: sha512-HOe1r+9VkU4TFmnU70z+r7OLmtR+/chB1rdcJUeQlAinjEeb0cKL20tlAtOagNZhbrtLnCvV19B4FmF1rgzl6A==} + dev: false /capture-exit/2.0.0: resolution: {integrity: sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==} @@ -12418,6 +12470,11 @@ packages: /electron-to-chromium/1.3.792: resolution: {integrity: sha512-RM2O2xrNarM7Cs+XF/OE2qX/aBROyOZqqgP+8FXMXSuWuUqCfUUzg7NytQrzZU3aSqk1Qq6zqnVkJsbfMkIatg==} + dev: true + + /electron-to-chromium/1.3.805: + resolution: {integrity: sha512-uUJF59M6pNSRHQaXwdkaNB4BhSQ9lldRdG1qCjlrAFkynPGDc5wPoUcYEQQeQGmKyAWJPvGkYAWmtVrxWmDAkg==} + dev: false /element-resize-detector/1.2.3: resolution: {integrity: sha512-+dhNzUgLpq9ol5tyhoG7YLoXL3ssjfFW+0gpszXPwRU6NjGr1fVHMEAF8fVzIiRJq57Nre0RFeIjJwI8Nh2NmQ==} @@ -12565,7 +12622,7 @@ packages: resolution: {integrity: sha512-2qbxE7ek3YxPJ1ML6V+satHkzHpJQKWkRHmRx6mfAoW59yP8YH8BFplbegSP+u2hBd6B6KCOpvJQ3dZAP+hkpg==} engines: {node: '>=4.3.0 <5.0.0 || >=5.10'} dependencies: - graceful-fs: 4.2.6 + graceful-fs: 4.2.8 memory-fs: 0.4.1 object-assign: 4.1.1 tapable: 0.2.9 @@ -12619,7 +12676,7 @@ packages: hasBin: true dev: true - /enzyme-adapter-react-16/1.15.6_f15f970d9b179e8975516dda0497bdea: + /enzyme-adapter-react-16/1.15.6_enzyme@3.11.0: resolution: {integrity: sha512-yFlVJCXh8T+mcQo8M6my9sPgeGzj85HSHi6Apgf1Cvq/7EL/J9+1JoJmJsRxZgyTvPMAqOEpRSu/Ii/ZpyOk0g==} peerDependencies: enzyme: ^3.0.0 @@ -12627,31 +12684,28 @@ packages: react-dom: ^16.0.0-0 dependencies: enzyme: 3.11.0 - enzyme-adapter-utils: 1.14.0_react@18.0.0-alpha-aecb3b6d1 + enzyme-adapter-utils: 1.14.0 enzyme-shallow-equal: 1.0.4 has: 1.0.3 object.assign: 4.1.2 object.values: 1.1.4 prop-types: 15.7.2 - react: 18.0.0-alpha-aecb3b6d1 - react-dom: 18.0.0-alpha-aecb3b6d1_react@18.0.0-alpha-aecb3b6d1 react-is: 16.13.1 - react-test-renderer: 16.14.0_react@18.0.0-alpha-aecb3b6d1 + react-test-renderer: 16.14.0 semver: 5.7.1 dev: true - /enzyme-adapter-utils/1.14.0_react@18.0.0-alpha-aecb3b6d1: + /enzyme-adapter-utils/1.14.0: resolution: {integrity: sha512-F/z/7SeLt+reKFcb7597IThpDp0bmzcH1E9Oabqv+o01cID2/YInlqHbFl7HzWBl4h3OdZYedtwNDOmSKkk0bg==} peerDependencies: react: 0.13.x || 0.14.x || ^15.0.0-0 || ^16.0.0-0 dependencies: - airbnb-prop-types: 2.16.0_react@18.0.0-alpha-aecb3b6d1 + airbnb-prop-types: 2.16.0 function.prototype.name: 1.1.4 has: 1.0.3 object.assign: 4.1.2 object.fromentries: 2.0.4 prop-types: 15.7.2 - react: 18.0.0-alpha-aecb3b6d1 semver: 5.7.1 dev: true @@ -13123,6 +13177,15 @@ packages: eslint-visitor-keys: 1.3.0 dev: true + /eslint-utils/3.0.0: + resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} + engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} + peerDependencies: + eslint: '>=5' + dependencies: + eslint-visitor-keys: 2.1.0 + dev: true + /eslint-utils/3.0.0_eslint@7.31.0: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} @@ -13359,11 +13422,11 @@ packages: setimmediate: 1.0.5 dev: false - /ethereumjs-abi/0.6.8: - resolution: {integrity: sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==} + /ethereumjs-abi/0.6.6: + resolution: {integrity: sha512-w8KubDsA/+OAuqtIR9RGsMcoZ5nhM8vxwjJAJvEIY+clhxA3BHoLG3+ClYQaQhD0n3mlDt3U5rBrmSVJvI3c8A==} dependencies: bn.js: 4.12.0 - ethereumjs-util: 6.2.1 + ethereumjs-util: 5.2.1 dev: false /ethereumjs-account/2.0.5: @@ -14248,7 +14311,7 @@ packages: /fs-extra/0.30.0: resolution: {integrity: sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=} dependencies: - graceful-fs: 4.2.6 + graceful-fs: 4.2.8 jsonfile: 2.4.0 klaw: 1.3.1 path-is-absolute: 1.0.1 @@ -14762,6 +14825,9 @@ packages: /graceful-fs/4.2.6: resolution: {integrity: sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==} + /graceful-fs/4.2.8: + resolution: {integrity: sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==} + /growly/1.3.0: resolution: {integrity: sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=} dev: true @@ -14942,6 +15008,13 @@ packages: has-symbol-support-x: 1.4.2 dev: false + /has-tostringtag/1.0.0: + resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.2 + dev: false + /has-unicode/2.0.1: resolution: {integrity: sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=} dev: true @@ -16009,6 +16082,14 @@ packages: call-bind: 1.0.2 has-symbols: 1.0.2 + /is-regex/1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: false + /is-regexp/1.0.0: resolution: {integrity: sha1-/S2INUXEa6xaYz57mgnof6LLUGk=} engines: {node: '>=0.10.0'} @@ -16323,7 +16404,7 @@ packages: - supports-color dev: true - /jest-cli/27.0.6_ts-node@10.1.0: + /jest-cli/27.0.6: resolution: {integrity: sha512-qUUVlGb9fdKir3RDE+B10ULI+LQrz+MCflEH2UJyoUjoHHCbxDrMxSzjQAPUMsic4SncI62ofYCcAvW6+6rhhg==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} hasBin: true @@ -16333,14 +16414,14 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 27.0.6_ts-node@10.1.0 + '@jest/core': 27.0.6 '@jest/test-result': 27.0.6 '@jest/types': 27.0.6 chalk: 4.1.1 exit: 0.1.2 graceful-fs: 4.2.6 import-local: 3.0.2 - jest-config: 27.0.6_ts-node@10.1.0 + jest-config: 27.0.6 jest-util: 27.0.6 jest-validate: 27.0.6 prompts: 2.4.1 @@ -16353,7 +16434,7 @@ packages: - utf-8-validate dev: true - /jest-config/27.0.6_ts-node@10.1.0: + /jest-config/27.0.6: resolution: {integrity: sha512-JZRR3I1Plr2YxPBhgqRspDE2S5zprbga3swYNrvY3HfQGu7p/GjyLOqwrYad97tX3U3mzT53TPHVmozacfP/3w==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} peerDependencies: @@ -16383,7 +16464,6 @@ packages: jest-validate: 27.0.6 micromatch: 4.0.4 pretty-format: 27.0.6 - ts-node: 10.1.0_typescript@4.3.5 transitivePeerDependencies: - bufferutil - canvas @@ -16994,7 +17074,7 @@ packages: supports-color: 8.1.1 dev: true - /jest/27.0.6_ts-node@10.1.0: + /jest/27.0.6: resolution: {integrity: sha512-EjV8aETrsD0wHl7CKMibKwQNQc3gIRBXlTikBmmHUeVMKaPFxdcUIBfoDqTSXDoGJIivAYGqCWVlzCSaVjPQsA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} hasBin: true @@ -17004,9 +17084,9 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 27.0.6_ts-node@10.1.0 + '@jest/core': 27.0.6 import-local: 3.0.2 - jest-cli: 27.0.6_ts-node@10.1.0 + jest-cli: 27.0.6 transitivePeerDependencies: - bufferutil - canvas @@ -17066,8 +17146,8 @@ packages: argparse: 1.0.10 esprima: 4.0.1 - /jsbi/3.1.5: - resolution: {integrity: sha512-w2BY0VOYC1ahe+w6Qhl4SFoPvPsZ9NPHY4bwass+LCgU7RK3PBoVQlQ3G1s7vI8W3CYyJiEXcbKF7FIM/L8q3Q==} + /jsbi/3.1.4: + resolution: {integrity: sha512-52QRRFSsi9impURE8ZUbzAMCLjPm4THO7H2fcuIvaaeFTbSysvkodbQQXIVsNgq/ypDbq6dJiuGKL0vZ/i9hUg==} dev: false /jsbn/0.1.1: @@ -17282,7 +17362,7 @@ packages: /jsonfile/2.4.0: resolution: {integrity: sha1-NzaitCi4e72gzIO1P6PWM6NcKug=} optionalDependencies: - graceful-fs: 4.2.6 + graceful-fs: 4.2.8 /jsonfile/4.0.0: resolution: {integrity: sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=} @@ -17525,7 +17605,7 @@ packages: /klaw/1.3.1: resolution: {integrity: sha1-QIhDO0azsbolnXh4XY6W9zugJDk=} optionalDependencies: - graceful-fs: 4.2.6 + graceful-fs: 4.2.8 /kleur/3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} @@ -17715,7 +17795,7 @@ packages: resolution: {integrity: sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=} engines: {node: '>=0.10.0'} dependencies: - graceful-fs: 4.2.6 + graceful-fs: 4.2.8 parse-json: 2.2.0 pify: 2.3.0 pinkie-promise: 2.0.1 @@ -18368,7 +18448,7 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} - /mini-create-react-context/0.4.1_d2630f1b5c5d613d08a8af07021f9fe5: + /mini-create-react-context/0.4.1_prop-types@15.7.2: resolution: {integrity: sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==} peerDependencies: prop-types: ^15.0.0 @@ -18376,7 +18456,6 @@ packages: dependencies: '@babel/runtime': 7.14.8 prop-types: 15.7.2 - react: 18.0.0-alpha-aecb3b6d1 tiny-warning: 1.0.3 dev: false @@ -18633,6 +18712,22 @@ packages: /nan/2.14.2: resolution: {integrity: sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==} + /nano-css/5.3.1: + resolution: {integrity: sha512-ENPIyNzANQRyYVvb62ajDd7PAyIgS2LIUnT9ewih4yrXSZX4hKoUwssy8WjUH++kEOA5wUTMgNnV7ko5n34kUA==} + peerDependencies: + react: '*' + react-dom: '*' + dependencies: + css-tree: 1.1.3 + csstype: 3.0.8 + fastest-stable-stringify: 2.0.2 + inline-style-prefixer: 6.0.0 + rtl-css-js: 1.14.1 + sourcemap-codec: 1.4.8 + stacktrace-js: 2.0.2 + stylis: 4.0.10 + dev: false + /nano-css/5.3.1_f991c289939c8299bed5e4a6a5a79a62: resolution: {integrity: sha512-ENPIyNzANQRyYVvb62ajDd7PAyIgS2LIUnT9ewih4yrXSZX4hKoUwssy8WjUH++kEOA5wUTMgNnV7ko5n34kUA==} peerDependencies: @@ -19663,7 +19758,7 @@ packages: resolution: {integrity: sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=} engines: {node: '>=0.10.0'} dependencies: - graceful-fs: 4.2.6 + graceful-fs: 4.2.8 pify: 2.3.0 pinkie-promise: 2.0.1 @@ -20539,14 +20634,13 @@ packages: react-dom: 18.0.0-alpha-aecb3b6d1_react@18.0.0-alpha-aecb3b6d1 dev: true - /react-error-boundary/3.1.3_react@18.0.0-alpha-aecb3b6d1: + /react-error-boundary/3.1.3: resolution: {integrity: sha512-A+F9HHy9fvt9t8SNDlonq01prnU8AmkjvGKV4kk8seB9kU3xMEO8J/PQlLVmoOIDODl5U2kufSBs4vrWIqhsAA==} engines: {node: '>=10', npm: '>=6'} peerDependencies: react: '>=16.13.1' dependencies: '@babel/runtime': 7.14.8 - react: 18.0.0-alpha-aecb3b6d1 dev: true /react-error-overlay/6.0.9: @@ -20557,13 +20651,12 @@ packages: resolution: {integrity: sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==} dev: true - /react-feather/2.0.9_react@18.0.0-alpha-aecb3b6d1: + /react-feather/2.0.9: resolution: {integrity: sha512-yMfCGRkZdXwIs23Zw/zIWCJO3m3tlaUvtHiXlW+3FH7cIT6fiK1iJ7RJWugXq7Fso8ZaQyUm92/GOOHXvkiVUw==} peerDependencies: react: ^16.8.6 || ^17 dependencies: prop-types: 15.7.2 - react: 18.0.0-alpha-aecb3b6d1 dev: false /react-helmet-async/1.0.9_f991c289939c8299bed5e4a6a5a79a62: @@ -20581,7 +20674,7 @@ packages: shallowequal: 1.1.0 dev: true - /react-highlight-words/0.17.0_react@18.0.0-alpha-aecb3b6d1: + /react-highlight-words/0.17.0: resolution: {integrity: sha512-uX1Qh5IGjnLuJT0Zok234QDwRC8h4hcVMnB99Cb7aquB1NlPPDiWKm0XpSZOTdSactvnClCk8LOmVlP+75dgHA==} peerDependencies: react: ^0.14.0 || ^15.0.0 || ^16.0.0-0 || ^17.0.0-0 @@ -20589,7 +20682,6 @@ packages: highlight-words-core: 1.2.2 memoize-one: 4.0.3 prop-types: 15.7.2 - react: 18.0.0-alpha-aecb3b6d1 dev: false /react-hook-form/7.12.0_react@18.0.0-alpha-aecb3b6d1: @@ -20633,15 +20725,12 @@ packages: resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} dev: true - /react-middle-ellipsis/1.2.1_f991c289939c8299bed5e4a6a5a79a62: + /react-middle-ellipsis/1.2.1: resolution: {integrity: sha512-BUQWVXIWwkY7qBqZx0qyeCnPIh188t0lLS0ftfBsU41HB6k769HyBwE23eP+qNXr4vEnmKTEmlicrypVdWYs0w==} engines: {node: '>=8', npm: '>=5'} peerDependencies: react: ^17.0.0 react-dom: ^17.0.0 - dependencies: - react: 18.0.0-alpha-aecb3b6d1 - react-dom: 18.0.0-alpha-aecb3b6d1_react@18.0.0-alpha-aecb3b6d1 dev: false /react-popper-tooltip/3.1.1_f991c289939c8299bed5e4a6a5a79a62: @@ -20688,7 +20777,7 @@ packages: engines: {node: '>=0.10.0'} dev: true - /react-router-dom/5.2.0_react@18.0.0-alpha-aecb3b6d1: + /react-router-dom/5.2.0: resolution: {integrity: sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==} peerDependencies: react: '>=15' @@ -20697,8 +20786,7 @@ packages: history: 4.10.1 loose-envify: 1.4.0 prop-types: 15.7.2 - react: 18.0.0-alpha-aecb3b6d1 - react-router: 5.2.0_react@18.0.0-alpha-aecb3b6d1 + react-router: 5.2.0 tiny-invariant: 1.1.0 tiny-warning: 1.0.3 dev: false @@ -20717,7 +20805,7 @@ packages: react-router: 6.0.0-beta.0_dd3df4049b9a65e1e2d003c7940c4871 dev: false - /react-router/5.2.0_react@18.0.0-alpha-aecb3b6d1: + /react-router/5.2.0: resolution: {integrity: sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==} peerDependencies: react: '>=15' @@ -20726,10 +20814,9 @@ packages: history: 4.10.1 hoist-non-react-statics: 3.3.2 loose-envify: 1.4.0 - mini-create-react-context: 0.4.1_d2630f1b5c5d613d08a8af07021f9fe5 + mini-create-react-context: 0.4.1_prop-types@15.7.2 path-to-regexp: 1.8.0 prop-types: 15.7.2 - react: 18.0.0-alpha-aecb3b6d1 react-is: 16.13.1 tiny-invariant: 1.1.0 tiny-warning: 1.0.3 @@ -20746,13 +20833,12 @@ packages: react: 18.0.0-alpha-aecb3b6d1 dev: false - /react-shallow-renderer/16.14.1_react@18.0.0-alpha-aecb3b6d1: + /react-shallow-renderer/16.14.1: resolution: {integrity: sha512-rkIMcQi01/+kxiTE9D3fdS959U1g7gs+/rborw++42m1O9FAQiNI/UNRZExVUoAOprn4umcXf+pFRou8i4zuBg==} peerDependencies: react: ^16.0.0 || ^17.0.0 dependencies: object-assign: 4.1.1 - react: 18.0.0-alpha-aecb3b6d1 react-is: 17.0.2 dev: true @@ -20783,27 +20869,25 @@ packages: refractor: 3.4.0 dev: true - /react-test-renderer/16.14.0_react@18.0.0-alpha-aecb3b6d1: + /react-test-renderer/16.14.0: resolution: {integrity: sha512-L8yPjqPE5CZO6rKsKXRO/rVPiaCOy0tQQJbC+UjPNlobl5mad59lvPjwFsQHTvL03caVDIVr9x9/OSgDe6I5Eg==} peerDependencies: react: ^16.14.0 dependencies: object-assign: 4.1.1 prop-types: 15.7.2 - react: 18.0.0-alpha-aecb3b6d1 react-is: 16.13.1 scheduler: 0.19.1 dev: true - /react-test-renderer/17.0.2_react@18.0.0-alpha-aecb3b6d1: + /react-test-renderer/17.0.2: resolution: {integrity: sha512-yaQ9cB89c17PUb0x6UfWRs7kQCorVdHlutU1boVPEsB8IDZH6n9tHxMacc3y0JoXOJUsZb/t/Mb8FUWMKaM7iQ==} peerDependencies: react: 17.0.2 dependencies: object-assign: 4.1.1 - react: 18.0.0-alpha-aecb3b6d1 react-is: 17.0.2 - react-shallow-renderer: 16.14.1_react@18.0.0-alpha-aecb3b6d1 + react-shallow-renderer: 16.14.1 scheduler: 0.20.2 dev: true @@ -20845,6 +20929,37 @@ packages: tslib: 2.3.0 dev: false + /react-universal-interface/0.6.2_tslib@2.3.0: + resolution: {integrity: sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==} + peerDependencies: + react: '*' + tslib: '*' + dependencies: + tslib: 2.3.0 + dev: false + + /react-use/17.2.4: + resolution: {integrity: sha512-vQGpsAM0F5UIlshw5UI8ULGPS4yn5rm7/qvn3T1Gnkrz7YRMEEMh+ynKcmRloOyiIeLvKWiQjMiwRGtdbgs5qQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 + react-dom: ^16.8.0 || ^17.0.0 + dependencies: + '@types/js-cookie': 2.2.7 + '@xobotyi/scrollbar-width': 1.9.5 + copy-to-clipboard: 3.3.1 + fast-deep-equal: 3.1.3 + fast-shallow-equal: 1.0.0 + js-cookie: 2.2.1 + nano-css: 5.3.1 + react-universal-interface: 0.6.2_tslib@2.3.0 + resize-observer-polyfill: 1.5.1 + screenfull: 5.1.0 + set-harmonic-interval: 1.0.1 + throttle-debounce: 3.0.1 + ts-easing: 0.2.0 + tslib: 2.3.0 + dev: false + /react-use/17.2.4_f991c289939c8299bed5e4a6a5a79a62: resolution: {integrity: sha512-vQGpsAM0F5UIlshw5UI8ULGPS4yn5rm7/qvn3T1Gnkrz7YRMEEMh+ynKcmRloOyiIeLvKWiQjMiwRGtdbgs5qQ==} peerDependencies: @@ -20869,15 +20984,23 @@ packages: tslib: 2.3.0 dev: false - /react-virtualized-auto-sizer/1.0.5_f991c289939c8299bed5e4a6a5a79a62: + /react-virtualized-auto-sizer/1.0.5: resolution: {integrity: sha512-kivjYVWX15TX2IUrm8F1jaCEX8EXrpy3DD+u41WGqJ1ZqbljWpiwscV+VxOM1l7sSIM1jwi2LADjhhAJkJ9dxA==} engines: {node: '>8.0.0'} peerDependencies: react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 + dev: false + + /react-window/1.8.6: + resolution: {integrity: sha512-8VwEEYyjz6DCnGBsd+MgkD0KJ2/OXFULyDtorIiTz+QzwoP94tBoA7CnbtyXMm+cCeAUER5KJcPtWl9cpKbOBg==} + engines: {node: '>8.0.0'} + peerDependencies: + react: ^15.0.0 || ^16.0.0 || ^17.0.0 + react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 dependencies: - react: 18.0.0-alpha-aecb3b6d1 - react-dom: 18.0.0-alpha-aecb3b6d1_react@18.0.0-alpha-aecb3b6d1 + '@babel/runtime': 7.14.8 + memoize-one: 5.2.1 dev: false /react-window/1.8.6_f991c289939c8299bed5e4a6a5a79a62: @@ -22978,7 +23101,7 @@ packages: glob: 7.1.7 has: 1.0.3 inherits: 2.0.4 - is-regex: 1.1.3 + is-regex: 1.1.4 minimist: 1.2.5 object-inspect: 1.11.0 resolve: 1.20.0 @@ -23442,7 +23565,7 @@ packages: typescript: 4.3.5 dev: false - /ts-jest/27.0.4_52cc4273aa16028085013af47e479e10: + /ts-jest/27.0.4_@types+jest@26.0.24+jest@27.0.6: resolution: {integrity: sha512-c4E1ECy9Xz2WGfTMyHbSaArlIva7Wi2p43QOMmCqjSSjHP06KXv+aT+eSY+yZMuqsMi3k7pyGsGj2q5oSl5WfQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} hasBin: true @@ -23464,14 +23587,13 @@ packages: bs-logger: 0.2.6 buffer-from: 1.1.1 fast-json-stable-stringify: 2.1.0 - jest: 27.0.6_ts-node@10.1.0 + jest: 27.0.6 jest-util: 27.0.6 json5: 2.2.0 lodash: 4.17.21 make-error: 1.3.6 mkdirp: 1.0.4 semver: 7.3.5 - typescript: 4.3.5 yargs-parser: 20.2.9 dev: true @@ -23617,14 +23739,13 @@ packages: typescript: 2.9.2 dev: false - /tsutils/3.21.0_typescript@4.3.5: + /tsutils/3.21.0: resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' dependencies: tslib: 1.14.1 - typescript: 4.3.5 dev: true /tty-browserify/0.0.0: @@ -23663,7 +23784,7 @@ packages: prelude-ls: 1.2.1 dev: true - /type-coverage-core/2.17.5_typescript@4.3.5: + /type-coverage-core/2.17.5: resolution: {integrity: sha512-FfkH2kIgQkkgC47V2WHJZWBbjYjMw2ZpQRdRGTcMBAnkijmRCp9I1LpOuI+Gv4MDtniRLnkAo8htGGt2iExFgA==} peerDependencies: typescript: 2 || 3 || 4 @@ -23672,16 +23793,15 @@ packages: minimatch: 3.0.4 normalize-path: 3.0.0 tslib: 2.3.0 - tsutils: 3.21.0_typescript@4.3.5 - typescript: 4.3.5 + tsutils: 3.21.0 dev: true - /type-coverage/2.18.0_typescript@4.3.5: + /type-coverage/2.18.0: resolution: {integrity: sha512-SAyrR6Xl7GfHNcXU8Y3wSnJfGftdCvf/b2JlJJtt7gt74T0dCF077/ukhlLjI/MsWmRCxW8k8x/d4AjrFiLSpQ==} hasBin: true dependencies: minimist: 1.2.5 - type-coverage-core: 2.17.5_typescript@4.3.5 + type-coverage-core: 2.17.5 transitivePeerDependencies: - typescript dev: true @@ -24172,6 +24292,14 @@ packages: use-isomorphic-layout-effect: 1.1.1_010541d7fdfc8cbcdd915345c89295c8 dev: true + /use-subscription/1.5.1: + resolution: {integrity: sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 + dependencies: + object-assign: 4.1.1 + dev: false + /use-subscription/1.5.1_react@18.0.0-alpha-aecb3b6d1: resolution: {integrity: sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==} peerDependencies: