hexbook.near logs NEP-297 events, standard hex_orderbook, version 2.1.0:
Accept any 2.x version: shapes only grow by optional fields, so the contract’s older logs (2.0.0, logged before v3; see the changelog) parse with the same code. Conventions. Keys are short. Amounts are decimal strings of raw units; prices raw decimal strings; hashes 64 hex characters. Sides are "s" (sell / ask, holds base) and "b" (buy / bid, holds quote). ts and x are u64 nanoseconds written as JSON numbers that exceed 2^53: parse them with a big-integer-aware JSON parser, never as a plain JSON.parse double.
Read logs only from successful receipts of hexbook.near. A failed receipt’s logs describe reverted state.
Hashes in the examples are shortened (3ed65e74…); real logs have all 64 characters.

Batched events

A batch logs its order_closed, order_created and place_skipped as one event each with data as an array, one item per order; prune does the same for its order_closed. Each array event is logged only when it has at least one item. Every other event has one object as data. Accept both forms for these three events.

order_created

A resting order: a batch placement (array data), or a taker’s remainder that rests (object data; it is logged before the trade of the same receipt).

trade

One per taker order that does not simply rest (also when it is refunded whole with no fills).
A buy of 0.0049975 QTC for 0.69965 USDT plus 0.00035 USDT fee; the maker order keeps 0.0050025 QTC.

order_closed

An order closed outside a trade (a trade never logs order_closed). The refund is credited to the maker’s internal balance.
close_order then pays the whole internal balance out (a claim follows).

claim

An internal balance paid out by mt_transfer: claim_balance, close_order’s claim, withdraw.

payout_failed

A payout mt_transfer failed; the amount was credited to the internal balance.

deposit

A deposit into the internal balance.

place_skipped

A batch placement that did not rest (not an error; nothing was debited). Batched: data is an array.

epoch

A maker’s epoch in a book was bumped (cancel_all, or batch with bump_epoch). Every order of m in b/q with a lower epoch is dead from this receipt on.

payout_mode

An account set its payout mode: { a, mode }, mode "internal" or "intents".

book

A book was created or its config changed. The owner re-logs the books created before this event existed with emit_book_events.

book_removed

{ b, q }: the book was removed (it had no orders).

Rebuilding state from events

Orders

  • order_created opens an order. Keep {h → m, s, p, b, q, a, x, e}: fills and closes only name the hash.
  • A trade fill [h, base, quote, fee, left] sets the order’s balance to left.
  • After a trade an order is closed iff its fill’s left is 0 or its hash is in c; c’s amount (equal to left when both appear) is refunded in the token the order held. A bid that can no longer buy one base unit and a dead order appear only in c, with their whole balance.
  • order_closed closes the order with refund r.
  • epoch makes the maker’s older orders in that book dead but does not close them; nor does reaching x. They close later through a trade’s c or an order_closed. To show a live book, apply both rules at the current time.

Fills and prices

For each trade: base = Σ fill base, quote = Σ fill quote, average raw price = Σquote / Σbase. The taker side is s; the makers are the m of each filled order.

Fees

tf is split over the book’s protocol taker collectors, then the trade’s refs, pro rata by pips, rounded down, dust to the first collector. mf is split over the maker collectors the same way. Use the fee config of the latest book event before the trade (or get_protocol_fee).

Payouts and balances

A trade’s payouts are aggregated per (token, account) across roles (one account can be taker, maker and fee collector at once), entries of 0 are dropped, and the list is sorted by token, then account. What goes in:
  • Makers in mi get their proceeds and c refunds credited to their internal balance; those are not among the trade’s payouts. What they get as taker or fee collector is.
  • np: the first np payouts of the sorted list are paid out by mt_transfer; the rest did not fit in the receipt’s gas and are credited to internal balances. The referrer-fee part of a credited payout goes to the taker instead. A paid payout that fails is credited later (payout_failed).
Internal balance per account:
Reconcile periodically with get_user_balance: placements debit the balance through their order_created, not an event of their own.