Reference
SDK reference
The @layerhop/sdk TypeScript client — LayerHop class options, quote, buildTx, submit, status, watch, types and errors.
@layerhop/sdk is a thin, typed client for the REST API. It has no runtime dependencies besides @layerhop/shared, uses the global fetch, and works in Node 20+, browsers and edge runtimes.
Coming soon
publication on npm. Inside the monorepo use
"@layerhop/sdk": "workspace:*".
new LayerHop(options?)#
import { LayerHop } from "@layerhop/sdk";
const lh = new LayerHop({
baseUrl: "http://localhost:8787",
apiKey: process.env.LAYERHOP_API_KEY,
channel: "api",
});| Option | Type | Default | Description |
|---|---|---|---|
baseUrl |
string |
https://api.layerhop.com |
API origin, without /v1. A trailing slash is removed. |
apiKey |
string |
— | Sent as the x-api-key header. Not enforced by the API yet. |
channel |
"api" | "web" | "widget" | "bot" |
"api" |
Fee channel sent with every quote. |
fetch |
typeof fetch |
globalThis.fetch |
Custom fetch (tests, proxies, retries). |
quote(params)#
Calls GET /v1/quote. Returns every successful quote, best for the user first.
quote(p: QuoteParams): Promise<QuoteResponse>| Param | Type | Description |
|---|---|---|
srcChain |
string | number |
Chain id or slug, e.g. "base", 8453. |
srcToken |
string |
Symbol from the token list or address / mint. |
amount |
string |
Integer string in base units of srcToken. |
dstChain |
string | number |
Chain id or slug. |
dstToken |
string |
Symbol or address / mint. |
sender |
string |
Address that signs on the source chain. |
recipient |
string |
Address that receives on the destination chain. |
slippageBps |
number? |
Default 50. Range 1–5000. |
interface QuoteResponse {
best: Quote; // same as quotes[0]
quotes: Quote[];
errors: { provider: string; code: string; message: string }[];
}
interface Quote {
quoteId: string;
provider: ProviderId; // "jupiter" | "relay" | "debridge" | "zerox" | "lifi" | …
dstAmount: string; // expected output, base units
dstAmountMin: string; // after slippage
estimatedSeconds: number;
fees: { ourFeeBps: number; providerFeeUsd?: number; gasUsd?: number };
expiresAt: number; // unix seconds
}buildTx(quoteId)#
Calls POST /v1/orders and returns only the transaction.
buildTx(quoteId: string): Promise<BuiltTx>
type BuiltTx = EvmTx | SvmTx;
type EvmTx = {
vm: "evm";
chainId: number;
to: string;
data: string;
value: string; // wei
approval?: { token: string; spender: string; amount: string };
};
type SvmTx = {
vm: "svm";
serializedTx: string; // base64 VersionedTransaction
submitViaApi?: boolean; // sign only, then call submit()
};Narrow on tx.vm. See Approvals and the submitViaApi flow.
submit(quoteId, signedTransaction)#
Calls POST /v1/orders/submit. Only for SvmTx with submitViaApi: true. Returns the Solana transaction signature.
submit(quoteId: string, signedTransaction: string /* base64 */): Promise<string>status(provider, id)#
Calls GET /v1/orders/{provider}/{id}. The id is URL-encoded for you.
status(provider: ProviderId, id: string): Promise<OrderStatus>
interface OrderStatus {
provider: ProviderId;
id: string;
state: "pending" | "filled" | "refunded" | "failed" | "unknown";
srcTxHash?: string;
dstTxHash?: string;
}Which id to pass per provider: Order tracking.
watch(provider, id, options?)#
Polls status() and yields each change of state until it is filled, refunded or failed, or until the timeout.
watch(provider: ProviderId, id: string, opts?: { intervalMs?: number; timeoutMs?: number }): AsyncGenerator<OrderStatus>| Option | Default |
|---|---|
intervalMs |
3000 |
timeoutMs |
1800000 (30 minutes) |
for await (const s of lh.watch("debridge", srcTxHash)) console.log(s.state);When the timeout is reached the generator simply ends; check the last state you saw. Errors from status() are thrown out of the loop — wrap it if you want to keep polling through transient provider errors.
LayerHopApiError#
Every non-2xx response is thrown as LayerHopApiError:
| Property | Type | Description |
|---|---|---|
code |
string |
Stable error code ("INTERNAL" if the body had none). |
message |
string |
Human-readable message. |
status |
number |
HTTP status. |
requestId |
string? |
Request id for support. |
import { LayerHopApiError } from "@layerhop/sdk";
try {
await lh.buildTx(id);
} catch (e) {
if (e instanceof LayerHopApiError && e.code === "QUOTE_EXPIRED") { /* re-quote */ }
}Re-exports#
For convenience the SDK re-exports from @layerhop/shared:
| Export | What |
|---|---|
CHAINS, getChain(idOrSlug) |
The chain registry. |
TOKENS, findToken(chainId, symbolOrAddress) |
The built-in token list. |
SOLANA_CHAIN_ID |
7565164, LayerHop's id for Solana. |
EVM_NATIVE, SOL_NATIVE |
Native coin addresses (0x000…000, wrapped-SOL mint). |
| Types | BuiltTx, EvmTx, SvmTx, OrderStatus, ProviderId, FeeChannel. |
import { findToken, getChain } from "@layerhop/sdk";
const base = getChain("base")!; // { id: 8453, … }
const usdc = findToken(base.id, "USDC")!; // { decimals: 6, address: "0x8335…" }
const amount = (100n * 10n ** BigInt(usdc.decimals)).toString(); // "100000000"Coming soon
@layerhop/reacthooks (useQuote,useSwap,useOrderStatus,useTokens) and Python, Go and Rust SDKs generated from the OpenAPI spec.