Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #205 from bnb-chain/feat/tokenApi1216
Browse files Browse the repository at this point in the history
feat: Load Meson from server api
Halibao-Lala authored Dec 19, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
2 parents 5789c21 + 1744cd7 commit 2a3b51b
Showing 13 changed files with 150 additions and 15 deletions.
2 changes: 2 additions & 0 deletions apps/canonical-bridge-server/.env.example
Original file line number Diff line number Diff line change
@@ -6,6 +6,8 @@ CMC_API_KEY=
CMC_API_ENDPOINT=https://pro-api.coinmarketcap.com
CBRIDGE_ENDPOINT=https://cbridge-prod2.celer.app
DEBRIDGE_ENDPOINT=https://deswap.debridge.finance/v1.0
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
7 changes: 7 additions & 0 deletions apps/canonical-bridge-server/src/common/constants/index.ts
Original file line number Diff line number Diff line change
@@ -8,6 +8,9 @@ export const CMC_API_ENDPOINT = process.env.CMC_API_ENDPOINT || 'https://pro-api
export const CBRIDGE_ENDPOINT = process.env.CBRIDGE_ENDPOINT || 'https://cbridge-prod2.celer.app';
export const DEBRIDGE_ENDPOINT =
process.env.DEBRIDGE_ENDPOINT || 'https://deswap.debridge.finance/v1.0';
export const STARGATE_ENDPOINT =
process.env.STARGATE_ENDPOINT || 'https://mainnet.stargate-api.com/v1/metadata?version=v2';
export const MESON_ENDPOINT = process.env.MESON_ENDPOINT || 'https://relayer.meson.fi/api/v1';
export const LLAMA_COINS_ENDPOINT = process.env.LLMA_COINS__ENDPOINT || 'https://coins.llama.fi';
export const COINGECKO_ENDPOINT = process.env.COINGECKO_ENDPOINT || 'https://api.coingecko.com/api';

@@ -28,6 +31,8 @@ export enum Tasks {
fetchLlamaPrice = 'fetchLlamaPrice',
fetchCbridge = 'fetchCbridge',
fetchDebridge = 'fetchDebridge',
fetchStargate = 'fetchStargate',
fetchMeson = 'fetchMeson',
cacheCmcConfig = 'cacheCmcConfig',
cacheLlamaConfig = 'cacheLlamaConfig',
}
@@ -43,6 +48,8 @@ export const CACHE_KEY = {
CMC_CRYPTO_TOKEN: 'cmc:token',
CBRIDGE_CONFIG: 'bridge:cbridge',
DEBRIDGE_CONFIG: 'bridge:debridge',
STARGATE_CONFIG: 'bridge:stargate',
MESON_CONFIG: 'bridge:meson',
CMC_CONFIG: 'cmc:config',
LLAMA_CONFIG: 'llama:config',
PLATFORM_MAPPING: 'llama:platform',
Original file line number Diff line number Diff line change
@@ -17,4 +17,14 @@ export class BridgeController {
getDeBridgeConfig() {
return this.cache.get(CACHE_KEY.DEBRIDGE_CONFIG);
}

@Get('/stargate')
getStargateConfig() {
return this.cache.get(CACHE_KEY.STARGATE_CONFIG);
}

@Get('/meson')
getMesonConfig() {
return this.cache.get(CACHE_KEY.MESON_CONFIG);
}
}
16 changes: 16 additions & 0 deletions apps/canonical-bridge-server/src/module/bridge/bridge.processor.ts
Original file line number Diff line number Diff line change
@@ -23,6 +23,10 @@ export class BridgeProcessor extends WorkerHost {
return this.fetchCBridge();
case Tasks.fetchDebridge:
return this.fetchDeBridge();
case Tasks.fetchMeson:
return this.fetchMeson();
case Tasks.fetchStargate:
return this.fetchStargate();
default:
}
}
@@ -49,4 +53,16 @@ export class BridgeProcessor extends WorkerHost {
if (!config) return;
await this.cache.set(`${CACHE_KEY.CBRIDGE_CONFIG}`, config);
}

