initfmfijirfri
This commit is contained in:
@@ -15,6 +15,7 @@ import relayProxyRoutes from './routes/relay-proxy.routes';
|
|||||||
import tronProxyRoutes from './routes/tron-proxy.routes';
|
import tronProxyRoutes from './routes/tron-proxy.routes';
|
||||||
import btcProxyRoutes from './routes/btc-proxy.routes';
|
import btcProxyRoutes from './routes/btc-proxy.routes';
|
||||||
import pricesRoutes from './routes/prices.routes';
|
import pricesRoutes from './routes/prices.routes';
|
||||||
|
import tokensRoutes from './routes/tokens.routes';
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
@@ -109,6 +110,9 @@ app.use('/api/btc', ...protect, mutateLimiter, btcProxyRoutes);
|
|||||||
// USD-цены (CoinGecko + KeyDB cache). GET-only, auth required, max 50 symbols.
|
// USD-цены (CoinGecko + KeyDB cache). GET-only, auth required, max 50 symbols.
|
||||||
app.use('/api/prices', ...protect, mutateLimiter, pricesRoutes);
|
app.use('/api/prices', ...protect, mutateLimiter, pricesRoutes);
|
||||||
|
|
||||||
|
// Token registry — всех известных contracts/mints по всем chain'ам. GET-only, auth required.
|
||||||
|
app.use('/api/tokens', ...protect, mutateLimiter, tokensRoutes);
|
||||||
|
|
||||||
// 404 для всего что не сматчилось выше — единый JSON-ответ, не express default text
|
// 404 для всего что не сматчилось выше — единый JSON-ответ, не express default text
|
||||||
app.use((_req, res) => {
|
app.use((_req, res) => {
|
||||||
res.status(404).json({ success: false, error: 'Not found' });
|
res.status(404).json({ success: false, error: 'Not found' });
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import type { ChainCode } from './address-validators';
|
|||||||
|
|
||||||
export interface EvmToken {
|
export interface EvmToken {
|
||||||
symbol: string;
|
symbol: string;
|
||||||
|
name: string;
|
||||||
contractAddress: string;
|
contractAddress: string;
|
||||||
decimals: number;
|
decimals: number;
|
||||||
coingeckoId?: string;
|
coingeckoId?: string;
|
||||||
@@ -17,6 +18,7 @@ export interface EvmToken {
|
|||||||
|
|
||||||
export interface TrxToken {
|
export interface TrxToken {
|
||||||
symbol: string;
|
symbol: string;
|
||||||
|
name: string;
|
||||||
contractAddress: string; // T...base58
|
contractAddress: string; // T...base58
|
||||||
decimals: number;
|
decimals: number;
|
||||||
coingeckoId?: string;
|
coingeckoId?: string;
|
||||||
@@ -24,11 +26,23 @@ export interface TrxToken {
|
|||||||
|
|
||||||
export interface SolToken {
|
export interface SolToken {
|
||||||
symbol: string;
|
symbol: string;
|
||||||
|
name: string;
|
||||||
mint: string; // SPL mint pubkey (base58)
|
mint: string; // SPL mint pubkey (base58)
|
||||||
decimals: number;
|
decimals: number;
|
||||||
coingeckoId?: string;
|
coingeckoId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flat shape для GET /api/tokens.
|
||||||
|
* Native coins имеют contract = null.
|
||||||
|
*/
|
||||||
|
export interface TokenListEntry {
|
||||||
|
chain: ChainCode;
|
||||||
|
symbol: string;
|
||||||
|
name: string;
|
||||||
|
contract: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CoinGecko coin IDs для native монет каждой chain.
|
* CoinGecko coin IDs для native монет каждой chain.
|
||||||
* Используется в `price-oracle.service.ts` для USD-цен в `/balance`.
|
* Используется в `price-oracle.service.ts` для USD-цен в `/balance`.
|
||||||
@@ -41,45 +55,102 @@ export const NATIVE_COINGECKO_IDS: Record<ChainCode, string> = {
|
|||||||
SOL: 'solana',
|
SOL: 'solana',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Native coin human names + tickers. На BSC ticker = "BNB" (не "BSC").
|
||||||
|
* Используется в GET /api/tokens для native entries.
|
||||||
|
*/
|
||||||
|
export const NATIVE_NAMES: Record<ChainCode, string> = {
|
||||||
|
BTC: 'Bitcoin',
|
||||||
|
ETH: 'Ethereum',
|
||||||
|
BSC: 'BNB',
|
||||||
|
TRX: 'Tron',
|
||||||
|
SOL: 'Solana',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const NATIVE_SYMBOLS: Record<ChainCode, string> = {
|
||||||
|
BTC: 'BTC',
|
||||||
|
ETH: 'ETH',
|
||||||
|
BSC: 'BNB', // ticker отличается от chain code
|
||||||
|
TRX: 'TRX',
|
||||||
|
SOL: 'SOL',
|
||||||
|
};
|
||||||
|
|
||||||
export const ETH_TOKENS: EvmToken[] = [
|
export const ETH_TOKENS: EvmToken[] = [
|
||||||
{ symbol: 'USDT', contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7', decimals: 6, coingeckoId: 'tether' },
|
{ symbol: 'USDT', name: 'Tether USD', contractAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7', decimals: 6, coingeckoId: 'tether' },
|
||||||
{ symbol: 'USDC', contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', decimals: 6, coingeckoId: 'usd-coin' },
|
{ symbol: 'USDC', name: 'USD Coin', contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', decimals: 6, coingeckoId: 'usd-coin' },
|
||||||
{ symbol: 'DAI', contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F', decimals: 18, coingeckoId: 'dai' },
|
{ symbol: 'DAI', name: 'Dai Stablecoin', contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F', decimals: 18, coingeckoId: 'dai' },
|
||||||
{ symbol: 'WBTC', contractAddress: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', decimals: 8, coingeckoId: 'wrapped-bitcoin' },
|
{ symbol: 'WBTC', name: 'Wrapped Bitcoin', contractAddress: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', decimals: 8, coingeckoId: 'wrapped-bitcoin' },
|
||||||
{ symbol: 'LINK', contractAddress: '0x514910771AF9Ca656af840dff83E8264EcF986CA', decimals: 18, coingeckoId: 'chainlink' },
|
{ symbol: 'LINK', name: 'Chainlink', contractAddress: '0x514910771AF9Ca656af840dff83E8264EcF986CA', decimals: 18, coingeckoId: 'chainlink' },
|
||||||
{ symbol: 'UNI', contractAddress: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984', decimals: 18, coingeckoId: 'uniswap' },
|
{ symbol: 'UNI', name: 'Uniswap', contractAddress: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984', decimals: 18, coingeckoId: 'uniswap' },
|
||||||
];
|
];
|
||||||
|
|
||||||
export const BSC_TOKENS: EvmToken[] = [
|
export const BSC_TOKENS: EvmToken[] = [
|
||||||
{ symbol: 'USDT', contractAddress: '0x55d398326f99059fF775485246999027B3197955', decimals: 18, coingeckoId: 'tether' },
|
{ symbol: 'USDT', name: 'Tether USD', contractAddress: '0x55d398326f99059fF775485246999027B3197955', decimals: 18, coingeckoId: 'tether' },
|
||||||
{ symbol: 'USDC', contractAddress: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d', decimals: 18, coingeckoId: 'usd-coin' },
|
{ symbol: 'USDC', name: 'USD Coin', contractAddress: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d', decimals: 18, coingeckoId: 'usd-coin' },
|
||||||
{ symbol: 'DOGE', contractAddress: '0xbA2aE424d960c26247Dd6c32edC70B295c744C43', decimals: 8, coingeckoId: 'dogecoin' },
|
{ symbol: 'DOGE', name: 'Dogecoin', contractAddress: '0xbA2aE424d960c26247Dd6c32edC70B295c744C43', decimals: 8, coingeckoId: 'dogecoin' },
|
||||||
{ symbol: 'WBNB', contractAddress: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', decimals: 18, coingeckoId: 'wbnb' },
|
{ symbol: 'WBNB', name: 'Wrapped BNB', contractAddress: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', decimals: 18, coingeckoId: 'wbnb' },
|
||||||
{ symbol: 'BUSD', contractAddress: '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', decimals: 18, coingeckoId: 'binance-usd' },
|
{ symbol: 'BUSD', name: 'Binance USD', contractAddress: '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', decimals: 18, coingeckoId: 'binance-usd' },
|
||||||
];
|
];
|
||||||
|
|
||||||
export const TRX_TOKENS: TrxToken[] = [
|
export const TRX_TOKENS: TrxToken[] = [
|
||||||
{ symbol: 'USDT', contractAddress: 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t', decimals: 6, coingeckoId: 'tether' },
|
{ symbol: 'USDT', name: 'Tether USD', contractAddress: 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t', decimals: 6, coingeckoId: 'tether' },
|
||||||
{ symbol: 'USDC', contractAddress: 'TEkxiTehnzSmSe2XqrBj4w32RUN966rdz8', decimals: 6, coingeckoId: 'usd-coin' },
|
{ symbol: 'USDC', name: 'USD Coin', contractAddress: 'TEkxiTehnzSmSe2XqrBj4w32RUN966rdz8', decimals: 6, coingeckoId: 'usd-coin' },
|
||||||
];
|
];
|
||||||
|
|
||||||
export const SOL_TOKENS: SolToken[] = [
|
export const SOL_TOKENS: SolToken[] = [
|
||||||
{ symbol: 'USDT', mint: 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB', decimals: 6, coingeckoId: 'tether' },
|
{ symbol: 'USDT', name: 'Tether USD', mint: 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB', decimals: 6, coingeckoId: 'tether' },
|
||||||
{ symbol: 'USDC', mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', decimals: 6, coingeckoId: 'usd-coin' },
|
{ symbol: 'USDC', name: 'USD Coin', mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', decimals: 6, coingeckoId: 'usd-coin' },
|
||||||
{ symbol: 'PUMP', mint: 'pumpCmXqMfrsAkQ5r49WcJnRayYRqmXz6ae8H7H9Dfn', decimals: 6, coingeckoId: 'pump-fun' },
|
{ symbol: 'PUMP', name: 'Pump.fun', mint: 'pumpCmXqMfrsAkQ5r49WcJnRayYRqmXz6ae8H7H9Dfn', decimals: 6, coingeckoId: 'pump-fun' },
|
||||||
{ symbol: 'JUP', mint: 'JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN', decimals: 6, coingeckoId: 'jupiter-exchange-solana' },
|
{ symbol: 'JUP', name: 'Jupiter', mint: 'JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN', decimals: 6, coingeckoId: 'jupiter-exchange-solana' },
|
||||||
{ symbol: 'WIF', mint: 'EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm', decimals: 6, coingeckoId: 'dogwifcoin' },
|
{ symbol: 'WIF', name: 'dogwifhat', mint: 'EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm', decimals: 6, coingeckoId: 'dogwifcoin' },
|
||||||
{ symbol: 'POPCAT', mint: '7GCihgDB8fe6KNjn2MYtkzZcRjQy3t9GHdC8uHYmW2hr', decimals: 9, coingeckoId: 'popcat' },
|
{ symbol: 'POPCAT', name: 'Popcat', mint: '7GCihgDB8fe6KNjn2MYtkzZcRjQy3t9GHdC8uHYmW2hr', decimals: 9, coingeckoId: 'popcat' },
|
||||||
{ symbol: 'TRUMP', mint: '6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', decimals: 6, coingeckoId: 'official-trump' },
|
{ symbol: 'TRUMP', name: 'Official Trump', mint: '6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', decimals: 6, coingeckoId: 'official-trump' },
|
||||||
{ symbol: 'PYTH', mint: 'HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3', decimals: 6, coingeckoId: 'pyth-network' },
|
{ symbol: 'PYTH', name: 'Pyth Network', mint: 'HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3', decimals: 6, coingeckoId: 'pyth-network' },
|
||||||
{ symbol: 'JTO', mint: 'jtojtomepa8beP8AuQc6eXt5FriJwfFMwQx2v2f9mCL', decimals: 9, coingeckoId: 'jito-governance-token' },
|
{ symbol: 'JTO', name: 'Jito', mint: 'jtojtomepa8beP8AuQc6eXt5FriJwfFMwQx2v2f9mCL', decimals: 9, coingeckoId: 'jito-governance-token' },
|
||||||
{ symbol: 'W', mint: '85VBFQZC9TZkfaptBWjvUw7YbZjy52A6mjtPGjstQAmQ', decimals: 6, coingeckoId: 'wormhole' },
|
{ symbol: 'W', name: 'Wormhole', mint: '85VBFQZC9TZkfaptBWjvUw7YbZjy52A6mjtPGjstQAmQ', decimals: 6, coingeckoId: 'wormhole' },
|
||||||
{ symbol: 'BONK', mint: 'DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263', decimals: 5, coingeckoId: 'bonk' },
|
{ symbol: 'BONK', name: 'Bonk', mint: 'DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263', decimals: 5, coingeckoId: 'bonk' },
|
||||||
{ symbol: 'ORCA', mint: 'orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE', decimals: 6, coingeckoId: 'orca' },
|
{ symbol: 'ORCA', name: 'Orca', mint: 'orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE', decimals: 6, coingeckoId: 'orca' },
|
||||||
{ symbol: 'PENGU', mint: '2zMMhcVQEXDtdE6vsFS7S7D5oUodfJHE8vd1gnBouauv', decimals: 6, coingeckoId: 'pudgy-penguins' },
|
{ symbol: 'PENGU', name: 'Pudgy Penguins', mint: '2zMMhcVQEXDtdE6vsFS7S7D5oUodfJHE8vd1gnBouauv', decimals: 6, coingeckoId: 'pudgy-penguins' },
|
||||||
{ symbol: 'RAY', mint: '4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R', decimals: 6, coingeckoId: 'raydium' },
|
{ symbol: 'RAY', name: 'Raydium', mint: '4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R', decimals: 6, coingeckoId: 'raydium' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const ALL_CHAINS_ORDERED: ChainCode[] = ['ETH', 'BSC', 'BTC', 'TRX', 'SOL'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает flat-list всех известных активов: native + tokens, для всех (или одного) chain.
|
||||||
|
* Используется в GET /api/tokens.
|
||||||
|
*/
|
||||||
|
export function getAllTokens(filterChain?: ChainCode): TokenListEntry[] {
|
||||||
|
const out: TokenListEntry[] = [];
|
||||||
|
const chains: ChainCode[] = filterChain ? [filterChain] : ALL_CHAINS_ORDERED;
|
||||||
|
|
||||||
|
for (const chain of chains) {
|
||||||
|
// Native first
|
||||||
|
out.push({
|
||||||
|
chain,
|
||||||
|
symbol: NATIVE_SYMBOLS[chain],
|
||||||
|
name: NATIVE_NAMES[chain],
|
||||||
|
contract: null,
|
||||||
|
});
|
||||||
|
// Tokens
|
||||||
|
if (chain === 'ETH' || chain === 'BSC') {
|
||||||
|
for (const tk of getEvmTokens(chain)) {
|
||||||
|
out.push({ chain, symbol: tk.symbol, name: tk.name, contract: tk.contractAddress });
|
||||||
|
}
|
||||||
|
} else if (chain === 'TRX') {
|
||||||
|
for (const tk of TRX_TOKENS) {
|
||||||
|
out.push({ chain, symbol: tk.symbol, name: tk.name, contract: tk.contractAddress });
|
||||||
|
}
|
||||||
|
} else if (chain === 'SOL') {
|
||||||
|
for (const tk of SOL_TOKENS) {
|
||||||
|
out.push({ chain, symbol: tk.symbol, name: tk.name, contract: tk.mint });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// BTC — только native
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
export function getEvmTokens(chain: ChainCode): EvmToken[] {
|
export function getEvmTokens(chain: ChainCode): EvmToken[] {
|
||||||
if (chain === 'ETH') return ETH_TOKENS;
|
if (chain === 'ETH') return ETH_TOKENS;
|
||||||
if (chain === 'BSC') return BSC_TOKENS;
|
if (chain === 'BSC') return BSC_TOKENS;
|
||||||
|
|||||||
36
apps/api/src/routes/tokens.routes.ts
Normal file
36
apps/api/src/routes/tokens.routes.ts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* GET /api/tokens — реестр всех известных активов всех 5 сетей + native.
|
||||||
|
*
|
||||||
|
* Read-only. Источник — `lib/token-registry.ts`. Никаких RPC calls,
|
||||||
|
* никаких user-specific данных — только статический list контрактов с symbol + name.
|
||||||
|
*
|
||||||
|
* Optional query: ?chain=ETH|BSC|BTC|TRX|SOL — filter одной сетью.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Router, Request, Response } from 'express';
|
||||||
|
import { getAllTokens } from '../lib/token-registry';
|
||||||
|
import { ALL_CHAINS } from '../services/wallet-generator.service';
|
||||||
|
import type { ChainCode } from '../lib/address-validators';
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
const ALLOWED = new Set<ChainCode>(ALL_CHAINS);
|
||||||
|
|
||||||
|
router.get('/', (req: Request, res: Response) => {
|
||||||
|
const chainParam = req.query.chain;
|
||||||
|
let filterChain: ChainCode | undefined;
|
||||||
|
if (chainParam !== undefined && chainParam !== null && chainParam !== '') {
|
||||||
|
const upper = String(chainParam).toUpperCase();
|
||||||
|
if (!ALLOWED.has(upper as ChainCode)) {
|
||||||
|
res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
error: `Invalid chain "${chainParam}" (allowed: ETH, BSC, BTC, TRX, SOL)`,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
filterChain = upper as ChainCode;
|
||||||
|
}
|
||||||
|
const data = getAllTokens(filterChain);
|
||||||
|
res.json({ success: true, data });
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
||||||
@@ -896,6 +896,83 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"TokenListEntry": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"chain",
|
||||||
|
"symbol",
|
||||||
|
"name",
|
||||||
|
"contract"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"chain": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ETH",
|
||||||
|
"BSC",
|
||||||
|
"BTC",
|
||||||
|
"TRX",
|
||||||
|
"SOL"
|
||||||
|
],
|
||||||
|
"example": "ETH"
|
||||||
|
},
|
||||||
|
"symbol": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "USDT"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Tether USD"
|
||||||
|
},
|
||||||
|
"contract": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true,
|
||||||
|
"description": "Contract address (EVM 0x..., TRX T..., SOL base58 mint). Для native = null.",
|
||||||
|
"example": "0xdAC17F958D2ee523a2206206994597C13D831ec7"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"TokensListResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"success": {
|
||||||
|
"type": "boolean",
|
||||||
|
"example": true
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/TokenListEntry"
|
||||||
|
},
|
||||||
|
"example": [
|
||||||
|
{
|
||||||
|
"chain": "ETH",
|
||||||
|
"symbol": "ETH",
|
||||||
|
"name": "Ethereum",
|
||||||
|
"contract": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"chain": "ETH",
|
||||||
|
"symbol": "USDT",
|
||||||
|
"name": "Tether USD",
|
||||||
|
"contract": "0xdAC17F958D2ee523a2206206994597C13D831ec7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"chain": "BSC",
|
||||||
|
"symbol": "BNB",
|
||||||
|
"name": "BNB",
|
||||||
|
"contract": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"chain": "TRX",
|
||||||
|
"symbol": "USDT",
|
||||||
|
"name": "Tether USD",
|
||||||
|
"contract": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -2643,6 +2720,48 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"/tokens": {
|
||||||
|
"get": {
|
||||||
|
"summary": "List all known token contracts across all chains",
|
||||||
|
"description": "Возвращает flat-list всех известных активов: native coins + tokens (ERC-20/BEP-20/TRC-20/SPL).\n\nИсточник — статический token-registry. Read-only, без RPC calls, без user-specific data.\n\nOptional ?chain=ETH|BSC|BTC|TRX|SOL — filter по одной сети.",
|
||||||
|
"tags": [
|
||||||
|
"Tokens"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "chain",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ETH",
|
||||||
|
"BSC",
|
||||||
|
"BTC",
|
||||||
|
"TRX",
|
||||||
|
"SOL"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"description": "Если задан — вернёт только active assets этой сети (1 native + N tokens)."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Token list",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TokensListResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Invalid chain parameter"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user