Marginfi transaction workflows separate signing control from execution requirements
Marginfi's Solana lending program supports deposits, borrowing, withdrawals and repayment through transactions its replacement SDK constructs for the signer. Execution requirements vary: ordinary actions may fit one transaction, preparatory updates may run sequentially and some position changes require an atomic bundle. The program powers Project 0; the legacy Marginfi frontend was retired in mid-2026.
The relevant choice concerns which balance should change and how the surrounding instructions must execute. Each bank identifies a lending pool with its own permissions and limits. Multiple banks can use the same token, so selecting a bank affects transaction construction and execution.
Signer Authorization Across Lending Workflows
Every transaction builder in
@0dotxyz/p0-ts-sdk
returns unsigned transactions; the caller supplies authorization and controls submission. The caller selects the target bank and supplies the requested amount in token UI units, while account authority determines whose signature authorizes the operation. The SDK assembles instructions from account data, bank configuration and relevant prices. The application or script presents the transaction to its signing system and submits it. Approval doesn't override collateral requirements, operational restrictions or oracle freshness checks the program applies. Borrowing and ordinary withdrawals must satisfy initial account-health checks; ordinary deposits and repayments don't require those checks.
A constructed transaction describes an intended state change. Signing approves its instructions; submission requests execution. The action's confirmed status establishes whether it completed.
When Can Transactions Run Sequentially?
Sequential submission suits ordinary borrow or withdrawal results needing a separate oracle update, provided no atomic-bundle requirement applies. Deposit and repayment builders return single transactions. Borrow and withdrawal builders may return preparation followed by the action. Preserve the returned order and confirm each transaction before continuing. A false
mustBeAtomicBundle
permits sequential sending; the action still needs fresh prices when it executes.
Which Workflows Require Atomic Execution?
Bridged swap workflows and integration-dependent flows require atomic bundles when their builders set
mustBeAtomicBundle
to
true
. Several transactions may express one position change. Sending those transactions sequentially can leave only part of the intended change executed. Here, a bridge token connects swap legs on Solana; it doesn't imply a cross-chain transfer.
A result with
mustBeAtomicBundle
set to
true
requires its returned transactions to land together as one atomic Jito bundle.
Within a single flash-loan transaction, the program postpones the relevant health check until the ending instruction. If that final initial-margin check fails, the entire transaction reverts.
Later price movements and interest accrual remain part of the account owner's debt and liquidation exposure.
Collateral Replacement and Debt Replacement
A hypothetical account supplies collateral token A and owes debt token B, with C and D representing alternative collateral and debt choices. Which existing balance remains in place during each replacement?
makeSwapCollateralTx
withdraws A, exchanges it for C and deposits C into the destination bank. A successful full-position replacement leaves supplied C in place of supplied A, while existing B debt retains its interest obligations.
makeSwapDebtTx
borrows D, swaps D into B and applies B to the existing debt. Supplied A remains in the account. The builder sizes the new borrow from the supplied USD-per-token market prices; it doesn't use an ExactOut quote.
The collateral replacement changes the supplied asset; the debt replacement changes borrowing exposure while preserving collateral. Debt repayment depends on swap output, so a quote alone doesn't establish a closed B balance. Confirmed balances distinguish a full debt replacement from a replacement leaving some B debt outstanding.
These outcomes apply only while the destination bank permits the requested action, the route fits and final health passes. C needs a depositable bank; D needs a borrowable bank. A changed price or configuration can invalidate the proposed replacement before execution.
Build Errors and Confirmed Partial Progress
A build-time error leaves submission with the caller because the builder hasn't signed or sent an action.
ORACLE_CRANK_FAILED
identifies banks whose required feeds couldn't update, while routing errors describe unusable quotes or routes exceeding transaction limits. Collateral-swap, debt-swap and loop builders offer bridged alternatives for size or quote failures when the caller hasn't pinned swap instructions.
BRIDGE_CONFLICT
means every bridge candidate conflicts with an opposite-side position in a required bank. Existing supplied balances can block a loop's bridge borrow; existing borrowed balances can block a collateral swap's bridge deposit. Changing the route doesn't remove account-health requirements or make a restricted bank operational.
Sequential workflows leave the sender responsible for a failed action after successful preparation. The
actionTxIndex
field identifies the lending action within result types exposing that field. An application should associate completion with that transaction's confirmed success, rather than the earlier price update. Repeating a borrow the program already completed can create additional debt. Rebuilding requires appropriate account, bank and price data; reusing an earlier transaction sequence doesn't establish that its prerequisites still hold.
For swap-based partial repayment,
makeRepayWithCollatTx
derives
amountToRepay
from the quote's minimum output and caps it at
totalPositionAmount
. If expected output exceeds the debt, the builder selects full-position repayment instead. When collateral and debt share a mint, it skips the swap and
amountToRepay
equals
withdrawAmount
. These fields describe construction; the application must confirm execution before reporting debt reduction.
SDK Versions and Program Compatibility
@mrgnlabs/marginfi-client-v2
stopped receiving updates on March 15, 2026. Program 0.1.10's August 25, 2026 mainnet deployment broke flash loans, health simulation and account transfers in the legacy SDK and p0-ts-sdk versions below 2.7.0; program 0.1.11 introduced additional oracle-decoding requirements.
Banks using program 0.1.11's new oracle variants require
@0dotxyz/p0-ts-sdk
2.8.0 or later for decoding.
An unknown variant in one bank can break older client initialization for the whole group, affecting position reads as well as actions.
Who Controls Bank Limits and Pauses?
Group administrators control bank caps, weights and operational states; account signers choose requested actions within those configurations. A supplied asset can earn interest while carrying zero collateral weight in an Isolated bank. An account can borrow only one Isolated asset at a time. Reduce-Only banks permit withdrawals and repayments while blocking deposits and new borrowing. Existing positions continue accruing interest, and liquidations continue. Paused banks block deposits, withdrawals, borrowing and repayment. Builder support alone doesn't establish permission to execute an action.
The global fee administrator holds a separate protocol-wide pause authority. Signer approval doesn't bypass these administrator-controlled states. Debt selection can also change automatic Efficiency Mode (Emode) treatment. Adding a non-preferential borrowed asset can remove preferential collateral weights otherwise available to the account. The signer controls that borrowing choice, while configured weights determine its effect on health. Ongoing account monitoring remains necessary after an authorized action completes.
Stake Conversion, Venue Deposits and Custom Instructions
Native stake requires conversion before ordinary lending.
Staked banks accept single-validator liquid staking tokens minted by the SPL single-pool program.
The stake account must delegate to the validator matching the selected bank, and
makeMintStakedLstTx
handles conversion. A separate deposit builder funds the staked bank under the account authority's authorization. The native-stake helpers are standalone functions exported from the package root. Converting stake alone doesn't create a lending balance, while stake delegated elsewhere doesn't qualify for that bank's token.
A Kamino-backed bank accepts the reserve's underlying token and routes deposits into that reserve. Its builders attach the reserve and obligation refreshes the action requires. The SDK's integration-state map holds a snapshot from initialization, so cached metadata doesn't represent a permanent view of the venue. Bank state and refreshed venue data govern whether the requested action can execute.
A matured Exponent principal-token position uses
makeRollPtTx
for rollover into a successor maturity. The builder composes withdrawal, redemption, purchase and deposit within its flash-loan flow. High-level builders assemble these dependencies around the chosen operation, while instruction-level construction gives the caller finer control over composition. That additional control includes responsibility for oracle accounts, venue refreshes and flash-loan boundaries.
Common questions about Marginfi
Does Reading a Marginfi Account Require a Connected Wallet?
Reading account state through Project0Client doesn't require a connected wallet. Project0Client.initialize creates a client without a wallet, and account-loading methods retrieve existing positions. Authorization becomes necessary when a transaction changes state. This separates inspection from execution: possessing an account address or loading its balances doesn't grant authority to withdraw collateral or borrow through that account.
Why Does a Marginfi Borrow Fail When Simulated on Its Own?
An isolated borrow simulation can fail when the action depends on an oracle update in a preceding transaction. Single-transaction simulation doesn't carry that preparation forward. The simulateBundle helper evaluates the returned set through an RPC endpoint supporting bundle simulation. A plain public endpoint may lack that method. Such a simulation failure doesn't by itself prove the complete ordered operation would fail.
How Do Marginfi Debt-Swap Quotes Identify the New Borrow?
Direct debt-swap quotes identify the new borrow through quoteResponse.inAmount, while bridged results map it to quoteResponse.outAmount. A defined bridgeMint identifies the bridged path. These quote amounts use native token units, so decimal conversion must match the relevant token. Reading the wrong side can reverse the meaning of the displayed amount; neither field confirms the debt the program ultimately records.
Does Marginfi Repayment With Collateral Have a Bridged Builder?
The makeRepayWithCollatTx builder has no bridged variant. It combines collateral withdrawal, any required swap and repayment inside a flash loan. Bridged variants exist for collateral swaps, debt swaps and loops, which restructure positions differently. Their availability doesn't provide an interchangeable repayment fallback. A repayment route exceeding transaction limits therefore needs a supported route or composition fitting that operation.
Must Existing Marginfi Accounts Change Address During SDK Migration?
Existing keypair-based accounts can retain their addresses when integrations migrate to p0-ts-sdk. The replacement SDK can still load and use them. New account creation uses program-derived addresses with account indices, allowing multiple accounts under one wallet. Changing the client package therefore doesn't itself move collateral or debt into a newly created account, and address generation differs from transferring an existing position.
When Should Extra Signers Accompany a Marginfi Transaction?
Extra signers must accompany signing when the SDK includes them in tx.signers. Builders can generate additional keypairs for temporary token accounts, and partial native-stake conversion can require a split-account keypair. Those signers complement the authority approving the operation. An application dropping this metadata can fail to sign the transaction completely, even when the wallet approves its own required signature.
Are Marginfi Priority Fees Included in Every SDK Builder?
Simple deposit, borrow, withdrawal and repayment builders don't automatically add compute-budget instructions. The SDK's built-in loop, swap, collateral-repayment, PT-rollover and position-transfer flows already include a compute-unit limit and price, so adding another pair can duplicate those instructions. Custom fee handling must respect the transaction's existing construction and flash-loan instruction ordering. makePriorityFeeMicroIx expresses its price in micro-lamports per compute unit.
Updated -