# Pendle SDK Boros

## Overview

Below is the documentation for the SDK. For more details about the overall architecture, contracts, API, and more, please refer to the [documentation](documentation/) folder.

The repository is organized as follows:

- [documentation](documentation/):
  - [lite-paper](documentation/lite-paper.md): lite paper for how boros works
  - [contracts-docs](documentation/contracts-docs/): contains the documentation to deep dive into the contracts, the overall architecture, and terminology
  - [API.docs.md](documentation/API.docs.md): API documentation
  - [SDK.docs.md](documentation/SDK.docs.md): SDK documentation
  - [example](documentation/example/): example code for the SDK
- [src](src/): contains the source code of the SDK

You can start with the [lite paper](documentation/lite-paper.md) to understand the overall architecture and mechanics of the platform.

Then you can go to the [API docs](documentation/API.docs.md) to understand the API and parameters.
After that, you can refer to [SDK docs](documentation/SDK.docs.md) and [example](documentation/example/) to see how to use the SDK.

## Installation

```bash
yarn add @pendle/sdk-boros
```


## Initialization

```typescript
constructor(walletClient: WalletClient, root: Address, accountId: number, rpcUrls: string[], agent?: Agent)
```

The Exchange class requires the following parameters for initialization:

- `walletClient`: A viem WalletClient instance for signing transactions
- `root`: The wallet address (Address type from viem)
- `accountId`: The numerical ID of the account to interact with
- `rpcUrls`: Array of RPC endpoint URLs for blockchain interactions
- `agent`: Optional Agent instance for transaction signing

Example:
```typescript
import { createWalletClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { Exchange } from 'pendle-sdk-boros';

const account = privateKeyToAccount(PRIVATE_KEY);

const walletClient = createWalletClient({
  transport: http(RPC_URL),
  account: account,
});

const exchange = new Exchange(
  walletClient,
  account.address,
  0, // accountId
  [RPC_URL]
);
```

## Example Flow: Creating an Agent and Placing an Order

Below is a complete example showing how to create an agent, approve it, and place an order:

```typescript
import { createWalletClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { Exchange, Agent, Side, TimeInForce, MarketAccLib } from 'pendle-sdk-boros';

// Setup wallet client
const PRIVATE_KEY = '0xYourPrivateKey';
const RPC_URL = 'https://your-rpc-endpoint.com';
const account = privateKeyToAccount(PRIVATE_KEY);
const accountId = 0;

const walletClient = createWalletClient({
  transport: http(RPC_URL),
  account: account,
});

async function placeOrderExample() {
  const exchange = new Exchange(
    walletClient,
    account.address,
    accountId,
    [RPC_URL]
  );

  const { agent } = await Agent.create(walletClient);

  const approvalTx = await exchange.approveAgent(agent);
  console.log('Agent approved:', approvalTx);
  const tokenId = 0;
  const marketId = 0;

  const marketAcc = MarketAccLib.pack(account.address, accountId, tokenId, marketId)

  const orderResult = await exchange.placeOrder({
    marketAcc: marketAcc,
    marketId: marketId,
    side: Side.LONG,
    size: 100000000000000000000n, // 100 tokens with 18 decimals
    limitTick: 1000,
    tif: TimeInForce.GOOD_TIL_CANCELLED,
  });

  console.log('Order placed:', orderResult);

  return orderResult;
}

placeOrderExample()
  .then(result => console.log('Example completed successfully'))
  .catch(error => console.error('Error in example:', error));
```

This example demonstrates the complete flow from initializing the Exchange class to successfully placing an order. The agent creation and approval steps are required before you can place orders on the platform.

## Order Management

### Place Order

```typescript
async placeOrder(params: PlaceOrderParams): Promise<{
  executeResponse: any;
  result: { order: any };
}>
```

Places a new order on the exchange.

Parameters:
- `marketAcc`: Use MarketAccLib to pack
- `marketId`: ID of the market
- `side`: Trade side (Enum: Side)
- `size`: Order size as bigint
- `limitTick`: Optional tick price limit
- `slippage`: Optional slippage tolerance
- `tif`: Time-in-force setting enum (GOOD_TIL_CANCELLED = 0, IMMEDIATE_OR_CANCEL = 1, FILL_OR_KILL = 2, ADD_LIQUIDITY_ONLY = 3, SOFT_ADD_LIQUIDITY_ONLY = 4)
- `nonces`: Optional array of nonces

