包含 webapp(Next.js 用户端)、webapp-back(Go 后端)、 antdesign(管理后台)、landingpage(营销落地页)、 数据库 SQL 和配置文件。
127 lines
3.4 KiB
TypeScript
127 lines
3.4 KiB
TypeScript
import { arbitrumSepolia, bscTestnet } from 'wagmi/chains'
|
||
import { getDynamicOverride } from './registry'
|
||
|
||
// 导入所有 ABI
|
||
import YTAssetFactory_ABI from './abis/YTAssetFactory.json'
|
||
import YTToken_ABI from './abis/YT-Token.json'
|
||
import USDY_ABI from './abis/USDY.json'
|
||
import YTLPToken_ABI from './abis/YTLPToken.json'
|
||
import YTPriceFeed_ABI from './abis/YTPriceFeed.json'
|
||
import YTVault_ABI from './abis/YTVault.json'
|
||
import YTPoolManager_ABI from './abis/YTPoolManager.json'
|
||
import YTRewardRouter_ABI from './abis/YTRewardRouter.json'
|
||
import lendingProxy_ABI from './abis/lendingProxy.json'
|
||
|
||
/**
|
||
* 合约名称枚举(用于类型安全)
|
||
* 地址全部从数据库动态加载,通过 /api/contracts 接口获取。
|
||
*/
|
||
export type ContractName =
|
||
| 'USDC'
|
||
| 'USDY'
|
||
| 'YT-A'
|
||
| 'YT-B'
|
||
| 'YT-C'
|
||
| 'YTLPToken'
|
||
| 'YTAssetFactory'
|
||
| 'YTVault'
|
||
| 'YTPriceFeed'
|
||
| 'YTPoolManager'
|
||
| 'YTRewardRouter'
|
||
| 'lendingProxy'
|
||
|
||
/**
|
||
* ABI 配置
|
||
*/
|
||
export const abis = {
|
||
// 代币
|
||
YTToken: YTToken_ABI,
|
||
USDY: USDY_ABI,
|
||
YTLPToken: YTLPToken_ABI,
|
||
|
||
// 核心合约
|
||
YTAssetFactory: YTAssetFactory_ABI,
|
||
YTVault: YTVault_ABI,
|
||
YTPriceFeed: YTPriceFeed_ABI,
|
||
YTPoolManager: YTPoolManager_ABI,
|
||
YTRewardRouter: YTRewardRouter_ABI,
|
||
|
||
// 借贷
|
||
lendingProxy: lendingProxy_ABI,
|
||
} as const
|
||
|
||
/**
|
||
* 获取合约地址(完全从动态注册表读取)
|
||
* 地址由后端 /api/contracts 接口提供(来源:system_contracts + assets 表)。
|
||
* 启动时由 useContractRegistry() 写入注册表。
|
||
* 未加载完成前返回 undefined,各 hook 通过 enabled: !!address 优雅处理。
|
||
*/
|
||
export function getContractAddress(
|
||
contractName: string,
|
||
chainId: number
|
||
): `0x${string}` | undefined {
|
||
return getDynamicOverride(contractName, chainId)
|
||
}
|
||
|
||
/**
|
||
* 获取合约 ABI
|
||
*/
|
||
export function getContractABI(contractName: keyof typeof abis) {
|
||
return abis[contractName]
|
||
}
|
||
|
||
/** 支持的网络 */
|
||
export const SUPPORTED_CHAINS = {
|
||
ARBITRUM_SEPOLIA: {
|
||
id: arbitrumSepolia.id,
|
||
name: 'Arbitrum Sepolia',
|
||
explorer: 'https://sepolia.arbiscan.io',
|
||
rpcUrl: 'https://sepolia-rollup.arbitrum.io/rpc',
|
||
},
|
||
BSC_TESTNET: {
|
||
id: bscTestnet.id,
|
||
name: 'BSC Testnet',
|
||
explorer: 'https://testnet.bscscan.com',
|
||
rpcUrl: 'https://bsc-testnet-rpc.publicnode.com',
|
||
},
|
||
} as const
|
||
|
||
/**
|
||
* 获取区块浏览器 URL
|
||
*/
|
||
export function getBlockExplorerUrl(chainId: number): string {
|
||
if (chainId === bscTestnet.id) {
|
||
return SUPPORTED_CHAINS.BSC_TESTNET.explorer
|
||
}
|
||
return SUPPORTED_CHAINS.ARBITRUM_SEPOLIA.explorer
|
||
}
|
||
|
||
/**
|
||
* 获取交易 URL
|
||
*/
|
||
export function getTxUrl(txHash: string, chainId?: number): string {
|
||
const explorer = chainId ? getBlockExplorerUrl(chainId) : SUPPORTED_CHAINS.BSC_TESTNET.explorer
|
||
return `${explorer}/tx/${txHash}`
|
||
}
|
||
|
||
/**
|
||
* 获取地址 URL
|
||
*/
|
||
export function getAddressUrl(address: string, chainId?: number): string {
|
||
const explorer = chainId ? getBlockExplorerUrl(chainId) : SUPPORTED_CHAINS.BSC_TESTNET.explorer
|
||
return `${explorer}/address/${address}`
|
||
}
|
||
|
||
/**
|
||
* 获取网络名称
|
||
*/
|
||
export function getNetworkName(chainId: number): string {
|
||
if (chainId === bscTestnet.id) {
|
||
return SUPPORTED_CHAINS.BSC_TESTNET.name
|
||
}
|
||
if (chainId === arbitrumSepolia.id) {
|
||
return SUPPORTED_CHAINS.ARBITRUM_SEPOLIA.name
|
||
}
|
||
return `Unknown Network (${chainId})`
|
||
}
|