> ## Documentation Index
> Fetch the complete documentation index at: https://docs.phoenix.trade/llms.txt
> Use this file to discover all available pages before exploring further.

# Native SOL collateral

> Deposit SOL and include it in Rise TypeScript and Rust margin calculations.

Native SOL stays in the trader account as lamports. No wrapping or USDC conversion is required.

<Info>
  **Migration required — September 16, 2026 deployment**

  Native SOL collateral support is being deployed on September 16. Update your integration for this deployment:

  1. Upgrade to the latest Rise SDK for TypeScript or Rust.
  2. Use the deposit helper below to deposit SOL into a trader account.
  3. Update your margin calculation using the example below. It includes the trader’s SOL balance, SOL’s index price, and the exchange’s collateral discount settings.

  If your app only counts USDC collateral, traders who deposit SOL will see less collateral and a worse account health score than they should. Updating the SDK is not enough if your app still leaves SOL out of its margin calculation.
</Info>

Depositing SOL adds collateral without changing the size, entry price, or direction of existing positions. The exchange counts a discounted portion of SOL’s value toward margin, so account health can change as SOL’s price changes.

Use an existing trader and its owner's signing wallet, with API/RPC endpoints for the same deployment.

## Available instructions

| Action               | TypeScript                                  | Rust                                                 | Details                                                                                                                                                                  |
| -------------------- | ------------------------------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Reserve capacity     | `buildReallocTraderIx`                      | `create_realloc_trader_ix`                           | Reserves one position-map entry for the SOL collateral balance; payer funds any additional rent. Safe to call repeatedly: no-op when sufficient capacity already exists. |
| Deposit              | `buildNativeSolDepositFlow`                 | `create_deposit_native_sol_ixs`                      | Reserve capacity, transfer lamports, then sync collateral subject to caps. Sync is permissionless.                                                                       |
| Withdraw             | `buildWithdrawNativeSolIx`                  | `create_withdraw_native_sol_ix`                      | Owner signs; system-owned destination. Accounted withdrawals are margin checked and throttled.                                                                           |
| Transfer traders     | `buildTransferNativeSolIx`                  | `create_transfer_native_sol_ix`                      | Reserve destination capacity first; supply risk accounts and required authority.                                                                                         |
| Sweep child → parent | `buildTransferNativeSolFromChildToParentIx` | `create_transfer_native_sol_from_child_to_parent_ix` | Flat isolated child; permissionless use depends on sweep preference.                                                                                                     |
| Swap SOL ↔ quote     | `buildSwapNativeIx`                         | `create_swap_native_ix`                              | Supply venue instructions and minimum output: quote lots when selling SOL, lamports when buying.                                                                         |
| Liquidate SOL        | `buildLiquidateNativeSolIx`                 | `create_liquidate_native_sol_ix`                     | Authorized liquidator/risk authority; venue instructions and maximum seized lamports.                                                                                    |

## Deposit SOL

Send **ReallocTrader → System transfer → SyncNative** in one transaction. Native SOL consumes a position-map slot even though it is not a perp position. Reallocate first so additional rent is funded separately; `SyncNative` cannot resize the account.

<Tip>
  Call `ReallocTrader` once to extend the position map by one entry and reserve space for the SOL collateral balance. It is safe to include it in later deposits: when sufficient capacity already exists, it is a no-op.
</Tip>

These examples derive PDA index `0`, subaccount `0` from the owner. Amounts are integer lamports: **0.01 SOL = 10,000,000 lamports**. Keep wallet SOL for rent and fees.

