Instructions
Eight entrypoints. The full trade lifecycle lives in four of them (open_position, update_triggers, tick_position,cancel_position); the remaining four are admin and feed operations.
initialize_config
Admin bootstraps the program. Creates the global Config PDA with fee bps, keeper reward bps, and fee receiver.
pub fn initialize_config(
ctx: Context<InitializeConfig>,
fee_bps: u16,
keeper_reward_bps: u16,
) -> Result<()>update_config
Admin rotates fee receiver, fee bps, or keeper reward bps. Any field passed asNone is left unchanged. Admin can also transfer admin authority by passing a new pubkey.
initialize_price_feed
Admin registers a price feed for a symbol. The feed account is a PDA seeded by [b"feed", symbol]. The supplied authority is allowed to call update_price_feed later.
pub fn initialize_price_feed(
ctx: Context<InitializePriceFeed>,
symbol: [u8; 16],
decimals: u8,
initial_price: u64,
) -> Result<()>update_price_feed
The feed authority pushes a new price. V1 replaces this with a verified-oracle verifier instruction; the authority then becomes an emergency override only.
open_position
Owner deposits SOL collateral and snapshots the entry price from the feed. Triggers are validated against the entry price (a long stop must be below entry, etc). Each owner can open multiple positions by varying nonce.
pub fn open_position(
ctx: Context<OpenPosition>,
nonce: u64,
side: u8, // 0=long, 1=short
collateral: u64, // lamports
stop_price: u64, // 0 = disabled
take_profit_price: u64, // 0 = disabled
trailing_offset: u64, // 0 = disabled
) -> Result<()>update_triggers
Owner edits the three trigger fields on an open position. Changing the trailing offset resets trailing_extreme back to entry.
tick_position
Permissionless. Anyone can land this instruction. The program reads the feed, advances the trailing extreme, and checks the three trigger conditions in order. If a trigger fires, the same instruction settles the position; if not, only tick_countand possibly trailing_extreme change. The signer (keeper) earns the keeper reward on a fire.
pub fn tick_position(ctx: Context<TickPosition>) -> Result<()>cancel_position
Owner closes an open position manually. Full collateral is refunded; no fee or keeper reward is charged. Status flips to CANCELLED.
Error mapping
See errors for the full HwalError enum. The most common runtime reverts are PriceFeedStale, PositionNotOpen, and the validation errors InvalidStopPrice / InvalidTakeProfitPrice / InvalidTrailingOffset at open time.