From a3782b5dd92e141bd9d9a1ed9c7224003c96e8a6 Mon Sep 17 00:00:00 2001 From: c4605 Date: Wed, 14 May 2025 22:46:22 +0800 Subject: [PATCH] feat: fetch EVM token info from backend API --- scripts/printOnChainConfigs.ts | 11 +- .../apiHelpers/getEVMOnChainConfig.ts | 81 +++++ .../apiHelpers/getEVMSupportedRoutes.ts | 29 +- src/evmUtils/contractHelpers.ts | 278 ++---------------- src/evmUtils/evmClients.ts | 4 +- src/evmUtils/evmContractAddresses.ts | 138 +-------- src/sdkUtils/types.internal.ts | 7 +- src/utils/types/knownIds.ts | 160 +++++----- tsconfig.json | 3 +- 9 files changed, 227 insertions(+), 484 deletions(-) create mode 100644 src/evmUtils/apiHelpers/getEVMOnChainConfig.ts diff --git a/scripts/printOnChainConfigs.ts b/scripts/printOnChainConfigs.ts index 1c75d67..e32f476 100644 --- a/scripts/printOnChainConfigs.ts +++ b/scripts/printOnChainConfigs.ts @@ -1,6 +1,8 @@ import { BroSDK } from "../src" -import { getAllAddresses } from "../src/evmUtils/contractHelpers" +import { getEVMOnChainConfig } from "../src/evmUtils/apiHelpers/getEVMOnChainConfig" +import { getEVMSupportedRoutes } from "../src/evmUtils/apiHelpers/getEVMSupportedRoutes" import { getSDKContext } from "../src/lowlevelUnstableInfos" +import { props } from "../src/utils/promiseHelpers" import { _allKnownEVMChains } from "../src/utils/types/knownIds" async function print(matchers: { chain: string[] }): Promise { @@ -13,8 +15,11 @@ async function print(matchers: { chain: string[] }): Promise { await Promise.all( chainIds.map(chainId => - getAllAddresses(ctx, chainId).then(resp => { - console.log(chainId, resp?.onChainAddresses ?? "undefined") + props({ + config: getEVMOnChainConfig(ctx, chainId), + routes: getEVMSupportedRoutes(ctx, chainId), + }).then(resp => { + console.log(chainId, resp) return resp }), ), diff --git a/src/evmUtils/apiHelpers/getEVMOnChainConfig.ts b/src/evmUtils/apiHelpers/getEVMOnChainConfig.ts new file mode 100644 index 0000000..be6b5f8 --- /dev/null +++ b/src/evmUtils/apiHelpers/getEVMOnChainConfig.ts @@ -0,0 +1,81 @@ +import { EVMAddress } from "../../sdkUtils/types" +import { SDKGlobalContext } from "../../sdkUtils/types.internal" +import { requestAPI } from "../../utils/apiHelpers" +import { + _allKnownEVMMainnetChains, + _allKnownEVMTestnetChains, + KnownChainId, +} from "../../utils/types/knownIds" +import { EVMEndpointContract } from "../evmContractAddresses" + +export type EVMOnChainConfigForEVMChain = null | Partial< + Record +> + +export type EVMOnChainConfigByEVMChain = Partial< + Record +> + +export async function getEVMOnChainConfig( + sdkContext: SDKGlobalContext, + chainId: KnownChainId.EVMChain, +): Promise { + const config = await getEVMOnChainConfigByChainType( + sdkContext, + KnownChainId.isEVMMainnetChain(chainId) ? "mainnet" : "testnet", + ) + + return config[chainId] ?? null +} +export async function getEVMOnChainConfigByChainType( + sdkContext: SDKGlobalContext, + network: "mainnet" | "testnet", +): Promise { + if ( + sdkContext.evm.onChainConfigCache != null && + sdkContext.evm.onChainConfigCache.get(network) != null + ) { + return sdkContext.evm.onChainConfigCache.get(network)! + } + + const promise = _getEVMOnChainConfigByChainTypeImpl( + sdkContext, + network, + ).catch(err => { + const cachedPromise = sdkContext.evm.onChainConfigCache?.get(network) + if (promise === cachedPromise) { + sdkContext.evm.onChainConfigCache?.delete(network) + } + throw err + }) + sdkContext.evm.onChainConfigCache?.set(network, promise) + return promise +} + +async function _getEVMOnChainConfigByChainTypeImpl( + sdkContext: SDKGlobalContext, + network: "mainnet" | "testnet", +): Promise { + const evmChains = + network === "mainnet" + ? _allKnownEVMMainnetChains + : _allKnownEVMTestnetChains + + const resp = await requestAPI(sdkContext, { + method: "POST", + path: "/2024-10-01/evm/on-chain-config", + body: { chains: evmChains }, + }) + + if (resp == null) return {} + + return resp.config +} +type Server_Resp_EVMOnChainConfigByEVMChain = Partial< + Record< + /* XLink SDK EVMChain */ string, + null | Partial> + > +> diff --git a/src/evmUtils/apiHelpers/getEVMSupportedRoutes.ts b/src/evmUtils/apiHelpers/getEVMSupportedRoutes.ts index 01e3521..f31c519 100644 --- a/src/evmUtils/apiHelpers/getEVMSupportedRoutes.ts +++ b/src/evmUtils/apiHelpers/getEVMSupportedRoutes.ts @@ -1,14 +1,20 @@ +import { + EVMAddress, + StacksContractAddress, + TokenId, +} from "../../sdkUtils/types" +import { SDKGlobalContext } from "../../sdkUtils/types.internal" import { getStacksToken } from "../../stacksUtils/contractHelpers" import { requestAPI } from "../../utils/apiHelpers" import { BigNumber } from "../../utils/BigNumber" import { isNotNull } from "../../utils/typeHelpers" -import { KnownChainId, KnownTokenId } from "../../utils/types/knownIds" -import { StacksContractAddress } from "../../sdkUtils/types" -import { SDKGlobalContext } from "../../sdkUtils/types.internal" +import { createEVMToken, KnownChainId, KnownTokenId } from "../../utils/types/knownIds" +import { evmChainIdToKnownChainId } from "../evmClients" export interface EVMSupportedRoute { evmChain: KnownChainId.EVMChain evmToken: KnownTokenId.EVMToken + evmTokenAddress: EVMAddress stacksChain: KnownChainId.StacksChain stacksToken: KnownTokenId.StacksToken proxyStacksTokenContractAddress: null | StacksContractAddress @@ -71,8 +77,7 @@ async function _getEVMSupportedRoutes( const routes = await Promise.all( resp.routes.map(async (route): Promise => { - const evmChain = route.evmChain as KnownChainId.KnownChain - const evmToken = route.evmToken as KnownTokenId.KnownToken + const evmChain = evmChainIdToKnownChainId(BigInt(route.evmChainId)) const stacksToken = await getStacksToken( sdkContext, stacksChain, @@ -80,12 +85,15 @@ async function _getEVMSupportedRoutes( ) if (stacksToken == null) return null - if (!KnownChainId.isEVMChain(evmChain)) return null - if (!KnownTokenId.isEVMToken(evmToken)) return null + if (route.evmToken != null && !KnownTokenId.isEVMToken(route.evmToken)) { + return null + } + if (evmChain == null || !KnownChainId.isEVMChain(evmChain)) return null return { evmChain, - evmToken, + evmToken: route.evmToken ?? createEVMToken(evmChain, route.evmTokenAddress), + evmTokenAddress: route.evmTokenAddress, stacksChain, stacksToken, proxyStacksTokenContractAddress: route.proxyStacksTokenContractAddress, @@ -109,8 +117,9 @@ async function _getEVMSupportedRoutes( return routes.filter(isNotNull) } interface SupportedEVMBridgeRoute { - evmChain: string - evmToken: string + evmChainId: `${number}` + evmToken?: TokenId + evmTokenAddress: EVMAddress stacksTokenContractAddress: StacksContractAddress proxyStacksTokenContractAddress: null | StacksContractAddress pegOutFeeRate: `${number}` diff --git a/src/evmUtils/contractHelpers.ts b/src/evmUtils/contractHelpers.ts index bc39b37..4be2553 100644 --- a/src/evmUtils/contractHelpers.ts +++ b/src/evmUtils/contractHelpers.ts @@ -1,24 +1,16 @@ -import { Address, Client, isAddress, zeroAddress } from "viem" -import { readContract } from "viem/actions" -import { BigNumber, BigNumberSource } from "../utils/BigNumber" -import { - KnownChainId, - KnownTokenId, - _allKnownEVMTokens, -} from "../utils/types/knownIds" +import { Address, Client } from "viem" import { EVMAddress, EVMNativeCurrencyAddress, evmNativeCurrencyAddress, } from "../sdkUtils/types" import { SDKGlobalContext } from "../sdkUtils/types.internal" -import { BridgeConfigAbi } from "./contractAbi/bridgeConfig" -import { - EVMEndpointContract, - EVMOnChainAddresses, - evmContractAddresses, -} from "./evmContractAddresses" +import { BigNumber, BigNumberSource } from "../utils/BigNumber" +import { KnownChainId, KnownTokenId } from "../utils/types/knownIds" import { nativeCurrencyAddress } from "./addressHelpers" +import { getEVMOnChainConfig } from "./apiHelpers/getEVMOnChainConfig" +import { getEVMSupportedRoutes } from "./apiHelpers/getEVMSupportedRoutes" +import { EVMEndpointContract } from "./evmContractAddresses" const CONTRACT_COMMON_NUMBER_SCALE = 18 export const numberFromSolidityContractNumber = ( @@ -53,26 +45,23 @@ export async function getEVMContractCallInfo( timeLockContractAddress?: Address } > { - const addresses = await getAllAddresses(sdkContext, chainId) - if (addresses == null) return + const client = sdkContext.evm.viemClients[chainId] + if (client == null) return + + const config = await getEVMOnChainConfig(sdkContext, chainId) + if (config == null) return const bridgeEndpointContractAddress = - addresses.onChainAddresses?.[EVMEndpointContract.BridgeEndpoint] ?? - addresses.localAddresses[EVMEndpointContract.BridgeEndpoint] + config[EVMEndpointContract.BridgeEndpoint] if (bridgeEndpointContractAddress == null) return const nativeBridgeEndpointContractAddress = - addresses.onChainAddresses?.[EVMEndpointContract.NativeBridgeEndpoint] ?? - addresses.localAddresses[EVMEndpointContract.NativeBridgeEndpoint] - const registryContractAddress = - addresses.onChainAddresses?.[EVMEndpointContract.Registry] ?? - addresses.localAddresses[EVMEndpointContract.Registry] - const timeLockContractAddress = - addresses.onChainAddresses?.[EVMEndpointContract.TimeLock] ?? - addresses.localAddresses[EVMEndpointContract.TimeLock] + config[EVMEndpointContract.NativeBridgeEndpoint] + const registryContractAddress = config[EVMEndpointContract.Registry] + const timeLockContractAddress = config[EVMEndpointContract.TimeLock] return { - client: addresses.client, + client, bridgeEndpointContractAddress, nativeBridgeEndpointContractAddress, registryContractAddress, @@ -91,16 +80,19 @@ export async function getEVMTokenContractInfo( tokenContractAddress: Address | EVMNativeCurrencyAddress } > { - const addresses = await getAllAddresses(sdkContext, chainId) - if (addresses == null) return + const client = sdkContext.evm.viemClients[chainId] + if (client == null) return - const tokenContractAddress = - addresses.onChainAddresses?.[tokenId] ?? addresses.localAddresses[tokenId] + const routes = await getEVMSupportedRoutes(sdkContext, chainId) + if (routes == null) return + const tokenContractAddress = routes.find( + r => r.evmToken === tokenId, + )?.evmTokenAddress if (tokenContractAddress == null) return return { - client: addresses.client, + client, tokenContractAddress: tokenContractAddress === nativeCurrencyAddress ? evmNativeCurrencyAddress @@ -113,223 +105,11 @@ export async function getEVMToken( chain: KnownChainId.EVMChain, tokenAddress: EVMAddress, ): Promise { - const addresses = await getAllAddresses(sdkContext, chain) - if (addresses == null) return + const routes = await getEVMSupportedRoutes(sdkContext, chain) + if (routes == null) return tokenAddress = tokenAddress.toLowerCase() as EVMAddress - return Object.values(_allKnownEVMTokens).find( - token => - ( - addresses.onChainAddresses?.[token] ?? addresses.localAddresses?.[token] - )?.toLowerCase() === tokenAddress, - ) -} - -export async function getAllAddresses( - sdkContext: SDKGlobalContext, - chainId: KnownChainId.EVMChain, -): Promise< - | undefined - | { - client: Client - onChainAddresses?: EVMOnChainAddresses - localAddresses: EVMOnChainAddresses - } -> { - const client = sdkContext.evm.viemClients[chainId] - const localAddresses = evmContractAddresses[chainId] - const configContractAddress = localAddresses[EVMEndpointContract.BridgeConfig] - - if (client == null) return - - let onChainAddresses: undefined | EVMOnChainAddresses - if (configContractAddress != null) { - onChainAddresses = await getOnChainConfigs( - sdkContext, - chainId, - configContractAddress, - ) - } - - return { - client, - onChainAddresses, - localAddresses, - } -} - -const getOnChainConfigs = async ( - sdkContext: SDKGlobalContext, - chain: KnownChainId.EVMChain, - configContractAddress: Address, -): Promise => { - const cache = sdkContext.evm.onChainConfigCache - const cacheKey = `${chain}:${configContractAddress}` as const - - if (cache != null) { - const cachedPromise = cache.get(cacheKey) - if (cachedPromise != null) return cachedPromise - } - - const client = sdkContext.evm.viemClients[chain] - if (client == null) return - - const promise = _getOnChainConfigsImpl( - client, - chain, - configContractAddress, - ).catch(err => { - queueMicrotask(() => { - if (cache != null && promise === cache.get(cacheKey)) { - cache.delete(cacheKey) - } - }) - throw err - }) - if (cache != null) { - cache.set(cacheKey, promise) - } - return promise -} - -const _getOnChainConfigsImpl = async ( - client: Client, - chain: KnownChainId.EVMChain, - configContractAddress: Address, -): Promise => { - const configs = await readContract(client, { - abi: BridgeConfigAbi, - address: configContractAddress, - functionName: "getConfigs", - args: [ - [ - ONCHAIN_CONFIG_KEY.ENDPOINT, - ONCHAIN_CONFIG_KEY.REGISTRY, - ONCHAIN_CONFIG_KEY.TIMELOCK, - ONCHAIN_CONFIG_KEY.ENDPOINT_NATIVE, - ONCHAIN_CONFIG_KEY.TOKEN_ABTC, - ONCHAIN_CONFIG_KEY.TOKEN_ALEX, - ONCHAIN_CONFIG_KEY.TOKEN_ATALEX, - ONCHAIN_CONFIG_KEY.TOKEN_LISTX, - ONCHAIN_CONFIG_KEY.TOKEN_USDT, - ONCHAIN_CONFIG_KEY.TOKEN_BTC, - ONCHAIN_CONFIG_KEY.TOKEN_LUNR, - ONCHAIN_CONFIG_KEY.TOKEN_SKO, - ONCHAIN_CONFIG_KEY.TOKEN_SUSDT, - ONCHAIN_CONFIG_KEY.TOKEN_UBTC, - ONCHAIN_CONFIG_KEY.TOKEN_WUBTC, - ONCHAIN_CONFIG_KEY.TOKEN_DB20, - ONCHAIN_CONFIG_KEY.TOKEN_DOG, - ONCHAIN_CONFIG_KEY.TOKEN_STX, - ONCHAIN_CONFIG_KEY.TOKEN_TRUMP, - ONCHAIN_CONFIG_KEY.TOKEN_GHIBLICZ, - ONCHAIN_CONFIG_KEY.TOKEN_ETH, - ONCHAIN_CONFIG_KEY.TOKEN_SOL, - ONCHAIN_CONFIG_KEY.TOKEN_LINK, - ], - ], - }).catch(err => { - console.groupCollapsed( - `Failed to read on-chain configs from ${configContractAddress} (${chain})`, - ) - console.error(err) - console.groupEnd() - return null - }) - - if (configs == null) { - return {} - } - - const EVMToken = KnownTokenId.EVM - return { - [EVMEndpointContract.BridgeEndpoint]: maybeAddress(configs[0]), - [EVMEndpointContract.Registry]: maybeAddress(configs[1]), - [EVMEndpointContract.TimeLock]: maybeAddress(configs[2]), - [EVMEndpointContract.NativeBridgeEndpoint]: maybeAddress(configs[3]), - [EVMToken.aBTC]: maybeAddress(configs[4]), - [EVMToken.ALEX]: maybeAddress(configs[5]), - [EVMToken.vLiALEX]: maybeAddress(configs[6]), - [EVMToken.vLiSTX]: maybeAddress(configs[7]), - // prettier-ignore - [EVMToken.USDT]: - chain === KnownChainId.EVM.Ethereum || - chain === KnownChainId.EVM.BSC - ? maybeAddress(configs[8]) - : undefined, - // prettier-ignore - [EVMToken.USDC]: - chain === KnownChainId.EVM.Base || - chain === KnownChainId.EVM.Arbitrum - ? maybeAddress(configs[8]) - : undefined, - // prettier-ignore - [EVMToken.WBTC]: - chain === KnownChainId.EVM.Ethereum || - chain === KnownChainId.EVM.Arbitrum - ? maybeAddress(configs[9]) - : undefined, - // prettier-ignore - [EVMToken.BTCB]: - chain === KnownChainId.EVM.BSC - ? maybeAddress(configs[9]) - : undefined, - // prettier-ignore - [EVMToken.cbBTC]: - chain === KnownChainId.EVM.Base - ? maybeAddress(configs[9]) - : undefined, - [EVMToken.LUNR]: maybeAddress(configs[10]), - [EVMToken.SKO]: maybeAddress(configs[11]), - [EVMToken.sUSDT]: maybeAddress(configs[12]), - [EVMToken.uBTC]: maybeAddress(configs[13]), - [EVMToken.wuBTC]: maybeAddress(configs[14]), - [EVMToken.DB20]: maybeAddress(configs[15]), - [EVMToken.DOG]: maybeAddress(configs[16]), - [EVMToken.STX]: maybeAddress(configs[17]), - [EVMToken.TRUMP]: maybeAddress(configs[18]), - [EVMToken.GHIBLICZ]: maybeAddress(configs[19]), - [EVMToken.ETH]: maybeAddress(configs[20]), - [EVMToken.SOL]: maybeAddress(configs[21]), - [EVMToken.LINK]: maybeAddress(configs[22]), - } -} -function maybeAddress(value: string | null): Address | undefined { - if (value == null) return undefined - if (value === "") return undefined - if (!isAddress(value)) return undefined - if (value === zeroAddress) return undefined - return value -} - -enum ONCHAIN_CONFIG_KEY { - ENDPOINT = "ENDPOINT", - ENDPOINT_NATIVE = "ENDPOINT_NATIVE", - REGISTRY = "REGISTRY", - TIMELOCK = "TIMELOCK", - MULTISIG = "MULTISIG", - MIGRATE = "MIGRATE", - MIGRATE_BOB = "MIGRATE_BOB", - MIGRATE_BOB_L2 = "MIGRATE_BOB_L2", - MIGRATE_BOB_L2_S = "MIGRATE_BOB_L2_S", - - TOKEN_ABTC = "TOKEN_ABTC", - TOKEN_ALEX = "TOKEN_ALEX", - TOKEN_ATALEX = "TOKEN_ATALEX", - TOKEN_LISTX = "TOKEN_LISTX", - TOKEN_USDT = "TOKEN_USDT", - TOKEN_BTC = "TOKEN_BTC", - TOKEN_LUNR = "TOKEN_LUNR", - TOKEN_SKO = "TOKEN_SKO", - TOKEN_SUSDT = "TOKEN_SUSDT", - TOKEN_DB20 = "TOKEN_DB20", - TOKEN_DOG = "TOKEN_DOG", - TOKEN_UBTC = "TOKEN_UBTC", - TOKEN_WUBTC = "TOKEN_WUBTC", - TOKEN_STX = "TOKEN_STX", - TOKEN_TRUMP = "TOKEN_TRUMP", - TOKEN_GHIBLICZ = "TOKEN_GHIBLICZ", - TOKEN_ETH = "TOKEN_ETH", - TOKEN_SOL = "TOKEN_SOL", - TOKEN_LINK = "TOKEN_LINK", + return routes.find( + r => r.evmTokenAddress.toLowerCase() === tokenAddress.toLowerCase(), + )?.evmToken } diff --git a/src/evmUtils/evmClients.ts b/src/evmUtils/evmClients.ts index af06aeb..6d844ac 100644 --- a/src/evmUtils/evmClients.ts +++ b/src/evmUtils/evmClients.ts @@ -24,10 +24,12 @@ import { lorenzo, xLayer, } from "./evmChainInfos" -import { EVMChain } from "./evmContractAddresses" import { KnownChainId } from "../utils/types/knownIds" import { entries } from "../utils/objectHelper" +type EVMChain = KnownChainId.EVMChain +const EVMChain = KnownChainId.EVM + export const defaultEvmClients: Partial> = { [EVMChain.Ethereum]: createClient({ diff --git a/src/evmUtils/evmContractAddresses.ts b/src/evmUtils/evmContractAddresses.ts index ba487ba..94092bd 100644 --- a/src/evmUtils/evmContractAddresses.ts +++ b/src/evmUtils/evmContractAddresses.ts @@ -1,13 +1,7 @@ -import { Address } from "viem" -import { KnownChainId, KnownTokenId } from "../utils/types/knownIds" -import { nativeCurrencyAddress } from "./addressHelpers" - -export type EVMChain = KnownChainId.EVMChain -export const EVMChain = KnownChainId.EVM - -type EVMToken = KnownTokenId.EVMToken -const EVMToken = KnownTokenId.EVM +/** + * source: https://github.com/alexgo-io/alex-app/blob/3d842513272ba7478dcd6512bae9fa8d883d2cc5/functions/_handlers/services/getEVMOnChainConfig.evmAddressHelpers.ts#L5-L17 + */ export type EVMEndpointContract = | typeof EVMEndpointContract.BridgeEndpoint | typeof EVMEndpointContract.NativeBridgeEndpoint @@ -21,129 +15,3 @@ export namespace EVMEndpointContract { export const TimeLock = "TimeLock" export const Registry = "Registry" } - -export type EVMOnChainAddresses = Partial< - Record -> - -export const evmContractAddresses: Record = { - [EVMChain.Ethereum]: { - // https://t.me/c/1599543687/57297 - [EVMEndpointContract.BridgeConfig]: - "0x79d1C91053baceced5C796aB8a765E4d5aB38e8a", - }, - [EVMChain.BSC]: { - // https://t.me/c/1599543687/57297 - [EVMEndpointContract.BridgeConfig]: - "0x7062dB5dcaECDb355878a0BAB00A6941345D8711", - }, - [EVMChain.CoreDAO]: { - // https://t.me/c/1599543687/57297 - [EVMEndpointContract.BridgeConfig]: - "0x7062dB5dcaECDb355878a0BAB00A6941345D8711", - }, - [EVMChain.Bsquared]: { - // https://t.me/c/1599543687/57297 - [EVMEndpointContract.BridgeConfig]: - "0xf99f62475F50BE59393dbdc148E6627E4E88Fc24", - }, - [EVMChain.BOB]: { - // https://t.me/c/1599543687/57297 - [EVMEndpointContract.BridgeConfig]: - "0xf99f62475F50BE59393dbdc148E6627E4E88Fc24", - }, - [EVMChain.Bitlayer]: { - // https://t.me/c/1599543687/57297 - [EVMEndpointContract.BridgeConfig]: - "0xf99f62475F50BE59393dbdc148E6627E4E88Fc24", - }, - [EVMChain.Lorenzo]: { - // https://t.me/c/1599543687/57297 - [EVMEndpointContract.BridgeConfig]: - "0xf99f62475F50BE59393dbdc148E6627E4E88Fc24", - }, - [EVMChain.Merlin]: { - // https://t.me/c/1599543687/57297 - [EVMEndpointContract.BridgeConfig]: - "0xf99f62475F50BE59393dbdc148E6627E4E88Fc24", - }, - [EVMChain.AILayer]: { - // https://t.me/c/1599543687/57439 - [EVMEndpointContract.BridgeConfig]: - "0xf99f62475F50BE59393dbdc148E6627E4E88Fc24", - }, - [EVMChain.Mode]: { - // https://t.me/c/1599543687/57779 - [EVMEndpointContract.BridgeConfig]: - "0xf99f62475F50BE59393dbdc148E6627E4E88Fc24", - }, - [EVMChain.XLayer]: { - // https://t.me/c/1599543687/58186 - [EVMEndpointContract.BridgeConfig]: - "0xf99f62475F50BE59393dbdc148E6627E4E88Fc24", - }, - [EVMChain.Arbitrum]: { - // https://t.me/c/1599543687/58824 - [EVMEndpointContract.BridgeConfig]: - "0xf99f62475F50BE59393dbdc148E6627E4E88Fc24", - }, - [EVMChain.Aurora]: { - // https://t.me/c/1599543687/59145 - [EVMEndpointContract.BridgeConfig]: - "0xf99f62475F50BE59393dbdc148E6627E4E88Fc24", - }, - [EVMChain.Manta]: { - // https://t.me/c/1599543687/60487 - [EVMEndpointContract.BridgeConfig]: - "0xf99f62475F50BE59393dbdc148E6627E4E88Fc24", - }, - [EVMChain.Linea]: { - // https://t.me/c/1599543687/61611 - // https://t.me/c/1599543687/61873 - // https://t.me/c/1599543687/61734 - [EVMEndpointContract.BridgeConfig]: - "0xf99f62475F50BE59393dbdc148E6627E4E88Fc24", - }, - [EVMChain.Base]: { - // https://t.me/c/1599543687/64684 - [EVMEndpointContract.BridgeConfig]: - "0xf99f62475F50BE59393dbdc148E6627E4E88Fc24", - }, - - // testnet - [EVMChain.Sepolia]: { - [EVMEndpointContract.BridgeConfig]: - "0xE76e9e28ab8f7974F8bA24e4d83f9550BFe08d21", - }, - [EVMChain.BSCTestnet]: {}, - [EVMChain.CoreDAOTestnet]: { - [EVMEndpointContract.BridgeConfig]: - "0xdbe8BBA9C95140bc4F5e3480Fe6a958Cd1C7E6CC", - }, - [EVMChain.BlifeTestnet]: { - [EVMEndpointContract.BridgeConfig]: - "0x643F9D448BC0F8D365bd0DbEEcB5BC6A7b96d922", - [EVMToken.WBTC]: nativeCurrencyAddress, - }, - [EVMChain.BitboyTestnet]: { - [EVMEndpointContract.BridgeEndpoint]: - "0x3114671EefE856B32851DF4bc5b6278d5A74b86b", - [EVMToken.sUSDT]: "0x0d05e721F127AF25bDa0FE8836F1A2127028ad01", - [EVMToken.aBTC]: "0xEf33A9Afa67bad73b8df4beBD4C5Adc678D70528", - [EVMToken.ALEX]: "0x1DcD5BE312cc70c1e86218D2aC86EDDf79a851E4", - }, - [EVMChain.BeraTestnet]: { - // https://t.me/c/1599543687/60509 - // [EVMEndpointContract.BridgeConfig]: - // "0xBa175fDaB00e7FCF603f43bE8f68dB7f4de9f3A9", - // https://t.me/c/1599543687/60499 - [EVMEndpointContract.Registry]: - "0x6c74Bc8c54114b8Fed89686cC345eBCd838Fa0b9", - [EVMToken.aBTC]: "0xD66FEeb23463f99f56363a7de7acEd7d04F3356e", - [EVMToken.ALEX]: "0x3114671EefE856B32851DF4bc5b6278d5A74b86b", - [EVMToken.vLiALEX]: "0x8EcfD0a81c2965d16b78e86b8E4Dc71D0109e0e1", - [EVMToken.vLiSTX]: "0x2e3149230f98e7474AAAB3c1F6323BADfC4A66F8", - [EVMToken.sUSDT]: "0x8F4eB4dB1493D800Bf476137A25dC3c3cD58952C", - [EVMToken.wuBTC]: "0x391c193a3268aA0A93D76EAc85B88985b5CB92da", - }, -} diff --git a/src/sdkUtils/types.internal.ts b/src/sdkUtils/types.internal.ts index 835b6c5..386e517 100644 --- a/src/sdkUtils/types.internal.ts +++ b/src/sdkUtils/types.internal.ts @@ -1,6 +1,6 @@ import { Client } from "viem" +import { EVMOnChainConfigByEVMChain } from "../evmUtils/apiHelpers/getEVMOnChainConfig" import { EVMSupportedRoute } from "../evmUtils/apiHelpers/getEVMSupportedRoutes" -import { EVMOnChainAddresses } from "../evmUtils/evmContractAddresses" import type { BRC20SupportedRoute } from "../metaUtils/apiHelpers/getBRC20SupportedRoutes" import type { RunesSupportedRoute } from "../metaUtils/apiHelpers/getRunesSupportedRoutes" import { StacksTokenInfo } from "../stacksUtils/apiHelpers/getAllStacksTokens" @@ -9,7 +9,6 @@ import { pMemoizeImpl } from "../utils/pMemoize" import { GeneralCacheInterface } from "../utils/types/GeneralCacheInterface" import { KnownChainId } from "../utils/types/knownIds" import { TransferProphet } from "../utils/types/TransferProphet" -import { EVMAddress } from "./types" export interface SDKGlobalContextCache extends GeneralCacheInterface {} @@ -82,8 +81,8 @@ export interface SDKGlobalContext { Promise > onChainConfigCache?: SDKGlobalContextCache< - `${KnownChainId.EVMChain}:${EVMAddress}`, - Promise + "mainnet" | "testnet", + Promise > viemClients: Partial> } diff --git a/src/utils/types/knownIds.ts b/src/utils/types/knownIds.ts index 45126ad..72352c7 100644 --- a/src/utils/types/knownIds.ts +++ b/src/utils/types/knownIds.ts @@ -1,9 +1,36 @@ -import { ChainId, RuneIdCombined, TokenId } from "../../sdkUtils/types" +import { + ChainId, + EVMAddress, + RuneIdCombined, + TokenId, +} from "../../sdkUtils/types" import { checkNever } from "../typeHelpers" const chainId = (value: T): ChainId => value as any const tokenId = (value: T): TokenId => value as any +export const createStacksToken = ( + stacksTokenId: string, +): KnownTokenId.StacksToken => { + return `stx-token-${stacksTokenId}` as any +} +export const createBRC20Token = ( + brc20tick: string, +): KnownTokenId.BRC20Token => { + return `brc20-token-${brc20tick}` as any +} +export const createRunesToken = ( + runeId: RuneIdCombined, +): KnownTokenId.RunesToken => { + return `runes-token-${runeId}` as any +} +export const createEVMToken = ( + evmChain: KnownChainId.EVMChain, + evmTokenAddress: EVMAddress, +): KnownTokenId.EVMToken => { + return `evm-token-${evmTokenAddress}(${evmChain})` as any +} + /** * The `KnownTokenId` namespace provides types of tokens supported by the SDK, * including Bitcoin, EVM-compatible tokens, and Stacks tokens. @@ -29,7 +56,7 @@ export namespace KnownTokenId { /** A namespace that contains constants and types for Bitcoin tokens. */ export namespace Bitcoin { /** Represents the Bitcoin token ID (BTC). */ - export const BTC = tokenId("btc-btc") + export const BTC = tokenId("btc-token-btc") } /** This type defines known Bitcoin tokens. */ export type BitcoinToken = (typeof _allKnownBitcoinTokens)[number] @@ -40,144 +67,115 @@ export namespace KnownTokenId { /** This type defines known BRC20 tokens. */ export type BRC20Token = TokenId<"a brc20 token"> export function isBRC20Token(value: TokenId): value is BRC20Token { - return value.startsWith("brc20-") + return value.startsWith("brc20-token-") } /** This type defines known Runes tokens. */ export type RunesToken = TokenId<"a runes token"> export function isRunesToken(value: TokenId): value is RunesToken { - return value.startsWith("runes-") + return value.startsWith("runes-token-") } /** A namespace that contains constants and types for EVM-compatible tokens. */ export namespace EVM { // USD[X]s /** Represents the sUSDT token ID on EVM-compatible blockchains. */ - export const sUSDT = tokenId("evm-susdt") + export const sUSDT = tokenId("evm-token-susdt") /** Represents the USDT token ID on EVM-compatible blockchains. */ - export const USDT = tokenId("evm-usdt") + export const USDT = tokenId("evm-token-usdt") /** Represents the USDC token ID on EVM-compatible blockchains. */ - export const USDC = tokenId("evm-usdc") + export const USDC = tokenId("evm-token-usdc") // BTC /** Represents the aBTC token ID on EVM-compatible blockchains. */ - export const aBTC = tokenId("evm-abtc") + export const aBTC = tokenId("evm-token-abtc") /** Represents the WBTC token ID on EVM-compatible blockchains. */ - export const WBTC = tokenId("evm-wbtc") + export const WBTC = tokenId("evm-token-wbtc") /** Represents the BTCB token ID on EVM-compatible blockchains. */ - export const BTCB = tokenId("evm-btcb") + export const BTCB = tokenId("evm-token-btcb") /** Represents the cbBTC token ID on EVM-compatible blockchains. */ - export const cbBTC = tokenId("evm-cbbtc") + export const cbBTC = tokenId("evm-token-cbbtc") /** Represents the LUNR token ID on EVM-compatible blockchains. */ - export const LUNR = tokenId("evm-lunr") + export const LUNR = tokenId("evm-token-lunr") /** Represents the ALEX token ID on EVM-compatible blockchains. */ - export const ALEX = tokenId("evm-alex") + export const ALEX = tokenId("evm-token-alex") /** Represents the SKO token ID on EVM-compatible blockchains. */ - export const SKO = tokenId("evm-sko") + export const SKO = tokenId("evm-token-sko") /** Represents the vLiSTX token ID on EVM-compatible blockchains. */ - export const vLiSTX = tokenId("evm-vlistx") + export const vLiSTX = tokenId("evm-token-vlistx") /** Represents the vLiALEX token ID on EVM-compatible blockchains. */ - export const vLiALEX = tokenId("evm-vlialex") + export const vLiALEX = tokenId("evm-token-vlialex") /** Represents the uBTC token ID on EVM-compatible blockchains. */ - export const uBTC = tokenId("evm-ubtc") + export const uBTC = tokenId("evm-token-ubtc") /** Represents the wuBTC token ID on EVM-compatible blockchains. */ - export const wuBTC = tokenId("evm-wubtc") + export const wuBTC = tokenId("evm-token-wubtc") /** Represents the DB20 token ID on EVM-compatible blockchains. */ - export const DB20 = tokenId("evm-db20") + export const DB20 = tokenId("evm-token-db20") /** Represents the DOG token ID on EVM-compatible blockchains. */ - export const DOG = tokenId("evm-dog") + export const DOG = tokenId("evm-token-dog") /** Represents the STX token ID on EVM-compatible blockchains. */ - export const STX = tokenId("evm-stx") + export const STX = tokenId("evm-token-stx") /** Represents the TRUMP token ID on EVM-compatible blockchains. */ - export const TRUMP = tokenId("evm-trump") - export const GHIBLICZ = tokenId("evm-ghiblicz") - export const ETH = tokenId("evm-eth") - export const SOL = tokenId("evm-sol") - export const LINK = tokenId("evm-link") + export const TRUMP = tokenId("evm-token-trump") + export const GHIBLICZ = tokenId("evm-token-ghiblicz") + export const ETH = tokenId("evm-token-eth") + export const SOL = tokenId("evm-token-sol") + export const LINK = tokenId("evm-token-link") } - /** This type defines known tokens on EVM-compatible blockchains. */ - export type EVMToken = (typeof _allKnownEVMTokens)[number] + /** This type includes all known tokens on EVM-compatible blockchains. */ + export type EVMToken = + | TokenId<`a EVM token`> + | (typeof _allKnownEVMTokens)[number] export function isEVMToken(value: TokenId): value is EVMToken { - return _allKnownEVMTokens.includes(value as any) + return value.startsWith("evm-token-") } /** A namespace that contains constants and types for Stacks tokens. */ export namespace Stacks { /** Represents the sUSDT token ID on the Stacks blockchain. */ - export const sUSDT = tokenId("stx-susdt") + export const sUSDT = tokenId("stx-token-susdt") /** Represents the sLUNR token ID on the Stacks blockchain. */ - export const sLUNR = tokenId("stx-slunr") + export const sLUNR = tokenId("stx-token-slunr") /** Represents the aBTC token ID on the Stacks blockchain. */ - export const aBTC = tokenId("stx-abtc") + export const aBTC = tokenId("stx-token-abtc") /** Represents the ALEX token ID on the Stacks blockchain. */ - export const ALEX = tokenId("stx-alex") + export const ALEX = tokenId("stx-token-alex") /** Represents the sSKO token ID on the Stacks blockchain. */ - export const sSKO = tokenId("stx-ssko") + export const sSKO = tokenId("stx-token-ssko") /** Represents the vLiSTX token ID on the Stacks blockchain. */ - export const vLiSTX = tokenId("stx-vlistx") + export const vLiSTX = tokenId("stx-token-vlistx") /** Represents the vLiALEX token ID on the Stacks blockchain. */ - export const vLiALEX = tokenId("stx-vlialex") + export const vLiALEX = tokenId("stx-token-vlialex") /** Represents the vLiaBTC token ID on the Stacks blockchain. */ - export const vLiaBTC = tokenId("stx-vliabtc") + export const vLiaBTC = tokenId("stx-token-vliabtc") /** Represents the DB20 token ID on the Stacks blockchain. */ - export const DB20 = tokenId("stx-db20") + export const DB20 = tokenId("stx-token-db20") /** Represents the uBTC token ID on the Stacks blockchain. */ - export const uBTC = tokenId("stx-ubtc") + export const uBTC = tokenId("stx-token-ubtc") /** Represents the DOG token ID on the Stacks blockchain. */ - export const DOG = tokenId("stx-dog") + export const DOG = tokenId("stx-token-dog") /** Represents the STX token ID on the Stacks blockchain. */ - export const STX = tokenId("stx-stx") + export const STX = tokenId("stx-token-stx") /** Represents the TRUMP token ID on the Stacks blockchain. */ - export const TRUMP = tokenId("stx-trump") - export const GHIBLICZ = tokenId("stx-ghiblicz") - export const ETH = tokenId("stx-eth") - export const SOL = tokenId("stx-sol") - export const LINK = tokenId("stx-link") + export const TRUMP = tokenId("stx-token-trump") + export const GHIBLICZ = tokenId("stx-token-ghiblicz") + export const ETH = tokenId("stx-token-eth") + export const SOL = tokenId("stx-token-sol") + export const LINK = tokenId("stx-token-link") } - const _allKnownStacksTokens = [ - Stacks.sUSDT, - Stacks.sLUNR, - Stacks.aBTC, - Stacks.ALEX, - Stacks.sSKO, - Stacks.vLiSTX, - Stacks.vLiALEX, - Stacks.vLiaBTC, - Stacks.DB20, - Stacks.uBTC, - Stacks.DOG, - Stacks.STX, - Stacks.TRUMP, - Stacks.GHIBLICZ, - Stacks.ETH, - Stacks.SOL, - Stacks.LINK, - ] as const + export type StacksToken = | TokenId<`a Stacks token`> | (typeof _allKnownStacksTokens)[number] export function isStacksToken(value: TokenId): value is StacksToken { - return value.startsWith("stx-") + return value.startsWith("stx-token-") } } -export const createStacksToken = ( - stacksTokenId: string, -): KnownTokenId.StacksToken => { - return `stx-${stacksTokenId}` as any -} -export const createBRC20Token = ( - brc20tick: string, -): KnownTokenId.BRC20Token => { - return `brc20-${brc20tick}` as any -} -export const createRunesToken = ( - runeId: RuneIdCombined, -): KnownTokenId.RunesToken => { - return `runes-${runeId}` as any -} + export const _allKnownBitcoinTokens = Object.values(KnownTokenId.Bitcoin) +export const _allKnownStacksTokens = Object.values(KnownTokenId.Stacks) export const _allKnownEVMTokens = Object.values(KnownTokenId.EVM) /** diff --git a/tsconfig.json b/tsconfig.json index 56a1020..15855f3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,8 @@ "node_modules", "lib", "examples/cross-chain-swap", - "examples/bridgeFrom" + "examples/bridgeFrom", + "generated/docs" ], "compilerOptions": { "module": "esnext",