The marginfi Rust CLI

With the marginfi CLI tool, you can interact with the marginfi protocol directly from your terminal, taking advantage of its borrowing and lending services. Built in Rust, this command-line interface simplifies the process of managing your marginfi activities. Whether you want to create a new bank, make deposits to existing banks, or perform other operations, the marginfi CLI provides a streamlined experience.


Installation

To get started, install the latest stable Rust toolchain and set it to default:

rustup default stable-x86_64-apple-darwin
rustc --version

Then, download the CLI tool, navigate inside the folder, and execute the build with the --all-features flag and target x86_64:

git clone https://github.com/mrgnlabs/marginfi-v2.git
cd marginfi-v2/clients/rust/marginfi-cli
cargo install --path . --target x86_64-apple-darwin --all-features

You can then test if the CLI has been installed correctly by running mfi. You should see output like so:

mfi
marginfi-v2-cli 0.1.0

USAGE:
    mfi [OPTIONS] <SUBCOMMAND>

OPTIONS:
        --dry-run              Dry run for any transactions involved
    -h, --help                 Print help information
    -V, --version              Print version information
    -y, --skip-confirmation

SUBCOMMANDS:
    account
    bank
    group
    help                        Print this message or the help of the given subcommand(s)
    inspect-padding
    inspect-size
    inspect-switchboard-feed
    lip
    profile

Getting Started

Step 1: Create a Profile

First, we must create a profile which we will use to interact with the marginfi protocol. To create a profile, use the profile subcommand:

mfi profile create --name <NAME> --cluster <CLUSTER> --keypair-path <KEYPAIR_PATH> --rpc-url <RPC_URL>

For example:

mfi profile create --name masterzorgon --cluster mainnet --keypair-path /Users/MasterZorgon/Documents/Keypairs/UPX866A3Lrdghw1BUdxBkCUMpVEZaokZqFxLskUTiMV.json --rpc-url https://api.mainnet-beta.solana.com

Confirm that you’ve successfully created a profile like so:

mfi profile show

The output should look like the following:

Profile:
    Name: masterzorgon
    Program: MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA
    Marginfi Group: None
    Marginfi Account: None
    Cluster: mainnet
    Rpc URL: https://api.mainnet-beta.solana.com
    Fee Payer: UPX866A3Lrdghw1BUdxBkCUMpVEZaokZqFxLskUTiMV
    Authority: UPX866A3Lrdghw1BUdxBkCUMpVEZaokZqFxLskUTiMV
    Keypair: /Users/MasterZorgon/Documents/Keypairs/UPX866A3Lrdghw1BUdxBkCUMpVEZaokZqFxLskUTiMV.json
    Multisig: None

Step 2: Create a Group

A group represents a lending pool with a set of rules and configurations. It acts as a container for multiple lending banks, each with its own settings. The group defines the overall parameters for the lending and borrowing activities within its scope.

You can create a group using the group subcommand:

mfi group create

You will then be shown the profile you recently created. Type the name of your profile to continue:

Command: Create

Profile:
    Name: masterzorgon
    Program: MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA
    Marginfi Group: None
    Marginfi Account: None
    Cluster: mainnet
    Rpc URL: https://api.mainnet-beta.solana.com
    Fee Payer: UPX866A3Lrdghw1BUdxBkCUMpVEZaokZqFxLskUTiMV
    Authority: UPX866A3Lrdghw1BUdxBkCUMpVEZaokZqFxLskUTiMV
    Keypair: /Users/MasterZorgon/Documents/Keypairs/UPX866A3Lrdghw1BUdxBkCUMpVEZaokZqFxLskUTiMV.json
    Multisig: None
        
Type the name of the profile [masterzorgon] to continue  

Step 3: Create an Account

An account represents an individual user's position within a group. Each user has their own account, which manages their deposits, borrows, and collateral levels. Accounts interact with the lending banks within a group to perform actions like depositing funds, borrowing assets, or repaying loans.

Before you can start borrowing and lending via the CLI, you must set an account and link it to your profile:

mfi account create