<CodeGroup>
  ```ts TypeScript theme={null}
  import {
    buildNativeSolDepositFlow,
    type Authority, type PhoenixInstructionClient,
  } from "@ellipsis-labs/rise";

  export async function nativeSolDeposit(
    client: PhoenixInstructionClient,
    owner: Authority,
    lamports = 10_000_000n, // 0.01 SOL
  ) {
    if (lamports <= 0n || lamports > 0xffff_ffff_ffff_ffffn) {
      throw new Error("Deposit must fit a positive u64");
    }
    return buildNativeSolDepositFlow({
      authority: owner, traderPdaIndex: 0, subaccountIndex: 0, lamports,
    }, client);
  }
  ```

  ```rust Rust theme={null}
  use phoenix_rise::core::{PhoenixMetadata, TraderKey};
  use phoenix_rise::ix::native_sol::{
      create_deposit_native_sol_ixs, SyncNativeParams,
  };
  use solana_instruction::Instruction;
  use solana_pubkey::Pubkey;

  pub fn native_sol_deposit(
      metadata: &PhoenixMetadata,
      owner: Pubkey,
      lamports: u64, // pass 10_000_000 for 0.01 SOL
  ) -> Result<(Pubkey, Vec<Instruction>), Box<dyn std::error::Error>> {
      let trader = TraderKey::new(owner).pda();
      let keys = metadata.keys();
      let sync = SyncNativeParams::builder()
          .trader_account(trader)
          .global_trader_index(keys.global_trader_index.iter()
              .map(|key| key.parse()).collect::<Result<_, _>>()?)
          .active_trader_buffer(keys.active_trader_buffer.iter()
              .map(|key| key.parse()).collect::<Result<_, _>>()?)
          .build()?;
      let instructions = create_deposit_native_sol_ixs(owner, owner, lamports, sync)?;
      Ok((trader, instructions.into_iter().map(Into::into).collect()))
  }
  ```
</CodeGroup>

The TypeScript helper takes a `PhoenixInstructionClient` configured with your deployment’s addresses and account fetcher (optionally its exchange cache). Both examples return unsigned instructions; the owner signs and sends them.

Rust’s `create_deposit_native_sol_ixs` includes reallocation, transfer, and sync. TypeScript’s `buildNativeSolDepositFlow` also includes reallocation for ordinary wallet-paid deposits. Sponsored deposits require a separate wallet-paid `ReallocTrader` preparation transaction and `traderCapacityPrepared: true`; the sponsored transaction contains only transfer + sync.

Have the wallet sign and submit with matching blockhash/preflight commitments. Confirm before reading margin. Caps can leave part of a successful deposit as uncredited excess, so always reread the accounted balance.

## Compute margin using API data

| Input               | SOL-specific requirement                                                                   |
| ------------------- | ------------------------------------------------------------------------------------------ |
| Balance             | Accounted SOL only; exclude rent and excess. Keep quote collateral separate.               |
| Collateral metadata | Asset index, decimals, pricing market, cap, and discount bounds from the collateral API.   |
| Prices              | Include the SOL pricing market's **index price**, even without a SOL perp position.        |
| Existing state      | Preserve positions, orders, funding, and risk parameters; refresh inputs when they change. |

Effective collateral includes **discounted** SOL value; portfolio value includes **undiscounted** SOL value. SOL adds no perp margin requirement, but the BTC position does. SOL does not increase the quote-withdrawal payout cap: withdraw native SOL or explicitly swap it.

Fetch market prices and collateral metadata from the API, then compute margin with the SDK. In TypeScript, use `getCalculator()` so collateral parameters are included. In Rust, use `to_trader_portfolio_with_metadata(&metadata)?` and pass `&metadata` to `compute_margin`; the quote-only `to_trader_portfolio()` path cannot value SOL. Supply current trader state from [Accounts](/sdk/accounts): TypeScript uses `resource.marginInputs()`; Rust uses the selected `SubaccountState` from the trader-state stream. Recompute after the confirmed deposit and order have appeared in that state.

