LCX Liberty. American DeFi. Your keys. Your assets. Your control.
TypeScript SDK
One npm package for the whole API: swaps, cross-chain, tokens, prices and your key. Typed end to end, and it never touches a private key.
Install
npm i lcx-liberty-sdk
ESM and CommonJS both ship, with type declarations. Node 18 or newer, or any bundler.
The client
One client, six namespaces. Each is a thin wrapper over the endpoints documented in the API reference, so anything true there is true here.
import { LibertyDex } from "lcx-liberty-sdk";
const lcx = new LibertyDex({ apiKey: process.env.LCX_API_KEY });| Namespace | What it covers |
|---|---|
lcx.swap | Price, build and submit a same-chain swap. |
lcx.crossChain | Quote across chains, and follow a transfer. |
lcx.tokens | The token registry, and what we vouch for. |
lcx.prices | USD prices: one token, a batch, or a past day. |
lcx.chains | Supported chains and index freshness. |
lcx.account | Your key: plan, quota and usage. |
apiKey the client talks to https://dex-api.lcx.com, the anonymous product host, which is rate limited per IP. With one it talks to https://swap-api.lcx.com. That is the same split the rest of these docs describe, and the only thing the key changes.A swap, end to end
execute is quote and build in one call. It hands back the quote it priced and the transaction that matches it, so nothing can sign a route it was not shown.
const { quote, transaction } = await lcx.swap.execute({
chainId: 1,
tokenIn: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // WETH
tokenOut: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
amount: "1",
decimals: 18,
taker: userAddress,
slippageBps: 50,
});
console.log(quote.output.amount, "USDC, floor", quote.output.minimumAmount);
// { to, data, value } — hand it to whatever holds the keys.
await wallet.sendTransaction(transaction);Approvals
Selling an ERC-20 needs an allowance for the router first. Ask before you spend gas on one: required is false when the allowance already covers the trade.
const { required, spender } = await lcx.swap.allowance({
chainId: 1,
token: WETH,
taker: userAddress,
amount: quote.input.amount, // raw units, not decimal
});Native ETH needs no approval. See Approvals in Core concepts for the permit path and what a router upgrade means for an existing allowance.
Errors
Every failure arrives as a LibertyError carrying the API's own machine code, so a caller branches on the code rather than matching on a message that is free to change.
import { LibertyError } from "lcx-liberty-sdk";
try {
await lcx.swap.execute(params);
} catch (e) {
if (e instanceof LibertyError) {
// e.code — "no_route", "rate_limited", "price_moved", ...
// e.status — the HTTP status
// e.details — whatever the endpoint attached
}
}The codes are the ones listed under Errors in Core concepts; the SDK adds none of its own.