diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index f95c3c63..65e87948 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @aiden-cao @wenty22 @Halibao-Lala @doge95 \ No newline at end of file +* @aiden-cao @wenty22 @Halibao-Lala @doge95 @robot-ux \ No newline at end of file diff --git a/.release/.changeset/bright-impalas-sniff.md b/.release/.changeset/bright-impalas-sniff.md new file mode 100644 index 00000000..11a379bb --- /dev/null +++ b/.release/.changeset/bright-impalas-sniff.md @@ -0,0 +1,6 @@ +--- +"@bnb-chain/canonical-bridge-widget": patch +"@bnb-chain/canonical-bridge-sdk": patch +--- + +Use stargate & meson api to fetch chain & token config diff --git a/.release/.changeset/dull-moose-deliver.md b/.release/.changeset/dull-moose-deliver.md new file mode 100644 index 00000000..7a08558c --- /dev/null +++ b/.release/.changeset/dull-moose-deliver.md @@ -0,0 +1,6 @@ +--- +"@bnb-chain/canonical-bridge-widget": patch +"@bnb-chain/canonical-bridge-sdk": patch +--- + +Remove duplicated tokens for stargate diff --git a/.release/.changeset/giant-rings-warn.md b/.release/.changeset/giant-rings-warn.md new file mode 100644 index 00000000..cd0e45b9 --- /dev/null +++ b/.release/.changeset/giant-rings-warn.md @@ -0,0 +1,5 @@ +--- +"@bnb-chain/canonical-bridge-widget": patch +--- + +Fix stargate fee display and handle api error diff --git a/.release/.changeset/hungry-doors-lick.md b/.release/.changeset/hungry-doors-lick.md new file mode 100644 index 00000000..aa293e89 --- /dev/null +++ b/.release/.changeset/hungry-doors-lick.md @@ -0,0 +1,6 @@ +--- +"@bnb-chain/canonical-bridge-widget": patch +"@bnb-chain/canonical-bridge-sdk": patch +--- + +Update token element's info diff --git a/.release/.changeset/itchy-dots-enjoy.md b/.release/.changeset/itchy-dots-enjoy.md new file mode 100644 index 00000000..b39fd553 --- /dev/null +++ b/.release/.changeset/itchy-dots-enjoy.md @@ -0,0 +1,6 @@ +--- +"@bnb-chain/canonical-bridge-widget": patch +"@bnb-chain/canonical-bridge-sdk": patch +--- + +Fix meson token display symbol issue diff --git a/.release/.changeset/poor-kings-compete.md b/.release/.changeset/poor-kings-compete.md new file mode 100644 index 00000000..5095b9dd --- /dev/null +++ b/.release/.changeset/poor-kings-compete.md @@ -0,0 +1,5 @@ +--- +"@bnb-chain/canonical-bridge-widget": patch +--- + +Fix tron does not display due to its id diff --git a/.release/.changeset/pre.json b/.release/.changeset/pre.json new file mode 100644 index 00000000..ae3bf878 --- /dev/null +++ b/.release/.changeset/pre.json @@ -0,0 +1,16 @@ +{ + "mode": "pre", + "tag": "alpha", + "initialVersions": { + "@bnb-chain/canonical-bridge-sdk": "0.4.5", + "@bnb-chain/canonical-bridge-widget": "0.5.15" + }, + "changesets": [ + "bright-impalas-sniff", + "dull-moose-deliver", + "hungry-doors-lick", + "itchy-dots-enjoy", + "poor-kings-compete", + "serious-cars-worry" + ] +} diff --git a/.release/.changeset/serious-cars-worry.md b/.release/.changeset/serious-cars-worry.md new file mode 100644 index 00000000..910f2f9c --- /dev/null +++ b/.release/.changeset/serious-cars-worry.md @@ -0,0 +1,5 @@ +--- +"@bnb-chain/canonical-bridge-widget": patch +--- + +Add more token info to token element diff --git a/.release/scripts/install.js b/.release/scripts/install.js index a881d541..60b69542 100644 --- a/.release/scripts/install.js +++ b/.release/scripts/install.js @@ -6,7 +6,6 @@ process.chdir(rootDir); console.log('Install changeset dependencies...'); exec('pnpm install', (err, stdout) => { - console.log('shshshshsh'); if (stdout) { console.log(stdout); } diff --git a/.vscode/settings.json b/.vscode/settings.json index e7884581..63ef4b16 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -60,6 +60,7 @@ "tronwallet", "tronweb", "unauthenticate", + "vconsole", "viem", "Wagmi", "walletkit" diff --git a/apps/canonical-bridge-server/.env.example b/apps/canonical-bridge-server/.env.example index db801b5b..58b52e75 100644 --- a/apps/canonical-bridge-server/.env.example +++ b/apps/canonical-bridge-server/.env.example @@ -10,4 +10,4 @@ STARGATE_ENDPOINT='https://mainnet.stargate-api.com/v1/metadata?version=v2' MESON_ENDPOINT=https://relayer.meson.fi/api/v1 REDIS_URL=http://127.0.0.1:6379 -DATABASE_URL=mysql://test:xxx@localhost:3306/bridge +DATABASE_URL= diff --git a/apps/canonical-bridge-server/Dockerfile b/apps/canonical-bridge-server/Dockerfile index 4a18b954..03f7f23b 100644 --- a/apps/canonical-bridge-server/Dockerfile +++ b/apps/canonical-bridge-server/Dockerfile @@ -1,9 +1,6 @@ -FROM busybox:1.36.1 as builder +FROM busybox:1.36.1 AS builder FROM node:20-buster -RUN useradd -u 9000 appuser -USER appuser - WORKDIR /opt/deploy COPY . . @@ -14,6 +11,10 @@ COPY --from=builder /bin/sleep /usr/local/bin/sleep WORKDIR /opt/deploy/apps/canonical-bridge-server +RUN useradd -u 9000 appuser +RUN chown -R appuser /opt/deploy/apps/canonical-bridge-server +USER appuser + EXPOSE 3000 ENV NODE_ENV production diff --git a/apps/canonical-bridge-server/src/app.module.ts b/apps/canonical-bridge-server/src/app.module.ts index 0762c0b1..41c71733 100644 --- a/apps/canonical-bridge-server/src/app.module.ts +++ b/apps/canonical-bridge-server/src/app.module.ts @@ -14,7 +14,7 @@ import { AllExceptionFilter } from './common/filters/all-exception.filter'; import { HttpExceptionFilter } from './common/filters/http-exception.filter'; import { TransformInterceptor } from './common/interceptors/transform.interceptor'; import { TimeoutInterceptor } from './common/interceptors/timeout.interceptor'; -import { REDIS_HOST, REDIS_PORT } from './common/constants'; +import { REDIS_HOST, REDIS_PORT, TIME } from './common/constants'; import { TokenModule } from './module/token/token.module'; import { BullModule } from '@nestjs/bullmq'; import { Web3Module } from '@/shared/web3/web3.module'; @@ -32,6 +32,7 @@ import { BridgeModule } from '@/module/bridge/bridge.module'; HealthModule, ScheduleModule.forRoot(), CacheModule.register({ + ttl: TIME.DAY, isGlobal: true, store: () => redisStore({ host: REDIS_HOST, port: REDIS_PORT }), }), diff --git a/apps/canonical-bridge-server/src/common/constants/index.ts b/apps/canonical-bridge-server/src/common/constants/index.ts index 280ff0a6..eeb1cc74 100644 --- a/apps/canonical-bridge-server/src/common/constants/index.ts +++ b/apps/canonical-bridge-server/src/common/constants/index.ts @@ -60,6 +60,15 @@ export const JOB_KEY = { CORN_PRICE_PREFIX: 'corn:price:', }; +export const TIME = { + SECOND: 1000, + MINUTE: 60 * 1000, + HOUR: 60 * 60 * 1000, + DAY: 24 * 60 * 60 * 1000, + WEEK: 7 * 24 * 60 * 60 * 1000, + MONTH: 30 * 24 * 60 * 60 * 1000, +}; + export const STARGATE_CHAIN_INFO = [ { chainId: 1, diff --git a/apps/canonical-bridge-server/src/module/bridge/bridge.processor.ts b/apps/canonical-bridge-server/src/module/bridge/bridge.processor.ts index e38e5242..8c8d5501 100644 --- a/apps/canonical-bridge-server/src/module/bridge/bridge.processor.ts +++ b/apps/canonical-bridge-server/src/module/bridge/bridge.processor.ts @@ -1,4 +1,4 @@ -import { CACHE_KEY, Queues, Tasks } from '@/common/constants'; +import { CACHE_KEY, Queues, Tasks, TIME } from '@/common/constants'; import { Processor, WorkerHost } from '@nestjs/bullmq'; import { Inject, Logger } from '@nestjs/common'; import { Job } from 'bullmq'; @@ -45,24 +45,24 @@ export class BridgeProcessor extends WorkerHost { const data = { chains: config.chains, tokens: tokenMap }; - await this.cache.set(`${CACHE_KEY.DEBRIDGE_CONFIG}`, data); + await this.cache.set(`${CACHE_KEY.DEBRIDGE_CONFIG}`, data, TIME.DAY); } async fetchCBridge() { const config = await this.web3Service.getTransferConfigsForAll(); if (!config) return; - await this.cache.set(`${CACHE_KEY.CBRIDGE_CONFIG}`, config); + await this.cache.set(`${CACHE_KEY.CBRIDGE_CONFIG}`, config, TIME.DAY); } async fetchStargate() { const config = await this.web3Service.getStargateConfigs(); if (!config) return; - await this.cache.set(`${CACHE_KEY.STARGATE_CONFIG}`, config); + await this.cache.set(`${CACHE_KEY.STARGATE_CONFIG}`, config, TIME.DAY); } async fetchMeson() { const config = await this.web3Service.getMesonConfigs(); if (!config) return; - await this.cache.set(`${CACHE_KEY.MESON_CONFIG}`, config); + await this.cache.set(`${CACHE_KEY.MESON_CONFIG}`, config, TIME.DAY); } } diff --git a/apps/canonical-bridge-server/src/module/bridge/bridge.schedule.ts b/apps/canonical-bridge-server/src/module/bridge/bridge.schedule.ts index 96317135..5af8ceae 100644 --- a/apps/canonical-bridge-server/src/module/bridge/bridge.schedule.ts +++ b/apps/canonical-bridge-server/src/module/bridge/bridge.schedule.ts @@ -10,7 +10,7 @@ export class BridgeSchedule implements OnModuleInit { constructor(@InjectQueue(Queues.SyncBridge) private syncBridge: Queue) {} - @Cron(CronExpression.EVERY_3_HOURS) + @Cron(CronExpression.EVERY_5_MINUTES) async syncBridgeInfo() { this.logger.log('syncBridgeInfo'); await this.syncBridge.add(Tasks.fetchCbridge, null, { diff --git a/apps/canonical-bridge-server/src/module/token/token.processor.ts b/apps/canonical-bridge-server/src/module/token/token.processor.ts index f91b5367..e632efd2 100644 --- a/apps/canonical-bridge-server/src/module/token/token.processor.ts +++ b/apps/canonical-bridge-server/src/module/token/token.processor.ts @@ -1,6 +1,6 @@ import { InjectQueue, Processor, WorkerHost } from '@nestjs/bullmq'; import { Inject, Logger } from '@nestjs/common'; -import { CACHE_KEY, JOB_KEY, Queues, Tasks, TOKEN_REQUEST_LIMIT } from '@/common/constants'; +import { CACHE_KEY, JOB_KEY, Queues, Tasks, TIME, TOKEN_REQUEST_LIMIT } from '@/common/constants'; import { Job, Queue } from 'bullmq'; import { ITokenJob } from '@/module/token/token.interface'; import { Web3Service } from '@/shared/web3/web3.service'; @@ -57,7 +57,7 @@ export class TokenProcessor extends WorkerHost { return r; }, {}); - await this.cache.set(`${CACHE_KEY.LLAMA_CONFIG}`, config); + await this.cache.set(`${CACHE_KEY.LLAMA_CONFIG}`, config, TIME.MONTH); return config; } @@ -79,7 +79,7 @@ export class TokenProcessor extends WorkerHost { return r; }, {}); - await this.cache.set(`${CACHE_KEY.CMC_CONFIG}`, config); + await this.cache.set(`${CACHE_KEY.CMC_CONFIG}`, config, TIME.MONTH); return config; } @@ -101,7 +101,7 @@ export class TokenProcessor extends WorkerHost { {} as Record, ); - await this.cache.set(`${CACHE_KEY.PLATFORM_MAPPING}`, mapping); + await this.cache.set(`${CACHE_KEY.PLATFORM_MAPPING}`, mapping, TIME.MONTH); this.tokenService.syncCoingeckoTokens(coins, platforms); } diff --git a/apps/canonical-bridge-server/src/shared/web3/web3.service.ts b/apps/canonical-bridge-server/src/shared/web3/web3.service.ts index 9e589553..3b7ee373 100644 --- a/apps/canonical-bridge-server/src/shared/web3/web3.service.ts +++ b/apps/canonical-bridge-server/src/shared/web3/web3.service.ts @@ -60,35 +60,49 @@ export class Web3Service { } async getTransferConfigsForAll() { - const { data } = await this.httpService.axiosRef.get( - `${CBRIDGE_ENDPOINT}/v2/getTransferConfigsForAll`, - ); - - return data; + try { + const { data } = await this.httpService.axiosRef.get( + `${CBRIDGE_ENDPOINT}/v2/getTransferConfigsForAll`, + ); + return data; + } catch (e) { + console.error(`Failed to retrieve cBridge data at ${new Date().getTime()}`, e.message); + } } async getDebridgeChains() { - const { data } = await this.httpService.axiosRef.get<{ chains: IDebridgeChain[] }>( - `${DEBRIDGE_ENDPOINT}/supported-chains-info`, - ); + try { + const { data } = await this.httpService.axiosRef.get<{ chains: IDebridgeChain[] }>( + `${DEBRIDGE_ENDPOINT}/supported-chains-info`, + ); - return data; + return data; + } catch (e) { + console.error(`Failed to retrieve DeBridge chain data at ${new Date().getTime()}`, e.message); + } } async getDebridgeChainTokens(chainId: number) { - const { data } = await this.httpService.axiosRef.get<{ - tokens: Record; - }>(`${DEBRIDGE_ENDPOINT}/token-list?chainId=${chainId}`); + try { + const { data } = await this.httpService.axiosRef.get<{ + tokens: Record; + }>(`${DEBRIDGE_ENDPOINT}/token-list?chainId=${chainId}`); - return data; + return data; + } catch (e) { + console.error( + `Failed to retrieve DeBridge token data from ${chainId} at ${new Date().getTime()}`, + e.message, + ); + } } async getStargateConfigs() { - const { data } = await this.httpService.axiosRef.get( - `${STARGATE_ENDPOINT}`, - ); - const processedTokenList = []; try { + const { data } = await this.httpService.axiosRef.get( + `${STARGATE_ENDPOINT}`, + ); + const processedTokenList = []; const v2List = data.v2; v2List.forEach((token) => { const chainInfo = STARGATE_CHAIN_INFO.filter( @@ -98,17 +112,22 @@ export class Web3Service { processedTokenList.push({ ...token, endpointID: chainInfo[0].endpointID }); } }); + return processedTokenList; } catch (e) { - console.log(`Failed to retrieve Stargate API data at ${new Date().getTime()}`, e); + console.error(`Failed to retrieve Stargate API data at ${new Date().getTime()}`, e.message); } - return processedTokenList; } async getMesonConfigs() { - const { data } = await this.httpService.axiosRef.get<{ result: IMesonChain[] }>( - `${MESON_ENDPOINT}/limits`, - ); - return data; + try { + const { data } = await this.httpService.axiosRef.get<{ result: IMesonChain[] }>( + `${MESON_ENDPOINT}/limits`, + ); + return data; + } catch (e) { + console.log(`Failed to retrieve Meson API data at ${new Date().getTime()}`, e); + return []; + } } async getAssetPlatforms() { diff --git a/apps/canonical-bridge-ui/core/components/VConsole/index.tsx b/apps/canonical-bridge-ui/core/components/VConsole/index.tsx new file mode 100644 index 00000000..4a9a701b --- /dev/null +++ b/apps/canonical-bridge-ui/core/components/VConsole/index.tsx @@ -0,0 +1,15 @@ +import { useMemo } from 'react'; + +export function VConsole() { + useMemo(async () => { + if (typeof window !== 'undefined') { + try { + new (await import('vconsole')).default(); + } catch (err) { + // eslint-disable-next-line no-console + console.log(`Init vconsole error!`, err); + } + } + }, []); + return null; +} diff --git a/apps/canonical-bridge-ui/package.json b/apps/canonical-bridge-ui/package.json index 01771be5..4f86c081 100644 --- a/apps/canonical-bridge-ui/package.json +++ b/apps/canonical-bridge-ui/package.json @@ -21,14 +21,15 @@ "@solana/web3.js": "~1.95.4", "@tanstack/react-query": "~5.50.1", "@tronweb3/tronwallet-adapter-react-hooks": "~1.1.9", - "axios": "~1.6.8", - "next": "~14.1.1", + "axios": "~1.7.4", + "next": "~14.2.21", "pino-pretty": "~11.2.1", "polished": "~4.3.1", "react": "~18.3.1", "react-dom": "~18.3.1", "supports-color": "~9.4.0", "tronweb": "~6.0.0", + "vconsole": "~3.15.1", "viem": "~2.21.14", "wagmi": "^2" }, @@ -51,7 +52,6 @@ "eslint-config-next": "14.2.3", "lint-staged": "~13.0.3", "prettier": "~2.7.1", - "supports-color": "8.1.1", "typescript": "5.5.4" }, "lint-staged": { diff --git a/apps/canonical-bridge-ui/pages/_app.tsx b/apps/canonical-bridge-ui/pages/_app.tsx index 8f21c5c4..a42d224f 100644 --- a/apps/canonical-bridge-ui/pages/_app.tsx +++ b/apps/canonical-bridge-ui/pages/_app.tsx @@ -5,6 +5,7 @@ import { AppProps } from 'next/app'; import { ThemeProvider } from '@/core/components/ThemeProvider'; import { SvgDefs } from '@/core/components/icons/SvgDefs'; +import { VConsole } from '@/core/components/VConsole'; const queryClient = new QueryClient({ defaultOptions: { @@ -19,6 +20,7 @@ const queryClient = new QueryClient({ export default function App({ Component, ...restProps }: AppProps) { return ( <> + diff --git a/apps/canonical-bridge-ui/pages/_document.tsx b/apps/canonical-bridge-ui/pages/_document.tsx index ccd364da..6950a6a6 100644 --- a/apps/canonical-bridge-ui/pages/_document.tsx +++ b/apps/canonical-bridge-ui/pages/_document.tsx @@ -10,16 +10,6 @@ export default class Document extends NextDocument { - -