async fetchStargate() {
const config = await this.web3Service.getStargateConfigs();
if (!config) return;
await this.cache.set(`${CACHE_KEY.STARGATE_CONFIG}`, config);
}

async fetchMeson() {
const config = await this.web3Service.getMesonConfigs();
if (!config) return;
await this.cache.set(`${CACHE_KEY.MESON_CONFIG}`, config);
}
}
Original file line number Diff line number Diff line change
@@ -21,6 +21,14 @@ export class BridgeSchedule implements OnModuleInit {
jobId: Tasks.fetchDebridge,
removeOnComplete: true,
});
await this.syncBridge.add(Tasks.fetchStargate, null, {
jobId: Tasks.fetchStargate,
removeOnComplete: true,
});
await this.syncBridge.add(Tasks.fetchMeson, null, {
jobId: Tasks.fetchMeson,
removeOnComplete: true,
});
}

async onModuleInit() {
59 changes: 59 additions & 0 deletions apps/canonical-bridge-server/src/shared/web3/web3.interface.ts
Original file line number Diff line number Diff line change
@@ -137,3 +137,62 @@ export interface ICoinPrice {
price: number;
decimals: number;
}

export interface IStargateBridgeTokenInfo {
stargateType: string;
address: `0x${string}`;
token: {
address: `0x${string}`;
decimals: number;
symbol: string;
};
lpToken: {
address: `0x${string}`;
decimals: number;
symbol: string;
};
farm: {
stargateStaking: {
address: `0x${string}`;
rewardTokens: [
{
address: `0x${string}`;
decimals: number;
symbol: string;
},
{
address: `0x${string}`;
decimals: number;
symbol: string;
},
];
};
};
id: string;
assetId: string;
chainKey: string;
chainName: string;
tokenMessaging: `0x${string}`;
sharedDecimals: number;
}
export interface IStargateTokenList {
v1: IStargateBridgeTokenInfo[];
v2: IStargateBridgeTokenInfo[];
}

export interface IMesonToken {
id: string;
symbol: string;
name: string;
decimals: number;
addr?: string;
min: string;
max: string;
}
export interface IMesonChain {
id: string;
name: string;
chainId: string;
address: string;
tokens: IMesonToken[];
}
18 changes: 18 additions & 0 deletions apps/canonical-bridge-server/src/shared/web3/web3.service.ts
Original file line number Diff line number Diff line change
@@ -9,6 +9,8 @@ import {
ICryptoCurrencyQuoteEntity,
IDebridgeChain,
IDebridgeToken,
IMesonChain,
IStargateTokenList,
ITransferConfigsForAll,
} from '@/shared/web3/web3.interface';
import {
@@ -17,6 +19,8 @@ import {
CMC_API_KEY,
COINGECKO_ENDPOINT,
DEBRIDGE_ENDPOINT,
STARGATE_ENDPOINT,
MESON_ENDPOINT,
LLAMA_COINS_ENDPOINT,
TOKEN_REQUEST_LIMIT,
} from '@/common/constants';
@@ -78,6 +82,20 @@ export class Web3Service {
return data;
}

async getStargateConfigs() {
const { data } = await this.httpService.axiosRef.get<IStargateTokenList>(
`${STARGATE_ENDPOINT}`,
);
return data;
}

async getMesonConfigs() {
const { data } = await this.httpService.axiosRef.get<{ result: IMesonChain[] }>(
`${MESON_ENDPOINT}/limits`,
);
return data;
}

async getAssetPlatforms() {
const { data } = await this.httpService.axiosRef.get<IAssetPlatform[]>(
`${COINGECKO_ENDPOINT}/v3/asset_platforms`,
Original file line number Diff line number Diff line change
@@ -3,26 +3,28 @@ import {
ICBridgeTransferConfig,
IDeBridgeTransferConfig,
ITransferConfig,
IMesonChain,
} from '@bnb-chain/canonical-bridge-widget';
import axios from 'axios';

import { env } from '@/core/env';
import stargateConfig from '@/token-config/mainnet/stargate/config.json';
import layerZeroConfig from '@/token-config/mainnet/layerZero/config.json';
import mesonConfig from '@/token-config/mainnet/meson/config.json';

export function useTransferConfig() {
const [transferConfig, setTransferConfig] = useState<ITransferConfig>();

useEffect(() => {
const initConfig = async () => {
const [cBridgeRes, deBridgeRes] = await Promise.all([
const [cBridgeRes, deBridgeRes, MesonRes] = await Promise.all([
axios.get<{ data: ICBridgeTransferConfig }>(`${env.SERVER_ENDPOINT}/api/bridge/cbridge`),
axios.get<{ data: IDeBridgeTransferConfig }>(`${env.SERVER_ENDPOINT}/api/bridge/debridge`),
axios.get<{ data: IMesonChain[] }>(`${env.SERVER_ENDPOINT}/api/bridge/meson`),
]);

const cBridgeConfig = cBridgeRes.data.data;
const deBridgeConfig = handleDeBridgeConfig(deBridgeRes.data.data);
const mesonConfig = MesonRes.data.data;

const transferConfig: ITransferConfig = {
defaultSelectedInfo: {
@@ -176,7 +178,7 @@ export function useTransferConfig() {
bridgedTokenGroups: [],
},
meson: {
config: mesonConfig.result as any,
config: mesonConfig,
exclude: {
chains: [],
tokens: { 42161: ['SOL'] },
4 changes: 4 additions & 0 deletions packages/canonical-bridge-widget/src/core/constants/index.ts
Original file line number Diff line number Diff line change
@@ -51,3 +51,7 @@ export const MIN_SOL_TO_ENABLED_TX = 0.05;
export const EVM_NATIVE_TOKEN_ADDRESS = '0x0000000000000000000000000000000000000000';

export const SOLANA_NATIVE_TOKEN_ADDRESS = '11111111111111111111111111111111';

export const NON_EVM_CHAIN_ID_MAP = {
tron: 728126428,
};
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ import { BridgeType } from '@bnb-chain/canonical-bridge-sdk';
import { BaseAdapter, ITransferTokenPair } from '@/modules/aggregator/shared/BaseAdapter';
import { IMesonChain, IMesonToken } from '@/modules/aggregator/adapters/meson/types';
import { isNativeToken } from '@/core/utils/address';
import { NON_EVM_CHAIN_ID_MAP } from '@/core/constants';

// const SUPPORTED_CHAIN_IDS = [56, 97, 3448148188, 728126428];
// const SUPPORTED_TOKENS = ['USDT', 'USDC'];
@@ -24,7 +25,11 @@ export class MesonAdapter extends BaseAdapter<IMesonChain[], IMesonChain, IMeson

const chainMap = new Map<number, IMesonChain>();
filteredChains.forEach((chain) => {
chainMap.set(Number(chain.chainId), chain);
const chainId =
chain.chainId === 'tron' ? NON_EVM_CHAIN_ID_MAP['tron'] : Number(chain.chainId);
if (!!Number(chainId)) {
chainMap.set(chainId, chain);
}
});

this.chains = filteredChains;
@@ -38,13 +43,13 @@ export class MesonAdapter extends BaseAdapter<IMesonChain[], IMesonChain, IMeson
const symbolMap = new Map<number, Map<string, IMesonToken>>();

chains.forEach((chain) => {
const chainId = Number(chain.chainId);
const chainId = chain.chainId === 'tron' ? 728126428 : Number(chain.chainId);

const filteredTokens = chain.tokens.filter((token) => {
const isExcludedToken = this.checkIsExcludedToken({
excludedList: this.excludedTokens?.[chainId],
tokenSymbol: token?.id?.toUpperCase(),
tokenAddress: token.addr,
tokenSymbol: token?.symbol?.toUpperCase(),
tokenAddress: token.addr ?? '0x0000000000000000000000000000000000000000',
});
// native token transfer requires smart contract deployment. Ignore it for now.
return !isExcludedToken && !isNativeToken(token.addr);
@@ -54,7 +59,7 @@ export class MesonAdapter extends BaseAdapter<IMesonChain[], IMesonChain, IMeson
symbolMap.set(chainId, new Map<string, IMesonToken>());

filteredTokens.forEach((token) => {
symbolMap.get(chainId)?.set(token.id?.toUpperCase(), token);
symbolMap.get(chainId)?.set(token.symbol?.toUpperCase(), token);
});

tokenMap.set(chainId, filteredTokens);
@@ -80,7 +85,7 @@ export class MesonAdapter extends BaseAdapter<IMesonChain[], IMesonChain, IMeson
const toToken = this.getToToken({
fromChainId: Number(fromChain.chainId),
toChainId: Number(toChain.chainId),
fromTokenSymbol: fromToken.id?.toUpperCase(),
fromTokenSymbol: fromToken.symbol?.toUpperCase(),
});

if (toToken) {
@@ -92,7 +97,7 @@ export class MesonAdapter extends BaseAdapter<IMesonChain[], IMesonChain, IMeson
fromTokenAddress: fromToken.addr,
toTokenAddress: toToken.addr,
};
transferableTokenMap.set(fromToken.id?.toUpperCase(), tokenPair);
transferableTokenMap.set(fromToken.symbol?.toUpperCase(), tokenPair);
}
});

@@ -126,14 +131,14 @@ export class MesonAdapter extends BaseAdapter<IMesonChain[], IMesonChain, IMeson

public getTokenInfo({ chainId, token }: { chainId: number; token: IMesonToken }) {
return {
name: (token as any).id?.toUpperCase(), // TODO
symbol: token.id.toUpperCase(),
name: token.name?.toUpperCase(), // TODO
symbol: token.symbol.toUpperCase(),
address: token.addr ?? '0x0000000000000000000000000000000000000000',
decimals: token.decimals,
...this.getTokenDisplaySymbolAndIcon({
chainId,
tokenAddress: token.addr ?? '0x0000000000000000000000000000000000000000',
defaultSymbol: token.id.toUpperCase(),
defaultSymbol: token.symbol.toUpperCase(),
}),
};
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export interface IMesonToken {
id: string;
symbol: string;
name: string;
addr: string;
decimals: number;
min: string;
Original file line number Diff line number Diff line change
@@ -3,3 +3,4 @@ export * from '@/modules/aggregator/adapters/cBridge/types';
export * from '@/modules/aggregator/adapters/deBridge/types';
export * from '@/modules/aggregator/adapters/layerZero/types';
export * from '@/modules/aggregator/adapters/stargate/types';
export * from '@/modules/aggregator/adapters/meson/types';
Original file line number Diff line number Diff line change
@@ -434,12 +434,13 @@ export function TransferButton({
const isValidToken = await bridgeSDK.meson.validateMesonToken({
fromChainId: fromChain?.id,
toChainId: toChain?.id,
fromTokenAddress: selectedToken.meson?.raw?.addr as `0x${string}`,
fromTokenAddress:
selectedToken.meson?.raw?.addr ?? '0x0000000000000000000000000000000000000000',
fromTokenSymbol: selectedToken.meson?.raw?.id as string,
fromTokenDecimals: selectedToken.meson?.raw?.decimals as number,
fromChainType: fromChain?.chainType,
toChainType: toChain?.chainType,
toTokenAddress: toToken?.meson?.raw?.addr as `0x${string}`,
toTokenAddress: toToken?.meson?.raw?.addr ?? '0x0000000000000000000000000000000000000000',
toTokenSymbol: toToken?.meson?.raw?.id,
toTokenDecimals: toToken?.meson?.raw?.decimals,
amount: Number(sendValue),

0 comments on commit 2a3b51b

Please sign in to comment.