From afe222f09229acdfe5f1c3294d021aa9daaa2240 Mon Sep 17 00:00:00 2001 From: kevin <35275952+kaladinlight@users.noreply.github.com> Date: Sun, 7 Jan 2024 17:18:17 -0700 Subject: [PATCH 1/6] feat: update 0x and zerion to use proxy api (#5950) Co-authored-by: Apotheosis <97164662+0xApotheosis@users.noreply.github.com> --- .env.base | 6 ------ react-app-rewired/headers/csps/defi/swappers/0x.ts | 14 +------------- react-app-rewired/headers/csps/zerion.ts | 2 +- src/config.ts | 2 -- .../getZrxTradeQuote/getZrxTradeQuote.test.ts | 7 ++----- .../swappers/ZrxSwapper/utils/helpers/helpers.ts | 12 ++++++------ .../swappers/ZrxSwapper/utils/zrxService.ts | 6 ------ src/state/apis/zerion/zerionApi.ts | 9 ++------- 8 files changed, 12 insertions(+), 46 deletions(-) diff --git a/.env.base b/.env.base index e2e16eeda29..3ba50e42523 100644 --- a/.env.base +++ b/.env.base @@ -144,9 +144,6 @@ REACT_APP_WHEREVER_PARTNER_KEY=00da1f18-3bba-4b71-824c-21e5ed772dfa REACT_APP_WALLET_CONNECT_PROJECT_ID=a28cc4392a374056df13372b666190a0 REACT_APP_WALLET_CONNECT_RELAY_URL=wss://relay.walletconnect.com -# zerion -REACT_APP_ZERION_API_KEY=emtfcHJvZF8xMjE3ZGRmYjhlZDY0ZGEzYmE2MjFiODg2NjQ5MTM4Yzo= - # zapper REACT_APP_ZAPPER_API_KEY=c1b0bac5-bfc4-44f2-9fee-ed82679f76b7 @@ -157,9 +154,6 @@ REACT_APP_FEATURE_COVALENT_JAYPEGS=true #oneinch REACT_APP_ONE_INCH_API_URL=https://api-shapeshift.1inch.io/v5.0 -# 0x -REACT_APP_ZRX_API_KEY=834f3988-83d1-43de-8aeb-9337d1eccdbf - REACT_APP_SNAP_ID=npm:@shapeshiftoss/metamask-snaps # REACT_APP_SNAP_ID=local:http://localhost:9000 diff --git a/react-app-rewired/headers/csps/defi/swappers/0x.ts b/react-app-rewired/headers/csps/defi/swappers/0x.ts index 55fd3d6d482..81b5866e233 100644 --- a/react-app-rewired/headers/csps/defi/swappers/0x.ts +++ b/react-app-rewired/headers/csps/defi/swappers/0x.ts @@ -1,17 +1,5 @@ import type { Csp } from '../../../types' export const csp: Csp = { - 'connect-src': [ - // @shapeshiftoss/swapper@1.15.0: https://github.com/shapeshift/lib/blob/f833ac7f8c70dee801eaa24525336ca6992e5903/packages/swapper/src/swappers/zrx/utils/zrxService.ts#L4 - 'https://api.0x.org', - // @shapeshiftoss/chain-adapters@1.22.1: https://github.com/shapeshift/lib/blob/476550629be9485bfc089decc4df85456968464a/packages/chain-adapters/src/ethereum/EthereumChainAdapter.ts#L226 - 'https://gas.api.0x.org', - // @shapeshiftoss/swapper: https://github.com/shapeshift/lib/blob/094c684297666bc4b78e7eb1805dbeed6e6e69b1/packages/swapper/src/swappers/zrx/utils/helpers/helpers.ts#L16 - 'https://avalanche.api.0x.org', - // @shapeshiftoss/swapper: https://github.com/shapeshift/lib/blob/baa02e4355bff52cd89efd93ea4f38a50fe284f5/packages/swapper/src/swappers/zrx/utils/helpers/helpers.ts#L24 - 'https://optimism.api.0x.org', - 'https://polygon.api.0x.org', - 'https://bsc.api.0x.org', - 'https://arbitrum.api.0x.org/', - ], + 'connect-src': ['https://0x.shapeshift.com'], } diff --git a/react-app-rewired/headers/csps/zerion.ts b/react-app-rewired/headers/csps/zerion.ts index a1a1b51fc8a..1204ee79415 100644 --- a/react-app-rewired/headers/csps/zerion.ts +++ b/react-app-rewired/headers/csps/zerion.ts @@ -1,5 +1,5 @@ import type { Csp } from '../types' export const csp: Csp = { - 'connect-src': ['https://api.zerion.io/v1/'], + 'connect-src': ['https://zerion.shapeshift.com'], } diff --git a/src/config.ts b/src/config.ts index c453a92a639..8b845988bde 100644 --- a/src/config.ts +++ b/src/config.ts @@ -68,7 +68,6 @@ const validators = { REACT_APP_MTPELERIN_REFERRAL_CODE: str(), REACT_APP_FRIENDLY_CAPTCHA_SITE_KEY: str(), REACT_APP_FEATURE_DASHBOARD_TABS: bool({ default: false }), - REACT_APP_ZERION_API_KEY: str(), REACT_APP_FEATURE_DEFI_DASHBOARD: bool({ default: false }), REACT_APP_ZAPPER_API_KEY: str(), REACT_APP_COVALENT_API_KEY: str(), @@ -150,7 +149,6 @@ const validators = { REACT_APP_ALCHEMY_POLYGON_JAYPEGS_BASE_URL: url(), REACT_APP_ALCHEMY_OPTIMISM_JAYPEGS_BASE_URL: url(), REACT_APP_ALCHEMY_ARBITRUM_JAYPEGS_BASE_URL: url(), - REACT_APP_ZRX_API_KEY: str(), REACT_APP_CHATWOOT_TOKEN: str(), REACT_APP_CHATWOOT_URL: str(), REACT_APP_FEATURE_CHATWOOT: bool({ default: false }), diff --git a/src/lib/swapper/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.test.ts b/src/lib/swapper/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.test.ts index 57f9e4a8cae..27557f2fed2 100644 --- a/src/lib/swapper/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.test.ts +++ b/src/lib/swapper/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.test.ts @@ -9,7 +9,6 @@ import { describe, expect, it, vi } from 'vitest' import { BTC } from '../../utils/test-data/assets' import { gasFeeData } from '../../utils/test-data/fees' import { setupQuote } from '../../utils/test-data/setupSwapQuote' -import { baseUrlFromChainId } from '../utils/helpers/helpers' import { zrxServiceFactory } from '../utils/zrxService' import { getZrxTradeQuote } from './getZrxTradeQuote' @@ -37,7 +36,7 @@ vi.mock('../utils/helpers/helpers', async () => { const actual = await vi.importActual('../utils/helpers/helpers') return { ...actual, - baseUrlFromChainId: vi.fn(() => 'https://api.0x.org/'), + baseUrlFromChainId: vi.fn(() => 'https://0x.shapeshift.com/ethereum'), } }) vi.mock('../../utils/helpers/helpers') @@ -72,9 +71,7 @@ vi.mock('context/PluginProvider/chainAdapterSingleton', () => { const mockOk = Ok const mockErr = Err describe('getZrxTradeQuote', () => { - const zrxService = zrxServiceFactory({ baseUrl: 'https://api.0x.org/' }) - - vi.mocked(baseUrlFromChainId).mockReturnValue('https://api.0x.org/') + const zrxService = zrxServiceFactory({ baseUrl: 'https://0x.shapeshift.com/ethereum' }) it('returns quote with fee data', async () => { const { quoteInput } = setupQuote() diff --git a/src/lib/swapper/swappers/ZrxSwapper/utils/helpers/helpers.ts b/src/lib/swapper/swappers/ZrxSwapper/utils/helpers/helpers.ts index 591f56b38de..478625fc6b4 100644 --- a/src/lib/swapper/swappers/ZrxSwapper/utils/helpers/helpers.ts +++ b/src/lib/swapper/swappers/ZrxSwapper/utils/helpers/helpers.ts @@ -17,17 +17,17 @@ import { zrxSupportedChainIds } from '../../types' export const baseUrlFromChainId = (chainId: ZrxSupportedChainId): string => { switch (chainId) { case KnownChainIds.EthereumMainnet: - return 'https://api.0x.org/' + return 'https:/0x.shapeshift.com/ethereum' case KnownChainIds.AvalancheMainnet: - return 'https://avalanche.api.0x.org/' + return 'https:/0x.shapeshift.com/avalanche' case KnownChainIds.OptimismMainnet: - return 'https://optimism.api.0x.org/' + return 'https:/0x.shapeshift.com/optimism' case KnownChainIds.BnbSmartChainMainnet: - return 'https://bsc.api.0x.org/' + return 'https:/0x.shapeshift.com/bnbsmartchain' case KnownChainIds.PolygonMainnet: - return 'https://polygon.api.0x.org/' + return 'https:/0x.shapeshift.com/polygon' case KnownChainIds.ArbitrumMainnet: - return 'https://arbitrum.api.0x.org/' + return 'https:/0x.shapeshift.com/arbitrum' default: assertUnreachable(chainId) } diff --git a/src/lib/swapper/swappers/ZrxSwapper/utils/zrxService.ts b/src/lib/swapper/swappers/ZrxSwapper/utils/zrxService.ts index 4b38384a4a2..d3d022a3cdd 100644 --- a/src/lib/swapper/swappers/ZrxSwapper/utils/zrxService.ts +++ b/src/lib/swapper/swappers/ZrxSwapper/utils/zrxService.ts @@ -1,7 +1,6 @@ import { SwapperName } from '@shapeshiftoss/swapper' import type { AxiosInstance, AxiosRequestConfig } from 'axios' import axios from 'axios' -import { getConfig } from 'config' import identity from 'lodash/identity' import type { RetryConfig } from 'retry-axios' import type { MonadicSwapperAxiosService } from 'lib/swapper/utils' @@ -19,11 +18,6 @@ type AxiosInstanceHoF = ( const axiosConfig: AxiosRequestConfig = { timeout: 10000, - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - '0x-api-key': getConfig().REACT_APP_ZRX_API_KEY, - }, adapter: cache.adapter, } diff --git a/src/state/apis/zerion/zerionApi.ts b/src/state/apis/zerion/zerionApi.ts index 0b00fbb8b08..d46c22d964c 100644 --- a/src/state/apis/zerion/zerionApi.ts +++ b/src/state/apis/zerion/zerionApi.ts @@ -3,7 +3,6 @@ import type { AssetId } from '@shapeshiftoss/caip' import { FEE_ASSET_IDS, fromAssetId } from '@shapeshiftoss/caip' import { isEvmChainId } from '@shapeshiftoss/chain-adapters' import axios from 'axios' -import { getConfig } from 'config' import memoize from 'lodash/memoize' import { isSome } from 'lib/utils' import { BASE_RTK_CREATE_API_CONFIG } from 'state/apis/const' @@ -11,15 +10,11 @@ import { BASE_RTK_CREATE_API_CONFIG } from 'state/apis/const' import { zerionImplementationToMaybeAssetId } from './mapping' import { zerionFungiblesSchema } from './validators/fungible' -const ZERION_BASE_URL = 'https://api.zerion.io/v1' +const ZERION_BASE_URL = 'https://zerion.shapeshift.com' const options = { method: 'GET' as const, baseURL: ZERION_BASE_URL, - headers: { - accept: 'application/json', - authorization: `Basic ${getConfig().REACT_APP_ZERION_API_KEY}`, - }, } // Looks like we're using a useless memoize here as zerionApi.endpoints.getRelatedAssetIds takes care of caching @@ -31,7 +26,7 @@ export const _getRelatedAssetIds = memoize(async (assetId: AssetId): Promise Date: Mon, 8 Jan 2024 01:46:40 +0100 Subject: [PATCH 2/6] fix: manual receive address empty confirm step (#5947) * fix: manual receive address empty confirm step * feat: ocd terminology --------- Co-authored-by: Apotheosis <0xapotheosis@gmail.com> --- .../components/ManualAddressEntry.tsx | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/components/MultiHopTrade/components/TradeInput/components/ManualAddressEntry.tsx b/src/components/MultiHopTrade/components/TradeInput/components/ManualAddressEntry.tsx index b31a7370e23..fd22e8a9a24 100644 --- a/src/components/MultiHopTrade/components/TradeInput/components/ManualAddressEntry.tsx +++ b/src/components/MultiHopTrade/components/TradeInput/components/ManualAddressEntry.tsx @@ -72,21 +72,26 @@ export const ManualAddressEntry: FC = memo((): JSX.Element | null => { required: true, validate: { validateAddress: async (rawInput: string) => { - dispatch(swappers.actions.setManualReceiveAddress(undefined)) - const value = rawInput.trim() // trim leading/trailing spaces - // this does not throw, everything inside is handled - const parseAddressInputWithChainIdArgs = { - assetId: buyAssetAssetId, - chainId: buyAssetChainId, - urlOrAddress: value, - disableUrlParsing: true, + try { + const value = rawInput.trim() // trim leading/trailing spaces + // this does not throw, everything inside is handled + const parseAddressInputWithChainIdArgs = { + assetId: buyAssetAssetId, + chainId: buyAssetChainId, + urlOrAddress: value, + disableUrlParsing: true, + } + const { address } = await parseAddressInputWithChainId(parseAddressInputWithChainIdArgs) + dispatch(swappers.actions.setManualReceiveAddress(address || undefined)) + const invalidMessage = isYatSupported + ? 'common.invalidAddressOrYat' + : 'common.invalidAddress' + return address ? true : invalidMessage + } catch (e) { + // This function should never throw, but in case it ever does, we never want to have a stale manual receive address stored + console.error(e) + dispatch(swappers.actions.setManualReceiveAddress(undefined)) } - const { address } = await parseAddressInputWithChainId(parseAddressInputWithChainIdArgs) - dispatch(swappers.actions.setManualReceiveAddress(address || undefined)) - const invalidMessage = isYatSupported - ? 'common.invalidAddressOrYat' - : 'common.invalidAddress' - return address ? true : invalidMessage }, }, }), From cc4e2d90a747103bce92f959143d2ee76a62f8ae Mon Sep 17 00:00:00 2001 From: Apotheosis <0xapotheosis@gmail.com> Date: Mon, 8 Jan 2024 23:12:51 +1100 Subject: [PATCH 3/6] chore: split WallectConnect projects (#5953) --- .env.base | 3 ++- src/config.ts | 3 ++- src/context/WalletProvider/WalletConnectV2/config.ts | 4 ++-- src/plugins/walletConnectToDapps/walletUtils.ts | 4 ++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.env.base b/.env.base index 3ba50e42523..e9caa93af0d 100644 --- a/.env.base +++ b/.env.base @@ -141,7 +141,8 @@ REACT_APP_ETHERSCAN_API_KEY=XT8BI6VDYUGD9675X861ATHZNK3AN6HRMF REACT_APP_WHEREVER_PARTNER_KEY=00da1f18-3bba-4b71-824c-21e5ed772dfa # WalletConnect -REACT_APP_WALLET_CONNECT_PROJECT_ID=a28cc4392a374056df13372b666190a0 +REACT_APP_WALLET_CONNECT_TO_DAPPS_PROJECT_ID=a28cc4392a374056df13372b666190a0 +REACT_APP_WALLET_CONNECT_WALLET_PROJECT_ID=f58c0242def84c3b9befe9b1e6086bbd REACT_APP_WALLET_CONNECT_RELAY_URL=wss://relay.walletconnect.com # zapper diff --git a/src/config.ts b/src/config.ts index 8b845988bde..9a7f2257c14 100644 --- a/src/config.ts +++ b/src/config.ts @@ -93,7 +93,8 @@ const validators = { REACT_APP_FEATURE_COINBASE_WALLET: bool({ default: false }), REACT_APP_FEATURE_LEDGER_WALLET: bool({ default: false }), REACT_APP_FEATURE_WALLET_CONNECT_V2: bool({ default: false }), - REACT_APP_WALLET_CONNECT_PROJECT_ID: str({ default: '' }), + REACT_APP_WALLET_CONNECT_TO_DAPPS_PROJECT_ID: str({ default: '' }), + REACT_APP_WALLET_CONNECT_WALLET_PROJECT_ID: str({ default: '' }), REACT_APP_WALLET_CONNECT_RELAY_URL: str({ default: 'wss://relay.walletconnect.com' }), REACT_APP_YAT_NODE_URL: url({ default: 'https://a.y.at' }), REACT_APP_TOKEMAK_STATS_URL: url({ default: 'https://stats.tokemaklabs.com/' }), diff --git a/src/context/WalletProvider/WalletConnectV2/config.ts b/src/context/WalletProvider/WalletConnectV2/config.ts index 1a936668ddf..b9cf275b60e 100644 --- a/src/context/WalletProvider/WalletConnectV2/config.ts +++ b/src/context/WalletProvider/WalletConnectV2/config.ts @@ -67,7 +67,7 @@ const walletConnectV2OptionalChainIds: AtLeastOneNumber = (() => { })() const { - REACT_APP_WALLET_CONNECT_PROJECT_ID, + REACT_APP_WALLET_CONNECT_WALLET_PROJECT_ID, REACT_APP_AVALANCHE_NODE_URL, REACT_APP_OPTIMISM_NODE_URL, REACT_APP_BNBSMARTCHAIN_NODE_URL, @@ -79,7 +79,7 @@ const { } = getConfig() export const walletConnectV2ProviderConfig: EthereumProviderOptions = { - projectId: REACT_APP_WALLET_CONNECT_PROJECT_ID, + projectId: REACT_APP_WALLET_CONNECT_WALLET_PROJECT_ID, chains: walletConnectV2RequiredChainIds, optionalChains: walletConnectV2OptionalChainIds, optionalMethods: [ diff --git a/src/plugins/walletConnectToDapps/walletUtils.ts b/src/plugins/walletConnectToDapps/walletUtils.ts index 5e43c97195c..5f70325b86f 100644 --- a/src/plugins/walletConnectToDapps/walletUtils.ts +++ b/src/plugins/walletConnectToDapps/walletUtils.ts @@ -10,9 +10,9 @@ let core: ICore // WalletConnect Core singleton export const getWalletConnectCore = () => { if (!core) { - const walletConnectProjectId = getConfig().REACT_APP_WALLET_CONNECT_PROJECT_ID + const walletConnectToDappsProjectId = getConfig().REACT_APP_WALLET_CONNECT_TO_DAPPS_PROJECT_ID core = new Core({ - projectId: walletConnectProjectId, + projectId: walletConnectToDappsProjectId, }) } From 092ed3bcccb08b818078f4a74a51c041af17b0d3 Mon Sep 17 00:00:00 2001 From: Apotheosis <0xapotheosis@gmail.com> Date: Tue, 9 Jan 2024 02:25:20 +1100 Subject: [PATCH 4/6] chore: remove missed console log (#5952) Co-authored-by: kevin <35275952+kaladinlight@users.noreply.github.com> --- .../filterAssetIdsBySellable/filterAssetIdsBySellable.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/swapper/swappers/CowSwapper/filterAssetIdsBySellable/filterAssetIdsBySellable.ts b/src/lib/swapper/swappers/CowSwapper/filterAssetIdsBySellable/filterAssetIdsBySellable.ts index 104809eb204..6b2b346b64d 100644 --- a/src/lib/swapper/swappers/CowSwapper/filterAssetIdsBySellable/filterAssetIdsBySellable.ts +++ b/src/lib/swapper/swappers/CowSwapper/filterAssetIdsBySellable/filterAssetIdsBySellable.ts @@ -7,7 +7,6 @@ import { getSupportedChainIds } from '../utils/helpers/helpers' export const filterAssetIdsBySellable = (assets: Asset[]): AssetId[] => { const supportedChainIds = getSupportedChainIds() - console.log({ assets, supportedChainIds }) return assets .filter(asset => { return ( From 2a1bc35ba9379fa20a6d629f59440d93be5d11af Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Mon, 8 Jan 2024 16:32:45 +0100 Subject: [PATCH 5/6] feat: rm useless vi.mock (#5954) --- .../ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/swapper/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.test.ts b/src/lib/swapper/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.test.ts index 27557f2fed2..ffe0aab867c 100644 --- a/src/lib/swapper/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.test.ts +++ b/src/lib/swapper/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.test.ts @@ -39,7 +39,6 @@ vi.mock('../utils/helpers/helpers', async () => { baseUrlFromChainId: vi.fn(() => 'https://0x.shapeshift.com/ethereum'), } }) -vi.mock('../../utils/helpers/helpers') vi.mock('@shapeshiftoss/chain-adapters', () => { const { KnownChainIds } = require('@shapeshiftoss/types') return { From 8298f8f35479dcbbcad0ecb7449e07dd40357388 Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Mon, 8 Jan 2024 16:39:32 +0100 Subject: [PATCH 6/6] fix: zrx base URLs (#5955) --- .../getZrxTradeQuote/getZrxTradeQuote.test.ts | 4 ++-- .../swappers/ZrxSwapper/utils/helpers/helpers.ts | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/lib/swapper/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.test.ts b/src/lib/swapper/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.test.ts index ffe0aab867c..81c4638f87f 100644 --- a/src/lib/swapper/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.test.ts +++ b/src/lib/swapper/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.test.ts @@ -36,7 +36,7 @@ vi.mock('../utils/helpers/helpers', async () => { const actual = await vi.importActual('../utils/helpers/helpers') return { ...actual, - baseUrlFromChainId: vi.fn(() => 'https://0x.shapeshift.com/ethereum'), + baseUrlFromChainId: vi.fn(() => 'https://0x.shapeshift.com/ethereum/'), } }) vi.mock('@shapeshiftoss/chain-adapters', () => { @@ -70,7 +70,7 @@ vi.mock('context/PluginProvider/chainAdapterSingleton', () => { const mockOk = Ok const mockErr = Err describe('getZrxTradeQuote', () => { - const zrxService = zrxServiceFactory({ baseUrl: 'https://0x.shapeshift.com/ethereum' }) + const zrxService = zrxServiceFactory({ baseUrl: 'https://0x.shapeshift.com/ethereum/' }) it('returns quote with fee data', async () => { const { quoteInput } = setupQuote() diff --git a/src/lib/swapper/swappers/ZrxSwapper/utils/helpers/helpers.ts b/src/lib/swapper/swappers/ZrxSwapper/utils/helpers/helpers.ts index 478625fc6b4..8b96696ff3e 100644 --- a/src/lib/swapper/swappers/ZrxSwapper/utils/helpers/helpers.ts +++ b/src/lib/swapper/swappers/ZrxSwapper/utils/helpers/helpers.ts @@ -17,17 +17,17 @@ import { zrxSupportedChainIds } from '../../types' export const baseUrlFromChainId = (chainId: ZrxSupportedChainId): string => { switch (chainId) { case KnownChainIds.EthereumMainnet: - return 'https:/0x.shapeshift.com/ethereum' + return 'https://0x.shapeshift.com/ethereum/' case KnownChainIds.AvalancheMainnet: - return 'https:/0x.shapeshift.com/avalanche' + return 'https://0x.shapeshift.com/avalanche/' case KnownChainIds.OptimismMainnet: - return 'https:/0x.shapeshift.com/optimism' + return 'https://0x.shapeshift.com/optimism/' case KnownChainIds.BnbSmartChainMainnet: - return 'https:/0x.shapeshift.com/bnbsmartchain' + return 'https://0x.shapeshift.com/bnbsmartchain/' case KnownChainIds.PolygonMainnet: - return 'https:/0x.shapeshift.com/polygon' + return 'https://0x.shapeshift.com/polygon/' case KnownChainIds.ArbitrumMainnet: - return 'https:/0x.shapeshift.com/arbitrum' + return 'https://0x.shapeshift.com/arbitrum/' default: assertUnreachable(chainId) }