For developers

Build with
a better hindsight.

Discover a market, compare compatible quotes, and integrate an exercisable right. Start with read-only prices; prepare for the contract flow.

Start here

What exists. What’s proposed.

SurfaceStatusBoundary
Public quote previewRead-only serviceETH/BTC use Base-fork trial configuration, chain 31337. Equities use chain 4663 with no execution. Check current discovery.
RH multiplier registryDeployed · read-only viewerRobinhood Chain, chain 4663. Public addresses, ABIs and recorded ranges are available in the multiplier explorer.
RH options & Aave helperAudit handoffSeparate from the deployed multiplier registry. RH trading is not enabled here.
Multi-maker registryDraft interfaceNo deployed contract. Bond and exit parameters await approval.
Purchase & exercise appPlannedNo wallet connection, signing or transaction action on these pages.
Pin the units before the UI.Prices: 1e8 scale · Token amounts: token decimals · Contract quantity: product decimals · Contract timestamps: seconds · API quote windows: milliseconds

Request prices and quantities are human decimal strings. Convert once at a verified boundary; never assume all quantities use 18 decimals.

01 · Available for read-only integration

Discover the valid terms.

Discovery defines the available products and expiry-specific strikes. A strike accepted for one expiry is not automatically accepted for another. Each maker supplies its own configuration version.

JavaScript · read-only
const base = 'https://hindsight-lookback-collateral-trial.devops-118.workers.dev';
const response = await fetch(base + '/discover/lookback', {
  credentials: 'omit', referrerPolicy: 'no-referrer',
  signal: AbortSignal.timeout(12_000)
});
if (!response.ok) throw new Error(`Discovery: ${response.status}`);
const discovery = await response.json();
// Select an actual market, expiry and activation from discovery.
// Use its quantity grid, price bounds and configVersion.
const estimate = await fetch(base + '/indicative', {
  method: 'POST', credentials: 'omit', referrerPolicy: 'no-referrer',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(selectedTerms),
  signal: AbortSignal.timeout(12_000)
});
if (!estimate.ok) throw new Error(`Quote: ${estimate.status}`);
const quote = await estimate.json(); // Indicative only, no signature.

Inspect a public discovery response

This button reads the reference service. It does not queue a signed order.

No request sent. Your browser will contact the selected public service.

Request fieldMeaning
marketIdExact market from that maker’s discovery.
activationHuman decimal strike accepted for the selected expiry.
ceiling / floorPeak sale cap or bottom purchase floor. Use only the applicable field.
quantityHuman decimal product quantity on the accepted grid.
optionExpiryActual offered expiry, Unix seconds.
configVersionVersion returned by the same maker’s discovery.
Quote validity, errors and privacy

Reject stale sources, expired quotes, wrong chains, unexpected tokens or implementations, and changed terms. Refresh discovery for CONFIG_CHANGED; refresh and review for BATCH_ROLLED. Never treat a timeout or missing value as a zero premium.

The proposed multi-maker client exposes requested terms and the client’s IP to the contacted makers. Send no wallet address or personal data for indicative discovery. Use no credentials or referrer and impose deadlines and JSON byte limits.

02 · Proposed integration contract

A directory, not an execution gate.

Draft ABI · v0Undeployed. Function names and policy remain subject to sign-off.

Pin a registry address, bytecode and chain in your deployment configuration. Read its maker list at one block. The registry identifies services to query; OptionBook independently checks signed orders.

Register + bondActiveExitingWithdraw remaining bond

Record

Owner
Manages registration and the bond.
Order account
Funds and owns orders; equals order.maker. A supported authorized operator may provide the signature.
Quote URL
HTTPS base for discovery and quotes. Metadata is plain data, never executable HTML.
Revision
Increments on material changes. Discard old pending responses.
Bond & state
Recorded balance, status and earliest withdrawal time.

Operations

