@liberfi.io/client
v0.1.102
Published
Dex Client for Liberfi React SDK
Readme
@liberfi.io/client
DEX API client for the Liberfi React SDK. This package wraps @chainstream-io/sdk and exposes a clean, domain-typed API that conforms to the IClient and ISubscribeClient interfaces defined in @liberfi.io/types. It handles all DTO conversion between the upstream SDK and the Liberfi domain types, so consumers never interact with raw SDK types.
Design Philosophy
- Adapter pattern —
ClientwrapsChainStreamClientand translates between upstream DTOs and Liberfi domain types, keeping consumers decoupled from the backend SDK. - Centralized DTO conversion — All mapping functions live in
utils.ts, separating data transformation from client orchestration. - Interface conformance —
Client implements API.IClient, API.ISubscribeClientensures compile-time contract enforcement. - Composite subscriptions — WebSocket methods compose multiple backend channels into a single
ISubscriptionwith a unifiedunsubscribe().
Installation
pnpm add @liberfi.io/clientThis package depends on:
@chainstream-io/sdk(bundled)@liberfi.io/types(workspace)@liberfi.io/utils(workspace)
API Reference
Classes
Client
Main API client implementing both API.IClient (REST) and API.ISubscribeClient (WebSocket).
import { Client } from "@liberfi.io/client";
const client = new Client("your-access-token", {
serverUrl: "https://api.example.com",
debug: true,
});Constructor:
| Parameter | Type | Description |
| ------------- | --------------------- | ---------------------------------------------------------- |
| accessToken | ClientTokenProvider | Static token string or an object with getToken() method. |
| options? | ClientOptions | Optional configuration. |
REST Methods (IClient):
| Method | Signature | Description |
| -------------------------------- | ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| getToken | (chain, address) => Promise<Token> | Fetch a single token. |
| getTokens | (chain, addresses) => Promise<Token[]> | Fetch multiple tokens. |
| getTokenCandles | (chain, address, resolution, options?) => Promise<TokenCandle[]> | Fetch OHLCV candles. |
| getTokenSecurity | (chain, address) => Promise<TokenSecurity> | Fetch token security info. |
| getTokenStats | (chain, address) => Promise<TokenStats> | Fetch token stats by timeframe. |
| getTokenHolders | (chain, address, options?) => Promise<CursorList<TokenHolder>> | Fetch paginated token holders. |
| getTokenMarketData | (chain, address) => Promise<TokenMarketData> | Fetch market data (price, TVL, holders). |
| getNewTokens | (chain, options?) => Promise<Token[]> | Fetch new token listings. |
| getFinalStretchTokens | (chain, options?) => Promise<Token[]> | Fetch tokens near migration completion. |
| getMigratedTokens | (chain, options?) => Promise<Token[]> | Fetch migrated tokens. |
| getTrendingTokens | (chain, resolution, options?) => Promise<Token[]> | Fetch trending tokens by timeframe. |
| getStockTokens | (chain, options?) => Promise<Token[]> | Fetch stock-like tokens. |
| searchTokens | (options?) => Promise<SearchTokenCursorList> | Search tokens with filters and pagination. |
| swapRoute | (params) => Promise<SwapRoute> | Get a swap route with unsigned transaction. Use this for all route requests so EVM native (e.g. ETH 0x0) is converted to the format required by KyberSwap; do not call the route API directly with raw token addresses. |
| sendTx | (params) => Promise<SendTxResult> | Submit a signed transaction. |
| checkTxSuccess | (chain, txHash, timeout?) => Promise<boolean> | Poll for transaction success. |
| getWalletPortfolios | (chain, address, options?) => Promise<WalletPortfolios> | Fetch wallet holdings. |
| getWalletPnl | (chain, address, resolution?) => Promise<WalletPnl> | Fetch wallet PnL summary. |
| getWalletPortfolioPnls | (chain, address, options?) => Promise<WalletPortfolioPnls> | Fetch per-token PnL with summary. |
| getWalletPortfoliosByTokens | (chain, address, tokenAddresses) => Promise<Portfolio[]> | Fetch holdings for specific tokens. |
| getWalletPortfolioPnlsByTokens | (chain, address, tokenAddresses) => Promise<PortfolioPnl[]> | Fetch PnL for specific tokens. |
| getWalletTrades | (chain, address, options?) => Promise<CursorList<Trade>> | Fetch wallet trade history. |
| getTokenTrades | (chain, address, options?) => Promise<CursorList<Trade>> | Fetch token trade history. |
| getWalletActivities | (chain, address, options?) => Promise<CursorList<Activity>> | Fetch wallet activities. |
| getTokenActivities | (chain, address, options?) => Promise<CursorList<Activity>> | Fetch token activities. |
| getPresignedUploadUrl | () => Promise<string> | Get a presigned IPFS upload URL. |
WebSocket Methods (ISubscribeClient):
| Method | Callback Data | Description |
| ------------------------------ | -------------------------- | ---------------------------------------------------- |
| subscribeToken | TokenSubscribed[] | Real-time token updates (stats, holders, liquidity). |
| subscribeTokenCandles | TokenCandle[] | Real-time candle updates. |
| subscribeWalletPnl | WalletPnlSubscribed[] | Real-time wallet PnL changes. |
| subscribeWalletPortfolios | PortfolioSubscribed[] | Real-time portfolio balance changes. |
| subscribeWalletPortfolioPnls | PortfolioPnlSubscribed[] | Real-time per-token PnL changes. |
| subscribeWalletTrades | Trade[] | Real-time wallet trades. |
| subscribeTokenTrades | Trade[] | Real-time token trades. |
| subscribeWalletActivities | Activity[] | Real-time wallet activities. |
| subscribeTokenActivities | Activity[] | Real-time token activities. |
| subscribeNewTokens | TokenSubscribed[] | Real-time new token listings. |
| subscribeTrendingTokens | TokenSubscribed[] | Real-time trending token updates. |
| subscribeMigratedTokens | TokenSubscribed[] | Real-time migrated token updates. |
| subscribeFinalStretchTokens | TokenSubscribed[] | Real-time final-stretch token updates. |
| subscribeStockTokens | TokenSubscribed[] | Real-time stock token updates. |
Types
| Name | Definition | Description |
| ----------------------- | ----------------------------------------------------------- | ---------------------------------------------------------- |
| ClientTokenProvider | ClientTokenProviderFn \| string | Access token: a raw string or an object with getToken(). |
| ClientTokenProviderFn | { getToken(): Promise<string> \| string } | Async/sync token provider interface. |
| ClientOptions | { debug?, serverUrl?, streamUrl?, autoConnectWebSocket? } | Client configuration. |
Constants
| Name | Type | Description |
| --------- | -------- | ------------------------------------- |
| version | string | Current package version ("0.1.37"). |
Utility Functions
The following DTO conversion functions are also exported. They are primarily intended for internal use by Client but are available for advanced scenarios (e.g. custom data pipelines).
| Function | Signature | Description |
| --------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| toChainDTO | (chain: Chain) => ChainSymbol | Convert Chain to SDK chain symbol. |
| fromChainDTO | (chain: string) => Chain | Convert SDK chain symbol to Chain. |
| fromTokenDTO | (input: TokenDTO) => Token | Convert SDK token to domain Token. |
| fromTokenStatsDTO | (input: TokenStat) => TokenStats | Convert SDK stats to domain TokenStats. |
| fromTokenMarketDataDTO | (input) => TokenMarketData | Convert SDK market data. |
| fromTokenCandle | (input: Candle) => TokenCandle | Convert SDK candle. |
| fromTokenSecurity | (input) => TokenSecurity | Convert SDK security data. |
| toMintForRoute | (dex, address) => string | Convert token address to the value to send in route API (e.g. EVM native 0x0 → KyberSwap sentinel). Use only when building the route request body outside client.swapRoute. |
| KYBERSWAP_NATIVE_SENTINEL | "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" | Sentinel address required by KyberSwap for native token; use with toMintForRoute if not using client.swapRoute. |
See src/utils.ts for the full list of conversion functions.
Usage Examples
Basic usage
import { Client } from "@liberfi.io/client";
import { Chain } from "@liberfi.io/types";
const client = new Client("your-api-token");
// Fetch a token
const token = await client.getToken(
Chain.SOLANA,
"So11111111111111111111111111111111111111112",
);
console.log(token.name, token.marketData?.priceInUsd);
// Search tokens
const results = await client.searchTokens({
chains: [Chain.SOLANA],
keyword: "bonk",
limit: 10,
});WebSocket subscription
const subscription = client.subscribeToken(
Chain.SOLANA,
"So11111111111111111111111111111111111111112",
(updates) => {
for (const update of updates) {
console.log("Price:", update.marketData?.priceInUsd);
}
},
);
// Later: unsubscribe
subscription.unsubscribe();Async token provider
const client = new Client({
getToken: async () => {
const response = await fetch("/api/auth/token");
const { accessToken } = await response.json();
return accessToken;
},
});Swap route (方案 A — 唯一支持的获取 route 方式)
所有 swap route 请求必须通过 client.swapRoute() 发起,以便 EVM 原生币(如 ETH 的 0x0)被正确转换为 KyberSwap 所需格式。不要用自定义 fetch 直接请求 POST /v2/dex/:chain/route 并传入原始的 inputMint/outputMint,否则 EVM 原生会返回 50010。
import { Client } from "@liberfi.io/client";
import { Chain, API } from "@liberfi.io/types";
const client = new Client("your-api-token");
// 使用 token 地址即可,包括 EVM 原生 0x0;client 内部会做 DEX 所需转换
const route = await client.swapRoute({
chain: Chain.ETHEREUM,
userAddress: "0xe778D43627387448Ccf2285B6FA1CA60Eb629750",
input: "0x0000000000000000000000000000000000000000", // ETH native
output: "0xfF541139c60bB38CE2159A13d656f0f38aA96ff4",
mode: API.SwapMode.EXACT_IN,
amount: "100000000000000",
slippage: 20,
});
// route.serializedTx 为未签名交易的 base64在 React 中请通过 @liberfi.io/react 的 useSwapRouteQuery 或 @liberfi.io/ui-trade 的 useSwap / useSwapScript 获取 route,它们内部都调用 client.swapRoute。
Future Improvements
- Narrow the public API surface — only export
Client, types, andversion; keep DTO converters internal. - Replace
console.warninparseLaunchPlatformFromFilterswith a debug-gated log or thrown error. - Add explicit
ClientOptionstoChainStreamClientoption mapping in the constructor. - Deduplicate
fromTradeDetailDTO/fromActivityDetailDTOlogic. - Add runtime validation in
fromTokenSecurityinstead ofascasts. - Consolidate
version.tsglobal side effect into a shared utility.