<CodeGroup>
  ```ts TypeScript theme={null}
  import {
    MarginMarketParamsStore,
    type PhoenixClient, type TraderMarginInputs,
  } from "@ellipsis-labs/rise";

  export async function apiSolMargin(
    client: PhoenixClient,
    inputs: TraderMarginInputs, // resource.marginInputs(); includes spot balances
  ) {
    const params = new MarginMarketParamsStore({ client: client.api });
    // Fetches market configuration, prices, and collateral metadata.
    const calculator = await params.getCalculator();
    const margin = calculator.computeTraderMarginFromInputs(inputs);
    console.log("margin (quote lots)", margin.subaccounts);
    return margin;
  }
  ```

  ```rust Rust theme={null}
  use phoenix_rise::api::{PhoenixHttpClient, PhoenixMetadata, SubaccountState};
  use phoenix_rise::math::TraderPortfolioMargin;

  pub async fn api_sol_margin(
      http: &PhoenixHttpClient,
      subaccount: &SubaccountState, // current trader-state API snapshot
  ) -> Result<TraderPortfolioMargin, Box<dyn std::error::Error>> {
      // Exchange snapshot includes collateral parameters; stats supply prices.
      let mut metadata = PhoenixMetadata::from_snapshot(http.get_exchange_snapshot().await?)?;
      for row in http.markets().get_latest_markets_stats().await?.markets {
          if metadata.get_market(&row.symbol).is_some() {
              metadata.apply_market_stats_v2(&row.into())?;
          }
      }
      let portfolio = subaccount.to_trader_portfolio_with_metadata(&metadata)?;
      let margin = portfolio.compute_margin(&metadata)?;
      println!("margin (quote lots): {margin:#?}");
      Ok(margin)
  }
  ```
</CodeGroup>

These are local calculations using API prices, with index freshness assumed. Keep the SOL pricing market even without a SOL perp position, and never add SOL’s USD value to quote collateral yourself. Use Hawkeye below for an on-chain simulation. Margin and quote collateral use quote lots (`1 quote lot = 0.000001 USD`).

Use the normal [order flow](/sdk/orders) to buy BTC: read the current bid/ask, compute the mid, and cap the buy price at `mid × (1 + slippagePercent / 100)` with a default of `1%`. SOL collateral does not change the order instruction. The deposit and order are separate transactions; a failed order leaves the deposit in place.

## View trader margin with Hawkeye

Hawkeye simulates on-chain margin, including discounted SOL value. Call this after the deposit and again after the order. Margin and quote collateral use quote lots (`1 quote lot = 0.000001 USD`).

<CodeGroup>
  ```ts TypeScript theme={null}
  import { decodeTrader, type PhoenixClient, type TraderAddress } from "@ellipsis-labs/rise";

  export async function printSolMargin(client: PhoenixClient, traderAccount: TraderAddress) {
    const account = await client.rpc.accounts.fetchAccount(traderAccount);
    const trader = decodeTrader(account.data);
    const result = await client.rpc.hawkeye.viewMargin({ traderAccount });
    if (result.err || !result.returnData) throw new Error("Hawkeye margin simulation failed");
    console.log("accounted SOL lamports", trader.nativeSolCollateral.toString());
    console.log("quote collateral", trader.state.quoteLotCollateral.toString());
    console.log("margin (quote lots)", result.returnData.decoded);
  }
  ```

  ```rust Rust theme={null}
  use phoenix_rise::accounts::trader::Trader;
  use phoenix_rise::core::PhoenixHawkeyeClient;
  use solana_pubkey::Pubkey;
  use solana_rpc_client::nonblocking::rpc_client::RpcClient;

  pub async fn print_sol_margin(
      rpc: &RpcClient,
      hawkeye: &PhoenixHawkeyeClient<'_>,
      trader: Pubkey,
  ) -> Result<(), Box<dyn std::error::Error>> {
      let account = rpc.get_account(&trader).await?;
      let decoded = Trader::try_from_account_bytes(&account.data)?;
      println!("accounted SOL lamports: {}", decoded.native_sol_collateral());
      println!("quote collateral: {}", decoded.header().trader_state.quote_lot_collateral.as_inner());
      println!("margin (quote lots): {:#?}", hawkeye.view_margin_for_trader(trader).await?.value);
      Ok(())
  }
  ```
</CodeGroup>