You will then be shown the profile you recently created. Type the name of your profile to continue:

Command: Create

Profile:
    Name: masterzorgon
    Program: MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA
    Marginfi Group: None
    Marginfi Account: None
    Cluster: mainnet
    Rpc URL: https://api.mainnet-beta.solana.com
    Fee Payer: UPX866A3Lrdghw1BUdxBkCUMpVEZaokZqFxLskUTiMV
    Authority: UPX866A3Lrdghw1BUdxBkCUMpVEZaokZqFxLskUTiMV
    Keypair: /Users/MasterZorgon/Documents/Keypairs/UPX866A3Lrdghw1BUdxBkCUMpVEZaokZqFxLskUTiMV.json
    Multisig: None
        
Type the name of the profile [masterzorgon] to continue

Step 4: Deposit to a Bank

Now that you’ve created your account, you can interact with the marginfi protocol. Let’s start with lending to a marginfi bank. In this example, we’re going to deposit 1 USDC into the USDC pool 3uxNepDbmkDNq6JhRja5Z8QwbTrfmkKP8AKZV5chYDGG:

mfi account deposit 3uxNepDbmkDNq6JhRja5Z8QwbTrfmkKP8AKZV5chYDGG 1

You will then be shown your profile and asked to confirm the profile you want to interact with by typing the profile name:

Command: Deposit {
    bank: 3uxNepDbmkDNq6JhRja5Z8QwbTrfmkKP8AKZV5chYDGG,
    ui_amount: 1.0,
}

Profile:
    Name: masterzorgon
    Program: MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA
    Marginfi Group: None
    Marginfi Account: None
    Cluster: mainnet
    Rpc URL: https://api.mainnet-beta.solana.com
    Fee Payer: UPX866A3Lrdghw1BUdxBkCUMpVEZaokZqFxLskUTiMV
    Authority: UPX866A3Lrdghw1BUdxBkCUMpVEZaokZqFxLskUTiMV
    Keypair: /Users/MasterZorgon/Documents/Keypairs/UPX866A3Lrdghw1BUdxBkCUMpVEZaokZqFxLskUTiMV.json
    Multisig: None
        
Type the name of the profile [masterzorgon] to continue

Subcommands

Group

Manages lending groups in the marginlend protocol.

  • Name
    add-bank
    Description

    Adds a new lending bank to the marginfi group. (Enabled with admin feature)

  • Name
    create
    Description

    Creates a new marginfi group. (Enabled with admin feature)

  • Name
    get
    Description

    Retrieves information about the specified marginfi group.

  • Name
    get-all
    Description

    Retrieves information about all marginfi groups.

  • Name
    handle-bankruptcy
    Description

    Handles bankruptcy for the specified marginfi accounts in the group. (Enabled with admin feature)

  • Name
    update
    Description

    Updates an existing marginfi group. (Enabled with admin feature)

  • Name
    update-lookup-table
    Description

    Updates the token lookup table for the marginfi group. (Enabled with admin feature)

Bank

Handles operations related to lending banks within groups.

  • Name
    collect-fees
    Description

    Collects fees from a lending bank. (Enabled with admin feature)

  • Name
    get
    Description

    Retrieves information about the specified lending bank.

  • Name
    get-all
    Description

    Retrieves information about all lending banks in the specified marginfi group.

  • Name
    inspect-price-oracle
    Description

    Inspects the price oracle for a lending bank.

  • Name
    settle-all-emissions
    Description

    Settles all pending emissions (rewards) for a lending bank. (Enabled with admin feature)

  • Name
    setup-emissions
    Description

    Sets up emissions (rewards) for a lending bank.

  • Name
    update
    Description

    Updates the configuration of a lending bank. (Enabled with admin feature)

  • Name
    update-emissions
    Description

    Updates the emissions (rewards) parameters for a lending bank. (Enabled with admin feature)

  • Name
    withdraw-fees
    Description

    Withdraws fees from a lending bank. (Enabled with admin feature)

  • Name
    withdraw-insurance
    Description

    Withdraws insurance funds from a lending bank. (Enabled with admin feature)

Profile

