Open Net Worth
Open Net Worth is an open-source personal AI wealth assistant you run yourself: one ledger for your whole financial life, worked by an AI agent you control.
Lend and borrow across Project 0 markets with live rates and liquidity.
FinanceTypeScript · JavaScriptGitHub @0dotxyzOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗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.
@solana/kit with Codama-generated program clientsnpm install @0dotxyz/p0-ts-sdk
# or
yarn add @0dotxyz/p0-ts-sdk
# or
pnpm add @0dotxyz/p0-ts-sdk
import { address, createSolanaRpc } from "@solana/kit";
import { Project0Client, getConfig } from "@0dotxyz/p0-ts-sdk";
// Connect to Solana. The endpoint is also used for bundle simulation (`simulateBundle`), which
// health-cache simulation needs.
const rpcEndpoint = "https://api.mainnet-beta.solana.com";
const rpc = createSolanaRpc(rpcEndpoint);
// Get configuration (mainnet-beta)
const config = getConfig("production");
// Initialize the client (loads all banks and oracle prices)
const client = await Project0Client.initialize({ rpc, rpcEndpoint }, config);
console.log(`Loaded ${client.banks.length} banks`);
const accountAddress = address("YOUR_MARGINFI_ACCOUNT_ADDRESS");
// Fetch your account (refreshes its health cache by simulation) and wrap it for a cleaner API.
// Pass your wallet's `TransactionSigner` as the third argument to sign what it builds; without
// one, transactions are built for a noop signer of the account authority (simulation only).
const wrappedAccount = await client.fetchAccount(accountAddress, false, walletSigner);
import { AssetTag } from "@0dotxyz/p0-ts-sdk";
// Option 1: Get bank by address
const bank = client.getBank(address("BANK_ADDRESS"));
// Option 2: Get all banks for a mint (e.g., USDC)
const USDC_MINT = address("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
const usdcBank = client.getBanksByMint(USDC_MINT, AssetTag.DEFAULT)[0];
import {
compileTransaction,
getBase64EncodedWireTransaction,
signTransactionMessageWithSigners,
} from "@solana/kit";
// Build deposit transaction: a Kit transaction message with fee payer, blockhash and lookup
// tables set, and the wrapper's signer embedded
const depositTx = await wrappedAccount.makeDepositTx(
usdcBank.address,
"100" // Amount in UI units (100 USDC)
);
// Simulate (optional, but recommended)
const simulation = await rpc
.simulateTransaction(getBase64EncodedWireTransaction(compileTransaction(depositTx.message)), {
encoding: "base64",
sigVerify: false,
})
.send();
console.log(`Compute units: ${simulation.value.unitsConsumed}`);
// Sign and send
// const signed = await signTransactionMessageWithSigners(depositTx.message);
// await rpc.sendTransaction(getBase64EncodedWireTransaction(signed), { encoding: "base64" }).send();
// 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.computeFreeCollateralFromCache();
console.log(`Free collateral: $${freeCollateral.toString()}`);
// Get health components
const health = wrappedAccount.computeHealthComponentsFromCache(MarginRequirementType.Initial);
const healthFactor = health.assets.div(health.liabilities);
console.log(`Health factor: ${healthFactor.toString()}`);
Check out the examples/ directory for complete, runnable examples:
Each example includes:
This is the beginning of the README. Read the rest at the original. Read the full README ↗