npm.io
2.2.7 • Published 3d ago

@0dotxyz/p0-ts-sdk

Licence
MIT
Version
2.2.7
Deps
17
Size
17.5 MB
Vulns
0
Weekly
2.0K

Project 0 TypeScript SDK

npm version npm downloads License: MIT TypeScript GitHub

A modern, type-safe TypeScript SDK for interacting with the P0 Protocol on Solana. Lend, borrow, and manage leveraged DeFi positions with a clean, developer-friendly API.

Read the Full Documentation

Features

  • Type-safe: Full TypeScript support with comprehensive type definitions
  • Tree-shakeable: Optimized ESM and CJS builds (<1MB)
  • Well-tested: Unit and integration tests with Vitest
  • Rich examples: 7+ runnable examples covering all core features
  • Modern tooling: Built with tsup, ESLint, Prettier
  • Solana-native: Built on Anchor with full on-chain integration
  • Production-ready: Used in production applications

Installation

npm install @0dotxyz/p0-ts-sdk
# or
yarn add @0dotxyz/p0-ts-sdk
# or
pnpm add @0dotxyz/p0-ts-sdk

Quick Start

1. Initialize the Client
import { Connection, PublicKey } from "@solana/web3.js";
import { Project0Client, getConfig } from "@0dotxyz/p0-ts-sdk";

// Connect to Solana
const connection = new Connection("https://api.mainnet-beta.solana.com", "confirmed");

// Get configuration (mainnet-beta)
const config = getConfig("production");

// Initialize the client (loads all banks and oracle prices)
const client = await Project0Client.initialize(connection, config);

console.log(`Loaded ${client.banks.length} banks`);
2. Load Your Account
import { MarginfiAccount, MarginfiAccountWrapper } from "@0dotxyz/p0-ts-sdk";

const accountAddress = new PublicKey("YOUR_MARGINFI_ACCOUNT_ADDRESS");

// Fetch your account
const account = await MarginfiAccount.fetch(accountAddress, client.program);

// Wrap it for cleaner API
const wrappedAccount = new MarginfiAccountWrapper(account, client);
3. Find a Bank
import { AssetTag } from "@0dotxyz/p0-ts-sdk";

// Option 1: Get bank by address
const bank = client.getBank(new PublicKey("BANK_ADDRESS"));

// Option 2: Get all banks for a mint (e.g., USDC)
const USDC_MINT = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
const usdcBanks = client.getBanksByMint(USDC_MINT);
4. Deposit Tokens
// Build deposit transaction
const depositTx = await wrappedAccount.makeDepositTx(
  usdcBank.address,
  "100" // Amount in UI units (100 USDC)
);

// Simulate (optional, but recommended)
const simulation = await connection.simulateTransaction(depositTx);
console.log(`Compute units: ${simulation.value.unitsConsumed}`);

// Sign and send
// depositTx.sign([wallet]);
// await connection.sendTransaction(depositTx);
5. Borrow Against Collateral
// Check how much you can borrow
const maxBorrow = wrappedAccount.computeMaxBorrowForBank(usdcBank.address);
console.log(`Max borrow: $${maxBorrow.toString()}`);

// Build borrow transaction
const borrowTx = await wrappedAccount.makeBorrowTx(
  usdcBank.address,
  "100" // Borrow 100 USDC
);

// Send transaction...
6. Monitor Account Health
import { MarginRequirementType } from "@0dotxyz/p0-ts-sdk";

// Get free collateral in USD
const freeCollateral = wrappedAccount.computeFreeCollateral();
console.log(`Free collateral: $${freeCollateral.toString()}`);

// Get health components
const health = wrappedAccount.computeHealthComponents(MarginRequirementType.Initial);

const healthFactor = health.assets.div(health.liabilities);
console.log(`Health factor: ${healthFactor.toString()}`);

Examples

Check out the examples/ directory for complete, runnable examples:

Each example includes:

  • Full setup instructions
  • Detailed comments
  • Error handling
  • Transaction simulation
Running Examples
cd examples
cp .env.example .env
# Edit .env with your values
tsx 01-deposit.ts

Core Concepts

Project0Client

The main SDK client that manages protocol interactions.

const client = await Project0Client.initialize(connection, config);

// Pre-loaded data (fetched once at initialization)
client.banks                // All available banks
client.bankMap              // Banks indexed by address
client.oraclePriceByBank   // Latest oracle prices
client.mintDataByBank      // Token mint metadata
client.addressLookupTables // For transaction optimization

// Methods
client.getBank(address)             // Get bank by address
client.getBanksByMint(mint, tag?)   // Get all banks for a mint

Benefits:

  • Single initialization loads all chain data
  • Reuse throughout your application
  • Automatic oracle price caching
  • Built-in lookup table support
MarginfiAccount & Wrapper

Your lending account on the protocol.

// Fetch raw account
const account = await MarginfiAccount.fetch(address, client.program);

// Wrap for clean API (recommended)
const wrapped = new MarginfiAccountWrapper(account, client);

// All methods have access to banks, oracles, etc.
wrapped.computeMaxBorrowForBank(bankAddress);
wrapped.makeDepositTx(bankAddress, amount);
wrapped.computeFreeCollateral();
Bank

A lending pool for a specific token.

const bank = client.getBank(bankAddress);

bank.mint; // Token mint address
bank.config; // Interest rates, weights, limits
bank.config.assetWeightInit; // Collateral factor (LTV)
bank.config.liabilityWeightInit; // Borrow weight
Balance

Your position in a specific bank.

const balance = account.balances[0];

