Skip to content
LogoLogo

Commands and recovery

Use these commands from the SDK example directory. Each quote command publishes once. Use one quote writer per trader and perp.

cargo run --locked -- account

Replace account with a command from the tables below.

Commands

markets needs only PUBLIC_ENDPOINT. Every other command needs TRADER_ID, PERP_ID and RPC_URL, plus PUBLIC_ENDPOINT for the program check except disable-rpc.

Keys are Solana JSON keypair files:

  • Owner commands use OWNER_KEYPAIR.
  • Bot commands use QUOTER_KEYPAIR.
  • Maker API commands also need MAKER_ENDPOINT.

The tables list any extra inputs.

Read state

CommandEffectExtra inputsUses
marketsList perps, marks and collateral marketsNonePublic API
accountRead collateral, health and perp positionsNonePublic API; no key required
stateRead levels, sequences, slot, strategy and enabled flagNoneBot, Maker API
fillsRead the last 50 maker fills on the selected perpHistorical store requiredBot, Maker API

state --raw includes strategy bytes.

Publish and disable quotes

CommandEffectExtra inputsUses
quote MODE BID ASK LOTS TTLReset the strategy and publish both sidesQuote argumentsBot, Maker API
disableKeep quote bytes; set enabled=falseNoneBot, Maker API
disable-rpcDisable quotes without the gatewayNoneBot, RPC

Both disable commands require the bot's on-chain Trade permission. Follow Stop quote writes before the final disable.

Manage the account

CommandEffectExtra inputsUses
setupCreate a missing trader; grant Trade + QuoteQUOTER_KEYPAIROwner, RPC
depositDeposit collateralCOLLATERAL_MINT, COLLATERAL_ATOMSOwner, RPC
openOpen a slot after the MAY_QUOTE grantNoneOwner, RPC
releaseRelease the slot for reuseNoneOwner, RPC
revokePermanently revoke the selected bot key on this traderQUOTER_KEYPAIROwner, RPC
settle-fundingBook accrued fundingNoneOwner as fee payer, RPC
settle-pnlSettle available realised PnLCOLLATERAL_MINTOwner as fee payer, RPC
withdrawWithdraw free collateralCOLLATERAL_MINT, WITHDRAW_ATOMSOwner, RPC

Deposit and withdrawal use existing owner associated token accounts. withdraw does not create one.

Operator permission

CommandEffectExtra inputsUses
grantGrant MAY_QUOTE to an existing traderOperator's ADMIN_KEYPAIROperator, RPC

The maker asks the Flint operator for this grant.

Quote arguments

  • MODE: order-list, density or relative-density.
  • BID and ASK: prices in ticks, with ASK greater than BID.
  • LOTS: quantity in contract lots.
  • TTL: lifetime in slots.

All four numbers must be positive UInt32 integers. Every mode expires automatically. Density modes install a one-tick band at each fair.

Settlement mint

For settle-pnl, use the perp's PnL currency in COLLATERAL_MINT, even if you deposited another asset. Restore your collateral mint before deposit or withdrawal. Settlement changes the trader account's balances; withdrawal moves funds to the owner's wallet.

Check a complete trade

Both examples require err == null at confirmed or finalized RPC commitment. After a timeout, follow Unknown transaction outcome before submitting a replacement.

  1. Submit a small, collateral-backed quote and wait for confirmation.
  2. Read state before expiry. Check the enabled flag, strategy and both sides.
  3. Have an independently funded taker cross one side. Save its signature.
  4. Run fills and account. Check the maker's direction, price, quantity, rebate and position against the taker's confirmed transaction.
  5. Stop maker quotes and cancel resting orders before closing both positions. Follow Shutdown to settle and test a small withdrawal.

Use the order instructions in your integration for taker and reduce-only orders. Local maker testing provides an isolated network, synthetic keys and an independent taker example.

Stop quote writes

Use this procedure before shutdown, planned key rotation, sequence reset or reopening a slot:

  1. Stop every writer for the affected account and perps, including submission queues and retries that can send signed transactions.
  2. Submit a disable if quotes are still fillable. A pending update can re-enable the slot, so repeat the disable after the remaining steps.
  3. Resolve every outstanding signed transaction. Wait for its confirmed or finalized result. If its outcome is unknown, follow Unknown transaction outcome. Continue until no earlier transaction can execute later.
  4. Read the current slot and account state. Then perform the final disable, cancellation, reset or reopen required by your procedure.