Example:
```typescript
const result = await exchange.placeOrder({
  marketAcc: '0xMarketAccHex',
  marketId: 0,
  side: Side.LONG,
  size: 100000000000000000000n, // 100 tokens with 18 decimals
  limitTick: 1000,
  tif: TimeInForce.GOOD_TIL_CANCELLED,
});
```

### Bulk Place Orders

Multiple versions are available for bulk placing orders.

#### bulkPlaceOrdersV5 (Recommended)

```typescript
async bulkPlaceOrdersV5(request: BulkPlaceOrderV5Params): Promise<any>
```

Supports mixed single and bulk order requests in a unified interface.

Parameters (`BulkPlaceOrderV5Params`):
- `orderRequests`: Array of `SingleOrderRequest | BulkOrderRequest` objects
- `nonces`: Optional array of nonces

`SingleOrderRequest` fields: `marketAcc`, `marketId`, `side`, `size`, `limitTick`, `tif`, `ammId?`, `slippage?`

`BulkOrderRequest` fields: `cross`, `bulks` (array of `{ marketId, orders, cancelData }`), `slippage?`

Example:
```typescript
// Single order requests
const results = await exchange.bulkPlaceOrdersV5({
  orderRequests: [
    {
      marketAcc: '0xMarketAccHex',
      marketId: 0,
      side: Side.LONG,
      size: 100000000000000000000n,
      limitTick: 1000,
      tif: TimeInForce.GOOD_TIL_CANCELLED,
    },
  ],
});

// Bulk order request
const results = await exchange.bulkPlaceOrdersV5({
  orderRequests: [
    {
      cross: true,
      bulks: [{
        marketId: 0,
        orders: {
          tif: TimeInForce.GOOD_TIL_CANCELLED,
          side: Side.LONG,
          sizes: [1000000000000000000n, 2000000000000000000n],
          limitTicks: [69, 89],
        },
        cancelData: { ids: [], isAll: false, isStrict: false },
      }],
    },
  ],
});
```

#### bulkPlaceOrdersV2

```typescript
async bulkPlaceOrdersV2(request: BulkPlaceOrderV2Params): Promise<any>
```

Places multiple orders for the same market account.

Parameters (`BulkPlaceOrderV2Params`):
- `marketAcc`: Hex market account identifier
- `marketId`: ID of the market
- `sides`: Array of Side values
- `sizes`: Array of order sizes as bigint
- `limitTicks`: Array of tick price limits
- `tif`: Time-in-force setting
- `ammId`: Optional AMM ID
- `slippage`: Optional slippage tolerance
- `nonces`: Optional array of nonces

### Cancel Orders

```typescript
async cancelOrders(params: CancelOrdersParams): Promise<{
  executeResponse: any;
  result: { cancelledOrders: any };
}>
```

Cancels one or more orders.

Parameters:
- `marketAcc`: Use MarketAccLib to pack
- `marketId`: ID of the market
- `cancelAll`: Boolean indicating whether to cancel all orders
- `orderIds`: Array of order ID strings to cancel (use empty array when cancelAll is true)
- `nonces`: Optional array of nonces

Example:
```typescript
// Cancel specific orders
const result = await exchange.cancelOrders({
  marketAcc: '0xMarketAccHex',
  marketId: 0,
  cancelAll: false,
  orderIds: ['123456789', '987654321']
});

// Cancel all orders
const result = await exchange.cancelOrders({
  marketAcc: '0xMarketAccHex',
  marketId: 0,
  cancelAll: true,
  orderIds: []
});
```

### Bulk Cancel Orders

```typescript
async bulkCancelOrders(cancelOrderRequests: CancelOrdersParams[]): Promise<Array<{
  executeResponse: any;
  result: { cancelledOrders: any };
}>>
```

Cancels multiple orders from different markets.

Parameters:
- `cancelOrderRequests`: Array of CancelOrdersParams objects



## Agent Management

### Approve Agent

```typescript
async approveAgent(agent?: Agent, nonce?: bigint): Promise<any>
```

Approves an agent for transaction signing. The approval is valid for 7 days.

Parameters:
- `agent`: Optional Agent instance. If not provided, uses the instance agent or creates a new one.
- `nonce`: Optional nonce for the approval transaction.

Example:
```typescript
// Approve a new agent (auto-creates one if none set)
const agentApproval = await exchange.approveAgent();

// Approve a specific agent
import { Agent } from 'pendle-sdk-boros';
const { agent } = await Agent.create(walletClient);
const agentApproval = await exchange.approveAgent(agent);
```