balance.bankPk; // Bank address
balance.assetShares; // Deposit shares
balance.liabilityShares; // Borrow shares
balance.active; // Is position active?

Package Structure

The SDK provides optimized entry points:

// Main SDK (core functionality)
import { Project0Client, MarginfiAccount, getConfig } from "@0dotxyz/p0-ts-sdk";

// Vendor utilities (oracle integrations, Jupiter, etc.)
import { fetchOracleData, OraclePrice } from "@0dotxyz/p0-ts-sdk/vendor";

Why separate vendor exports?

  • Reduces bundle size for simple use cases
  • Oracle libraries (Pyth, Switchboard) are large
  • Tree-shake what you don't need

Key Features

Type Safety

Full TypeScript support with exported types:

import type {
  MarginfiAccountType,
  BankType,
  BalanceType,
  OraclePrice,
  MarginRequirementType,
  Project0Config,
} from "@0dotxyz/p0-ts-sdk";
Multiple Bank Support

Handle cases where multiple banks exist for the same mint:

// Get ALL SOL banks (main + Kamino)
const solBanks = client.getBanksByMint(WSOL_MINT);

// Filter by tag
const mainSolBanks = client.getBanksByMint(WSOL_MINT, AssetTag.SOL);
const kaminoBanks = client.getBanksByMint(WSOL_MINT, AssetTag.KAMINO);
Health Calculations

Built-in account health monitoring:

import { MarginRequirementType } from "@0dotxyz/p0-ts-sdk";

// Free collateral (how much you can still borrow)
const free = wrapped.computeFreeCollateral();

// Health components (assets vs liabilities)
const health = wrapped.computeHealthComponents(
  MarginRequirementType.Initial // or Maintenance
);

// Max amounts
const maxBorrow = wrapped.computeMaxBorrowForBank(bankAddress);
const maxWithdraw = wrapped.computeMaxWithdrawForBank(bankAddress);

Testing

The SDK includes comprehensive tests:

# Unit tests (fast, no RPC needed)
pnpm test:unit

# Integration tests (requires RPC)
SOLANA_RPC_URL=https://api.mainnet-beta.solana.com pnpm test:integration

# All tests
pnpm test

# With coverage
pnpm test:coverage

Testing Strategy:

  • Unit tests: Pure calculations, conversions, validations
  • Integration tests: Real chain data, transaction building, simulations

See TESTING.md for details.

Development

Prerequisites
  • Node.js >= 18.0.0
  • pnpm (recommended)
Setup
# Install dependencies
pnpm install

# Build the SDK
pnpm build

# Watch mode (for development)
pnpm dev

# Type check
pnpm typecheck

# Lint and format
pnpm lint
pnpm format
Project Structure
p0-ts-sdk/
├── src/
│   ├── index.ts              # Main SDK exports
│   ├── vendor/               # Vendor entry point (oracles, etc.)
│   ├── config.ts             # Network configurations
│   ├── models/               # Core models
│   │   ├── client.ts         # Project0Client
│   │   ├── account.ts        # MarginfiAccount
│   │   ├── account-wrapper.ts # MarginfiAccountWrapper
│   │   ├── bank.ts           # Bank model
│   │   └── ...
│   ├── services/             # Business logic
│   │   ├── account/          # Account operations
│   │   ├── price/            # Oracle price fetching
│   │   └── ...
│   ├── instructions/         # Transaction builders
│   ├── types/                # TypeScript types
│   ├── idl/                  # Anchor IDL
│   └── utils/                # Helpers
├── tests/
│   ├── unit/                 # Unit tests (mocked)
│   ├── integration/          # Integration tests (real RPC)
│   └── fixtures/             # Test data
├── examples/                 # 7+ runnable examples
└── dist/                     # Build output
    ├── index.js              # ESM bundle
    ├── index.cjs             # CJS bundle
    ├── index.d.ts            # Type definitions
    └── vendor.*              # Vendor bundles
Available Scripts
Script Description
pnpm build Build ESM + CJS bundles
pnpm dev Watch mode for development
pnpm test Run all tests
pnpm test:unit Run unit tests only
pnpm test:integration Run integration tests
pnpm test:coverage Generate coverage report
pnpm lint Lint with ESLint
pnpm format Format with Prettier
pnpm typecheck TypeScript type checking
pnpm clean Remove build artifacts
pnpm changeset Create a changeset for releases
pnpm version Bump version from changesets
pnpm release Build and publish to npm

Publishing

This package uses Changesets for version management and npm publishing.

See RELEASING.md for detailed instructions, or .changeset/QUICKSTART.md for a quick reference.

Quick publish:

npm login
pnpm changeset    # Document changes
pnpm version      # Bump version
pnpm release      # Publish to npm
git push --follow-tags

Contributing

We welcome contributions! Please see our contributing guidelines:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes with tests
  4. Run pnpm test and pnpm lint
  5. Commit your changes (git commit -m 'Add amazing feature')
  6. Push to the branch (git push origin feature/amazing-feature)
  7. Open a Pull Request
Development Workflow
# 1. Make changes
vim src/models/client.ts

# 2. Add tests
vim tests/unit/models/client.test.ts

# 3. Run tests
pnpm test:unit

# 4. Build
pnpm build

# 5. Test with examples
cd examples && tsx 01-deposit.ts

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

This SDK is built on top of the marginfi protocol, leveraging its on-chain programs and infrastructure.

Additional thanks to:

Disclaimer

This SDK is provided as-is. Always:

  • Understand the risks of DeFi protocols
  • Monitor your account health
  • Use appropriate risk management
  • Audit your integration code

Built for builders by the P0 team

Keywords