Below is the documentation for the SDK. For more details about the overall architecture, contracts, API, and more, please refer to the documentation folder.
The repository is organized as follows:
- documentation:
- lite-paper: lite paper for how boros works
- contracts-docs: contains the documentation to deep dive into the contracts, the overall architecture, and terminology
- API.docs.md: API documentation
- SDK.docs.md: SDK documentation
- example: example code for the SDK
- src: contains the source code of the SDK
You can start with the lite paper to understand the overall architecture and mechanics of the platform.
Then you can go to the API docs to understand the API and parameters. After that, you can refer to SDK docs and example to see how to use the SDK.
yarn add @pendle/sdk-borosconstructor(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 transactionsroot: The wallet address (Address type from viem)accountId: The numerical ID of the account to interact withrpcUrls: Array of RPC endpoint URLs for blockchain interactionsagent: Optional Agent instance for transaction signing
Example:
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]
);Below is a complete example showing how to create an agent, approve it, and place an order:
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.
async placeOrder(params: PlaceOrderParams): Promise<{
executeResponse: any;
result: { order: any };
}>Places a new order on the exchange.
Parameters:
marketAcc: Use MarketAccLib to packmarketId: ID of the marketside: Trade side (Enum: Side)size: Order size as bigintlimitTick: Optional tick price limitslippage: Optional slippage tolerancetif: 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:
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,
});Multiple versions are available for bulk placing orders.
async bulkPlaceOrdersV5(request: BulkPlaceOrderV5Params): Promise<any>Supports mixed single and bulk order requests in a unified interface.
Parameters (BulkPlaceOrderV5Params):
orderRequests: Array ofSingleOrderRequest | BulkOrderRequestobjectsnonces: 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:
// 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 },
}],
},
],
});async bulkPlaceOrdersV2(request: BulkPlaceOrderV2Params): Promise<any>Places multiple orders for the same market account.
Parameters (BulkPlaceOrderV2Params):
marketAcc: Hex market account identifiermarketId: ID of the marketsides: Array of Side valuessizes: Array of order sizes as bigintlimitTicks: Array of tick price limitstif: Time-in-force settingammId: Optional AMM IDslippage: Optional slippage tolerancenonces: Optional array of nonces
async cancelOrders(params: CancelOrdersParams): Promise<{
executeResponse: any;
result: { cancelledOrders: any };
}>Cancels one or more orders.
Parameters:
marketAcc: Use MarketAccLib to packmarketId: ID of the marketcancelAll: Boolean indicating whether to cancel all ordersorderIds: Array of order ID strings to cancel (use empty array when cancelAll is true)nonces: Optional array of nonces
Example:
// 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: []
});async bulkCancelOrders(cancelOrderRequests: CancelOrdersParams[]): Promise<Array<{
executeResponse: any;
result: { cancelledOrders: any };
}>>Cancels multiple orders from different markets.
Parameters:
cancelOrderRequests: Array of CancelOrdersParams objects
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:
// 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);setAgent(agent: Agent): void
getAgent(): Agent | undefinedSet or get the agent used for signing transactions.
Example:
const { agent } = await Agent.create(walletClient);
exchange.setAgent(agent);
const currentAgent = exchange.getAgent();async deposit(params: DepositParams): Promise<any>Deposits funds into the exchange. Handles ERC20 approval automatically.
Parameters:
userAddress: Address of the usertokenId: Token ID of the collateraltokenAddress: Optional token contract address (auto-resolved from tokenId if not provided)amount: Amount to deposit as bigintaccountId: Account ID to deposit intomarketId: Market ID to deposit into
Example:
const receipt = await exchange.deposit({
userAddress: '0xYourWalletAddress',
tokenId: 0,
amount: 1000000000000000000n, // 1 token with 18 decimals
accountId: 0,
marketId: 0,
});async withdraw(params: WithdrawParams): Promise<any>Withdraws funds from the exchange.
Parameters:
userAddress: Address of the usertokenId: Token ID of the collateralamount: Amount to withdraw as bigint
Example:
const receipt = await exchange.withdraw({
userAddress: '0xYourWalletAddress',
tokenId: 0,
amount: 1000000000000000000n // 1 token with 18 decimals
});async cashTransfer(params: CashTransferParams): Promise<any>Transfers cash between markets.
Parameters:
marketId: ID of the marketisDeposit: true if transferring from vault to marketIdamount: Amount to transfer as bigintnonces: Optional array of nonces
Example:
const response = await exchange.cashTransfer({
marketId: 1,
isDeposit: true,
amount: 1000000000000000000n // 1 token with 18 decimals
});async closeActivePositions(params: CloseActivePositionsParams): Promise<any>Closes active positions.
Parameters:
marketAcc: Hexadecimal market account identifiermarketId: ID of the marketside: Trade side (Side enum)size: Size to close as bigintlimitTick: Tick price limittif: Time-in-force setting (TimeInForce enum)slippage: Optional slippage tolerancenonces: Optional array of nonces
Example:
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,
});async updateSettings(params: UpdateSettingsParams): Promise<any>Updates account settings.
Parameters:
marketAcc: Hexadecimal market account identifiermarketId: ID of the marketleverage: Leverage valuesignature: Signature as hexadecimalagent: Agent address as hexadecimaltimestamp: Timestamp
Example:
const response = await exchange.updateSettings({
marketAcc: '0xMarketAccHex',
marketId: 0,
leverage: 5, // 5x leverage
signature: '0xSignatureHex',
agent: '0xAgentAddress',
timestamp: Math.floor(Date.now() / 1000)
});async getMarkets(params?: GetMarketsParams): Promise<any>Retrieves market data.
Parameters:
skip: Optional number of records to skiplimit: Optional limit on the number of recordsisWhitelisted: Optional filter for whitelisted markets
Example:
const markets = await exchange.getMarkets({
skip: 0,
limit: 10,
isWhitelisted: true
});async getOrderBook(params: GetOrderBookParams): Promise<any>Retrieves the order book for a market.
Parameters:
marketId: ID of the markettickSize: Tick size (0.00001, 0.0001, 0.001, 0.01, or 0.1)
Example:
const orderBook = await exchange.getOrderBook({
marketId: 0,
tickSize: 0.001
});async getPnlLimitOrders(params: GetPnlLimitOrdersParams): Promise<any>Retrieves PnL (Profit and Loss) limit orders.
Parameters:
tokenId: Token IDmarketId: ID of the marketuserAddress: Optional user address (defaults to Exchange root)accountId: Optional account ID (defaults to Exchange accountId)skip: Optional number of records to skiplimit: Optional limit on the number of recordsisActive: Optional filter for active ordersorderBy: Optional field to order by ('timeClosed', 'positionSize', 'avgFixedApr', 'avgUnderlyingApr', 'pnl')fromContract: Optional boolean to query directly from contract
Example:
const pnlOrders = await exchange.getPnlLimitOrders({
tokenId: 0,
marketId: 0,
skip: 0,
limit: 10,
isActive: true,
orderBy: 'pnl'
});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:
const collaterals = await exchange.getCollaterals({});
// Or with explicit address
const collaterals = await exchange.getCollaterals({
userAddress: '0xYourWalletAddress',
accountId: 0
});async getUserPositions(params: GetPnlLimitOrdersParams): Promise<any>Retrieves user positions from on-chain data (both isolated and cross-market positions).
Parameters:
tokenId: Token IDmarketId: ID of the marketuserAddress: Optional user address (defaults to Exchange root)accountId: Optional account ID (defaults to Exchange accountId)
Example:
const positions = await exchange.getUserPositions({
tokenId: 0,
marketId: 0,
});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:
const marketData = await exchange.getMarketData(0);
console.log('Mid APR:', marketData.midApr);async getGasBalance(): Promise<number>Returns the gas balance in USD for the current user.
Example:
const gasBalance = await exchange.getGasBalance();
console.log('Gas balance (USD):', gasBalance);async payTreasury(params: PayTreasuryParams): Promise<any>Pays gas fees to the treasury.
Parameters:
isCross: Whether this is a cross-market paymentmarketId: ID of the marketusdAmount: Amount in USD to paynonces: Optional array of nonces
Example:
const result = await exchange.payTreasury({
isCross: true,
marketId: 0,
usdAmount: 1,
});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:
await exchange.enterMarkets(true, [0, 1]);
await exchange.exitMarkets(true, [0]);async getAssets(): Promise<any>Retrieves all available assets.
Example:
const assets = await exchange.getAssets();async getCumulativePnl(params: { marketAcc: MarketAcc; marketId: number }): Promise<any>Retrieves cumulative PnL for a market account.
Example:
const pnl = await exchange.getCumulativePnl({
marketAcc: '0xMarketAccHex',
marketId: 0,
});