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
- π 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
npm install @0dotxyz/p0-ts-sdk
# or
yarn add @0dotxyz/p0-ts-sdk
# or
pnpm add @0dotxyz/p0-ts-sdkimport { 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`);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);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);// 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);// Check how much you can borrow (account health + bank borrow cap + bank liquidity)
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...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()}`);Check out the examples/ directory for complete, runnable examples:
- 01-deposit.ts - Deposit tokens and earn interest
- 02-borrow.ts - Borrow against your collateral
- 03-withdraw.ts - Withdraw your deposits
- 04-repay.ts - Repay borrowed amounts
- 05-oracle-prices.ts - Work with oracle price feeds
- 06a-account-health-simulated.ts - Monitor account health
- 06b-account-health-calculated.ts - Calculate health metrics
Each example includes:
- β Full setup instructions
- β Detailed comments
- β Error handling
- β Transaction simulation
cd examples
cp .env.example .env
# Edit .env with your values
tsx 01-deposit.tsThe 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 mintBenefits:
- Single initialization loads all chain data
- Reuse throughout your application
- Automatic oracle price caching
- Built-in lookup table support
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();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 weightYour 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?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
Full TypeScript support with exported types:
import type {
MarginfiAccountType,
BankType,
BalanceType,
OraclePrice,
MarginRequirementType,
Project0Config,
} from "@0dotxyz/p0-ts-sdk";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);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 β bank-aware:
// borrow = min(health-based, remaining borrow cap, available bank liquidity, rate-limit headroom)
// withdraw = min(health-based, available bank liquidity, rate-limit headroom)
// deposit = remaining deposit cap (optionally min'd with your wallet balance)
// (rate-limit headroom = bank net-outflow limiter in tokens + group USD limiter, if enabled)
const maxBorrow = wrapped.computeMaxBorrowForBank(bankAddress);
const maxWithdraw = wrapped.computeMaxWithdrawForBank(bankAddress);
const maxDeposit = wrapped.computeMaxDepositForBank(bankAddress, { walletBalance: 1_000 });
// Pass { ignoreBankLimits: true } to get the purely health-based borrow/withdraw amountThe 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:coverageTesting Strategy:
- Unit tests: Pure calculations, conversions, validations
- Integration tests: Real chain data, transaction building, simulations
See TESTING.md for details.
- Node.js >= 18.0.0
- pnpm (recommended)
# 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 formatp0-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
| 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 |
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-tagsWe welcome contributions! Please see our contributing guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes with tests
- Run
pnpm testandpnpm lint - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
# 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.tsThis project is licensed under the MIT License - see the LICENSE file for details.
This SDK is built on top of the marginfi protocol, leveraging its on-chain programs and infrastructure.
Additional thanks to:
- Solana Web3.js - Solana JavaScript API
- Anchor - Solana development framework
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