# _gamma documentation (full) # Introduction Source: https://app.gma.fi/docs/introduction.md _gamma is a non-custodial yield platform built on Solana. You deposit into a vault, receive an SPL share token that represents your position, and autonomous software agents do the ongoing work of finding and rebalancing toward risk-adjusted yield. You keep custody of your share tokens at all times, and every vault runs on-chain programs that anyone can verify. The platform has operated institutional-grade infrastructure since 2022. Its agents monitor 2,000+ assets across 1,000+ pools on 20+ Solana protocols, continuously, so that capital is not left sitting in a single protocol or a stale position. ## The problem it addresses Earning competitive yield in DeFi is operationally demanding. Rates move constantly, liquidity shifts between protocols, leverage positions need health monitoring, and capturing the best risk-adjusted return means rebalancing across many venues. Doing this by hand requires time, tooling, and expertise that most depositors do not have. _gamma turns that ongoing effort into a single deposit. ## Gamma Economic Agents (G.E.A.s) Each vault is operated by a **Gamma Economic Agent (G.E.A.)** — an autonomous, ML-powered agent that ingests market data, computes a risk-adjusted view of each strategy, solves for a target portfolio balancing yield against risk and transition cost, and executes on-chain around the clock. The agents hold no user funds beyond a small operational float: deposits live in on-chain vault programs, and an agent can only move funds within an allowlisted set of protocols and instructions. See [How it works](/docs/how-it-works). ## Key features - **Non-custodial by design.** Funds sit in on-chain vault programs; you hold the share token. The agent cannot withdraw to arbitrary destinations. - **Continuous monitoring and optimization.** Allocation is recomputed and rebalanced around the clock, not on a fixed manual schedule. - **Automated execution and rebalancing.** Agents build, sign, and submit the on-chain transactions to move funds, and only rebalance when the expected improvement clears the real cost of the transition. - **Hands-free compounding, full control.** Yield accrues to the vault and is reflected in a rising share price — nothing to claim or restake. Deposit or request a withdrawal at any time; there are no lock-ups. - **Risk-adjusted allocation.** Allocation optimizes yield *subject to* risk limits, not in spite of them, with diversification across venues and health monitoring on leveraged positions. - **Transparency.** NAV is published on-chain and is verifiable by anyone. Share price is simply NAV divided by total shares. ## Products at a glance _gamma currently offers three vault products, each denominated in a single asset and issuing its own SPL share token. | Product | Asset | Share token | Focus | | --- | --- | --- | --- | | [gmSTBL](/docs/products) | USDC | gmSTBL | Stablecoin lending, rate arbitrage, fixed-yield, RWA-backed stable assets | | [gmSOL](/docs/products) | SOL | gmSOL | LST optimization, SOL lending, leveraged staking loops | | [plRWA](/docs/products) | USDC | plRWA | Tokenized real-world assets on Plume (Nest vaults) | Yields are variable and are never promised in this documentation. The pages that follow describe mechanisms, not expected returns. Next: [Products](/docs/products) --- # Products Source: https://app.gma.fi/docs/products.md Each _gamma product is a non-custodial vault — internally a Gamma Economic Agent (G.E.A.) — that you deposit into and receive an SPL share token for. The three live products differ by the asset you deposit and the strategies the agent runs. Share price is always `NAV / total shares`, published on-chain and verifiable by anyone. --- # gmSTBL (Stablecoins) Source: https://app.gma.fi/docs/products/gmstbl.md gmSTBL is _gamma's stablecoin vault. You deposit and withdraw in **USDC** and receive **gmSTBL** share tokens. The agent pursues risk-adjusted yield across a suite of stablecoin strategies while keeping exposure within the stable asset class. | Attribute | Value | | --- | --- | | Deposit / withdraw asset | USDC | | Share token | gmSTBL (SPL) | | Strategy class | Stablecoins | | Share price | NAV / total shares, published on-chain | ## Strategies The gmSTBL agent allocates across four broad strategy types, rebalancing continuously based on risk-adjusted rates. ### Lending optimization The agent monitors real-time supply rates, utilization, liquidity depth, and protocol risk across stablecoin lending venues — including Kamino, MarginFi, Project Zero, Save, Loopscale, and Jupiter Lend — and routes deposits toward the highest risk-adjusted yield. Idle capital not deployed elsewhere is automatically routed to lending rather than left sitting. ### Stablecoin rate arbitrage Rate and funding-rate arbitrage kept within the stable asset class: **both legs stay stable-denominated**, and cross-class pairings (for example a stablecoin leg against SOL or ETH) are excluded by design, so the strategy's exposure stays stable. ### Yield-bearing stable assets The vault can hold tokenized, yield-bearing stable assets such as T-bill and RWA-backed tokens. These instruments update their rates on a slower cadence (typically around monthly) and are treated accordingly by the rate engine rather than as high-frequency market data. ### Fixed-yield exposure via Exponent The agent can take fixed-yield exposure through Exponent's markets — it provides liquidity in principal-token (PT) pools and may hold yield-token (YT) positions to maturity, when the risk-adjusted terms are attractive. These positions are marked and valued into NAV using cross-mint rates. ## Risk controls - **Provider tier caps** limit concentration with any single lending or arbitrage venue. - **Both-legs-in-class** gating keeps rate-arbitrage exposure stable-denominated. - **Staleness and freshness guards** exclude stale rate inputs and block user operations when NAV is stale. - **Cost-aware rebalancing** only moves funds when the improvement clears transition costs. See [The ML solver](/docs/how-it-works) for how these constraints enter the allocation decision, and [Rate analysis](/docs/how-it-works) for how each strategy's rate is scored. ## Deposits and withdrawals Deposits are instant and mint gmSTBL at the current share price. Withdrawals are either instant (when the vault holds enough liquid USDC) or queued via an on-chain withdrawal receipt while the agent frees liquidity — typically minutes. See [Deposits](/docs/deposits-withdrawals) and [Withdrawals](/docs/deposits-withdrawals). Yields are variable and on-chain verifiable; no specific return is promised here. Next: [gmSOL (Solana)](/docs/products/gmsol) --- # gmSOL (Solana) Source: https://app.gma.fi/docs/products/gmsol.md gmSOL is _gamma's SOL vault. You deposit and withdraw in **SOL** and receive **gmSOL** share tokens. The agent pursues SOL-denominated yield from staking, lending, and controlled leverage, with health monitoring on every leveraged position. | Attribute | Value | | --- | --- | | Deposit / withdraw asset | SOL | | Share token | gmSOL (SPL) | | Strategy class | Solana | | Share price | NAV / total shares, published on-chain | ## Strategies ### Liquid staking token (LST) optimization The agent holds and rotates between liquid staking tokens when the reward difference justifies the move. Because LST-to-LST swaps are near-free, the agent can shift toward the best-yielding staking token without meaningfully eroding value on transaction cost. Rotations still pass the same cost-versus-benefit test as any other rebalance. ### SOL lending SOL can be supplied to lending venues for additional yield, with the agent monitoring supply rates, utilization, liquidity depth, and protocol risk and routing toward the highest risk-adjusted return. Idle SOL not otherwise deployed is routed to lending. ### Leveraged staking loops Controlled leverage loops that amplify staking yield, via venues such as Kamino multiply and Project Zero loops. Leverage is bounded by strict per-strategy caps, with continuous liquidation-health monitoring and automated deleveraging if a position's health deteriorates; loops are opened only where they can be closed cleanly. ## Risk controls - **Strict leverage caps** bound every loop; the agent does not exceed the configured ceiling for a strategy. - **Liquidation-health monitoring** with automated deleveraging protects positions if the market moves against the loop. - **Provider tier caps** limit concentration with any single protocol. - **Cost-aware rebalancing** and **NAV freshness gates** apply as they do across all vaults. Because SOL is a volatile asset, the value of a gmSOL position moves with SOL itself; the vault optimizes SOL-denominated yield, not USD-denominated returns. See [The ML solver](/docs/how-it-works) and [Rate analysis](/docs/how-it-works). ## Deposits and withdrawals Deposits are instant and mint gmSOL at the current share price. Withdrawals are instant when the vault holds enough liquid SOL, or queued via an on-chain receipt while the agent unwinds positions to free liquidity — typically minutes. Fully closing a leveraged loop can occasionally take longer than a simple lending exit. See [Deposits](/docs/deposits-withdrawals) and [Withdrawals](/docs/deposits-withdrawals). Yields are variable and on-chain verifiable; no specific return is promised here. Next: [plRWA (Plume RWA)](/docs/products/plrwa) --- # plRWA (Plume RWA) Source: https://app.gma.fi/docs/products/plrwa.md plRWA is _gamma's real-world-asset vault. You deposit and withdraw in **USDC** and receive **plRWA** share tokens. The vault routes capital into institutional tokenized real-world assets — Nest vaults on the **Plume** network — earning yield sourced from off-chain assets rather than on-chain lending markets. | Attribute | Value | | --- | --- | | Deposit / withdraw asset | USDC | | Share token | plRWA (SPL) | | Strategy class | RWA (Plume / Nest) | | Settlement | Cross-chain (USDC bridged to Plume and back) | | Share price | NAV / total shares, published on-chain | ## What it invests in plRWA allocates exclusively into institutional RWA vaults curated on Plume (the Nest vaults). These represent tokenized real-world assets and pay yield on the cadence of the underlying instruments. This isolation — deposits only ever reaching the approved RWA venue — is enforced server-side by the agent's allowlist, not just in the interface. ## Cross-chain mechanics plRWA is cross-chain. When you deposit, USDC is bridged from Solana to Plume and deployed into the RWA vaults; when you redeem, the position is unwound and USDC is bridged back to Solana. Deposits bridge USDC to Plume via CCTP; redemptions return via LayerZero. Because settlement crosses chains and the underlying assets are real-world instruments, redemptions above the vault's on-chain liquidity buffer take longer to fulfill than the SOL or stablecoin vaults — typically a matter of days rather than minutes. Plan withdrawals accordingly. See [Withdrawals](/docs/deposits-withdrawals). ## Yield cadence RWA yields update on the cadence of the underlying assets — rate updates are typically around monthly, characteristic of tokenized real-world instruments. The rate engine treats these as slow-moving asset-token rates and exempts them from the high-frequency staleness filters that apply to on-chain market data. As with every vault, the realized yield is variable and reflected in the share price; no specific return is promised here. ## Risk controls - **Allowlist isolation** — capital can only reach the approved Nest RWA venue. - **Liquidity buffer** — a portion is held liquid on Solana to serve instant and smaller withdrawals. - **Cross-chain settlement** — redemptions carry an on-chain withdrawal receipt, so funds in transit are never in limbo. - **NAV freshness gates** apply as they do across all vaults. ## Deposits and withdrawals Deposits are instant on the Solana side and mint plRWA at the current share price. Withdrawals draw from the liquidity buffer when possible; larger redemptions queue while the cross-chain unwind completes. See [Deposits](/docs/deposits-withdrawals) and [Withdrawals](/docs/deposits-withdrawals). Next: [Agents (G.E.A.s)](/docs/how-it-works) --- # How it works Source: https://app.gma.fi/docs/how-it-works.md Every _gamma vault is operated by an autonomous **Gamma Economic Agent (G.E.A.)** that runs a continuous loop: ingest market data, analyze it, solve for a target portfolio, execute the moves, and publish NAV. This page gives a high-level overview of each stage. ![_gamma architecture pipeline: Data ingestion, then Rate analysis, then ML solver, then Agent execution, feeding back to data ingestion](/diagrams/architecture-pipeline.svg) ## The agent ![The agent loop: Monitor, then Analyze, then Solve, then Execute, repeating every cycle](/diagrams/agent-loop.svg) Each vault has its own agent — gmSTBL, gmSOL, and plRWA each run independently, so a strategy's risk and rebalancing stay contained to its own vault. The agent is a crash-safe, autonomous workflow: work is decomposed into discrete steps whose progress is persisted, so if a process is interrupted mid-cycle it resumes exactly where it left off rather than restarting or double-executing. An agent holds no user funds beyond a small operational float. Deposits live in on-chain vault programs, and the agent can only construct transactions that move funds within the protocols and instructions its policies permit — it cannot withdraw to an arbitrary destination. Those policies are multisig-gated, and changes require multiple signers. The agent never holds a raw private key in application memory: signing happens inside **Google Cloud KMS** with hardware-backed keys that never leave the secure boundary. Combined with the multisig-gated policies, this means even a compromise of the application layer cannot move funds outside the approved policy. ## Data ingestion The agent continuously collects market data — rates, liquidity, and prices — across the integrated protocols, cross-checked against on-chain state. On-chain state is authoritative: where a provider-published figure disagrees with the chain, the chain wins, and untrustworthy or stale inputs are dropped rather than acted on. Coverage spans the venues the vaults use, including Kamino, MarginFi, Project Zero, Save, Loopscale, Jupiter Lend, Exponent, and the Nest RWA vaults on Plume. ## Rate analysis From that validated data the agent produces a proprietary, risk-adjusted return estimate for each asset and strategy — a common scale on which a stablecoin lending position, a rate-arbitrage loop, and a fixed-yield position can be compared like-for-like. Actual realized yield remains variable and on-chain verifiable; the risk-adjusted estimate is an internal ranking signal, not a promised return. ## The ML solver An optimization engine continuously computes a target portfolio that balances yield against risk, and rebalances only when the expected improvement clears the real cost of the transition. The result is a diversified target, not an all-in bet on the single highest nominal rate. Configuration expresses business intent by forcing or excluding specific investments through explicit constraints, rather than by distorting the underlying math. ## NAV and shares A vault's value and your position both reduce to two numbers: **NAV** (net asset value — what the vault is worth) and **total shares** (how many share tokens exist). Share price is simply: ``` share price = NAV / total shares ``` ![Share price equals NAV divided by total shares — NAV is the on-chain value of all positions, total shares is the share-token supply](/diagrams/nav-share-price.svg) NAV is the on-chain value of every position the vault holds — lending balances, leverage-loop equity, LST holdings, fixed-yield positions, RWA vault positions, and any liquid asset. Because positions are valued from on-chain reads, NAV reflects the vault's real, verifiable state, and anyone can independently reconstruct it. The agent publishes NAV on-chain with **freshness protection**: the vault program blocks deposits and withdrawals when NAV is stale, so you never transact at a mispriced value. Yield accrues to NAV, so as the vault earns, the share price rises and each share is worth more — there is nothing to claim or restake. Deposits mint shares and withdrawals burn them, both at the same fresh, NAV-derived price, so existing depositors are neither diluted by new deposits nor shortchanged by withdrawals. Next: [Deposits & withdrawals](/docs/deposits-withdrawals) --- # Deposits & withdrawals Source: https://app.gma.fi/docs/deposits-withdrawals.md ## Deposits A deposit into a _gamma vault (a Gamma Economic Agent, or G.E.A.) exchanges your assets for share tokens. Deposits settle in a single on-chain transaction that you sign with your own wallet. There is no minimum deposit and there are no lock-up periods. ![Deposit flow: you send USDC to the vault, which mints gmSTBL share tokens back to your wallet at the current share price](/diagrams/deposit-flow.svg) Each vault takes a specific asset: gmSTBL takes USDC, gmSOL takes SOL, and plRWA takes USDC. Share tokens are standard SPL tokens that live in your wallet. Holding them is what makes your position non-custodial — only your wallet can redeem your shares. Every vault publishes its Net Asset Value (NAV) on-chain, and the share price is simply `NAV / total shares outstanding`. When you deposit, the program mints shares at the **current** price (`shares = deposit amount / share price`), so a deposit neither dilutes nor is diluted by existing holders. The program will not let you deposit against a stale price: if the published NAV is too old, user operations are blocked until it refreshes. There is no deposit fee. Once your deposit confirms, your shares begin accruing yield immediately — reflected as **share-price appreciation** over time, not as new tokens. You never need to claim, compound, or reinvest; yield compounds inside the vault automatically. ## Two withdrawal paths You can request a withdrawal from a G.E.A. at any time — there are no lock-ups. What happens next depends on how much liquid asset the vault is holding at that moment. - **Instant path** — if the vault already holds enough liquid USDC (or SOL) to cover your redemption, the withdrawal settles in a single transaction and the assets land in your wallet right away. - **Queued path** — if your withdrawal is larger than the vault's liquid headroom, the program creates an **on-chain withdrawal receipt** recording your pending shares. The agent then exits positions to free the liquidity, and once it is ready you claim your assets in a second transaction. The app decides which path applies by reading the vault's on-chain liquid balance against its tracked pending withdrawals, so the classification reflects real state at request time. ![Withdrawal lifecycle: Request creates an on-chain receipt, then Freeing funds, then Bridging (cross-chain RWA only), then Ready to claim, then Claim; the instant path skips straight to Ready to claim](/diagrams/withdrawal-lifecycle.svg) ## The on-chain receipt The queued path is not a promise held off-chain — it is a receipt written to the Solana program. Your pending shares are recorded on-chain the moment you request, so your funds are **never in limbo**: the claim is enforced by the program, not by _gamma. If anything interrupted _gamma's operations, the receipt and your right to claim against it would still exist on-chain. Once the vault has freed enough liquidity the position becomes claimable; you submit a claim transaction from your wallet and the assets transfer to you. Until you claim, your shares remain recorded on the receipt. ## Staged progress While a withdrawal is queued, the app shows a live checklist so you always know where it stands: | Stage | Meaning | | -------------- | ---------------------------------------------------------- | | Received | The on-chain receipt was created for your pending shares. | | Freeing funds | The agent is exiting positions to fund the withdrawal. | | Bridging | Cross-chain RWA only — funds are settling back from Plume. | | Ready to claim | Liquidity is available; submit the claim to receive assets.| The **Bridging** stage appears only for cross-chain RWA redemptions (the plRWA vault, whose positions settle back over a bridge). Stablecoin and SOL vaults free liquidity with on-chain divests and skip it entirely. ## Timing Timing depends entirely on which path your withdrawal takes. The instant path settles in one transaction — seconds. The queued path has a median around 10 minutes on stablecoin vaults (SOL vaults are similar — a few agent cadences), and cross-chain RWA is typically longer, with the bridge settling hours to about a day. These are typical figures, not guarantees. When a withdrawal is queued, the app does not quote a hardcoded wait. It shows an arrival **band** derived from the vault's own recent history — the p50 (median) and p90 request-to-ready durations measured over the last 30 days — presented as a range (for example "10 min–2 h"). The estimate is hedged: it is suppressed when there is not enough recent history to be meaningful, and the displayed median is floored at roughly one agent cadence, so the app never advertises a p50 faster than the agent can realistically act. For cross-chain RWA the app merges the agent's free-up band with the measured bridge-settlement band and shows the slower of the two. You do not need to keep the app open — the receipt persists on-chain, and you can return to claim once the position is marked ready. ## The withdrawal fee A small basis-point fee applies to withdrawals. The fee is a **per-vault on-chain policy**, not a fixed platform constant — read the live value programmatically from the `withdrawalFeeBps` field of a vault's [`stats`](/docs/api/vault-endpoints) endpoint rather than assuming a number. | Parameter | Value | | ---------------- | --------------------------------------------------------- | | Withdrawal fee | Currently 30 bps (0.30%) on the live vaults | | Retained by | The vault, for the benefit of remaining depositors | | Full-exit waiver | Waived when you redeem your entire share balance | The fee is retained inside the vault rather than paid out to _gamma, so it accrues to the depositors who remain. When you exit your full position the fee is waived to avoid stranding dust. There is no separate deposit fee. Vaults may also charge a performance fee, which is read directly from the on-chain vault account. Withdrawals are also subject to net-outflow guardrails (hourly and daily caps measured against NAV, with deposits offsetting withdrawals) that smooth large redemptions; in normal conditions these are not binding. Next: [Security](/docs/security) --- # Security Source: https://app.gma.fi/docs/security.md ## Non-custodial design _gamma never takes custody of your assets. When you deposit, your capital moves into an on-chain vault program and you receive share tokens — standard SPL tokens held in your own wallet. Those shares are your claim on the vault's Net Asset Value. The Gamma Economic Agent (G.E.A.) that runs a vault is an optimizer, not a custodian: it decides how pooled assets are allocated across vetted protocols, but it cannot pay them out to itself or to any wallet it chooses. The vault is a Solana program with rules baked into its instructions. Only the holder of the share tokens can redeem them, and withdrawals settle to the redeeming wallet. The agent's signing authority is scoped to allocating into and out of approved protocols — not to sweeping funds out of the vault. Deposits and withdrawals are blocked when the published NAV is stale, so you can never enter or exit at a mispriced value. There are no lock-up periods, and your right to claim is enforced by the program, so even in the unwinding window your funds are never in limbo (see [Deposits & withdrawals](/docs/deposits-withdrawals)). What you trust is narrow and auditable: the vault program that holds funds and enforces redemption, the on-chain policies that constrain what the agent may touch, and the key-management system that guards the agent's signing key. You do not trust _gamma with custody, because it never has it. ## Key management Each G.E.A. signs its transactions through Google Cloud KMS. The signing keys are hardware-backed keys managed in Google Cloud KMS; key material is never exposed to application code, never written to disk, and never exported. Signing happens **inside** the KMS boundary. This means a compromise of _gamma's application servers does not expose an agent key. The most an attacker in that position could attempt is to request a signature — and agent operations are governed by multisig-gated policies restricting which protocols and instructions agents may use, with every signing request recorded in an audit log. Keys can be rotated on a managed schedule, access to request signatures is scoped narrowly following least-privilege principles, and a valid signature still only authorizes actions the vault permits, not arbitrary transfers. No single failure — a leaked server credential or a compromised process — is enough to move user funds. ## Protocol policies A G.E.A. does not have free rein over the funds it manages. Its operations are governed by multisig-gated policies restricting which protocols and instructions agents may use, so the set of things an agent can do is a small, reviewed, enumerable list. Policy is expressed across several dimensions: | Dimension | What it controls | | ------------------ | ----------------------------------------------------------- | | Approved protocols | Which programs and destinations the agent may interact with. | | Operation types | Which instructions/operations are permitted. | | Position limits | Caps on exposure to any given protocol or position. | | Emergency controls | The ability to pause activity if something goes wrong. | These policies are not something _gamma can change unilaterally at runtime. Adding a protocol, changing a limit, or altering what the agent may do is a multisig-gated action requiring multiple signers, which keeps the permission set reviewable and slow to change. Quantitative caps work together with the risk framework's provider tier caps and diversification constraints (see [Risk management](#risk-management)) to keep the portfolio from concentrating into any one venue, and emergency controls can halt agent activity if a protocol shows signs of trouble. The agent optimizes continuously and signs its own transactions, but its worst case is bounded by that reviewed permission set, not by trust in a single operator or key. ## Smart contracts User assets live in _gamma's on-chain vault programs on Solana. These programs enforce the properties above: only share holders can redeem, and the agent cannot pay funds to arbitrary destinations. Because so much of the platform's safety is enforced in these contracts, their correctness is foundational. The contracts undergo independent security review; upgrades follow a controlled release process rather than instantaneous unilateral pushes — changes are multisig-gated so that no single key can alter the programs on its own. We deliberately do not enumerate specific firms or findings here so this page stays accurate over time; refer to the official _gamma channels for the current, dated details. If you believe you have found a security issue, please report it privately through the official contact channels rather than disclosing it publicly. You do not have to take the security model on faith: | Property | How to verify | | ----------------- | ------------------------------------------------------- | | Vault holdings | Read the vault's on-chain positions directly. | | Share price / NAV | Recompute `NAV / total shares` from chain state. | | Your position | Your share balance and withdrawal receipt are on-chain. | ## Risk management Earning yield in DeFi means taking on real risks — smart-contract, market, and protocol risk among them. _gamma's approach is not to eliminate risk but to measure it continuously and constrain exposure so no single failure dominates a vault, automatically, as part of every rebalance. Each protocol a G.E.A. can use is scored on an ongoing basis — audit history and code maturity, TVL history and stability, incident record, and liquidity depth. These scores feed the ML solver, which optimizes yield **against** risk rather than chasing the highest headline rate. To prevent concentration, providers are grouped into tiers with caps on how much of a vault can sit with any one provider, forcing diversification even when one venue temporarily offers the best yield. Staleness filters on ingested rates, prices, and liquidity, on-chain cross-checks of provider-published data, and NAV freshness gates in the vault program guard against bad data. Where strategies use leverage (for example leveraged staking loops on the SOL vault), the agent continuously monitors position health factors and automatically deleverages if liquidation risk rises — a mechanical response that does not wait for human intervention. | Risk | Mitigation | | ------------------ | ------------------------------------------------------------- | | Smart-contract | Independently reviewed programs, vetted protocols, responsible disclosure. | | Market | Risk-adjusted sizing, hedged strategies, position limits. | | Protocol | Continuous scoring, diversification, provider tier caps. | | Data / pricing | Staleness filters, on-chain cross-checks, NAV freshness gates. | | Leverage | Health-factor monitoring, automated deleveraging. | None of this makes a vault risk-free. Yields are variable and not promised, underlying protocols can fail, and market conditions can move against a position. What _gamma provides is disciplined, continuous, on-chain-verifiable risk control — exposure that is measured, capped, and diversified rather than left unmanaged. Next: [Getting started](/docs/getting-started) --- # Getting started Source: https://app.gma.fi/docs/getting-started.md ## Connect a wallet _gamma is non-custodial, so everything starts with your own wallet. Connecting a wallet lets you deposit, hold your share tokens, and redeem — all signed by you. _gamma never holds your keys or your assets. Click **Connect** in the app and choose your wallet, then approve the connection request; this only grants the app permission to request signatures, never to move funds on its own. **Supported wallets (Solana):** | Wallet | Notes | | -------- | ---------------------------------------- | | Phantom | Browser extension and mobile. | | Solflare | Browser extension and mobile. | | Ledger | Hardware wallet, via a supported wallet. | | Others | Additional Solana wallets are supported. | On mobile, use your wallet app's in-app browser or the deep-link connection flow — you approve each transaction inside your wallet app. For larger balances, a hardware wallet such as Ledger keeps your private key on the device and has you physically confirm each signature. Connecting a wallet lets the app read your public address and build transactions for you to review and sign. It does **not** give _gamma access to your private keys, and it does not authorize any transfer — every deposit, withdrawal, and claim is a separate transaction you explicitly approve. Verify you are on the correct _gamma URL before connecting, read each transaction before approving, and disconnect when done on shared devices. ## Deposit funds Make sure your connected wallet holds the asset the vault takes, plus a little SOL for transaction fees. There is no minimum deposit and there are no lock-up periods, so you can start with any amount. | Vault | Deposit asset | | ------ | ------------- | | gmSTBL | USDC | | gmSOL | SOL | | plRWA | USDC | 1. **Choose a vault.** Open the vault (G.E.A.) you want from the app. 2. **Enter an amount.** The form shows the estimated shares you will receive at the current price. 3. **Review.** Shares are minted at the live share price (`NAV / total shares`), so the estimate reflects an up-to-date valuation. 4. **Sign.** Approve the transaction in your wallet. This is the only step that moves funds, and you control it. 5. **Confirm.** Once the transaction confirms on Solana, your share tokens appear in your wallet and your position shows up in your portfolio. You receive share tokens (gmSTBL, gmSOL, or plRWA) — standard SPL tokens held in your wallet. Your position starts earning immediately, and yield shows up as **share-price appreciation** over time rather than as extra tokens; you never need to claim or compound manually. **Fees.** There is no deposit fee. A small withdrawal fee (currently 30 bps on the live vaults, waived on full exit and retained for remaining depositors) applies when you leave; because it is a per-vault on-chain policy, read the live value from `stats.withdrawalFeeBps` rather than assuming a number. See [Deposits & withdrawals](/docs/deposits-withdrawals) for the full policy. If a deposit is blocked, it is because the vault program blocks deposits when the published NAV is stale, to stop you entering at a mispriced value. This is rare and self-resolving — NAV is republished on a fixed cadence, so wait a moment and try again. ## Choose a strategy Each vault (G.E.A.) targets a different asset and risk profile. Your denomination matters: gmSOL earns in SOL terms and carries SOL price exposure, while gmSTBL and plRWA are USDC-denominated. Choose based on the asset you actually want to be long. | Vault | Asset | Profile | | ------ | ----- | ------------------------------------------------------------------- | | gmSTBL | USDC | Stablecoin yield — lending, stable rate arbitrage, RWA, fixed-yield. | | gmSOL | SOL | SOL-denominated — LST optimization, SOL lending, leveraged staking. | | plRWA | USDC | Institutional RWA yield on Plume; RWA rate cadence. | **Reading the APY cards.** Vault pages show more than one APY figure, and they mean different things: | Figure | What it means | | ---------------- | ---------------------------------------------------------- | | Current APY | The vault's present blended rate across its live positions. | | Solver-predicted | What the ML solver projects for its target portfolio. | | Realized APY | What the vault has actually earned historically. | None of these are promises. Yields are variable and derived from on-chain state — treat predicted and current figures as estimates and realized figures as history, not a guaranteed forward return. **Allocation breakdown.** Each vault page shows how the G.E.A. has allocated capital across protocols, so you can see which venues the vault is using and in what proportion. Because allocation is bounded by provider caps and on-chain position limits, expect the exposure to be diversified rather than concentrated in one protocol. See [How it works](/docs/how-it-works). **Rewards indicators.** Some positions earn protocol rewards in addition to base yield — for example Project Zero weekly reward distributions. Where these apply, the app surfaces a rewards indicator next to the APY. Watch also for **x2 Points** campaign badges on vault pages, which mark boosted points accrual (see the [FAQ](/docs/faq)). Next: [FAQ](/docs/faq) --- # FAQ Source: https://app.gma.fi/docs/faq.md ## Does _gamma take custody of my funds? No. _gamma is non-custodial. Your assets sit in on-chain vault programs, and you hold share tokens (gmSTBL, gmSOL, or plRWA) in your own wallet. Only your wallet can redeem your shares, and the agent cannot withdraw funds to an arbitrary destination. See [Non-custodial design](/docs/security). ## What do the G.E.A.s actually do? A Gamma Economic Agent (G.E.A.) is an ML-powered autonomous agent. It continuously monitors rates, liquidity, and prices across vetted Solana protocols, computes a risk-adjusted target portfolio, and rebalances toward it — only when the improvement clears the measured cost of transacting. Every action it takes must pass on-chain policy checks. It optimizes your capital; it never takes custody of it. ## What are the risks? Yields are variable and not guaranteed. You are exposed to smart-contract risk in the underlying protocols, market risk, and protocol risk. _gamma manages these with continuous protocol risk scoring, provider tier caps, diversification, staleness and NAV freshness guards, and automated deleveraging on leveraged positions — but it cannot eliminate risk. See [Risk management](/docs/security). ## Can I withdraw any time? Yes. There are no lock-up periods — you can request a withdrawal whenever you like. If the vault holds enough liquid asset, it settles instantly. Otherwise the program records an on-chain **withdrawal receipt** for your pending shares, the agent frees liquidity by unwinding positions, and you **claim** your assets in a second transaction once they are ready. Because the receipt is on-chain, your funds are never in limbo. See [Withdrawals](/docs/deposits-withdrawals). ## How long do withdrawals take? Instant when the vault is liquid enough. When queued, the median is around 10 minutes on stablecoin vaults; the app shows a data-driven arrival band (p50/p90) from recent history. Cross-chain RWA redemptions (plRWA) settle back over a bridge and typically take longer — hours up to about a day. See [Timing](/docs/deposits-withdrawals). ## What are the fees? There is no deposit fee. A small withdrawal fee — currently 30 bps (0.30%) on the live vaults — applies on withdrawals; it is retained in the vault for the benefit of remaining depositors, and it is waived when you redeem your entire balance. The fee is a per-vault on-chain policy, so read the live value from `stats.withdrawalFeeBps` rather than assuming a fixed number. Vaults may also charge a performance fee, which is read directly from the on-chain vault account. ## Is there a minimum deposit? No. There is no minimum deposit and no lock-up. You can start with any amount. ## How do yields accrue? Yield compounds inside the vault and shows up as **share-price appreciation**. The share price is `NAV / total shares`; as the vault's positions earn, NAV rises and each share becomes worth more. You do not receive new tokens and you never need to manually claim or compound — you simply redeem more value per share than you put in. All of this is on-chain and independently verifiable. ## How is _gamma different from other yield platforms? _gamma pairs an ML-driven optimizer with a strictly non-custodial, policy-bounded on-chain design. The agent works 24/7 across many protocols, but it can only touch the protocols and instructions its multisig-gated policies permit, its signing key is hardware-backed in Google Cloud KMS, and every figure is derived from on-chain state. You get hands-free optimization without handing over custody or trusting an off-chain ledger. ## What is the points program? _gamma runs a points program, and some vaults display **x2 Points** campaign badges indicating boosted accrual for depositing in that vault. Points indicators appear on the vault pages alongside APY and rewards. Next: [API overview](/docs/api/overview) --- # API reference Source: https://app.gma.fi/docs/api.md The _gamma API exposes vault analytics, wallet holdings, and unsigned transaction builders. The partner tier is Bearer-key gated (`Authorization: Bearer gma_api_...`); a small keyless public tier serves circulating supply and the gmSTBL oracle price. All partner responses use a `{ success, data }` envelope. Start with the overview, then authentication. --- # API overview Source: https://app.gma.fi/docs/api/overview.md The _gamma API gives partners programmatic access to the protocol: read vault directories, NAV, statistics, allocations, and per-wallet portfolio data, and build unsigned deposit and withdraw transactions that your own wallet signs and submits. ## Base URL All endpoints live under `/api`. | Environment | Base URL | | --- | --- | | Production | `https://app.gma.fi` | | Beta | `https://beta.gma.fi` | Examples in this reference use `https://app.gma.fi`. ## Response envelope Every JSON endpoint returns the same envelope. On success: ```json { "success": true, "data": { } } ``` On error: ```json { "success": false, "error": "Human-readable message", "details": "optional, dev-only extra context" } ``` Always branch on `success` rather than inferring status from the HTTP code alone. ## Tiers The API has two tiers: - **Keyless (public)** — `GET /api/circulating-supply` and `GET /api/oracle`. No credential; `Access-Control-Allow-Origin: *`; cached at the edge (~60s). See [Public endpoints](/docs/api/public-endpoints). - **Partner (API-key gated)** — everything else. Requires an `Authorization: Bearer gma_api_...` header. Keys carry a `read` or `write` scope and may be restricted to specific vaults and a single wallet. See [Authentication](/docs/api/authentication). ## Rate limits - **Keyless endpoints** are rate limited per client IP at roughly **20 requests / 5 seconds**. - **Partner endpoints** are rate limited per API key using the key's configured per-minute limit (RPM), keyed by the key ID. Rate-limited responses return HTTP `429` with `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, and `Retry-After` headers. Successful partner responses also carry the `X-RateLimit-*` headers so you can pace requests. Be a good citizen and back off on `429`. ## Units Token amounts are returned in Solana-style objects (`{ mint, symbol, amount, decimals, uiAmount }`) where `amount` is raw lamports (smallest unit) and `uiAmount` is the human value. APY and PnL fields are **fractional decimals** (`0.0824` = 8.24%) unless a page states otherwise. Two endpoints return **percent** values instead — `portfolio-history` and the `pnlPct` field of `pnl-history` — and both call this out explicitly. Read the unit notes on [Vault endpoints](/docs/api/vault-endpoints) before charting anything. Next: [Authentication](/docs/api/authentication) --- # Authentication Source: https://app.gma.fi/docs/api/authentication.md All partner endpoints require an API key, passed as a Bearer token in the `Authorization` header. Keyless [public endpoints](/docs/api/public-endpoints) take no credential. ## Header format ```bash curl "https://app.gma.fi/api/agents" \ -H "Authorization: Bearer YOUR_API_KEY" ``` Keys are issued in the form `gma_api_...`. The scheme must be exactly `Bearer` and the token must start with `gma_api_`; anything else is rejected with `401`. To request a key, see [Request an API key](/docs/api/request-key). ## Scopes Each key carries one scope. `write` implies `read`, so a write key can call every partner endpoint. | Scope | Access | | --- | --- | | `read` | Read-only endpoints: agents, positions, history (GET), NAV, stats, allocations, vault history, pnl-history, portfolio-history, rebalances, withdraw status. | | `write` | Everything a `read` key can do, plus deposit, withdraw (initiate/claim), and `POST /api/history` activity ingestion. | ## Error responses | Status | Meaning | | --- | --- | | `401` | Missing `Authorization` header, non-Bearer scheme, malformed key, or an invalid/revoked/expired key. | | `403` | Insufficient scope (e.g. a `read` key on a write endpoint), a vault outside the key's allowlist, or a wallet outside the key's binding. | | `429` | Rate limit exceeded (or the key has no valid RPM configured). | | `503` | Temporarily unavailable due to maintenance (see below). | ### Maintenance During **deposit-blocking maintenance**, the mutating money-movement endpoints — `POST /api/vault/{vault_id}/deposit` and the `POST /api/vault/{vault_id}/withdraw` initiate/claim actions — return `503`; read endpoints keep serving. During **full maintenance**, *all* endpoints return `503`, including the keyless public endpoints such as `GET /api/oracle`. Treat `503` as transient and retry with backoff. ## Per-consumer vault allowlist A key belongs to a consumer, and a consumer may be restricted to specific vaults. When a key is scoped to an allowlist, any request for a vault outside it returns `403` with `"Vault not in consumer scope"`. An unrestricted consumer (no allowlist) may access every registered vault, and `GET /api/agents` and `GET /api/positions` transparently return only the vaults in scope. ## Wallet binding A key may additionally be bound to a single wallet. A wallet-bound key may only read or build transactions for its bound wallet; any other `wallet` parameter returns `403` with `"Wallet does not match API key wallet binding"`. Multi-wallet partner keys have no binding and may act on any wallet. ## Keep keys server-side Treat production API keys as server-side secrets. **Never embed a `read` or `write` key in a browser bundle.** Browser-wallet applications should call a dedicated endpoint on their own backend; that backend attaches the _gamma Bearer key and pins the allowed wallet, vault, and operation before forwarding the request. The transaction-signing examples in [Transactions](/docs/api/transactions) follow this pattern. Next: [Vault endpoints](/docs/api/vault-endpoints) --- # Vault endpoints Source: https://app.gma.fi/docs/api/vault-endpoints.md These endpoints read vault-level and vault-scoped data. All require a `read`-scope API key. Replace `VAULT_ID` with a registered vault pubkey (examples use `GPZW7ihHMMfZg5eNDmn376mwVzBKHh867vdWmjvNvYPK`). > **Warning:** Units — APY and PnL fields are **fractional decimals** (`0.0824` = 8.24%) on `stats`, `allocations`, and `history`. Two places return **percent** (`0..100`) instead: every field in [`portfolio-history`](#get-vault-portfolio-history) (`solverTarget.predictedApy`, each target's `targetPct` and `predictedApy`), and the `pnlPct` field of [`pnl-history`](#get-vault-pnl-history). Do not mix the two. ## GET /api/agents Returns the catalog of vault agents, filtered to the key's vault scope. On-chain program internals are deliberately not exposed. ```bash curl "https://app.gma.fi/api/agents" \ -H "Authorization: Bearer YOUR_API_KEY" ``` Response `data` is an array of `AgentSummary`: | Field | Description | | --- | --- | | `vaultId` | Vault pubkey (base58). | | `slug` | Agent slug/id. | | `name` | Internal vault name. | | `strategyType` | Strategy category. | | `display` | `{ title, description, icon, color, riskLevel, riskPercentage }`. | | `assets` | Deposit asset token: `{ symbol, mint, decimals, imageUrl }`. | | `shares` | Share token: `{ symbol, mint, decimals, imageUrl }`. | | `capacityLimit` | Deposit cap in asset lamports (raw), or `null`. | ## GET /api/vault/{vault_id}/nav Current NAV and pricing, read from the on-chain `LpVault` account (cached ~10s). ```bash curl "https://app.gma.fi/api/vault/GPZW7ihHMMfZg5eNDmn376mwVzBKHh867vdWmjvNvYPK/nav" \ -H "Authorization: Bearer YOUR_API_KEY" ``` | Field | Description | | --- | --- | | `vaultId`, `vaultName` | Vault identity. | | `agentAuthority` | On-chain fund authority (agent wallet owning the vault's protocol positions), or `null`. | | `sharePrice` | Asset per share. | | `totalShares` | Token amount object `{ mint, symbol, amount, decimals, uiAmount }`. | | `nav` | Net asset value (TVL) as a token amount object. | | `capacityLimit` | Token amount object, or `null`. | | `updatedAt` | ISO timestamp of the on-chain read. | ## GET /api/vault/{vault_id}/stats Aggregated headline statistics. ```bash curl "https://app.gma.fi/api/vault/GPZW7ihHMMfZg5eNDmn376mwVzBKHh867vdWmjvNvYPK/stats" \ -H "Authorization: Bearer YOUR_API_KEY" ``` | Field | Description | | --- | --- | | `vaultId`, `sharePrice` | Vault identity and price. | | `nav`, `tvl` | NAV in asset units; TVL in USD (`nav × spot`, or `nav` for USDC vaults). | | `capacity` | Human capacity limit, or `null`. | | `depositors`, `volume24h`, `pending` | Depositor count, 24h volume, pending intentions. | | `performanceFeeBps` | Performance fee in basis points. | | `withdrawalFeeBps`, `withdrawalFeeEnforced` | Withdrawal fee bps and whether it is enforced. | | `hourlyNetWithdrawalCapBps`, `dailyNetWithdrawalCapBps` | Net withdrawal guardrails (bps). | | `withdrawalLimits` | Current withdrawal-limit state, or `null`. | | `currentAPY`, `solverPredictedAPY`, `realizedAPY`, `predictedAPY`, `historicalAPY` | The five APY metrics. **Fractional** (`0.0824` = 8.24%); nullable. | | `totalPnL` | Total vault PnL in asset units; nullable. | ## GET /api/vault/{vault_id}/allocations Current actual holdings. By default the verbose solver/leverage internals are stripped; `?detail=full` includes them. ```bash curl "https://app.gma.fi/api/vault/GPZW7ihHMMfZg5eNDmn376mwVzBKHh867vdWmjvNvYPK/allocations?detail=full" \ -H "Authorization: Bearer YOUR_API_KEY" ``` Response `data` is `{ allocations: [...] }`. Each allocation: | Field | Description | | --- | --- | | `provider`, `tokenName`, `tokenMint`, `productId` | Position identity (nullable). | | `ratio` | Deployed-balance ratio of the position. | | `balance` | Human balance. | | `predictedApy` | Raw predicted APY at the position's actual leverage (**fractional**). | | `displayApy` | Clamped combined APY for display, or `null` when the leg's rate is implausible. | | `leverage` | Display leverage, or `null`. | | `marketType` | Market type, or `null`. | | `isIdle` | Whether the position is idle. | With `?detail=full`, each allocation additionally includes: `hasRate`, `historicApyMean`, `historicApyStd`, `solverPredictedApy`, `nativeYieldApy`, `leverageIsTarget`, `leverageSource`, `actualLeverage`, `targetLeverage`, and a `properties` object. ## GET /api/vault/{vault_id}/history Time-series for a single vault metric. `metric` is **required**; `range` normalizes to `24h|7d|30d|90d|1yr|all` (unknown ⇒ `7d`). | Param | Values | | --- | --- | | `metric` | `share-price`, `tvl`, `apy`, `realized-apy`, `historical-apy` (required). | | `range` | `24h`, `7d`, `30d`, `90d`, `1yr`, `all` (default `7d`). | ```bash curl "https://app.gma.fi/api/vault/GPZW7ihHMMfZg5eNDmn376mwVzBKHh867vdWmjvNvYPK/history?metric=apy&range=30d" \ -H "Authorization: Bearer YOUR_API_KEY" ``` Response `data` is `{ metric, range, points: [...] }`. Each point is `{ date (ISO), value (number|null), usdValue? (number|null) }`. `usdValue` is present only for `share-price`. The `apy`, `realized-apy`, and `historical-apy` metrics return **fractional** values. ## GET /api/vault/{vault_id}/pnl-history {#get-vault-pnl-history} Per-user PnL time series for one vault. `wallet` is **required**; a wallet-bound key may only query its own wallet. | Param | Values | | --- | --- | | `wallet` | Wallet pubkey (required). | | `range` | `24h`, `7d`, `30d`, `90d`, `1yr`, `all` (default `7d`). | ```bash curl "https://app.gma.fi/api/vault/GPZW7ihHMMfZg5eNDmn376mwVzBKHh867vdWmjvNvYPK/pnl-history?wallet=YOUR_WALLET_PUBKEY&range=30d" \ -H "Authorization: Bearer YOUR_API_KEY" ``` Response `data` is `{ wallet, vaultId, range, points: [...] }`. Each point: | Field | Description | | --- | --- | | `date` | ISO timestamp. | | `shares` | Human shares held at the snapshot. | | `sharePrice` | Native value per share. | | `value` | Asset value: `shares × sharePrice`. | | `costBasis` | Cumulative deposited − redeemed, in asset units. | | `pnl` | `value + redeemed − deposited`, in asset units. | | `pnlPct` | **PERCENT** (`pnl / deposited × 100`) — not fractional. | Values are asset-denominated (USD for USDC vaults); the latest point reconciles with [`/api/positions`](/docs/api/wallet-endpoints). ## GET /api/vault/{vault_id}/portfolio-history {#get-vault-portfolio-history} Per-rebalance snapshots showing what changed in the vault's holdings. | Param | Values | | --- | --- | | `limit` | Snapshot count, `1..100` (default `10`). | ```bash curl "https://app.gma.fi/api/vault/GPZW7ihHMMfZg5eNDmn376mwVzBKHh867vdWmjvNvYPK/portfolio-history?limit=5" \ -H "Authorization: Bearer YOUR_API_KEY" ``` Response `data` is an array of `PortfolioHistoryEntry` (ISO dates, human balances, the holding `product_kind` discriminator, and a solver-target block). > **PERCENT warning.** In every entry, `solverTarget.predictedApy`, and each target's `targetPct` and `predictedApy`, are **percent (`0..100`)**, not fractional — matching the in-app history drawer. Do not divide by 100 twice or multiply a fractional value here. ## GET /api/vault/{vault_id}/rebalances Timestamps at which the agent's portfolio composition changed within the range. | Param | Values | | --- | --- | | `range` | `24h`, `7d`, `30d`, `90d`, `1yr`, `all` (default `7d`). | ```bash curl "https://app.gma.fi/api/vault/GPZW7ihHMMfZg5eNDmn376mwVzBKHh867vdWmjvNvYPK/rebalances?range=7d" \ -H "Authorization: Bearer YOUR_API_KEY" ``` Response `data` is `{ range, points: [{ date (ISO) }] }`. Next: [Wallet endpoints](/docs/api/wallet-endpoints) --- # Wallet endpoints Source: https://app.gma.fi/docs/api/wallet-endpoints.md These endpoints are keyed by a wallet pubkey. Reads need a `read`-scope key; recording activity needs `write`. A wallet-bound key may only act on its bound wallet. ## GET /api/positions Wallet holdings across every vault in the key's scope. | Param | Description | | --- | --- | | `wallet` | Wallet pubkey (required). | ```bash curl "https://app.gma.fi/api/positions?wallet=YOUR_WALLET_PUBKEY" \ -H "Authorization: Bearer YOUR_API_KEY" ``` Response `data` is `{ wallet, vaults: [...] }`. Each vault entry: | Field | Description | | --- | --- | | `vaultId`, `vaultName` | Vault identity. | | `shares` | Token amount object `{ mint, symbol, amount, decimals, uiAmount }`. | | `sharePrice` | Current share price. | | `currentValue`, `depositedValue`, `redeemedValue`, `totalReturn` | Token amount objects, in asset units. | | `totalReturnPercentage` | Return percentage. | | `pendingWithdrawal` | `{ shares, estimatedValue }`, both token amount objects. | ## GET /api/history Deposit/withdrawal history for a wallet in one vault. | Param | Description | | --- | --- | | `wallet` | Wallet pubkey (required). | | `vault_id` | Registered vault pubkey (optional; defaults to the default vault). | | `limit` | Max results, default `50`, capped at `100`. | | `offset` | Pagination offset, default `0`. | ```bash curl "https://app.gma.fi/api/history?wallet=YOUR_WALLET_PUBKEY&vault_id=GPZW7ihHMMfZg5eNDmn376mwVzBKHh867vdWmjvNvYPK&limit=10" \ -H "Authorization: Bearer YOUR_API_KEY" ``` Response `data` is `{ wallet, vaultId, transactions: [...], hasMore, pagination }`. Each transaction: | Field | Description | | --- | --- | | `intentId` | Interaction intent id. | | `type` | `deposit` or `withdrawal`. | | `status` | Intent status. | | `requestedAt`, `completedAt` | ISO timestamps (`completedAt` may be `null`). | | `amountUsdc` | Asset amount (human). | | `sharesAmount` | Shares (human). | | `signatures` | `{ request, complete }` transaction signatures (nullable). | `pagination` is `{ limit, offset, nextOffset }` (`nextOffset` is `null` when there are no more results). ## POST /api/history {#post-apihistory} Records a confirmed, wallet-authored vault interaction immediately, so partner-submitted transactions do not wait for the periodic backfill. **Requires a `write`-scope key.** Send this right after a deposit or withdraw transaction confirms. The confirmed transaction on-chain is the sole authority: type, amount, mints, status, and balance changes are all derived from chain data and are never accepted from the request body. Only these body fields are allowed (any other field is rejected): | Field | Description | | --- | --- | | `wallet` | Wallet pubkey (required). | | `vault_id` | Registered vault pubkey (required). | | `signature` | Confirmed Solana transaction signature (required). | | `withdrawal_reservation_id` | UUID from the withdraw builder (optional; carry it when recording a queued withdrawal initiate). | ```bash curl -X POST "https://app.gma.fi/api/history" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '{"wallet":"YOUR_WALLET_PUBKEY","vault_id":"GPZW7ihHMMfZg5eNDmn376mwVzBKHh867vdWmjvNvYPK","signature":"CONFIRMED_TRANSACTION_SIGNATURE"}' ``` Response `data`: | Field | Description | | --- | --- | | `wallet`, `vaultId`, `signature` | Echo of the recorded interaction. | | `recorded` | `true` when newly recorded. | | `duplicate` | `true` when the same wallet/vault/signature was already recorded — an **idempotent success** (HTTP `200`), treat it as success. | | `intentId` | The interaction intent id, or `null`. | Error semantics worth handling: - `409` `"No pending withdrawal found for this claim"` — record the confirmed **initiate** signature first, then retry the **claim** signature. - `422` — the transaction is not found/unconfirmed/failed, or is not a recordable _gamma vault interaction. `Content-Type` must be `application/json`; oversized bodies return `413`. Next: [Transactions](/docs/api/transactions) --- # Transactions Source: https://app.gma.fi/docs/api/transactions.md The deposit and withdraw endpoints return an **unsigned, base64-encoded `VersionedTransaction`** that your wallet signs and submits. They require a `write`-scope key. The withdraw-status read requires `read`. After a transaction confirms, record it with [`POST /api/history`](/docs/api/wallet-endpoints#post-apihistory) so the activity feed updates immediately. ## POST /api/vault/{vault_id}/deposit Builds an unsigned deposit transaction. Body: | Field | Description | | --- | --- | | `wallet` | Wallet pubkey (required). | | `amount` | Deposit amount in **lamports** (smallest asset unit). Wins if both are present. | | `uiAmount` | Human amount (e.g. `1.5` USDC) — an ergonomic alternative to `amount`. | ```bash curl -X POST "https://app.gma.fi/api/vault/GPZW7ihHMMfZg5eNDmn376mwVzBKHh867vdWmjvNvYPK/deposit" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '{"wallet":"YOUR_WALLET_PUBKEY","amount":100000000}' ``` Response `data`: | Field | Description | | --- | --- | | `transaction` | Base64 `VersionedTransaction` to sign and submit. | | `message` | Human summary of the deposit. | | `details` | `{ vaultId, vaultName, depositAmount, depositAmountHuman, assetDecimals, estimatedSharesReceived, currentSharePrice }`. | ## GET /api/vault/{vault_id}/withdraw Withdrawal status for a wallet. | Param | Description | | --- | --- | | `wallet` | Wallet pubkey (required). | ```bash curl "https://app.gma.fi/api/vault/GPZW7ihHMMfZg5eNDmn376mwVzBKHh867vdWmjvNvYPK/withdraw?wallet=YOUR_WALLET_PUBKEY" \ -H "Authorization: Bearer YOUR_API_KEY" ``` Response `data`: | Field | Description | | --- | --- | | `hasPendingWithdrawal` | Whether a pending withdrawal exists. | | `pendingShares` | Pending shares (raw), or `0`. | | `estimatedUsdcAmount` | Estimated asset value of the pending shares. | | `canClaimNow` | Whether the receipt is claimable on-chain now. | | `createdAt` | Receipt creation time (oldest pending), or `null`. | | `estimate` | Arrival-time band `{ kind, band }`, or `null`. | | `progress` | Live staging progress, or `null`. | ## POST /api/vault/{vault_id}/withdraw Initiates a new withdrawal **or** claims a pending one, chosen from on-chain state (or forced with an explicit `action`). `PUT` is an alias for `POST`. Body: | Field | Description | | --- | --- | | `wallet` | Wallet pubkey (required). | | `sharesAmount` | Shares to withdraw, **raw units** (required when initiating a new withdrawal). | | `action` | `initiate` or `claim` (optional; auto-detected otherwise). | ```bash curl -X POST "https://app.gma.fi/api/vault/GPZW7ihHMMfZg5eNDmn376mwVzBKHh867vdWmjvNvYPK/withdraw" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '{"wallet":"YOUR_WALLET_PUBKEY","sharesAmount":50000000}' ``` Response `data` always includes `action` (`initiate` or `claim`), the base64 `transaction`, a `message`, and `details`. When **initiating**, `details` carries the withdrawal accounting: | Field | Description | | --- | --- | | `withdrawalPolicy` | Fee/cap policy in effect. | | `withdrawalLimits` | Current net-withdrawal limit state. | | `withdrawalEstimate` | Gross/fee/net asset breakdown for the request. | | `withdrawalReservation` | `{ id, expiresAt }` — a capacity reservation. **Carry `id` as `withdrawal_reservation_id` when you record the confirmed initiate** via `POST /api/history`. | When **claiming**, `details` omits the reservation and estimate; the `message` states the approximate amount to claim. ## Signing, submitting, and recording 1. **Deserialize** the base64 into a `VersionedTransaction`. 2. **Simulate** (recommended) before signing. 3. **Sign** with the wallet. 4. **Submit** and confirm. 5. **Record** the confirmed signature with `POST /api/history` (carry `withdrawal_reservation_id` for a queued initiate). Blockhash freshness matters: build, sign, and submit promptly. A transaction whose blockhash has expired must be rebuilt (call the endpoint again) rather than retried as-is. ```typescript import { Connection, VersionedTransaction } from '@solana/web3.js'; // Your backend keeps the _gamma write key server-side; the browser never sees it. const PARTNER_API = '/api/gamma'; // 1. Ask your backend for the unsigned transaction. const res = await fetch(PARTNER_API + '/deposit', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ wallet: wallet.publicKey.toBase58(), amount: 100_000_000, // 100 USDC in lamports (6 decimals) }), }); const { data } = await res.json(); // 2. Deserialize the base64 transaction. const transaction = VersionedTransaction.deserialize( Buffer.from(data.transaction, 'base64'), ); // 3. Sign (browser wallet shown; a Keypair works server-side). const signedTx = await window.solana.signTransaction(transaction); // 4. Submit and confirm. const connection = new Connection('https://api.mainnet-beta.solana.com', 'confirmed'); const signature = await connection.sendRawTransaction(signedTx.serialize()); const confirmation = await connection.confirmTransaction(signature, 'confirmed'); if (confirmation.value.err) throw new Error('Transaction failed'); // 5. Record the confirmed signature (idempotent; duplicate === true is success). await fetch(PARTNER_API + '/history', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ wallet: wallet.publicKey.toBase58(), vault_id: 'GPZW7ihHMMfZg5eNDmn376mwVzBKHh867vdWmjvNvYPK', signature, }), }); ``` For a queued withdrawal, record the **initiate** signature (with its reservation id) before recording the **claim**; a claim recorded first returns `409`. See [`POST /api/history`](/docs/api/wallet-endpoints#post-apihistory). Next: [Public endpoints](/docs/api/public-endpoints) --- # Public endpoints Source: https://app.gma.fi/docs/api/public-endpoints.md These two endpoints are the keyless public tier. They take **no** `Authorization` header, send `Access-Control-Allow-Origin: *` (browser-callable), and are edge-cached for ~60 seconds. They are rate limited per client IP (~20 requests / 5 seconds). ## GET /api/circulating-supply Circulating supply of the gmSTBL share token. For gmSTBL, total supply equals circulating supply (no locked tokens). ```bash curl "https://app.gma.fi/api/circulating-supply" ``` ```json { "circulatingSupply": 51173000.42 } ``` Note: this endpoint returns the bare object above, not the `{ success, data }` envelope. ## GET /api/oracle The gmSTBL share price (NAV per share) in USD, for Switchboard and other oracle integrations. Read from the on-chain `LpVault` account (cached ~10s internally, plus the ~60s edge cache). ```bash curl "https://app.gma.fi/api/oracle" ``` ```json { "sharePrice": 1.023456 } ``` Note: this endpoint also returns the bare object above, not the `{ success, data }` envelope. Next: [Request an API key](/docs/api/request-key) --- # Request an API key Source: https://app.gma.fi/docs/api/request-key.md Partner API keys are issued on request. The keyless [public endpoints](/docs/api/public-endpoints) need no key; everything else requires a Bearer `gma_api_...` key with a `read` or `write` scope, optionally restricted to specific vaults and a single wallet. ## How to request Email **[support@gma.fi](mailto:support@gma.fi)** with your request. Include: | Field | Description | | --- | --- | | Name | Your name or organization. | | Email | The contact email for the key. | | Use case | What you are building and which endpoints you need. | | Contact handle | A handle we can reach you on (X, Discord, or Telegram). | You can also reach the team on [X](https://x.com/_gammafi), [Discord](https://discord.gg/3pWfJceqV9), or [Telegram](https://t.me/gammafi_official). ## What to tell us So we can scope the key correctly, mention: - Whether you need **read** only, or **write** (deposit/withdraw transaction building and activity recording). - Whether the key should be limited to **specific vaults**. - Whether it should be **bound to a single wallet**. - Your expected request volume, so we can set an appropriate per-key rate limit. ## After you receive a key The raw key is shown once — store it as a server-side secret. **Never embed it in a browser bundle.** Browser-wallet applications should proxy requests through their own backend, which attaches the key. See [Authentication](/docs/api/authentication) for scopes, vault allowlists, and wallet binding. Next: [AI / LLM integration](/docs/resources/ai-llm-integration) --- # AI / LLM integration Source: https://app.gma.fi/docs/resources/ai-llm-integration.md This documentation is built **LLM-first**: every page is real server-rendered HTML backed by a markdown source, and that source is exposed directly so language models and agents can consume it without scraping rendered HTML. ## The surfaces | Surface | What it is | | --- | --- | | [`/llms.txt`](/llms.txt) | An [llmstxt.org](https://llmstxt.org)-format index — the site summary plus a link to every page's raw markdown, grouped by section. | | [`/llms-full.txt`](/llms-full.txt) | The full corpus: every page's markdown concatenated into one file. | | `/docs/.md` | The raw markdown for any page. Append `.md` to a docs URL, or use the "Copy page" control's **View .md**. | | Copy page control | The button at the top of each page copies that page's exact markdown source to your clipboard. | All of these are generated from the same markdown files that render the pages, so they never drift from what a human reads. ## Pointing an agent at the docs - For a lightweight index an agent can crawl, start from [`/llms.txt`](/llms.txt) and fetch the per-page `.md` links it needs. - For a single-shot context load, fetch [`/llms-full.txt`](/llms-full.txt) — it contains the whole documentation set. - For one page, fetch its `.md` URL (for example, `https://app.gma.fi/docs/products/gmstbl.md`). The raw markdown uses standard headings, tables, and fenced code blocks, so it maps cleanly into a model's context. Diagrams are referenced as images with descriptive alt text, which is preserved in the markdown. ## Building on the API instead? If you want live data rather than documentation, see the [API reference](/docs/api/overview) — it is Bearer-key gated and returns JSON. Next: [Community & support](/docs/resources/community) --- # Community & support Source: https://app.gma.fi/docs/resources/community.md ## Channels | Channel | Link | | --- | --- | | X (Twitter) | [@_gammafi](https://x.com/_gammafi) | | Discord | [discord.gg/3pWfJceqV9](https://discord.gg/3pWfJceqV9) | | Telegram | [t.me/gammafi_official](https://t.me/gammafi_official) | ## Partner API keys The partner API is Bearer-key gated. To request a key — or ask about integration — follow the flow on [Request an API key](/docs/api/request-key), or email `support@gma.fi`. ## Security disclosure If you believe you have found a security issue in the on-chain programs or the platform, please report it **privately** through the official contact channels rather than disclosing it publicly, so it can be addressed before it can be exploited. See [Smart contracts](/docs/security) for the security model. Next: [Brand kit](/docs/resources/brand) --- # Brand kit Source: https://app.gma.fi/docs/resources/brand.md Assets and guidance for partners, exchanges, and press referencing _gamma. Everything here is assembled from the production design system. If you need a format that isn't included, reach out through the channels on [Request an API key](/docs/api/request-key). ## Download **[Download brand kit (.zip)](/brand/gamma-brand-kit.zip)** — logos (SVG + PNG), the favicon, a `colors.txt`, and a `README.md` with these usage rules. ## Logos | Asset | Format | File | | ----- | ------ | ---- | | Wordmark | SVG, PNG | `logos/svg/gamma-wordmark.svg`, `logos/png/gamma-wordmark.png` | | Glyph / mark | SVG | `logos/svg/gamma-mark.svg` | | Favicon | ICO | `favicon/favicon.ico` | The wordmark is written `_gamma` — lowercase, with the leading underscore. Use the wordmark wherever space allows; use the glyph only where the wordmark would be illegibly small (favicons, avatars, app tiles). ### Clear space and minimum size - Keep clear space around the logo equal to the height of the underscore glyph on all sides. - Minimum wordmark width: 96px on screen. Minimum glyph size: 24px. - Prefer the SVG for any scalable placement; use the PNG only where SVG is unsupported. ### Do - Use the logo on the dark background (`#08070A`) or a sufficiently dark surface. - Preserve the original colors and proportions. - Give it room — respect the clear space. ### Don't - Don't recolor, add gradients the mark doesn't ship with, or apply glows/shadows. - Don't stretch, squash, rotate, or otherwise distort it. - Don't place the logo on a low-contrast or busy background, or reconstruct the wordmark in another typeface. ## Colors The signature look is a magenta-to-purple gradient on a near-black background. | Role | Hex | | ---- | --- | | Background | `#08070A` | | Foreground | `#F9FAFB` | | Primary purple | `#8C4DFF` | | Purple (light) | `#A26BFF` | | Magenta (accent) | `#D857DB` | | Cyan (info) | `#22D3EE` | | Success | `#57DB5E` | | Destructive | `#DB5757` | **Signature gradient:** `linear-gradient(90deg, #D857DB 0%, #8C4DFF 100%)` (magenta → purple). ## Typography - **Geist** — interface and body text. - **JetBrains Mono** — code and numeric/monospace contexts. Both are open-source (SIL Open Font License) and self-hosted by the app. The brand kit does **not** ship font binaries; install them from their official sources if you need to match the type. Next: [_gamma documentation](/docs) ---