# Orca CLMM Agent

A TypeScript library for managing and analyzing Orca Whirlpool concentrated liquidity positions on Solana.

## Features

- Fetch and analyze Orca Whirlpool positions for a wallet
- Calculate position balance and relative position within price range
- Convert tick indices to prices and vice versa
- Fetch fee quotes and convert to human-readable format
- Analyze position status (in-range, out-of-range)

## Installation

```bash
npm install orca-clmm-agent
# or
yarn add orca-clmm-agent
# or
bun add orca-clmm-agent
```

## Usage

### Loading Positions

```typescript
import { getOrcaPositions } from "orca-clmm-agent";
import { createSolanaRpc, mainnet } from "@solana/kit";
import { setWhirlpoolsConfig } from "@orca-so/whirlpools";

// Set up Orca Whirlpools configuration for mainnet
await setWhirlpoolsConfig("solanaMainnet");

// Create RPC connection
const rpc = createSolanaRpc(mainnet("https://api.mainnet-beta.solana.com"));

// Get positions for a wallet
const walletAddress = "";
const positions = await getOrcaPositions(walletAddress, rpc); // getDetailedPositions(walletAddress, rpc)

// Process positions
for (const position of positions) {
  console.log(`Position ${position.name}:`);
  console.log(`Current Price: ${position.currentMarketPrice}`);
  console.log(`In Range: ${position.isInRange}`);
}
```

### Open Position Example

```typescript
import { setDefaultFunder, setWhirlpoolsConfig } from "@orca-so/whirlpools";
import * as dotenv from "dotenv";
import { loadKeypairFromFile } from "./solana";
import {
  address,
  createKeyPairSignerFromBytes,
  createSolanaRpc,
  mainnet,
} from "@solana/kit";
import { fetchOrcaPoolByAddress, openPosition } from "orca-clmm-agent";

dotenv.config();

async function openPositionExample() {
  await setWhirlpoolsConfig("solanaMainnet");

  const bytes = await loadKeypairFromFile("./examples/keypair.json");
  const wallet = await createKeyPairSignerFromBytes(bytes);
  setDefaultFunder(wallet);

  const rpcUrl = process.env.RPC_URL || "https://api.mainnet-beta.solana.com";
  const rpc = createSolanaRpc(mainnet(rpcUrl));

  const whirlpoolAddress = address(
    "CJX9KVBAwobF7ijE7cd4kujyaHw2QCjyN9be94i5Seyo"
  );
  const pool = await fetchOrcaPoolByAddress(whirlpoolAddress);
  const onChainPool = await getOnChainPool(pool, rpc); // for latest price

  await openPosition({
    rpc,
    whirlpoolAddress,
    params: { tokenA: 1n },
    price: onChainPool.price,
    lowerMultiple: 0.9,
    upperMultiple: 1.1,
    slippageToleranceBps: 100,
    wallet,
  });
}

openPositionExample();
```

## License

MIT

### Visualizing Liquidity Depth

The example script `examples/getLiquidityInTicks.ts` exports a `points.json` file containing the global liquidity at each tick. Use `examples/main.py` to plot bid and ask depth around the current price. The values in `points.json` are cumulative – do not sum them again when graphing.