Stopping a process leaves its stored quotes and resting orders active until they expire or you remove them. Revoking a key removes its authority; stored quotes and orders remain active under their existing rules.

Planned key rotation

For a compromised key, revoke its on-chain authority first.

  1. Follow Stop quote writes for the old key. Disable each slot, cancel resting orders and confirm the results. Use disable-rpc with the old bot key if the gateway is unavailable.
  2. Set QUOTER_KEYPAIR to a new key with fee SOL and run setup with the owner. Flint supplies fee SOL. This reuses the owned trader account.
  3. Read state and confirm a short-lived quote with the new key.
  4. Set QUOTER_KEYPAIR to the old key and run revoke with the owner.
  5. Restore the new key path, verify the old key cannot write, then start the writer.

Revocation is permanent for that key on that trader. An API session cannot restore the on-chain grant.

Shutdown

  1. Follow Stop quote writes. Disable each slot and cancel resting orders. Confirm the transactions and read state to check the results.
  2. Read account and close exposure with reduce-only orders if leaving the market. Removing quotes does not close positions.
  3. Settle funding and PnL. Verify flat positions and enough free collateral for the intended withdrawal. A flat position can still owe fees or funding; a refused no-op settlement does not prove exposure is closed.
  4. Release unused slots and revoke any bot grant with the owner.
  5. Set WITHDRAW_ATOMS to integer token atoms and run withdraw, or use the dashboard. Check account collateral and the owner's token balance. WSOL withdrawals return wrapped tokens to the owner's token account.

Releasing a slot returns no rent, settles no cash and leaves exposure open.

Fix an error

ObservationNext step
Package install 401/403Ask the operator for registry/package access.
No email sign-in codeCheck the address and spam folder. Ask your Flint contact to check email registration and code delivery.
No Perps after email loginAsk the operator to check perp_maker_id.
Account ID takenCheck ownership; ask for another ID if someone else owns it.
Delegate existsInspect the grant. Expired or revoked grants need a new key; setup cannot renew them.
No MAY_QUOTEAsk the operator to grant the existing trader account.
No slot / maker limitOpen after permission, or wait for a released slot if all 32 are occupied.
Sequence did not advanceStop competing writers, read state and allocate a counter above the accepted value.
Sequence exhaustedStop all writers and use the guarded reset.
Transaction outcome unknownFollow the procedure below.
Rust chain streams not readyStop the bot; ask the operator to restore blockhash, slot and fee feeds.
Stale mark/oracle or absent healthStop quoting; ask the operator to restore prices and keeper updates.
Nothing to settleCheck outstanding funding/PnL; a no-op may be refused.
PnL exceeds pool liquidityAccept a partial payout or wait for pool funding. Unsettled gains are not wallet cash.

Unknown transaction outcome

Both examples print prepared <signature> blockhash=<hash> before submission; TypeScript also prints lastValidBlockHeight. Save those values, the command, trader/perp IDs and intended change. A submission error can occur after acceptance.

  1. Stop retries that build new transactions. Keep the original signed bytes if available.
  2. Query getSignatureStatuses on your configured RPC with searchTransactionHistory: true. Use getTransaction at confirmed or finalized commitment for instructions and logs.
  3. If confirmed or finalized with err: null, do not repeat the action. Reconcile state and account, plus fills for a trade.
  4. If execution failed, inspect logs and state; correct the cause before rebuilding.
  5. If no status is available, check lifetime: compare TypeScript's lastValidBlockHeight with getBlockHeight; for Rust, check the saved blockhash with isBlockhashValid at confirmed commitment. While valid, keep observing. Transport retries must send the same signed bytes.
  6. After expiry, search history again and reconcile account and slot state. Expiry stops future execution but does not rule out earlier execution. If history is unavailable or state inconsistent, keep the writer stopped and ask the operator to reconcile before rebuilding.

Quote expiry is separate: an empty or expired quote does not prove its transaction failed.