Split//Layer
The vision$SLLaunch app
Documentation/Build with SplitLayer/Developer reference
BUILD WITH SPLITLAYER

Developer reference

Integrate the workspace carefully: exact amounts, explicit routes, and wallet-owned signing.

6 min readUpdated September 9, 2026

Integration surface

This repository is a Next.js application, not a published SplitLayer SDK or a separately hosted public API. Its internal endpoints support the included interface. Their responses follow the configured upstream provider and may change as the app evolves.

For an independent integration, start from the official LI.FI quote and transfer-status APIs. Keep provider credentials on your server. The browser wallet is responsible for all signatures.

The application endpoints

Quote amount is a human decimal string with at most six places; the server converts it to USDC base units. Slippage is an integer from 10 to 100 basis points. Source and destination must be different enabled networks. The recipient is the connected address.

The server binds reviewed quote terms and transaction data with an HMAC signature. Allowed LI.FI transaction targets and transfer calldata are validated before execution. This protects the application boundary; it is not an audit or a guarantee of bridge solvency.

TypeScript / application client
const response = await fetch('/api/quote', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    fromChainId: 8453,
    toChainId: 42161,
    amount: '10.00',
    address: connectedWalletAddress,
    slippageBps: 50,
  }),
});
if (!response.ok) throw new Error('Quote unavailable');
const reviewedQuote = await response.json();
EndpointInputPurpose
POST /api/quotefromChainId, toChainId, amount, address, slippageBpsValidated native-USDC quote with a signed 60-second expiry
POST /api/quote/validateverificationToken, optional includeFundsVerify signature and expiry; optionally read balance, allowance, and native gas balance
GET /api/receipthash, chainIdSource-chain receipt status or pending
GET /api/balancesaddressRegistered-chain USDC balances; null when a network read fails
GET /api/statushash, fromChainId, toChainId, optional toolNormalized route status, substatus, and receiving details
GET /api/assetsaddress, tokenAddress, chainId=4663Read-only imported ERC-20 metadata and wallet balance
GET /api/rwaNoneOfficial Robinhood Chain asset metadata and available reference prices

Requesting an upstream quote

This example shows the upstream API and assumes a valid connected EVM address. Production code should use allowlisted token addresses rather than symbols. It must validate the chains, assets, recipient, amount, slippage, and transaction target returned by the provider.

TypeScript / server
const params = new URLSearchParams({
  fromChain: '8453',
  toChain: '42161',
  fromToken: 'USDC',
  toToken: 'USDC',
  fromAmount: '10000000', // 10 USDC, 6 decimals
  fromAddress: connectedWalletAddress,
  toAddress: connectedWalletAddress,
  slippage: '0.005',
  integrator: 'splitlayer',
});

const response = await fetch(
  `https://li.quest/v1/quote?${params}`,
  { cache: 'no-store' },
);
if (!response.ok) throw new Error('Quote unavailable');
const quote = await response.json();
// Validate and show the quote before requesting a signature.

Keep amounts exact

Read decimals from the verified token registry. Parse human input into integer base units, using string-based decimal parsing and bigint. Do not multiply a JavaScript floating-point number by 10 raised to the token decimals for transaction amounts.

Separate display formatting from validation. Reject negative values, exponent notation, too many decimal places, zero-sized transfers, and amounts greater than the actual source balance. A USD portfolio estimate must never be treated as a token spending allowance.

Execution boundary

  • Invalidate the quote whenever the account, chains, token, amount, or slippage changes.
  • Require a reviewed quote and the expected connected chain before execution.
  • Validate that the quote recipient and source address equal the intended wallet addresses.
  • Read the current ERC-20 allowance and request only the allowance the route requires.
  • Wait for an approval receipt before submitting the bridge transaction.
  • Record the submitted transaction hash immediately; an RPC timeout is not proof that it was never sent.
  • Derive transfer records from wallet-submitted transaction hashes and provider status; never infer successful settlement from a local UI transition.

Track status without guessing

The internal status endpoint proxies the configured provider. Apply bounded polling with backoff, retain the transaction hash, and inspect the receiving transaction. A transport error should remain unknown or pending until there is evidence of a terminal result.

TypeScript
const params = new URLSearchParams({
  hash: sourceTransactionHash,
  fromChainId: '8453',
  toChainId: '42161',
});
const response = await fetch(`/api/status?${params}`);
const result = await response.json();

// Interpret both fields; DONE alone is insufficient.
const settled = result.status === 'DONE'
  && result.substatus === 'COMPLETED';
const needsReview = ['PARTIAL', 'REFUNDED'].includes(
  result.substatus,
);

Running and deploying

See the repository README for environment variables, validation commands, and Railway deployment details. The application currently has no persistent server database. If shared persistent data is introduced, use PostgreSQL and run database migrations at application start rather than during Railway's build phase.

shell
npm install
npm run dev

# Production build
npm run build
npm start