Read
makerCount / makerIdAt / getMaker / isEligible
Owner
register / update / topUpBond / requestExit / withdrawBond
Admin
slash with amount and evidence hash.
Protocol config
Bond token, minimum bond and exit delay.
Download draft registry ABI ↓
Lifecycle and signer rules
  • Requesting exit removes the maker from new discovery immediately. It does not revoke any OptionBook order or existing option obligation.
  • Rotating the order account invalidates pending frontend responses through the record revision. It does not cancel orders signed by the previous account. Cancel those through OptionBook.
  • Only records that are Active, above the minimum bond and explicitly eligible are queried. Topping up an Exiting or Exited record does not automatically reactivate it.
  • Active and Exiting balances remain slashable until withdrawal. The withdrawal transition must settle state atomically. Slash events publish the amount and evidence hash; policy and fund destination remain draft.
  • The exit-delay policy must account for the maximum accepted order validity plus a margin. Maker service and frontend must enforce that bound. Open options can outlive this delay; the bond does not insure them.

Draft status enum: 0 Inactive, 1 Active, 2 Exiting, 3 Exited. Maker IDs and indexed positions remain stable; exited records stay readable. Read makerCount and makerIdAt in pages at a shared block number. isEligible is the authoritative eligibility check.

Fan out, then compare like for like.

  1. Read registry count and paginated IDs at the same block. Show enumeration coverage and any query limit; never silently imply every maker was queried.
  2. Capture chain, maker revision and requested terms before concurrent work. Request each eligible HTTPS endpoint with a timeout, a bounded body reader, no credentials and no referrer. Ignore stale responses after a context change.
  3. Validate each discovery against your own chain, Book, schema, token, feed and implementation allowlist. Discovery never enlarges the allowlist.
  4. Ask compatible makers for the same quantity, expiry, activation, cap/floor and delivery/receive tokens. Compare total premium in the same premium token. A different collateral/token combination is a separate comparison group.
  5. Show the lowest valid indicative premium returned by the deadline, how many makers responded, and any failures. Do not claim all-market best price or reserved liquidity.
  6. Before an eventual fill, refresh the registry state and revision. Revalidate the signed order and simulate. A changed price or context requires a fresh user review.
Client adapter outline · proposed registry
// registryAbi is DRAFT-MakerRegistry-v0.json. No address is deployed.
const blockNumber = await client.getBlockNumber();
const read = (functionName, args = []) => client.readContract({
  address: configuredRegistry, abi: registryAbi,
  functionName, args, blockNumber
});
const count = await read('makerCount');
// Page makerIdAt(index) at this SAME block, then getMaker(id).
// Check isEligible(id), chain and revision before sending a request.
// Use a bounded queue, not unbounded Promise.all over the directory.
const results = await boundedMap(eligibleMakers, concurrency, async maker => {
  const discovery = await readBoundedJSON(maker.quoteBaseUrl, '/discover/lookback');
  const request = validateAndBuildExactTerms(discovery, reviewedTerms, allowlist);
  const quote = await postBoundedJSON(maker.quoteBaseUrl, '/indicative', request);
  return validateQuote(quote, request, maker, allowlist);
});
// Above callbacks are application adapters, not an exported SDK.
// Discard results if chain, request ID or registry revision has changed.
// Rank only equal terms + same premium token, using integer total amounts.
// Display enumeration, response and timeout coverage alongside the result.

Launch clients may use a bounded, disclosed maker count in registration order. Concurrency limits must not silently drop makers; queued work and deadline coverage must be visible.

Proposed · signed-offer execution for vaults

Replace the auction process.

Maker discovery and competition can happen through registered quote services. A vault still needs an onchain intent and execution policy; the registry is not a settlement contract.

  1. Publish a bounded intent. Bind the vault, chain, request nonce, approved Book/product, quantity, tokens, strikes, expiry and maximum premium or minimum proceeds. Reserve the required budget in the vault’s accounting.
  2. Collect matching offers. Workers return signed Book orders for the same terms. Anyone may submit a candidate or batch. A submission does not prove it is the best offer outside that batch.
  3. Validate and fill atomically. Check the current intent nonce, remaining size, registry eligibility, full signed terms and Book signer policy before execution. Account for the actual receipt, consume the intent and track the created option exactly once.
  4. Preserve vault accounting. Pending deposits, withdrawals, share minting, cancellations and option callbacks require an explicit integration. Keep existing Factory dependencies until equivalent responsibilities have been implemented and reviewed.
