Running a keeper
A keeper keeps batches moving. Everything it does is open to anyone, except that the protocol keeper gets the first 13 blocks of each settle window (see Encrypted orders).
During each batch
Call poke(market) in different L1 blocks. Each call records one price sample, and the first sample of a batch also folds the previous batch into the market's reference price. Settlement needs at least 2 samples and voids the batch otherwise.
Encrypted orders
Read the SealedCommitted(batch, trader, index, commitment, ciphertext) events. The ciphertext is a tlock (drand quicknet) armoured string; once its round is published, timelockDecrypt returns the order as JSON:
{ "v": 1, "trader": "0x…", "batch": "123", "market": "2", "side": 0,
"amount": "2250000000", "limitPx": "236000000", "salt": "0x…" }
Check it against the commitment (keccak256(abi.encode(trader, batch, market, side, amount, limitPx, salt))) and group by market.
After each reveal window
For every market with orders (decrypted, or revealed by hand), call settleWithReveals(batch, market, reveals) with that market's decrypted orders; an empty list works for a market with hand-revealed orders only. After the settle window (26 blocks), call collectForfeits(batch) once.
The protocol keeper
The protocol runs one, and its state (last batch seen, encrypted orders seen and decrypted, transactions sent, gas left) is public at blackpool-keeper.fly.dev. When a batch holds at least one sealed order, it samples all nine markets in one Multicall3 call every 3 L1 blocks through the whole batch, and once every 12 batches otherwise to keep reference prices fresh. It waits for every encrypted order of a batch to be decrypted before settling it, so none misses its batch. Settlement pays the keeper nothing.