### Set/Get Agent

```typescript
setAgent(agent: Agent): void
getAgent(): Agent | undefined
```

Set or get the agent used for signing transactions.

Example:
```typescript
const { agent } = await Agent.create(walletClient);
exchange.setAgent(agent);
const currentAgent = exchange.getAgent();
```

## Funds Management

### Deposit

```typescript
async deposit(params: DepositParams): Promise<any>
```

Deposits funds into the exchange. Handles ERC20 approval automatically.

Parameters:
- `userAddress`: Address of the user
- `tokenId`: Token ID of the collateral
- `tokenAddress`: Optional token contract address (auto-resolved from tokenId if not provided)
- `amount`: Amount to deposit as bigint
- `accountId`: Account ID to deposit into
- `marketId`: Market ID to deposit into

Example:
```typescript
const receipt = await exchange.deposit({
  userAddress: '0xYourWalletAddress',
  tokenId: 0,
  amount: 1000000000000000000n, // 1 token with 18 decimals
  accountId: 0,
  marketId: 0,
});
```

### Withdraw

```typescript
async withdraw(params: WithdrawParams): Promise<any>
```

Withdraws funds from the exchange.

Parameters:
- `userAddress`: Address of the user
- `tokenId`: Token ID of the collateral
- `amount`: Amount to withdraw as bigint

Example:
```typescript
const receipt = await exchange.withdraw({
  userAddress: '0xYourWalletAddress',
  tokenId: 0,
  amount: 1000000000000000000n // 1 token with 18 decimals
});
```

### Cash Transfer

```typescript
async cashTransfer(params: CashTransferParams): Promise<any>
```

Transfers cash between markets.

Parameters:
- `marketId`: ID of the market
- `isDeposit`: true if transferring from vault to marketId
- `amount`: Amount to transfer as bigint
- `nonces`: Optional array of nonces

Example:
```typescript
const response = await exchange.cashTransfer({
  marketId: 1,
  isDeposit: true,
  amount: 1000000000000000000n // 1 token with 18 decimals
});
```

## Position Management

### Close Active Positions

```typescript
async closeActivePositions(params: CloseActivePositionsParams): Promise<any>
```

Closes active positions.

Parameters:
- `marketAcc`: Hexadecimal market account identifier
- `marketId`: ID of the market
- `side`: Trade side (Side enum)
- `size`: Size to close as bigint
- `limitTick`: Tick price limit
- `tif`: Time-in-force setting (TimeInForce enum)
- `slippage`: Optional slippage tolerance
- `nonces`: Optional array of nonces

Example:
```typescript
const response = await exchange.closeActivePositions({
  marketAcc: '0xMarketAccHex',
  marketId: 0,
  side: Side.LONG,
  size: 100000000000000000000n, // 100 tokens with 18 decimals
  limitTick: 1000,
  tif: TimeInForce.IMMEDIATE_OR_CANCEL,
});
```

## Settings Management

### Update Settings

```typescript
async updateSettings(params: UpdateSettingsParams): Promise<any>
```

Updates account settings.

Parameters:
- `marketAcc`: Hexadecimal market account identifier
- `marketId`: ID of the market
- `leverage`: Leverage value
- `signature`: Signature as hexadecimal
- `agent`: Agent address as hexadecimal
- `timestamp`: Timestamp

Example:
```typescript
const response = await exchange.updateSettings({
  marketAcc: '0xMarketAccHex',
  marketId: 0,
  leverage: 5, // 5x leverage
  signature: '0xSignatureHex',
  agent: '0xAgentAddress',
  timestamp: Math.floor(Date.now() / 1000)
});
```

## Data Retrieval

### Get Markets

```typescript
async getMarkets(params?: GetMarketsParams): Promise<any>
```

Retrieves market data.

Parameters:
- `skip`: Optional number of records to skip
- `limit`: Optional limit on the number of records
- `isWhitelisted`: Optional filter for whitelisted markets

Example:
```typescript
const markets = await exchange.getMarkets({
  skip: 0,
  limit: 10,
  isWhitelisted: true
});
```

### Get Order Book

```typescript
async getOrderBook(params: GetOrderBookParams): Promise<any>
```

Retrieves the order book for a market.

Parameters:
- `marketId`: ID of the market
- `tickSize`: Tick size (0.00001, 0.0001, 0.001, 0.01, or 0.1)

