# SDK

## Nemo Protocol SDK Documentation

### Table of Contents

1. [Overview](#overview)
2. [Installation](#installation)
3. [Core Features](#core-features)
4. [API Reference](#api-reference)
5. [Type Definitions](#type-definitions)

***

### Overview

The Nemo Protocol SDK provides core functionality for querying user positions, calculating market values, and managing yield distributions in the Nemo Protocol.

#### Key Features

* **Position Query**: Query all positions for any Sui address
* **Holder Statistics**: Get PT, YT, LP holder counts and position quantities
* **Market Value Calculation**: Calculate current market values in SUI or underlying assets
* **Yield Management**: Query and claim available yield
* **Pool Information**: Get comprehensive pool statistics and market data

***

### Installation

#### Package Installation

```bash
npm install @nemoprotocol/contract-sdk
# or
yarn add @nemoprotocol/contract-sdk
# or
pnpm add @nemoprotocol/contract-sdk
```

#### Environment Configuration

```bash
# Build-time configuration
API_BASE_URL=https://api.nemoprotocol.com npm run build

# Development configuration (.env file)
API_BASE_URL=https://api.nemoprotocol.com
```

#### SDK Initialization

```typescript
import { PositionQuery, PoolQuery } from '@nemoprotocol/contract-sdk'

const positionQuery = new PositionQuery({
  network: 'mainnet', // or 'testnet', 'devnet', 'localnet'
  rpcUrl: 'https://sui-mainnet.mystenlabs.com' // optional
})

const poolQuery = new PoolQuery()
```

***

### Core Features

#### 1. Position Query

Query all positions for a specific Sui address in the Nemo protocol.

**LP Position Query**

```typescript
const lpPositions = await positionQuery.queryLpPositions({
  address: '0x...', // user address
  positionTypes: [
    '0x...::market::LpPosition<0x...::coin::SUI>',
    '0x...::market::LpPosition<0x...::coin::USDC>'
  ],
  maturity: '2024-12-31', // optional filter
  marketStateId: '0x...' // optional filter
})

// Response format:
// [
//   {
//     id: { id: '0x...' },
//     name: 'LP-SUI-2024-12-31',
//     expiry: '2024-12-31',
//     lpAmount: '1000000000',
//     description: 'LP position for SUI',
//     marketStateId: '0x...'
//   }
// ]
```

**PY Position Query**

```typescript
const pyPositions = await positionQuery.queryPyPositions({
  address: '0x...', // user address
  positionTypes: [
    '0x...::py_state::PyState<0x...::coin::SUI>',
    '0x...::py_state::PyState<0x...::coin::USDC>'
  ],
  maturity: '2024-12-31', // optional filter
  pyStateId: '0x...' // optional filter
})

// Response format:
// [
//   {
//     id: '0x...',
//     maturity: '2024-12-31',
//     ptBalance: '500000000',
//     ytBalance: '300000000',
//     pyStateId: '0x...'
//   }
// ]
```

#### 2. Holder Statistics

Get users holding different asset types (PT, YT, LP) and their position quantities.

**PT/YT Holder Count**

```typescript
const holdersCount = await positionQuery.queryPyPositionHoldersCount({
  positionTypes: [
    '0x...::py_state::PyState<0x...::coin::SUI>',
    '0x...::py_state::PyState<0x...::coin::USDC>'
  ],
  maturity: '2024-12-31',
  pyStateId: '0x...',
  pageSize: 50 // optional
})

console.log('PT Holders:', holdersCount.ptHolders)
console.log('YT Holders:', holdersCount.ytHolders)
console.log('Total Holders:', holdersCount.totalHolders)
console.log('Holders by Type:', holdersCount.holdersByType)
console.log('Total Positions:', holdersCount.totalPositions)
```

**LP Holder Count**

```typescript
const lpHoldersCount = await positionQuery.queryLpPositionHoldersCount({
  positionTypes: [
    '0x...::market::LpPosition<0x...::coin::SUI>',
    '0x...::market::LpPosition<0x...::coin::USDC>'
  ],
  maturity: '2024-12-31',
  marketStateId: '0x...',
  pageSize: 50 // optional
})

console.log('LP Holders:', lpHoldersCount.totalHolders)
console.log('Holders by Type:', lpHoldersCount.holdersByType)
console.log('Total Positions:', lpHoldersCount.totalPositions)
```

#### 3. Market Value Calculation

Calculate and display current market values of user positions (priced in SUI or underlying assets).

**Yield Query**

```typescript
const yieldResult = await positionQuery.queryYield({
  address: '0x...',
  ytBalance: '1000000000',
  pyPositions: [
    {
      id: '0x...',
      maturity: '2024-12-31',
      ptBalance: '500000000',
      ytBalance: '300000000',
      pyStateId: '0x...'
    }
  ],
  receivingType: 'sy', // or 'underlying'
  config: {
    nemoContractId: '0x...',
    version: '1.0.0',
    coinType: '0x...::coin::SUI',
    pyStateId: '0x...',
    syCoinType: '0x...::sy_coin::SyCoin<0x...::coin::SUI>',
    yieldFactoryConfigId: '0x...',
    marketStateId: '0x...',
    underlyingCoinType: '0x...::coin::SUI',
    underlyingProtocol: 'Scallop',
    priceOracleConfigId: '0x...',
    oraclePackageId: '0x...',
    oracleTicket: '0x...',
    oracleVoucherPackageId: '0x...'
  }
})

console.log('Output Value:', yieldResult.outputValue)
console.log('Output Amount:', yieldResult.outputAmount)
```

#### 4. Yield Claiming

**⚠️ Note: This feature is currently missing from the SDK**

Query and display available yield that users can claim in the NEMO protocol.

```typescript
// TODO: Implement yield claiming functionality
async function queryClaimableYield(address: string) {
  // This functionality needs to be implemented
  throw new Error('Yield claiming not yet implemented')
}
```

#### 5. Pool Information

Query basic information and statistics for different pools.

**Pool Query**

```typescript
const pools = await poolQuery.queryPools()

// Response format:
// [
//   {
//     id: '0x...',
//     tvl: '1000000000000',
//     tvlRateChange: '5.2',
//     coinLogo: 'https://...',
//     maturity: '2024-12-31',
//     startTime: '2024-01-01',
//     coinName: 'SUI',
//     coinType: '0x...::coin::SUI',
//     ptTokenType: '0x...::pt_coin::PtCoin<0x...::coin::SUI>',
//     nemoContractId: '0x...',
//     boost: '1.5',
//     provider: 'Scallop',
//     providerLogo: 'https://...',
//     cap: '10000000000000',
//     marketStateId: '0x...',
//     syCoinType: '0x...::sy_coin::SyCoin<0x...::coin::SUI>',
//     underlyingCoinType: '0x...::coin::SUI',
//     providerMarket: '0x...',
//     providerVersion: '1.0.0',
//     priceOracleConfigId: '0x...',
//     decimal: '9',
//     underlyingApy: '8.5',
//     coinPrice: '1.2',
//     underlyingPrice: '1.2',
//     pyStateId: '0x...',
//     syStateId: '0x...',
//     conversionRate: '1.0',
//     marketFactoryConfigId: '0x...',
//     swapFeeForLpHolder: '0.003',
//     underlyingCoinName: 'SUI',
//     underlyingCoinLogo: 'https://...',
//     version: '1.0.0',
//     perPoints: '1000000',
//     oraclePackageId: '0x...',
//     oracleTicket: '0x...',
//     oracleVoucherPackageId: '0x...',
//     yieldTokenType: '0x...::yt_coin::YtCoin<0x...::coin::SUI>',
//     tokenRegistryState: '0x...',
//     ptPrice: '0.95',
//     ptTvl: '500000000000',
//     syTvl: '500000000000',
//     marketState: {
//       marketCap: '1000000000000',
//       totalSy: '500000000000',
//       lpSupply: '1000000000000',
//       totalPt: '500000000000',
//       rewardMetrics: [...]
//     },
//     scaledPtApy: '12.5',
//     scaledUnderlyingApy: '8.5',
//     feeApy: '2.0',
//     sevenAvgUnderlyingApy: '8.2',
//     sevenAvgUnderlyingApyRateChange: '0.3',
//     ytPrice: '0.15',
//     lpPrice: '1.0',
//     ytTokenLogo: 'https://...',
//     ptTokenLogo: 'https://...',
//     lpTokenLogo: 'https://...',
//     ytReward: '150000000',
//     underlyingProtocol: 'Scallop',
//     yieldFactoryConfigId: '0x...',
//     pyPositionTypeList: ['0x...::py_state::PyState<0x...::coin::SUI>'],
//     marketPositionTypeList: ['0x...::market::LpPosition<0x...::coin::SUI>'],
//     lpPriceRateChange: '2.1',
//     ptPriceRateChange: '-1.5',
//     ytPriceRateChange: '5.2',
//     incentiveApy: '3.0',
//     incentives: [...],
//     poolApy: '15.5',
//     tradeStatus: 'active'
//   }
// ]
```

***

### API Reference

#### PositionQuery Class

**Constructor**

```typescript
new PositionQuery(config: PositionQueryConfig)
```

**Parameters:**

* `config.network`: Network type ('mainnet' | 'testnet' | 'devnet' | 'localnet')
* `config.rpcUrl`: Custom RPC URL (optional)

**Methods**

**queryLpPositions()**

```typescript
async queryLpPositions(options: {
  address: string;
  positionTypes: string[];
  maturity?: string;
  marketStateId?: string;
}): Promise<LpPosition[]>
```

**queryPyPositions()**

```typescript
async queryPyPositions(options: {
  address: string;
  positionTypes: string[];
  maturity?: string;
  pyStateId?: string;
}): Promise<PyPosition[]>
```

**queryPyPositionHoldersCount()**

```typescript
async queryPyPositionHoldersCount(options: {
  positionTypes: string[];
  maturity?: string;
  pyStateId?: string;
  pageSize?: number;
}): Promise<{
  ptHolders: number;
  ytHolders: number;
  totalHolders: number;
  holdersByType: Record<string, { ptHolders: number; ytHolders: number }>;
  totalPositions: number;
}>
```

**queryLpPositionHoldersCount()**

```typescript
async queryLpPositionHoldersCount(options: {
  positionTypes: string[];
  maturity?: string;
  marketStateId?: string;
  pageSize?: number;
}): Promise<{
  totalHolders: number;
  holdersByType: Record<string, number>;
  totalPositions: number;
}>
```

**queryYield()**

```typescript
async queryYield(params: QueryYieldParams): Promise<{
  outputValue: string;
  outputAmount: string;
}>
```

#### PoolQuery Class

**Constructor**

```typescript
new PoolQuery()
```

**Methods**

**queryPools()**

```typescript
async queryPools(): Promise<PortfolioItem[]>
```

***

### Type Definitions

#### PositionQueryConfig

```typescript
interface PositionQueryConfig {
  network?: 'mainnet' | 'testnet' | 'devnet' | 'localnet';
  rpcUrl?: string;
}
```

#### LpPosition

```typescript
interface LpPosition {
  id: { id: string };
  name: string;
  expiry: string;
  lpAmount: string;
  description: string;
  marketStateId: string;
}
```

#### PyPosition

```typescript
interface PyPosition {
  id: string;
  maturity: string;
  ptBalance: string;
  ytBalance: string;
  pyStateId: string;
}
```

#### PortfolioItem

```typescript
interface PortfolioItem {
  id: string;
  tvl: string;
  tvlRateChange: string;
  coinLogo: string;
  maturity: string;
  startTime: string;
  coinName: string;
  coinType: string;
  ptTokenType: string;
  nemoContractId: string;
  boost: string;
  provider: string;
  providerLogo: string;
  cap: string;
  marketStateId: string;
  syCoinType: string;
  underlyingCoinType: string;
  providerMarket: string;
  providerVersion: string;
  priceOracleConfigId: string;
  decimal: string;
  underlyingApy: string;
  coinPrice: string;
  underlyingPrice: string;
  pyStateId: string;
  syStateId: string;
  conversionRate: string;
  marketFactoryConfigId: string;
  swapFeeForLpHolder: string;
  underlyingCoinName: string;
  underlyingCoinLogo: string;
  version: string;
  perPoints: string;
  oraclePackageId: string;
  oracleTicket: string;
  oracleVoucherPackageId: string;
  yieldTokenType: string;
  tokenRegistryState: string;
  ptPrice: string;
  ptTvl: string;
  syTvl: string;
  marketState: MarketState;
  scaledPtApy: string;
  scaledUnderlyingApy: string;
  feeApy: string;
  sevenAvgUnderlyingApy: string;
  sevenAvgUnderlyingApyRateChange: string;
  ytPrice: string;
  lpPrice: string;
  ytTokenLogo: string;
  ptTokenLogo: string;
  lpTokenLogo: string;
  ytReward: string;
  underlyingProtocol: string;
  yieldFactoryConfigId: string;
  pyPositionTypeList: string[];
  marketPositionTypeList: string[];
  lpPriceRateChange: string;
  ptPriceRateChange: string;
  ytPriceRateChange: string;
  incentiveApy: string;
  incentives: Incentive[];
  poolApy: string;
  tradeStatus: string;
}
```

***

**Document Version**: 1.0

**Last Updated**: \[Date]


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.nemoprotocol.com/resources/sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