Manages user profiles or configurations.

  • Name
    create
    Description

    Creates a new profile configuration.

  • Name
    list
    Description

    Lists all available profile configurations.

  • Name
    set
    Description

    Sets the current profile configuration.

  • Name
    show
    Description

    Shows the current profile configuration.

  • Name
    update
    Description

    Updates an existing profile configuration.

InspectPadding

The inspect-padding subcommand, which is compiled only when the dev feature is enabled, is used to inspect the padding or memory layout-related information for development or debugging purposes.

PatchIdl

The patch-idl subcommand, which is compiled only when the dev feature is enabled, is used to modify the JSON Interface Definition Library (IDL) file for the MarginFi program.

InspectSize

The inspect-size subcommand, which is compiled only when the dev feature is enabled, is used to print the size (in bytes) of various data structures used in the application.

Account

Manages user accounts within the marginlend protocol.

  • Name
    borrow
    Description

    Borrows funds from a lending bank.

  • Name
    create
    Description

    Creates a new marginfi account.

  • Name
    deposit
    Description

    Deposits funds into a lending bank.

  • Name
    get
    Description

    Retrieves information about the specified marginfi account or the currently active account.

  • Name
    liquidate
    Description

    Liquidates a marginfi account by repaying its debt and seizing collateral.

  • Name
    list
    Description

    Lists all available marginfi accounts.

  • Name
    set-flag
    Description

    Sets a flag on a marginfi account.

  • Name
    use
    Description

    Sets the currently active marginfi account.

  • Name
    withdraw
    Description

    Withdraws funds from a lending bank.

Lip

The lip subcommand is related to managing LIP (Liquidity Incentive Program) campaigns and deposits.

  • Name
    list-campaigns
    Description

    Lists all LIP campaigns.

  • Name
    list-deposits
    Description

    Lists all deposits made to LIP campaigns.

InspectSwitchboardFeed

The inspect-switchboard-feed subcommand, which is compiled only when the dev feature is enabled, inspects Switchboard oracle feeds, used for obtaining price data on listings.

ShowOracleAges

Displays information about the ages or staleness of oracle data sources, with an option to filter for only stale oracles.


Examples

Create a Permissionless Isolated Bank

With marginfi permissionless banks, you can create your own isolated bank for any token you want backed by any collateral you want. Below is an example of how to create your first permissionless bank using the marginfi CLI.

Step 2. Assign your CLI profile to a group

Every bank belongs to a group, which acts as a container for banks, setting their configuration and administrative rules. If you have already setup your CLI profile with a group, you can skip this step.

To create a bank within a group, your CLI profile must be assigned to that group.

To get started, query your currency profile configuration and confirm that the Marginfi Group field is empty:

Profile:
    Name: nathan
    Program: MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA
    Marginfi Group: None
    Marginfi Account: None
    Cluster: mainnet
    Rpc URL: <YOUR-RPC-URL>
    Fee Payer: UPX866A3Lrdghw1BUdxBkCUMpVEZaokZqFxLskUTiMV
    Authority: UPX866A3Lrdghw1BUdxBkCUMpVEZaokZqFxLskUTiMV
    Keypair: <PATH-TO-LOCAL-KEYPAIR>>
    Multisig: None

If the Marginfi Group field is empty, update the field with a group pubkey like so:

mfi profile show update <PROFILE-NAME> --group <GROUP-PUBKEY>

For example:

mfi profile update nathan --group 4qp6Fx6tnZkY5Wropq9wUYgtFxXKwE6viZxFHg3rdAG8

Step 3. Use the bank creation command

Using the CLI, type the command mfi group add-bank. This command initializes the process of creating a new bank within your group. You will be prompted to provide several arguments to set up your bank correctly.

A group represents a container that sets configuration and admin rules for banks. It acts as a container for multiple lending banks, each with its own settings. The group defines the overall parameters for the lending and borrowing activities within its scope.

We create a bank using the add-bank subcommand under group because the group serves as the overarching structure that manages and coordinates the individual banks.

