Huma Finance
Huma 2.0 PayFi yield on Solana: PST APY, price and pool liquidity, wallet balances, USDC deposits with optional lockups, queued redemptions, native instant withdrawals, and claims.
The Huma Finance node talks to the Huma 2.0 permissionless pool on Solana through Huma's official SDK. Depositing USDC mints PST, the PayFi Strategy Token (USDC yield plus Huma Feathers rewards). The older Maxi mode minted mPST; Huma retired it in April 2026, and existing mPST positions can still be read and redeemed here. PST represents a share of pool assets, and its USDC redemption value grows as yield accrues. PST is a normal SPL token: it trades against USDC on Jupiter and Meteora, and it can be used as collateral on Kamino.
No API key is needed. Reads come from the Huma program on chain and from Huma's public rewards API. The four operations that move funds, deposit, requestWithdrawal, instantWithdraw, and claimProcessed, sign with your connected wallet: Solaris AI builds the transaction, decodes it, refuses anything outside the expected shape, signs it through your embedded wallet, and broadcasts it. No private key ever leaves the platform, and every signing operation carries a Dry run switch that builds and simulates the transaction without signing.
PST has three ways out, and the node covers all of them. A queued redemption (requestWithdrawal) pays NAV with no fee, but Huma processes it later under a daily cap. A native instant withdrawal (instantWithdraw) burns PST for USDC in the same transaction at NAV minus a fee that depends on how liquid the pool is at that moment. A secondary swap on Relay or Jupiter sells PST at the market price, outside every Huma cap. getPoolStatus and a dry run of instantWithdraw give you the numbers to choose.
Prerequisites
- Read operations: nothing.
depositandrequestWithdrawal: a connected wallet with server-side signing authorized, the USDC or PST being moved, and about 0.01 SOL for account rent and network fees. The first deposit in a mode creates a lender account and a token account for that mode; a withdrawal from a wallet that received its tokens by transfer or swap creates the lender account in the same transaction.
What to build with it
- Yield monitor: a cron trigger once a day,
getApyin Classic mode, a Condition on{humaResponse.data.totalApyPercent}, and a Telegram message when the APY drops below your floor. - Park idle USDC: a Balance node reading the wallet's USDC, a Condition on the amount, then
depositwith the amount templated from the balance. Run it with Dry run first; the output carries the simulation result and any funding gap. - Slow exit with a receipt:
requestWithdrawalfor the unlocked balance fromgetBalances, then a dailygetBalancesuntilpendingRedemptionsreads zero, then a Discord message. - Fast exit:
getBalances, then a Relay or Jupiter swap from the PST mint (59obFNBzyTBGowrkif5uK7ojS58vsuWz3ZCvg6tfZAGw) to USDC. The swap settles immediately and never touches the redemption queue or its daily cap. - Best-route exit:
instantWithdrawwith Dry run on for the exact net USDC Huma would pay right now, a Jupiter quote for the same PST, a Condition comparing the two, then either the liveinstantWithdrawor the swap. AddgetBalancesfirst and refuse the run whenpendingRequestsis not zero or the amount exceedsunlocked. - Sweep processed redemptions: a daily
claimProcessed. It reads the chain and signs nothing when there is nothing to claim.
Operations
Every operation takes a Mode: classic for PST or maxi for mPST. The two modes are separate positions with their own APY, price, balances, and token account. Huma retired Maxi mode in April 2026 (new deposits and switches disabled, rewards ended 26 May 2026), so maxi is only useful for reading or redeeming an existing mPST position: the node refuses a Maxi deposit even though the program would still accept one.
Yield
getApy: the target base APY of the mode, read from the on-chain mode config, plus Huma's estimated Feathers rewards APY from the rewards API. Both come back in basis points (baseApyBps, estRewardsApyBps, totalApyBps) and in percent (baseApyPercent, estRewardsApyPercent, totalApyPercent). The rewards estimate exists for Classic only; Maxi reports zero there, because its rewards are Feathers rather than a USDC rate.
getTokenPrice: the current PST or mPST price in USDC, computed on chain as pool assets divided by token supply. price is a decimal string such as 1.034512 and priceRaw is the same figure in 6-decimal base units. tokenMint, symbol, and underlyingMint name the token and USDC.
getPoolStatus: the pool's liquidity and limits, read from its on-chain config and state accounts. No wallet is involved. status is on, off, preClosure, or closed, and acceptingDeposits is true while the pool is on with room under liquidityCap (depositRoom is that room). poolUsdcOnHand is the USDC sitting in the pool vault, liquidAssetsDeployed is what the pool has lent out but can recall, and totalAssets sums every mode. The instant-withdrawal fee is keyed to the pool's liquid-asset ratio after a withdrawal: instantFeeTiers lists each tier (fee in basis points while the ratio is below a threshold), estimatedLiquidRatioPercent is the ratio right now, and estimatedInstantFeeBps is the tier that ratio falls in. On mainnet in September 2026 the tiers were 3 bps above 12% liquidity, then 20 bps, 1%, 1.5%, 1.8%, and 100% below 5%. instantReserveFloor is USDC the pool keeps back from instant withdrawals. redemptionWindow and instantWindow report the program's daily caps on shares with today's usage and what remains. The estimate is informational: a dry run of instantWithdraw returns the exact fee the program computes.
Position
getBalances: the wallet's position in the mode. Owner Wallet is optional; leave it empty to read the connected wallet, or pass any base58 address (no signature is involved). The output splits the balance into unlocked (redeemable now), locked (inside a 3 or 6 month lockup, reported by Huma's rewards API), and pendingRedemptions (escrowed in open redemption requests, read from the Huma program's lender account on chain, with pendingRequests counting the open requests), plus claimableUsdc (processed USDC Huma could not transfer to the wallet and holds for you to claim; usually 0), total (unlocked plus locked), the current price, and valueUsdc (total times price). Every figure is a decimal string with a matching ...Raw field in base units. A wallet that never held the token reads all zeros rather than failing. Lockups have no on-chain record, so locked depends on Huma's rewards API: when that read fails the node reports locked as 0, unlocked as the full held balance, and explains in lockupReadWarning instead of failing.
Wallet
deposit signs a live transaction. It builds the deposit with the SDK, verifies that the bytes carry exactly the requested amount, lockup, and mode mint and that your wallet is the only signer, checks the wallet's USDC and SOL, and then signs and broadcasts once.
- Amount (USDC) is in human units with at most 6 decimals:
25is 25 USDC. The minimum is 1 USDC. Huma caps each wallet at 2,000,000 USDC across PST and mPST; the SDK refuses to build a deposit past it and the node reports that refusal. - Lockup is optional:
none(default, redeem any time),3m(2x Feathers), or6m(3x Feathers). A locked position cannot be withdrawn until its term ends, and transferring, swapping, or lending locked tokens forfeits the bonus retroactively. Lockups only move forward; a later deposit can extend one but never shorten it. Set a lockup deliberately, never as a default. - With Dry run on (the default for a freshly placed node), the node returns
status: "simulated"withsimulation.ok,simulation.error,simulation.unitsConsumed, the estimated PST at the current price, andbalanceWarningwhen the wallet is short. Nothing is signed. With it off, the output carriessignature,txExplorer, andstatusofconfirmedorpending.
requestWithdrawal signs a live transaction. It files a redemption request for Amount PST or mPST (human units, minimum 1). This is not an instant withdrawal: the tokens move out of the wallet into the request, and Huma pays out USDC when it processes the request. Requests are processed first-come first-served, typically within one business day with a seven day service level, under a daily global cap that resets at 00:00 UTC. Only the unlocked balance can be requested; the node reads the lockup figure from Huma's rewards API and refuses a request that exceeds it, and when that read is unavailable the node refuses to sign, because lockups have no on-chain record and the program cannot tell locked tokens from unlocked ones; the dry run still runs and explains the gap in lockupReadWarning. Once the transaction confirms, the node re-reads the lender account on chain and reports the new pendingRedemptions and pendingRequests. It also tells Huma's services about the request; synced reports whether that call succeeded, and a failed sync (for example for a wallet that has never signed in to app.huma.finance) never fails the run because Huma also scans the chain and the pending figure above comes from the chain regardless. For an instant exit, swap PST to USDC on Relay or Jupiter instead.
instantWithdraw signs a live transaction through the program's own instant-withdrawal path, which Huma's public documentation does not yet describe (Solaris AI verified it against the deployed program). It burns Amount PST (human units, minimum 0.01) and pays USDC into your wallet in the same transaction: the shares' value at NAV minus a fee. The fee is progressive across the liquid-asset-ratio tiers the withdrawal crosses, so it is 3 bps while the pool is liquid and climbs steeply when the pool is short; the pool pulls USDC back from its lending strategy (JupLend today) when its vault balance is not enough. Max fee is your ceiling in basis points of the USDC value (default 25): the node converts it to the absolute cap the program expects, and the program refuses the withdrawal when its fee would exceed that cap, so a low cap is the safety net against a stressed pool. Only the unlocked balance can be withdrawn; the node applies the same lockup check as requestWithdrawal. The dry run returns assets (USDC at NAV), fee, feeBps, and netUsdc, exactly as the program computed them, which makes it the quote to compare against a swap. A live run reads the same receipt from the landed transaction and reports fromStrategy when the pool had to recall lending liquidity. The withdrawal counts against its own daily cap (instantWindow in getPoolStatus), separate from the redemption queue.
claimProcessed collects USDC from redemption requests Huma already processed but could not transfer to your wallet at the time (the claimableUsdc figure from getBalances; usually zero, non-zero only when the payout transfer failed and the funds were parked for you). The node reads the chain first and returns status: "nothing-to-claim" without signing when nothing is waiting, so it is safe to run on a schedule. When something is waiting it signs the program's disburse instruction, which pays out everything at once; claimed reports the amount on a confirmed run.
Before signing any of these transactions, Solaris AI decodes what was built and refuses anything outside the expected shape: only the Huma program and the Associated Token program may appear, only your wallet may sign, any token account being created must be your own (or, for an instant withdrawal, the pool's receipt-token account that the lending pull needs), the deposit, redemption, or instant-withdrawal instruction must carry exactly the requested amount (plus the requested lockup on a deposit and the computed fee cap on an instant withdrawal), and the USDC must be paid to your own account. The signature and blockhash are saved before the first broadcast. The landing helper may resend the same signed bytes, but the engine never retries the operation with a new signature. A transaction still unconfirmed after the sixty-second landing budget is reported as pending; the next run reconciles that evidence against the chain before signing another transaction.
Configuration
| Field | Type | Required | Description |
|---|---|---|---|
| mode | string | Yes | classic (PST) | maxi (mPST, retired: reads and requestWithdrawal only) |
| owner | string | No | getBalances wallet to read instead of the connected wallet |
| amount | string | deposit, requestWithdrawal, instantWithdraw | Human units, up to 6 decimals; at least 1 (0.01 for instantWithdraw); templates accepted |
| lockup | string | No | deposit: none (default) | 3m | 6m |
| maxFeeBps | string | No | instantWithdraw: fee ceiling in whole basis points, 1 to 10000, default 25 |
| dryRun | boolean | No | deposit, requestWithdrawal, instantWithdraw, claimProcessed: build and simulate, never sign |
Output
Read operations return the standard envelope with the figures under data:
{
"success": true,
"operation": "getBalances",
"data": {
"mode": "classic",
"owner": "7fUAJdStEuGbc3sM84cKRL6yYaaSstxLsvvDvHtiQVEm",
"tokenMint": "59obFNBzyTBGowrkif5uK7ojS58vsuWz3ZCvg6tfZAGw",
"symbol": "PST",
"unlocked": "250",
"unlockedRaw": "250000000",
"locked": "0",
"lockedRaw": "0",
"pendingRedemptions": "0",
"pendingRedemptionsRaw": "0",
"pendingRequests": "0",
"claimableUsdc": "0",
"claimableUsdcRaw": "0",
"total": "250",
"totalRaw": "250000000",
"price": "1.034512",
"valueUsdc": "258.628",
"lockupReadWarning": null
}
}Reference fields downstream with the response name (default humaResponse), for example {humaResponse.data.totalApyPercent} after getApy, {humaResponse.data.unlocked} after getBalances, or {humaResponse.data.signature} after deposit.
StonkFunNew
Launchpad for coins paired with anything (tokenized stocks, pre-IPO tokens, currencies, SOL): discovery feeds, holder rewards, burns and buybacks, launching a coin, and claiming creator fees.
Alchemy
Solana RPC, token prices, balances, NFTs, and Digital Asset Standard (DAS) data via Alchemy.
