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

# Kipseli PropAMM

> Integrate with Kipseli PropAMM — a professional AMM for token swaps on Base Mainnet

## What is Kipseli PropAMM?

Kipseli PropAMM is a professional Automated Market Maker deployed on Base that enables token swaps with competitive, on-chain pricing. Integrators can get quotes and execute swaps by combining on-chain contract calls with a lightweight signing API.

All quotes are vs USDC.

***

## Contract Addresses (Base Mainnet)

| Contract           | Address                                                                                                               |
| ------------------ | --------------------------------------------------------------------------------------------------------------------- |
| Router (PropAmm)   | [0x71c2ed90cc288229be59f26b8b3eef3c07d7ab99](https://basescan.org/address/0x71c2ed90cc288229be59f26b8b3eef3c07d7ab99) |
| Helper (QuoteLens) | [0x62aff80b3d2afe0e497f1ef735a6fdc9c3ef1acf](https://basescan.org/address/0x62aff80b3d2afe0e497f1ef735a6fdc9c3ef1acf) |
| EIP-712 Verifier   | [0xca369e97cc161c3c3a7368f9bc55a47f36a0a91e](https://basescan.org/address/0xca369e97cc161c3c3a7368f9bc55a47f36a0a91e) |

***

## Contract Interfaces

### Router (IPropAmm)

```solidity theme={null}
interface IPropAmm {
    function swap(
        address tokenIn,
        uint amountIn,
        address tokenOut,
        uint minOutAmount,
        uint quoteTimestamp,
        bytes calldata verificationData
    ) external returns (uint amountOut);

    function quote(
        address tokenIn,
        uint amountIn,
        address tokenOut,
        uint timestampInMilisec,
        bytes memory sig
    ) external view returns (uint amountOut);
}
```

### Helper (IQuoteLens)

```solidity theme={null}
interface IQuoteLens {
    function getListedTokens() external view returns (address[] memory);
    function getQuoteToken() external view returns (address);
    function getReserveBalances(address[] memory tokens) external view returns (uint[] memory);
}
```

***

## Whitelist Requirement

Both on-chain quoting (EIP-712 signature) and the swap signing API require your address to be **whitelisted**. Contact the Kipseli team and provide your signing address to get access.

***

## Integration Overview

### Getting a Quote

Choose one of two methods:

**Method 1 — On-chain via EIP-712 signature**

1. Generate `timestampInMilisec` (current time in ms). Must be within **10 seconds** of the current block.
2. Sign the EIP-712 typed data with your whitelisted key (see [EIP-712 Signature](#eip-712-signature) below).
3. Call `quote(tokenIn, amountIn, tokenOut, timestampInMilisec, signature)` on the Router.
4. Receive `amountOut` — your expected output amount.

**Method 2 — Off-chain via API**

Call `GET /v1/price` to get the live on-chain orderbook for all configured pairs. See [Get Orderbook](/api-reference/get-price).

***

### Executing a Swap

**Step 1 — Get verification data**

Call `POST /v1/swap/sign` with your swap parameters. The API returns `verificationData` and `timestamp`. Optionally pass `amountIn` (and `minAmountOut`) to also receive pre-built `calldata`. See [Request Swap Verification](/api-reference/sign-quote).

**Step 2 — Approve the Router**

```solidity theme={null}
IERC20(tokenIn).approve(
    0x71C2Ed90CC288229Be59F26b8B3EEF3C07d7ab99,
    amountIn
);
```

**Step 3 — Call `swap()`**

*Option A — build the call yourself:*

```solidity theme={null}
IPropAmm(0x71C2Ed90CC288229Be59F26b8B3EEF3C07d7ab99).swap(
    tokenIn,
    amountIn,
    tokenOut,
    minOutAmount,      // slippage protection — derive from quote()
    timestamp,         // from API response
    verificationData   // from API response
);

Both `timestamp` and `verificationData` must be passed directly from the API response without modification. If either is changed or expired, the transaction will revert.

```

*Option B — use the `calldata` returned by the API (requires `amountIn` in Step 1):*

```solidity theme={null}
(bool success, ) = address(0x71C2Ed90CC288229Be59F26b8B3EEF3C07d7ab99).call(calldata);
require(success, "swap failed");
```

***

## EIP-712 Signature

To call `quote()` on-chain, you must sign the following struct with a whitelisted key:

```solidity theme={null}
PropAmmVerification(
    address tokenIn,
    address tokenOut,
    uint256 timestampInMilisec
)
```

**Domain:**

```json theme={null}
{
  "name": "VerificationImpl",
  "version": "1",
  "chainId": 8453,
  "verifyingContract": "0xCa369e97cc161c3c3a7368f9bC55A47F36a0A91E"
}
```

**Example (ethers.js):**

```javascript theme={null}
const domain = {
  name: "VerificationImpl",
  version: "1",
  chainId: 8453,
  verifyingContract: "0xCa369e97cc161c3c3a7368f9bC55A47F36a0A91E",
};

const types = {
  PropAmmVerification: [
    { name: "tokenIn", type: "address" },
    { name: "tokenOut", type: "address" },
    { name: "timestampInMilisec", type: "uint256" },
  ],
};

const value = { tokenIn, tokenOut, timestampInMilisec };

const signature = await signer.signTypedData(domain, types, value);

// Call on-chain:
// quote(tokenIn, amountIn, tokenOut, timestampInMilisec, signature)
```

***

## Fee Structure

The `fee` field in swap requests uses **0.1 bps resolution**:

| Value | Rate             |
| ----- | ---------------- |
| `1`   | 0.1 bps (0.001%) |
| `10`  | 1 bps (0.01%)    |
| `30`  | 3 bps (0.03%)    |
| `100` | 10 bps (0.10%)   |

* Fee is **deducted from the output amount** (`amountOut`).
* Fees are **settled monthly** in a mutually agreed currency (e.g. USDC, ETH).

## Error Format

All API errors follow a consistent envelope:

```json theme={null}
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "tokenIn: invalid EVM address",
    "requestId": "abc-123"
  }
}
```

| Code                | HTTP Status | Description                    |
| ------------------- | ----------- | ------------------------------ |
| `INVALID_JSON`      | 400         | Malformed or missing JSON body |
| `UNSUPPORTED_FIELD` | 400         | Unknown field in request body  |
| `VALIDATION_ERROR`  | 422         | Field-level validation failure |
| `SIGNING_FAILED`    | 500         | secp256k1 signing error        |
| `ENCODING_FAILED`   | 500         | ABI encoding error             |
| `INTERNAL_ERROR`    | 500         | Unexpected server error        |