error: The following required arguments were not provided:
    --mint <MINT>
    --asset-weight-init <ASSET_WEIGHT_INIT>
    --asset-weight-maint <ASSET_WEIGHT_MAINT>
    --liability-weight-init <LIABILITY_WEIGHT_INIT>
    --liability-weight-maint <LIABILITY_WEIGHT_MAINT>
    --deposit-limit-ui <DEPOSIT_LIMIT_UI>
    --borrow-limit-ui <BORROW_LIMIT_UI>
    --pyth-oracle <PYTH_ORACLE>
    --optimal-utilization-rate <OPTIMAL_UTILIZATION_RATE>
    --plateau-interest-rate <PLATEAU_INTEREST_RATE>
    --max-interest-rate <MAX_INTEREST_RATE>
    --insurance-fee-fixed-apr <INSURANCE_FEE_FIXED_APR>
    --insurance-ir-fee <INSURANCE_IR_FEE>
    --protocol-fixed-fee-apr <PROTOCOL_FIXED_FEE_APR>
    --protocol-ir-fee <PROTOCOL_IR_FEE>
    --risk-tier <RISK_TIER>
    --oracle-type <ORACLE_TYPE>

Here is an explanation for each argument:

  • Name
    --mint
    Type
    Pubkey
    Description

    The token mint address.

  • Name
    --seed
    Type
    bool
    Description

    Generates a PDA for the bank key.

  • Name
    --asset-weight-init
    Type
    f64
    Description

    Initial weight of the asset for risk calculations.

  • Name
    --asset-weight-maint
    Type
    f64
    Description

    Maintenance weight of the asset for risk calculations.

  • Name
    --liability-weight-init
    Type
    f64
    Description

    Initial weight of the liability for risk calculations.

  • Name
    --liability-weight-maint
    Type
    f64
    Description

    Maintenance weight of the liability for risk calculations.

  • Name
    --deposit-limit-ui
    Type
    u64
    Description

    User interface limit for deposits.

  • Name
    --borrow-limit-ui
    Type
    u64
    Description

    User interface limit for borrowing.

  • Name
    --pyth-oracle
    Type
    Pubkey
    Description

    Pyth oracle for price feeds.

  • Name
    --optimal-utilization-rate
    Type
    f64
    Description

    Optimal rate at which the asset is utilized.

  • Name
    --plateau-interest-rate
    Type
    f64
    Description

    Interest rate at the optimal utilization rate.

  • Name
    --max-interest-rate
    Type
    f64
    Description

    Maximum possible interest rate.

  • Name
    --insurance-fee-fixed-apr
    Type
    f64
    Description

    Fixed annual insurance fee rate.

  • Name
    --insurance-ir-fee
    Type
    f64
    Description

    Interest rate component of the insurance fee.

  • Name
    --protocol-fixed-fee-apr
    Type
    f64
    Description

    Fixed annual protocol fee rate.

  • Name
    --protocol-ir-fee
    Type
    f64
    Description

    Interest rate component of the protocol fee.

  • Name
    --risk-tier
    Type
    RiskTierArg: Collateral (0), Isolated (1)
    Description

    The risk tier classification of the asset.

  • Name
    --oracle-type
    Type
    OracleTypeArg: PythEma (0), Switchboard (1)
    Description

    The type of oracle used for price feeds.

  • Name
    --oracle-max-age
    Type
    u16
    Description

    Max oracle age in seconds, 0 for default (60s).

Step 4. Provide the required arguments

Using the CLI, type the command mfi group add-bank and provide the required arguments using double-dashes.

In this example, I will create a permissionless pool for the $BODEN token.

mfi group add-bank  
  --mint 3psH1Mj1f7yUfaD5gh6Zj7epE8hhrMkMETgv5TshQA4o 
  --asset-weight-init 0.5 
  --asset-weight-maint 0.4 
  --liability-weight-init 1.5 
  --liability-weight-maint 1.6 
  --deposit-limit-ui 1000000 
  --borrow-limit-ui 500000 
  --pyth-oracle HdmQWanpTqq6eKASuBKe1ejrHkgSiaAfjZ4qEJEKM9jj 
  --optimal-utilization-rate 0.7 
  --plateau-interest-rate 0.08 
  --insurance-fee-fixed-apr 0.02 
  --insurance-ir-fee 0.05 
  --protocol-fixed-fee-apr 0.02 
  --protocol-ir-fee 0.05 
  --risk-tier 'isolated' 
  --oracle-type 'switchboard' 
  --max-interest-rate 0.25 
  --oracle-max-age 30

