Commit Graph

2 Commits

Author SHA1 Message Date
Anton Sauchyk 9a3f2c0bfb fix(utils): decode omitted trailing optional args in IDL instruction decoder (#185)
create_v2 instructions can legally omit the trailing is_cashback_enabled
OptionBool from the wire; decode_instruction rejected that form, so every
consumer of parse_token_creation_from_instruction silently dropped those
coins (the committed blocksubscribe fixture carries one such 145-byte
create_v2).

- When the arg buffer is exhausted and every remaining arg is
  option-typed (native option or pump.fun's OptionBool), report them as
  unset (None) instead of failing the decode; mandatory args still fail.
- Count trailing optional args as 0 bytes in the instruction min-size
  table.
- Decode Anchor's native option type (1-byte tag + value), previously
  unsupported entirely - update_buyback_config's Option<u64> could not
  even be sized.
- Add learning-examples/verify_create_v2_optional_args.py machine-checking
  the omitted, present, truncated-mandatory and native-option forms plus
  the event-parser path against the committed fixture.
- Drop the append-0x00 workaround in verify_extreme_fast_zero_rpc.py and
  update the stale CLAUDE.md note about the strict decoder.

Fixes #184

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 20:32:15 +02:00
Anton Sauchyk 7bc6f25508 feat(trading): zero-RPC extreme-fast buys and listener race hardening (#170) (#183)
Extreme-fast mode submits with no RPC calls between detection and buy
when the listener parsed the on-chain CreateEvent (geyser/logs/blocks):
TokenInfo.state_from_event carries the canonical creator, mayhem/cashback
flags and quote_mint, so the pre-buy curve refresh is skipped. The geyser
listener now delegates to the event-first parser instead of inlining
instruction decoding, which also catches create_v2 transactions that omit
the trailing is_cashback_enabled byte.

Listeners without event data (pumpportal) keep the refresh, hardened per
issue #170: bonding curve derived from the mint instead of the payload's
bondingCurveKey, curve and mint read in one slot-consistent
getMultipleAccounts (correcting the guessed token program), and an
unreadable curve now skips the token within trade.curve_refresh_budget
instead of submitting a buy built from guessed accounts.

Machine-checked by verify_extreme_fast_zero_rpc.py and
verify_pumpportal_buy_path.py; validated live via simulate_bot_buy_path
on both geyser and pumpportal paths.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 18:29:03 +02:00