A registry does not reserve capacity.

Current Book orders are not bound to a vault-specific taker or request ID. Another taker can consume capacity first. A future binding mechanism would need a defined signed schema; it is not supplied by the draft registry.

Current Book authorization supports the maker’s own signature and the supported MarketMakerBeacon operator policy. A registry record must not invent an incompatible signer rule. No generic contract-wallet signing support is implied.

03 · Future purchase and exercise flow

From a quote to a right.

The current site stops at an indicative estimate. The reference execution flow is described here for integrators; these pages do not run it.

  1. Prepare. Call POST /request only after the buyer proceeds. Display the returned authoritative price and batch timing; it may differ from the earlier estimate.
  2. Wait for the batch. Read GET /batches/{batchAt} inside its active window. Find the exact returned request ID. Pending or expired responses are not offers.
  3. Verify. Check the EIP-712 domain (OptionBook, version 1.0, exact chain and Book), schema hash, maker account, every strike, both expiries, tokens, implementation and signed extra data. Validate current registry revision and status.
  4. Simulate and fill. Validate the quantity/collateral round trip and exercise minimum. Refresh balances, allowance, nonce/cancellation and capacity. Approve the reviewed premium and call fillOrder(order, signature, referrer) only after user confirmation.
  5. Exercise. Find an eligible historical oracle round and its neighbours, preview delivery, then call exercise(roundId, quantity, maxDeliveryIn) as the buyer. Exercise before expiry; unused rights are not automatically exercised.
The signed quantity boundary matters.

R14 includes minFillContracts in the signed order but excludes numContracts. The reference quote still binds a requested size through its exercise terms and collateral grid. Do not replace that size without revalidating the complete quote.

Curated ABI subsets from source revision 87dc632. No deployment address is implied. Compare against the exact deployed bytecode before use.

Lookback terms and observation eligibility

extraOptionData = abi.encode(deliveryCollateral, startTimestamp, maxDeviationBps, minPartialExerciseSize). These static fields occupy 128 bytes. RH adds a final uint64 referenceBlock, occupying 160 bytes in total.

Only the selected round must fall inside the observation window. It must cross activation; its immediate neighbours validate the observation within the configured deviation bound. All three must be published by the exercise and before expiry. The predecessor can predate the window. The cap/floor clips the eligible observed price, not the activation threshold.

A partial exercise reduces quantity and reserve. It does not reset the window, cap/floor or past eligible observations. Each portion must meet the signed minimum, or use the entire remainder, and may not leave an invalid small remainder.

Optional USDC → aUSDC premium funding

The proposed Aave router accepts one underlying approval, supplies to its pinned pool and fills the pinned Book atomically. It supports the maker-short direction and six-decimal configured underlying/aToken. The caller sets maxUnderlyingIn and minContractsOut.

Its input budget is nominal premium plus up to six underlying atoms: two for supply rounding and four for two premium-transfer debit bounds. The specified index range is 1–2 RAY. Excess is refunded within the transfer budget. Live deployment qualification remains outstanding. This helper changes premium funding, not exercise delivery tokens.

04 · RH-specific accounting

Keep the share unit consistent.

RH oracle observations price a raw Stock Token. Divide by the historical multiplier to recover the ordinary-share price.

Share price = token oracle price ÷ historical multipliersharePrice8 = mulDiv(tokenPrice8, 1e18, multiplier18)

Example: 707 ÷ 1.01 = 700

Earlier peak: 1,000 ÷ 1.005 ≈ 995.02 per share

Query candidates(token, round.updatedAt) for each observation and its neighbours. Before the first record, there is no history. Between ranges or within a shared second, preserve every possible value and show the resulting price range. The live multiplier is not a replacement for historical data.

A public registry

The multiplier and header registries are deployed on Robinhood Chain, chain 4663. Anyone can read them or contribute valid observations. No Hindsight account or API key is required.

Addresses, ABIs and read example ↗

The deployed read-only registry is separate from approval or deployment of RH option trading. RH exercise and split handling still require their own integration review.