Files
observer/crates/blackbeard-data/migrations/0011_intents_solver.sql
T
grenadeandClaude Opus 5.5 2d80325c3b
ci / gate (push) Failing after 1m34s
feat(api): solver inventory per side of each pair, read from our node
NEAR Intents has no order book: solvers quote privately per request and
nothing on chain carries a price level. What is on chain is the inventory
they fill from, inside intents.near — and intents.near is on the shard our
node tracks, so mt_batch_balance_of is answered locally in about 40 ms.

The scan now records every solver it sees filling any pair — a named account
with no referral, which the #30 survey found to be solvers without exception
— in intents_solver (migration 0011), so the list survives restarts and is
there before QTC has a trade of its own. Once a minute the observer asks
intents.near what each holds of the asset and every counter traded against
it, and serves it at /intents/inventory: the asset as the side that serves
buyers, each counter as the side that serves sellers, with how many solvers
hold it and the largest holder.

The market page shows it as a table, the asset and the ten counters most
solvers hold with the rest folded, under a note that says what it is not: no
price levels, shared across pairs so the rows do not add up, and not a
ceiling. Checked live against our node with wNEAR configured: 11 solvers,
74 tokens read in one pass. Before QTC is listed the panel's job is its one
row — when solvers start stocking QTC, it shows here before the first trade.

Closes #34

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015pkwBsR54NRmZyU4QVhvfj
2026-10-03 23:12:32 +03:00

16 lines
785 B
SQL

-- Accounts seen filling trades on NEAR Intents. blackbeard/observer#34.
--
-- Recorded by the intents scan from every executed outcome it reads, not only
-- the tracked asset's: a leg with no referral, on a named account, is a solver
-- (the #30 survey found 589 such legs and every one was a solver). The list is
-- what the inventory poll asks intents.near about, so it has to survive a
-- restart — and it is ours: a solver that only ever fills by a route this
-- indexer does not read is not in it.
create table intents_solver (
account text primary key,
first_seen_height bigint not null,
last_seen_height bigint not null,
fills bigint not null default 0,
updated_at timestamptz not null default now()
);