_gammadocs
API Reference

Transactions

Build unsigned deposit and withdraw transactions, check withdrawal status, and sign, submit, and record them.

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 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.
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).
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).
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.

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.

Next: Public endpoints