diff --git a/.release/.changeset/few-cherries-smile.md b/.release/.changeset/few-cherries-smile.md deleted file mode 100644 index 14575efd..00000000 --- a/.release/.changeset/few-cherries-smile.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bnb-chain/canonical-bridge-widget": patch ---- - -Support custom breakpoints diff --git a/.release/.changeset/gorgeous-maps-fly.md b/.release/.changeset/gorgeous-maps-fly.md deleted file mode 100644 index 4eb23f4e..00000000 --- a/.release/.changeset/gorgeous-maps-fly.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bnb-chain/canonical-bridge-widget": patch ---- - -Fix wallet issues diff --git a/.release/.changeset/grumpy-squids-collect.md b/.release/.changeset/grumpy-squids-collect.md deleted file mode 100644 index 4eb23f4e..00000000 --- a/.release/.changeset/grumpy-squids-collect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bnb-chain/canonical-bridge-widget": patch ---- - -Fix wallet issues diff --git a/.release/.changeset/honest-lies-cheer.md b/.release/.changeset/honest-lies-cheer.md deleted file mode 100644 index 22d8e410..00000000 --- a/.release/.changeset/honest-lies-cheer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bnb-chain/canonical-bridge-widget": patch ---- - -Remove delayTime for wallet diff --git a/.release/.changeset/late-swans-sparkle.md b/.release/.changeset/late-swans-sparkle.md deleted file mode 100644 index 4eb23f4e..00000000 --- a/.release/.changeset/late-swans-sparkle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bnb-chain/canonical-bridge-widget": patch ---- - -Fix wallet issues diff --git a/.release/.changeset/lovely-maps-study.md b/.release/.changeset/lovely-maps-study.md deleted file mode 100644 index e782ac60..00000000 --- a/.release/.changeset/lovely-maps-study.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bnb-chain/canonical-bridge-widget": patch ---- - -Support custom connect wallet button diff --git a/.release/.changeset/pre.json b/.release/.changeset/pre.json deleted file mode 100644 index 61f7478b..00000000 --- a/.release/.changeset/pre.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "mode": "pre", - "tag": "alpha", - "initialVersions": { - "@bnb-chain/canonical-bridge-sdk": "0.4.1", - "@bnb-chain/canonical-bridge-widget": "0.5.1" - }, - "changesets": [ - "few-cherries-smile", - "gorgeous-maps-fly", - "grumpy-squids-collect", - "honest-lies-cheer", - "late-swans-sparkle", - "lovely-maps-study", - "quick-pots-tease", - "tall-spiders-love", - "twelve-moose-sit" - ] -} diff --git a/.release/.changeset/quick-pots-tease.md b/.release/.changeset/quick-pots-tease.md deleted file mode 100644 index 76aa1823..00000000 --- a/.release/.changeset/quick-pots-tease.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bnb-chain/canonical-bridge-widget": patch ---- - -Show all tokens in token list with different token address diff --git a/.release/.changeset/tall-spiders-love.md b/.release/.changeset/tall-spiders-love.md deleted file mode 100644 index f8453a4c..00000000 --- a/.release/.changeset/tall-spiders-love.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bnb-chain/canonical-bridge-widget": patch ---- - -Separate wallet component diff --git a/.release/.changeset/twelve-moose-sit.md b/.release/.changeset/twelve-moose-sit.md deleted file mode 100644 index 79edb826..00000000 --- a/.release/.changeset/twelve-moose-sit.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bnb-chain/canonical-bridge-widget": patch ---- - -Add log for solana diff --git a/apps/canonical-bridge-ui/core/components/icons/SvgDefs.tsx b/apps/canonical-bridge-ui/core/components/icons/SvgDefs.tsx new file mode 100644 index 00000000..f14ee92d --- /dev/null +++ b/apps/canonical-bridge-ui/core/components/icons/SvgDefs.tsx @@ -0,0 +1,69 @@ +import { Icon } from '@bnb-chain/space'; + +export function SvgDefs() { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} diff --git a/apps/canonical-bridge-ui/core/components/icons/wallets/PhantomIcon.tsx b/apps/canonical-bridge-ui/core/components/icons/wallets/PhantomIcon.tsx index 39aef1c8..1c042d97 100644 --- a/apps/canonical-bridge-ui/core/components/icons/wallets/PhantomIcon.tsx +++ b/apps/canonical-bridge-ui/core/components/icons/wallets/PhantomIcon.tsx @@ -10,11 +10,6 @@ export function PhantomIcon(props: IconProps) { fill="#AB9FF2" /> - - - - - ); } diff --git a/apps/canonical-bridge-ui/core/components/icons/wallets/TronLinkIcon.tsx b/apps/canonical-bridge-ui/core/components/icons/wallets/TronLinkIcon.tsx index 74e219b9..d522dd44 100644 --- a/apps/canonical-bridge-ui/core/components/icons/wallets/TronLinkIcon.tsx +++ b/apps/canonical-bridge-ui/core/components/icons/wallets/TronLinkIcon.tsx @@ -8,12 +8,6 @@ export function TronLinkIcon(props: IconProps) { d="M7.30721 0C3.27132 0 0 3.59886 0 8.03839V56.9616C0 61.4011 3.27132 65 7.30721 65H57.6928C61.7283 65 65 61.4011 65 56.9616V8.03839C65 3.59886 61.7283 0 57.6928 0H7.30721Z" fill="url(#paint0_linear_18_3)" /> - - - - - - - - - - - - ); } diff --git a/apps/canonical-bridge-ui/core/components/icons/wallets/TrustWalletIcon.tsx b/apps/canonical-bridge-ui/core/components/icons/wallets/TrustWalletIcon.tsx index bcc92ccd..f10d3e2f 100644 --- a/apps/canonical-bridge-ui/core/components/icons/wallets/TrustWalletIcon.tsx +++ b/apps/canonical-bridge-ui/core/components/icons/wallets/TrustWalletIcon.tsx @@ -16,34 +16,6 @@ export function TrustWalletIcon(props: IconProps) { d="M18.6662 6.66673L12.0003 4.5V19.5C16.7622 17.4998 18.6662 13.6665 18.6662 11.5001V6.66673Z" fill="url(#paint1_linear_7476_132116)" /> - - - - - - - - - - - - - - ); } diff --git a/apps/canonical-bridge-ui/pages/_app.tsx b/apps/canonical-bridge-ui/pages/_app.tsx index 011805d1..8f21c5c4 100644 --- a/apps/canonical-bridge-ui/pages/_app.tsx +++ b/apps/canonical-bridge-ui/pages/_app.tsx @@ -4,6 +4,7 @@ import Head from 'next/head'; import { AppProps } from 'next/app'; import { ThemeProvider } from '@/core/components/ThemeProvider'; +import { SvgDefs } from '@/core/components/icons/SvgDefs'; const queryClient = new QueryClient({ defaultOptions: { @@ -23,6 +24,7 @@ export default function App({ Component, ...restProps }: AppProps) { + diff --git a/packages/canonical-bridge-widget/CHANGELOG.md b/packages/canonical-bridge-widget/CHANGELOG.md index ec483cf0..f9ed6d81 100644 --- a/packages/canonical-bridge-widget/CHANGELOG.md +++ b/packages/canonical-bridge-widget/CHANGELOG.md @@ -1,5 +1,26 @@ # @bnb-chain/canonical-bridge-widget +## 0.5.4 + +### Patch Changes + +- 8d3b6d1: Support custom breakpoints +- b95b3ab: Fix wallet issues +- fb73ca4: Fix wallet issues +- da03355: Remove delayTime for wallet +- bcf65ef: Fix colorMode does not follow the parameter +- 6d78c07: Fix wallet issues +- 3146b01: Support custom connect wallet button +- dc0fcac: Show all tokens in token list with different token address +- cdf450d: Separate wallet component +- 0f6c74c: Add log for solana + +## 0.5.4-alpha.4 + +### Patch Changes + +- Fix colorMode does not follow the parameter + ## 0.5.4-alpha.3 ### Patch Changes diff --git a/packages/canonical-bridge-widget/package.json b/packages/canonical-bridge-widget/package.json index b465b330..52df5051 100644 --- a/packages/canonical-bridge-widget/package.json +++ b/packages/canonical-bridge-widget/package.json @@ -1,6 +1,6 @@ { "name": "@bnb-chain/canonical-bridge-widget", - "version": "0.5.4-alpha.3", + "version": "0.5.4", "description": "canonical bridge widget", "author": "bnb-chain", "private": false, diff --git a/packages/canonical-bridge-widget/src/CanonicalBridgeProvider.tsx b/packages/canonical-bridge-widget/src/CanonicalBridgeProvider.tsx index ff25475a..79554080 100644 --- a/packages/canonical-bridge-widget/src/CanonicalBridgeProvider.tsx +++ b/packages/canonical-bridge-widget/src/CanonicalBridgeProvider.tsx @@ -1,9 +1,9 @@ import React, { useContext, useMemo } from 'react'; -import { ColorMode, IntlProvider } from '@bnb-chain/space'; +import { ColorMode, IntlProvider, theme } from '@bnb-chain/space'; import { ChainType, IChainConfig, ITransferConfig } from '@/modules/aggregator/types'; import { StoreProvider } from '@/modules/store/StoreProvider'; -import { ThemeProvider, ThemeProviderProps } from '@/core/theme/ThemeProvider'; +import { ThemeProvider } from '@/core/theme/ThemeProvider'; import { AggregatorProvider } from '@/modules/aggregator/components/AggregatorProvider'; import { TokenBalancesProvider } from '@/modules/aggregator/components/TokenBalancesProvider'; import { TokenPricesProvider } from '@/modules/aggregator/components/TokenPricesProvider'; @@ -17,7 +17,12 @@ export interface ICanonicalBridgeConfig { appearance: { colorMode?: ColorMode; - theme?: ThemeProviderProps['themeConfig']; + theme?: { + dark?: any; + light?: any; + fontFamily?: string; + breakpoints?: Partial; + }; locale?: string; messages?: Record; bridgeTitle?: string; @@ -75,7 +80,7 @@ export function CanonicalBridgeProvider(props: CanonicalBridgeProviderProps) { appearance: { bridgeTitle: 'BNB Chain Cross-Chain Bridge', - mode: 'dark', + colorMode: 'dark', locale: 'en', messages: locales.en, ...config.appearance, @@ -100,10 +105,7 @@ export function CanonicalBridgeProvider(props: CanonicalBridgeProviderProps) { - + diff --git a/packages/canonical-bridge-widget/src/core/constants/index.ts b/packages/canonical-bridge-widget/src/core/constants/index.ts index e5189218..6604baee 100644 --- a/packages/canonical-bridge-widget/src/core/constants/index.ts +++ b/packages/canonical-bridge-widget/src/core/constants/index.ts @@ -15,6 +15,11 @@ export const DEFAULT_ADDRESS = '0x6836CbaCbBd1E798cC56802AC7d8BDf6Da0d0980'; export const DEFAULT_TRON_ADDRESS = 'TTb3A6ASFejJuGcM1UVcRCJA23WGiJKSiY'; export const DEFAULT_SOLANA_ADDRESS = 'J7JYXS8PMMBgfFKP1bqUu7mGgWyWUDL9xqfYujznc61r'; +export const CBRIDGE_ENDPOINT = 'https://cbridge-prod2.celer.app/v2'; +export const DEBRIDGE_ENDPOINT = 'https://deswap.debridge.finance/v1.0'; +export const STARGATE_ENDPOINT = 'https://mainnet.stargate-api.com/v1/metadata?version=v2'; +export const MESON_ENDPOINT = 'https://relayer.meson.fi/api/v1'; + export const nativeTokenMap = { 1: 'ETH', 10: 'ETH', diff --git a/packages/canonical-bridge-widget/src/core/theme/ThemeProvider.tsx b/packages/canonical-bridge-widget/src/core/theme/ThemeProvider.tsx index 95b70912..9de3dfa3 100644 --- a/packages/canonical-bridge-widget/src/core/theme/ThemeProvider.tsx +++ b/packages/canonical-bridge-widget/src/core/theme/ThemeProvider.tsx @@ -1,4 +1,4 @@ -import { ChakraProvider, theme, createLocalStorageManager, ColorMode } from '@bnb-chain/space'; +import { ChakraProvider, ColorMode, theme } from '@bnb-chain/space'; import { useMemo } from 'react'; import { merge } from 'lodash'; @@ -8,24 +8,13 @@ import { walletStyles } from '@/core/theme/walletStyles'; import { useBridgeConfig } from '@/CanonicalBridgeProvider'; export interface ThemeProviderProps { - colorMode?: ColorMode; children: React.ReactNode; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - themeConfig?: { - dark?: any; - light?: any; - fontFamily?: string; - breakpoints?: Partial; - }; } -export const ThemeProvider = ({ - children, - colorMode = 'dark', - themeConfig, -}: ThemeProviderProps) => { - const { appName: APP_NAME } = useBridgeConfig(); - const colorModeManager = createLocalStorageManager(`${APP_NAME}-color-mode`); +export const ThemeProvider = ({ children }: ThemeProviderProps) => { + const { appearance } = useBridgeConfig(); + const { theme: themeConfig, colorMode } = appearance; + const customTheme = useMemo(() => { return { ...theme, @@ -57,7 +46,13 @@ export const ThemeProvider = ({ return ( { + // cBridge + const validateCBridgeToken = async ({ + isPegged, + fromChainId, + toChainId, + tokenAddress, + bridgeAddress, + tokenSymbol, + }: ICBridgeTokenValidateParams) => { + try { + if (!fromChainId || !toChainId || !tokenAddress || !bridgeAddress || !tokenSymbol) { + return false; + } + const { data: cBridgeConfig } = await axios.get( + `${CBRIDGE_ENDPOINT}/getTransferConfigsForAll`, + ); + if (!cBridgeConfig) return false; + if (isPegged === true) { + // pegged token + const peggedToken = cBridgeConfig.pegged_pair_configs.filter((pair) => { + return ( + (pair.pegged_deposit_contract_addr === bridgeAddress && + pair?.org_chain_id === fromChainId && + pair?.org_token.token.address === tokenAddress && + pair?.org_token.token.symbol === tokenSymbol && + pair?.pegged_chain_id === toChainId) || + (pair?.pegged_chain_id === fromChainId && + pair.pegged_burn_contract_addr === bridgeAddress && + pair.pegged_token.token.address === tokenAddress && + pair.pegged_token.token.symbol === tokenSymbol && + pair?.org_chain_id === toChainId) + ); + }); + if (!!peggedToken && peggedToken.length > 0) { + console.log('cBridge pegged token info matched', peggedToken); + return true; + } + console.log('Can not find cBridge pegged info'); + console.log('-- isPegged', isPegged); + console.log('-- fromChainId', fromChainId); + console.log('-- tokenAddress', tokenAddress); + console.log('-- bridgeAddress', bridgeAddress); + return false; + } else { + // bridge address + const addressInfo = cBridgeConfig.chains.filter((chain) => { + return chain.id === fromChainId && chain.contract_addr === bridgeAddress; + }); + // token address + const tokenInfo = cBridgeConfig.chain_token[fromChainId].token.filter((t) => { + return ( + t.token.address.toLowerCase() === tokenAddress.toLowerCase() && + t.token.symbol === tokenSymbol + ); + }); + if (addressInfo?.length > 0 && tokenInfo?.length > 0) { + console.log('cBridge pool info matched', addressInfo, tokenInfo); + return true; + } else { + console.log('Can not find cBridge pool info'); + console.log('-- isPegged', isPegged); + console.log('-- fromChainId', fromChainId); + console.log('-- tokenAddress', tokenAddress); + console.log('-- bridgeAddress', bridgeAddress); + return false; + } + } + } catch (error) { + // eslint-disable-next-line no-console + console.log('cBridge token address validation error', error); + return false; + } + }; + + // deBridge + const validateDeBridgeToken = async ({ + fromChainId, + tokenSymbol, + tokenAddress, + }: IDeBridgeTokenValidateParams) => { + try { + if (!fromChainId || !tokenAddress || !tokenSymbol) return false; + const { data: deBridgeConfig } = await axios.get<{ + tokens: { [key: string]: IDeBridgeToken }; + }>(`${DEBRIDGE_ENDPOINT}/token-list?chainId=${fromChainId}`); + + if (!deBridgeConfig?.tokens) return false; + const tokenInfo = deBridgeConfig.tokens[tokenAddress.toLowerCase()]; + if (!!tokenInfo && tokenInfo?.address === tokenAddress && tokenInfo?.symbol === tokenSymbol) { + console.log('deBridge token info matched', tokenInfo); + return true; + } + console.log('Could not find deBridge token info'); + console.log('-- fromChainId', fromChainId); + console.log('-- tokenSymbol', tokenSymbol); + console.log('-- tokenAddress', tokenAddress); + return false; + } catch (error: any) { + // eslint-disable-next-line no-console + console.log('deBridge token validation error', error); + return false; + } + }; + + // Stargate + const validateStargateToken = async ({ + fromChainId, + tokenAddress, + bridgeAddress, + tokenSymbol, + }: IStargateTokenValidateParams) => { + try { + if (!fromChainId || !tokenAddress || !bridgeAddress || !tokenSymbol) return false; + const { data: stargateConfig } = await axios.get<{ data: IStargateTokenList }>( + `${STARGATE_ENDPOINT}`, + ); + + // Get chain name by chain id + const chainKey = stargateChainKey[fromChainId] ?? ''; + + if (!chainKey) return false; + if (!stargateConfig) return false; + + const tokenInfo = stargateConfig.data?.v2?.filter((token) => { + return ( + token.chainKey === chainKey && + token.address.toLowerCase() === bridgeAddress.toLowerCase() && + token.token.symbol === tokenSymbol && + token.token.address.toLowerCase() === tokenAddress.toLowerCase() + ); + }); + + console.log('tokenInfo', tokenInfo, stargateConfig.data?.v2); + if (!!tokenInfo && tokenInfo.length > 0) { + console.log('Stargate token info matched', tokenInfo); + return true; + } + console.log('Could not find Stargate token info'); + console.log('-- fromChainId', fromChainId); + console.log('-- tokenAddress', tokenAddress); + console.log('-- bridgeAddress', bridgeAddress); + console.log('-- tokenSymbol', tokenSymbol); + return false; + } catch (error: any) { + console.log('Stargate token validation error', error); + return false; + } + }; + + // Meson + const validateMesonToken = async ({ + fromChainId, + tokenSymbol, + bridgeAddress, + tokenAddress, + }: IMesonTokenValidateParams) => { + try { + if (!fromChainId || !tokenAddress || !tokenSymbol || !bridgeAddress) return false; + const { data: mesonConfig } = await axios.get<{ result: IMesonTokenList[] }>( + `${MESON_ENDPOINT}/limits`, + ); + + const hexNum = fromChainId?.toString(16); + const chainInfo = mesonConfig.result.filter((chainInfo) => { + const tokenInfo = chainInfo.tokens.filter( + (token) => token?.addr === tokenAddress && token.id === tokenSymbol.toLowerCase(), + ); + if (!!tokenInfo && tokenInfo.length > 0) { + console.log('Meson token info', tokenInfo); + } + return ( + chainInfo.chainId === `0x${hexNum}` && + chainInfo.address === bridgeAddress && + tokenInfo?.length > 0 && + !!tokenInfo + ); + }); + if (!!chainInfo && chainInfo.length > 0) { + console.log('Meson chain info matched', chainInfo); + return true; + } + console.log('Could not find Meson token'); + console.log('-- fromChainId', fromChainId); + console.log('-- bridgeAddress', bridgeAddress); + console.log('-- tokenAddress', tokenAddress); + console.log('-- tokenSymbol', tokenSymbol); + return false; + } catch (error: any) { + console.log('Meson token validation error', error); + return false; + } + }; + + return { validateCBridgeToken, validateDeBridgeToken, validateStargateToken, validateMesonToken }; +};