> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sodax.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> SODAX is mainnet-only (no testnet chains or RPC endpoints exist) with a hub-and-spoke architecture; Sonic is the hub. SODAX is non-custodial protocol/software: it routes and settles; independent solvers on the marketplace fill — never say 'our solver', 'the SODAX solver', that SODAX trades, takes custody, or fills orders. For frontend/React integrations, prefer @sodax/dapp-kit hooks over calling @sodax/sdk directly. SDK operations — the methods that build, submit or await a transaction, and the API/quote calls — return Result<T, E> ({ ok: true, value } or { ok: false, error }): check result.ok, never wrap them in try/catch or branch on error.message; discriminate on the narrow error.code union instead. Synchronous config getters (getPartnerFee, getSupportedSwapTokens, getVault, ...) return their value directly, not a Result.

# Quickstart on LightLink

> Install the SDK, wire up a LightLink wallet provider, and execute your first cross-network swap from LightLink.

This page takes you from zero to a cross-network swap sourced from LightLink. No new contracts, no approval for native ETH, one signed transaction for your user.

<Note>
  Building with an AI assistant? Add the [SODAX Builders MCP](/builders-mcp) (`https://builders.sodax.com/mcp`) to Claude, Cursor, or any MCP-capable tool and it can pull live token lists, real quotes, and these docs while it writes your integration.
</Note>

## 1. Install

```bash theme={null}
npm install @sodax/sdk @sodax/wallet-sdk-core
# or: pnpm add / yarn add
```

## 2. Create a LightLink wallet provider

LightLink is an EVM network to the SDK, so it uses the same `EvmWalletProvider` as every other EVM network, keyed by `ChainKeys.LIGHTLINK_MAINNET`.

<CodeGroup>
  ```typescript Private key (scripts / bots) theme={null}
  import { EvmWalletProvider } from '@sodax/wallet-sdk-core';
  import { ChainKeys } from '@sodax/sdk';

  const walletProvider = new EvmWalletProvider({
    privateKey: '0x…', // private key of the LightLink account
    chainId: ChainKeys.LIGHTLINK_MAINNET,
    rpcUrl: 'https://replicator.phoenix.lightlink.io/rpc/v1', // LightLink Phoenix RPC
  });
  ```

  ```typescript Browser extension (dApps) theme={null}
  import { EvmWalletProvider } from '@sodax/wallet-sdk-core';

  // walletClient and publicClient are viem clients for LightLink Phoenix mainnet,
  // usually supplied by wagmi from the user's connected EVM wallet
  const walletProvider = new EvmWalletProvider({
    walletClient,
    publicClient,
  });
  ```
</CodeGroup>

Building in React? [`@sodax/wallet-sdk-react`](/developers/packages/connection/wallet-sdk-react) connects EVM wallets for you and hands back a ready-made provider via `useWalletProvider`. See [Wallets](/lightlink/wallets).

## 3. Look up supported tokens

Token addresses and decimals come from the SDK config, so you never hard-code them. On LightLink this matters more than usual: the `.LL` tokens use 18 decimals even where the same asset uses fewer on its home network.

```typescript theme={null}
import { Sodax, ChainKeys, type XToken } from '@sodax/sdk';

const sodax = new Sodax();

// find() returns XToken | undefined, so narrow before using the address
const bySymbol = (tokens: readonly XToken[], symbol: string) => {
  const token = tokens.find(t => t.symbol === symbol);
  if (!token) throw new Error(`${symbol} is not a supported swap token`);
  return token;
};

const eth = bySymbol(sodax.swaps.getSupportedSwapTokensByChainId(ChainKeys.LIGHTLINK_MAINNET), 'ETH');
const usdcBase = bySymbol(sodax.swaps.getSupportedSwapTokensByChainId(ChainKeys.BASE_MAINNET), 'USDC');
```

## 4. Quote and swap

`swap()` runs the full lifecycle: it creates the intent on LightLink, verifies the transaction landed, relays it to the hub, and notifies the solver to fill on the destination network.

```typescript theme={null}
import type { SolverIntentQuoteRequest } from '@sodax/sdk';

// 0.1 ETH, built from the token's own decimals
const inputAmount = 10n ** BigInt(eth.decimals) / 10n;

// Quote: 0.1 ETH -> USDC on Base
const quoteResult = await sodax.swaps.getQuote({
  token_src: eth.address,
  token_dst: usdcBase.address,
  token_src_blockchain_id: ChainKeys.LIGHTLINK_MAINNET,
  token_dst_blockchain_id: ChainKeys.BASE_MAINNET,
  amount: inputAmount,
  quote_type: 'exact_input',
} satisfies SolverIntentQuoteRequest);

if (!quoteResult.ok) throw new Error('Quote failed');
const { quoted_amount } = quoteResult.value;

// `deadline` is an absolute Unix timestamp; getSwapDeadline turns an offset into one
const deadlineResult = await sodax.swaps.getSwapDeadline(300n); // 5 minutes from now
if (!deadlineResult.ok) throw new Error('Deadline lookup failed');

// Execute
const swapResult = await sodax.swaps.swap({
  params: {
    inputToken: eth.address,
    outputToken: usdcBase.address,
    inputAmount,
    minOutputAmount: (quoted_amount * 99n) / 100n, // your slippage policy
    deadline: deadlineResult.value,
    allowPartialFill: false,
    srcChainKey: ChainKeys.LIGHTLINK_MAINNET,
    dstChainKey: ChainKeys.BASE_MAINNET,
    srcAddress: await walletProvider.getWalletAddress(),
    dstAddress: '0x...', // recipient on Base
    solver: '0x0000000000000000000000000000000000000000',
    data: '0x',
  },
  walletProvider,
  timeout: 120_000,
});

if (swapResult.ok) {
  console.log('Submitted. Hub tx:', swapResult.value.intentDeliveryInfo.dstTxHash);
} else {
  console.error('Swap failed:', swapResult.error);
}
```

`ok` means the intent was created, relayed to the hub, and the solver notified, **not** that it was
filled. Poll `sodax.swaps.getStatus({ intent_tx_hash: intentDeliveryInfo.dstTxHash })` until the
status is `SolverIntentStatusCode.SOLVED`, which is the only success signal. The
[main quickstart](/quickstart) has the full polling loop, including why `NOT_FOUND` is not terminal.

A few things to know on LightLink:

* **ETH needs no approval.** It is the native token. Swapping an ERC-20 (USDC, LL, the `.LL` tokens, and the rest) needs an allowance first; see [Approvals](/lightlink/swaps#approvals).
* **The user pays gas in ETH.** The SDK sends standard gas-paying transactions, not Enterprise Mode ones, so the signing account needs a little ETH even when it swaps a different token.
* **Amounts follow `token.decimals`.** Every `.LL` token uses 18; USDC uses 6. Never reuse a decimals value from the asset's home network.

## Next steps

* [Swaps on LightLink](/lightlink/swaps): approvals, fees, and manual orchestration.
* [Money Market on LightLink](/lightlink/money-market): supply and borrow with cross-network collateral.
* Full API reference: [Swaps](/developers/packages/foundation/sdk/functional-modules/swaps) in the SDK docs.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.