> For the complete documentation index, see [llms.txt](https://docs.libertyswap.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.libertyswap.finance/resources/liberty-swap-api-1.md).

# Liberty Swap API

The official integration API for LibertySwap V3. 🚀

## Overview

LibertySwap provides an off-chain quoting system that generates executable calldata for supported cross-chain swaps. DApps and integration partners use the API to resolve the source transaction target, calculate fees, and build the transaction that the user signs from their own wallet.

**Key Concepts:**

* **Non-Custodial API**: The API never takes custody of user funds or signs on the user's behalf. It only generates transaction payloads for LibertySwap or Circle contracts.
* **Cross-Chain Payload Generation**: The quote response contains the source transaction target, approval payload when required, calldata, and native value.
* **Direct and CCTP Routing**: LibertySwap V3 combines Liberty liquidity pools with Circle CCTP V2 Fast Transfer.
* **Privacy Swaps**: Railgun shielding is integrated into `/quote`; the API encrypts the raw Railgun recipient and returns ready-to-sign Liberty pool calldata. See [Privacy Swaps](#privacy-swaps).

Base URL: `https://apis.libertyswap.finance/v3/swap`

Quote endpoint: `GET /quote`

Healthcheck endpoint: `GET /healthcheck`

Router registry: `GET https://apis.libertyswap.finance/v3/app/routers`

## Supported Pairs

### Standard Swaps (Public)

| Asset          | Inbound: Public Networks → PulseChain                                                                                                                                              | Outbound: PulseChain → Public Networks                                                                                                                                             |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **USDC**       | Direct: Ethereum, Base, BSC. CCTP: Avalanche, Arbitrum, Optimism, Polygon, UniChain, Linea, World Chain, Plume, Morph, Ink, Monad, Sonic, Sei, HyperEVM, Pharos, Cronos → **USDC** | **USDC** → Direct: Ethereum, Base, BSC. CCTP: Avalanche, Arbitrum, Optimism, Polygon, UniChain, Linea, World Chain, Plume, Morph, Ink, Monad, Sonic, Sei, HyperEVM, Pharos, Cronos |
| **ETH / WETH** | Ethereum, Base, Robinhood Chain native ETH → PulseChain **WETH**                                                                                                                   | PulseChain **WETH** → Ethereum, Base, Robinhood Chain native ETH                                                                                                                   |
| **USDT / DAI** | Ethereum USDT/DAI, BSC USDT → PulseChain **USDC**                                                                                                                                  | *(Inbound only)*                                                                                                                                                                   |
| **USD1**       | BSC USD1 → PulseChain **USDC**                                                                                                                                                     | *(Inbound only)*                                                                                                                                                                   |

The following source pairs return `route.type = CCTP_INBOUND`:

| Source           | Destination     |
| ---------------- | --------------- |
| Avalanche USDC   | PulseChain USDC |
| Arbitrum USDC    | PulseChain USDC |
| Optimism USDC    | PulseChain USDC |
| Polygon USDC     | PulseChain USDC |
| UniChain USDC    | PulseChain USDC |
| Linea USDC       | PulseChain USDC |
| World Chain USDC | PulseChain USDC |
| Plume USDC       | PulseChain USDC |
| Morph USDC       | PulseChain USDC |
| Ink USDC         | PulseChain USDC |
| Monad USDC       | PulseChain USDC |
| Sonic USDC       | PulseChain USDC |
| Sei USDC         | PulseChain USDC |
| HyperEVM USDC    | PulseChain USDC |
| Pharos USDC      | PulseChain USDC |
| Cronos USDC      | PulseChain USDC |

The CCTP outbound destination list is the same as the CCTP inbound EVM source list above. All other currently supported source transactions target a Liberty pool and return `route.type = DIRECT`. This includes CCTP outbound: the user first calls the PulseChain pool, and the backend performs the later CCTP leg.

## Privacy Swaps

LibertySwap's Railgun integration supports shielding and unshielding to reduce transfer linkability.

| Asset          | Shielding (Public → Railgun)                                        | Unshielding (Railgun → Public)                                      |
| -------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- |
| **USDC**       | PulseChain, Ethereum, Base, BSC → **USDC (Railgun Ethereum / BSC)** | **USDC (Railgun Ethereum / BSC)** → PulseChain, Ethereum, Base, BSC |
| **USDT / DAI** | Ethereum, BSC → **USDC (Railgun Ethereum / BSC)**                   | *(Inbound only)*                                                    |
| **USD1**       | BSC → **USDC (Railgun Ethereum / BSC)**                             | *(Inbound only)*                                                    |
| **ETH / WETH** | Ethereum, PulseChain → **WETH (Railgun Ethereum / BSC)**            | **WETH (Railgun Ethereum / BSC)** → PulseChain, Ethereum            |

Railgun destinations use virtual routing IDs in `dstChain`; they are not RPC network chain IDs. For shielding, pass the raw `0zk...` Railgun address as `recipient` and `2` as `recipientType`. Railgun shielding returns `route.type = DIRECT` because the source transaction targets a Liberty pool.

**Shielding quote example:**

```bash
curl "https://apis.libertyswap.finance/v3/swap/quote?srcToken=USDC&dstToken=USDC&amount=1000000000&srcChain=369&dstChain=69696969&recipient=0zk...&recipientType=2"
```

## Fees

The API calculates the Liberty protocol fee based on bridge direction:

* **Public chain → PulseChain:** `0.3%`
* **PulseChain → public chain:** `0.5%`
* **Privacy swaps:** `0.5%`

For CCTP inbound, the API sets `maxFee` to Circle's estimated Fast Transfer fee plus a 20% safety margin. This margin applies only to the estimated Circle fee, not to the transferred amount. Liberty absorbs the executed Circle fee, so `destAmount` reflects the Liberty protocol fee without subtracting the Circle fee a second time.

## Amount Limits

The API enforces per-transaction limits. A request outside the configured range returns `400 Bad Request`.

* **Stablecoins (USDC/USDT/DAI/USD1):** minimum `10`, maximum `25,000` token units
* **ETH / WETH:** minimum `0.01`, maximum `20` token units

## Chain IDs Reference

Pass numeric `srcChain` and `dstChain` values:

| Network         | Chain ID |
| --------------- | -------: |
| Ethereum        |      `1` |
| Optimism        |     `10` |
| Cronos          |     `25` |
| BSC             |     `56` |
| UniChain        |    `130` |
| Polygon         |    `137` |
| Monad           |    `143` |
| Sonic           |    `146` |
| PulseChain      |    `369` |
| World Chain     |    `480` |
| HyperEVM        |    `999` |
| Sei             |   `1329` |
| Pharos          |   `1672` |
| Morph           |   `2818` |
| Robinhood Chain |   `4663` |
| Base            |   `8453` |
| Arbitrum        |  `42161` |
| Avalanche       |  `43114` |
| Ink             |  `57073` |
| Linea           |  `59144` |
| Plume           |  `98866` |

Railgun uses separate virtual routing IDs. These values are passed as `srcChain` or `dstChain` for Railgun flows, but they must not be used as RPC network chain IDs:

| Railgun route    | Virtual chain ID | Underlying network |
| ---------------- | ---------------: | ------------------ |
| Railgun Ethereum |       `69696969` | Ethereum (`1`)     |
| Railgun BSC      |       `96969696` | BSC (`56`)         |

## API Documentation

### Get Quote

`GET /quote`

Fetches the estimated destination amount and executable source transaction payload.

**General Conventions:**

* `amount` is a base-10 integer string in the source token's smallest unit.
* `recipient` is required. Use a non-zero EVM address for standard swaps or a raw `0zk...` address for Railgun shielding.
* `methodParameters.value` and `methodParameters.calldata` are hex strings.
* The endpoint currently generates EVM transactions. Solana CCTP instructions require a separate SVM transaction builder.

**Example Request:**

```bash
curl "https://apis.libertyswap.finance/v3/swap/quote?srcToken=USDC&dstToken=USDC&amount=1000000000&srcChain=42161&dstChain=369&recipient=0x18d618759B8F22CB9935D9e4d4c91751a890fae5"
```

#### Query Parameters

| Parameter       | Type    | Required | Description                                                                                                                                                                                 |
| --------------- | ------- | -------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `srcToken`      | string  |      Yes | Supported source token symbol or address.                                                                                                                                                   |
| `dstToken`      | string  |      Yes | Supported destination token symbol or address.                                                                                                                                              |
| `amount`        | string  |      Yes | Source amount in the token's smallest unit. For example, `1000000` is 1 USDC on a 6-decimal chain.                                                                                          |
| `srcChain`      | string  |      Yes | Source network chain ID.                                                                                                                                                                    |
| `dstChain`      | string  |      Yes | Destination network chain ID.                                                                                                                                                               |
| `recipient`     | string  |      Yes | Receiver address. Use a non-zero EVM address for standard swaps. For Railgun shielding, pass the raw `0zk...` address; `/quote` encrypts and encodes it internally.                         |
| `recipientType` | integer |       No | Recipient format: `0` for a standard EVM recipient; `2` for Railgun/CUSTOM. Defaults to `0`; a raw `0zk...` recipient is automatically encoded as type `2`.                                 |
| `integratorId`  | string  |       No | Integrator EVM wallet address, or its canonical left-zero-padded `bytes32` ID. The API verifies that it is registered and active in the relevant Liberty Registry before returning a quote. |

#### Response Schema

| Field                       | Type             | Description                                                                                                                         |
| --------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `to`                        | string           | Contract address to receive the source transaction: a Liberty pool for `DIRECT`, or Circle TokenMessenger V2 for `CCTP_INBOUND`.    |
| `srcToken`                  | object           | Resolved source token address, symbol, decimals, and chain ID.                                                                      |
| `destToken`                 | object           | Resolved destination token address, symbol, decimals, and chain ID.                                                                 |
| `srcAmount`                 | string           | Requested source amount in source-token smallest units.                                                                             |
| `destAmount`                | string           | Estimated amount after the Liberty protocol fee and, when supplied, the active integrator fee, in destination-token smallest units. |
| `fee.chainId`               | number           | Destination pool chain ID where the displayed fees are calculated.                                                                  |
| `fee.token`                 | string           | Always `destination`; all fee amounts use destination-token smallest units.                                                         |
| `fee.protocol.percentage`   | number           | Liberty protocol fee percentage, such as `0.3` or `0.5`.                                                                            |
| `fee.protocol.amount`       | string           | Liberty protocol fee amount.                                                                                                        |
| `fee.integrator.percentage` | number           | Integrator fee percentage; `0` when no integrator is supplied.                                                                      |
| `fee.integrator.amount`     | string           | Integrator fee amount; `0` when no integrator is supplied.                                                                          |
| `fee.integrator.id`         | string, optional | Validated integrator ID.                                                                                                            |
| `fee.integrator.address`    | string, optional | Integrator wallet address.                                                                                                          |
| `fee.total.amount`          | string           | Sum of protocol and integrator fees.                                                                                                |
| `approval`                  | object, optional | ERC-20 approval payload. Omitted for a native source token.                                                                         |
| `approval.token`            | string           | ERC-20 contract that receives the approval transaction.                                                                             |
| `approval.spender`          | string           | Contract authorized to spend the source token.                                                                                      |
| `approval.amount`           | string           | Required allowance in source-token smallest units.                                                                                  |
| `approval.calldata`         | string           | Encoded ERC-20 `approve(spender, amount)` calldata.                                                                                 |
| `methodParameters.calldata` | string           | Encoded main source transaction calldata.                                                                                           |
| `methodParameters.value`    | string           | Native value to send with the main transaction; `0x0` for ERC-20 sources.                                                           |
| `route.type`                | string           | `DIRECT` or `CCTP_INBOUND`.                                                                                                         |

#### CCTP Inbound Response Example

```json
{
  "to": "0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d",
  "srcToken": {
    "address": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
    "symbol": "USDC",
    "decimals": 6,
    "chainId": 42161
  },
  "destToken": {
    "address": "0x15D38573d2feeb82e7ad5187aB8c1D52810B1f07",
    "symbol": "USDC",
    "decimals": 6,
    "chainId": 369
  },
  "srcAmount": "1000000000",
  "destAmount": "997000000",
  "fee": {
    "chainId": 369,
    "token": "destination",
    "protocol": {
      "percentage": 0.3,
      "amount": "3000000"
    },
    "integrator": {
      "percentage": 0,
      "amount": "0"
    },
    "total": {
      "amount": "3000000"
    }
  },
  "approval": {
    "token": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
    "spender": "0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d",
    "amount": "1000000000",
    "calldata": "0x..."
  },
  "methodParameters": {
    "calldata": "0x...",
    "value": "0x0"
  },
  "route": {
    "type": "CCTP_INBOUND"
  }
}
```

### Integrator Quotes

Pass your registered integrator wallet as `integratorId`. The API validates it and returns the applicable integrator fee in the quote. Clients only need to sign the returned approval and transaction payloads.

```bash
curl --get "https://apis.libertyswap.finance/v3/swap/quote" \
  --data-urlencode "srcToken=USDC" \
  --data-urlencode "dstToken=USDC" \
  --data-urlencode "amount=1000000000" \
  --data-urlencode "srcChain=42161" \
  --data-urlencode "dstChain=369" \
  --data-urlencode "recipient=0x18d618759B8F22CB9935D9e4d4c91751a890fae5" \
  --data-urlencode "integratorId=YOUR_REGISTERED_INTEGRATOR_WALLET"
```

The quote service needs an RPC URL for the registry chain only when an integrator is supplied: `ETHEREUM_RPC_URL`, `BSC_RPC_URL`, `PULSECHAIN_RPC_URL`, `BASE_RPC_URL`, or `ROBINHOOD_RPC_URL`. It returns `503` if that required deployment configuration is unavailable rather than estimating an unverified integrator fee.

## CCTP Inbound

For a supported EVM CCTP source USDC → PulseChain USDC request, the API returns Circle TokenMessenger V2 and encodes:

```solidity
depositForBurnWithHook(
  amount,
  6,                  // Base CCTP domain
  baseHubBytes32,     // mintRecipient
  sourceUsdc,
  baseHubBytes32,     // destinationCaller
  maxFee,
  1000,               // Fast Transfer finality
  hookData
)
```

The packed `hookData` layout is:

```
version(1)
| destChainId(32)
| targetToken(20)
| integratorId(32)
| recipientType(1)
| recipientLength(1)
| recipient(N)
```

Circle attests the complete burn message, including `hookData`. The Base Hub reads the destination chain, target token, integrator, recipient type, and recipient from that attested data. Altering these bytes invalidates the attestation, so the relayer cannot redirect the swap.

For ERC-20 sources:

{% stepper %}
{% step %}

## Send approval when required

Send `approval.calldata` to `approval.token` when the existing allowance is below `approval.amount`.
{% endstep %}

{% step %}

## Send the source transaction

Send `methodParameters.calldata` to `to` with `methodParameters.value`.
{% endstep %}
{% endstepper %}

## Security Best Practices

{% hint style="warning" %}
**IMPORTANT:** Verify `quote.to` before asking the user to sign or broadcasting the transaction.
{% endhint %}

### Official Router Deployments

Current Liberty V3 router deployments are published dynamically by:

`GET https://api.libertyswap.finance/v3/app/routers`

Do not hardcode a global whitelist copied from this README. Match `quote.to` against the exact `(srcChain, srcToken)` deployment. Legacy routers can remain online for historical operations and must not be accepted merely because they appear in an older release.

### Recommended Integration Logic

```javascript
const CCTP_TOKEN_MESSENGER_V2 =
  '0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d';

const quoteResponse = await fetch(quoteUrl);
if (!quoteResponse.ok) {
  throw new Error(`Quote failed with HTTP ${quoteResponse.status}`);
}
const quote = await quoteResponse.json();

if (quote.route.type === 'CCTP_INBOUND') {
  if (quote.to.toLowerCase() !== CCTP_TOKEN_MESSENGER_V2.toLowerCase()) {
    throw new Error('Unexpected Circle TokenMessenger');
  }
} else {
  const routerResponse = await fetch(
    'https://api.libertyswap.finance/v3/app/routers'
  );
  const { data: routers } = await routerResponse.json();

  const expected = routers.find(
    router =>
      router.chainId === Number(srcChain) &&
      router.symbol.toUpperCase() === quote.srcToken.symbol.toUpperCase()
  );

  if (!expected || expected.router.toLowerCase() !== quote.to.toLowerCase()) {
    throw new Error('Unexpected LibertySwap source router');
  }
}

const signer = await provider.getSigner();

if (quote.approval) {
  const approvalTx = await signer.sendTransaction({
    to: quote.approval.token,
    data: quote.approval.calldata,
    value: 0
  });
  await approvalTx.wait();
}

const sourceTx = await signer.sendTransaction({
  to: quote.to,
  data: quote.methodParameters.calldata,
  value: quote.methodParameters.value
});

const receipt = await sourceTx.wait();
console.log('Source transaction confirmed:', receipt.hash);
```

The router registry check catches accidental deployment drift. Because the quote API and registry are both LibertySwap infrastructure, integrations requiring an independent trust anchor should pin reviewed deployments in their own configuration.

## API Rate Limiting

* **Limit:** 30 requests per minute per source IP
* **Error:** Exceeding the limit returns `429 Too Many Requests`