Here are explanations for each argument:

  • Name
    --mint
    Type
    Pubkey: 3psH1Mj1f7yUfaD5gh6Zj7epE8hhrMkMETgv5TshQA4o
    Description

    This is the unique address of the token being added to the bank. It remains unchanged as it's specific to the asset.

  • Name
    --asset-weight-init
    Type
    f64: 0.5
    Description

    For risk calculations, only 50% of the asset's value is considered initially, reflecting its high volatility.

  • Name
    --asset-weight-maint
    Type
    f64: 0.4
    Description

    For ongoing risk maintenance, only 40% of the asset's value is considered, providing an extra safety margin.

  • Name
    --liability-weight-init
    Type
    f64: 1.5
    Description

    Borrowed amounts are treated as 150% of their value for initial risk calculations, accounting for higher volatility risk.

  • Name
    --liability-weight-maint
    Type
    f64: 1.6
    Description

    For ongoing risk maintenance, borrowed amounts are treated as 160% of their value, providing an extra safety buffer.

  • Name
    --deposit-limit-ui
    Type
    u64: 1000000
    Description

    Allows for larger deposits, assuming this is a cryptocurrency with lower individual token value.

  • Name
    --borrow-limit-ui
    Type
    u64: 500000
    Description

    Borrowing limit is set lower than the deposit limit to maintain a safety buffer for this volatile asset.

  • Name
    --pyth-oracle
    Type
    Pubkey: HdmQWanpTqq6eKASuBKe1ejrHkgSiaAfjZ4qEJEKM9jj
    Description

    This remains unchanged as it's the specific address for the Pyth oracle providing price information for this asset.

  • Name
    --optimal-utilization-rate
    Type
    f64: 0.7
    Description

    The bank aims to have 70% of its assets in use, slightly lower than before to maintain more liquidity for a volatile asset.

  • Name
    --plateau-interest-rate
    Type
    f64: 0.08
    Description

    The interest rate is 8% when utilization is at the optimal rate, increased to reflect the higher risk of the volatile asset.

  • Name
    --insurance-fee-fixed-apr
    Type
    f64: 0.02
    Description

    A fixed 2% annual fee for insurance, doubled from the previous value due to higher risk.

  • Name
    --insurance-ir-fee
    Type
    f64: 0.05
    Description

    An additional 5% of the interest rate goes to insurance, increased to cover potential rapid value changes.

  • Name
    --protocol-fixed-fee-apr
    Type
    f64: 0.02
    Description

    A fixed 2% annual fee for the protocol, doubled to compensate for higher operational risks.

  • Name
    --protocol-ir-fee
    Type
    f64: 0.05
    Description

    An additional 5% of the interest rate goes to the protocol, increased due to higher risk.

  • Name
    --risk-tier
    Type
    RiskTierArg: Isolated (1)
    Description

    The asset remains classified as "Isolated" risk, appropriate for a highly volatile asset.

  • Name
    --oracle-type
    Type
    OracleTypeArg: PythEma (0)
    Description

    The bank continues to use Pyth as its oracle for price information.

  • Name
    --max-interest-rate
    Type
    f64: 0.25
    Description

    The highest possible interest rate is now 25%, significantly increased to account for the asset's volatility.

  • Name
    --oracle-max-age
    Type
    u16: 30
    Description

    New parameter added to ensure price updates occur at least every 30 seconds, providing more up-to-date information for this volatile asset.

Conclusion

Congrats! You just created a permissionless bank using the marginfi CLI. If you're building an application using marginfi's permissionless banks, please reach out to @nathanzebedee on Telegram for support. We would love to assist you!

Was this page helpful?