Example:
```typescript
const orderBook = await exchange.getOrderBook({
  marketId: 0,
  tickSize: 0.001
});
```

### Get PnL Limit Orders

```typescript
async getPnlLimitOrders(params: GetPnlLimitOrdersParams): Promise<any>
```

Retrieves PnL (Profit and Loss) limit orders.

Parameters:
- `tokenId`: Token ID
- `marketId`: ID of the market
- `userAddress`: Optional user address (defaults to Exchange root)
- `accountId`: Optional account ID (defaults to Exchange accountId)
- `skip`: Optional number of records to skip
- `limit`: Optional limit on the number of records
- `isActive`: Optional filter for active orders
- `orderBy`: Optional field to order by ('timeClosed', 'positionSize', 'avgFixedApr', 'avgUnderlyingApr', 'pnl')
- `fromContract`: Optional boolean to query directly from contract

Example:
```typescript
const pnlOrders = await exchange.getPnlLimitOrders({
  tokenId: 0,
  marketId: 0,
  skip: 0,
  limit: 10,
  isActive: true,
  orderBy: 'pnl'
});
```

### Get Collaterals

```typescript
async getCollaterals(params: { userAddress?: Address; accountId?: number }): Promise<any>
```

Retrieves collateral information. Uses Exchange's root and accountId as defaults.

Parameters:
- `userAddress`: Optional user address (defaults to Exchange root)
- `accountId`: Optional account ID (defaults to Exchange accountId)

Example:
```typescript
const collaterals = await exchange.getCollaterals({});

// Or with explicit address
const collaterals = await exchange.getCollaterals({
  userAddress: '0xYourWalletAddress',
  accountId: 0
});
```

### Get User Positions

```typescript
async getUserPositions(params: GetPnlLimitOrdersParams): Promise<any>
```

Retrieves user positions from on-chain data (both isolated and cross-market positions).

Parameters:
- `tokenId`: Token ID
- `marketId`: ID of the market
- `userAddress`: Optional user address (defaults to Exchange root)
- `accountId`: Optional account ID (defaults to Exchange accountId)

Example:
```typescript
const positions = await exchange.getUserPositions({
  tokenId: 0,
  marketId: 0,
});
```

### Get Market Data

```typescript
async getMarketData(marketId: number): Promise<{
  midApr: number;
  impliedApr: number;
  bestBidApr: number | undefined;
  bestBidTick: number | undefined;
  bestAskApr: number | undefined;
  bestAskTick: number | undefined;
  lastTradedApr: number;
  markApr: number;
  marketStatus: MarketStatus;
}>
```

Retrieves detailed market data including APR and tick information.

Example:
```typescript
const marketData = await exchange.getMarketData(0);
console.log('Mid APR:', marketData.midApr);
```

### Get Gas Balance

```typescript
async getGasBalance(): Promise<number>
```

Returns the gas balance in USD for the current user.

Example:
```typescript
const gasBalance = await exchange.getGasBalance();
console.log('Gas balance (USD):', gasBalance);
```

### Pay Treasury

```typescript
async payTreasury(params: PayTreasuryParams): Promise<any>
```

Pays gas fees to the treasury.

Parameters:
- `isCross`: Whether this is a cross-market payment
- `marketId`: ID of the market
- `usdAmount`: Amount in USD to pay
- `nonces`: Optional array of nonces

Example:
```typescript
const result = await exchange.payTreasury({
  isCross: true,
  marketId: 0,
  usdAmount: 1,
});
```

### Enter/Exit Markets

```typescript
async enterMarkets(cross: boolean, marketIds: number[], nonces?: bigint[]): Promise<any>
async exitMarkets(cross: boolean, marketIds: number[], nonces?: bigint[]): Promise<any>
```

Activate or deactivate markets.

Example:
```typescript
await exchange.enterMarkets(true, [0, 1]);
await exchange.exitMarkets(true, [0]);
```

### Get Assets

```typescript
async getAssets(): Promise<any>
```

Retrieves all available assets.

Example:
```typescript
const assets = await exchange.getAssets();
```

### Get Cumulative PnL

```typescript
async getCumulativePnl(params: { marketAcc: MarketAcc; marketId: number }): Promise<any>
```

Retrieves cumulative PnL for a market account.

Example:
```typescript
const pnl = await exchange.getCumulativePnl({
  marketAcc: '0xMarketAccHex',
  marketId: 0,
});
```