feat(api): solver inventory per side of each pair, read from our node
ci / gate (push) Failing after 1m34s

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
This commit is contained in:
2026-10-03 23:12:32 +03:00
co-authored by Claude Opus 5.5
parent fb7148cc98
commit 2d80325c3b
19 changed files with 710 additions and 9 deletions
@@ -0,0 +1,32 @@
{
"db_name": "PostgreSQL",
"query": "select account, fills, last_seen_height from intents_solver order by fills desc",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "account",
"type_info": "Text"
},
{
"ordinal": 1,
"name": "fills",
"type_info": "Int8"
},
{
"ordinal": 2,
"name": "last_seen_height",
"type_info": "Int8"
}
],
"parameters": {
"Left": []
},
"nullable": [
false,
false,
false
]
},
"hash": "1f83a928a4758bea96d635769ede11a6aae975d77a8b8289f95a6bd96c3b5f21"
}
@@ -0,0 +1,16 @@
{
"db_name": "PostgreSQL",
"query": "\n insert into intents_solver (account, first_seen_height, last_seen_height, fills)\n select account, $3, $3, fills from unnest($1::text[], $2::bigint[]) as t(account, fills)\n on conflict (account) do update set\n first_seen_height = least(intents_solver.first_seen_height, excluded.first_seen_height),\n last_seen_height = greatest(intents_solver.last_seen_height, excluded.last_seen_height),\n fills = intents_solver.fills + excluded.fills,\n updated_at = now()\n ",
"describe": {
"columns": [],
"parameters": {
"Left": [
"TextArray",
"Int8Array",
"Int8"
]
},
"nullable": []
},
"hash": "3f3344e1b8b27450f527aaefc5ffa9e1a0dd73ba2836d98474927a9b3193de16"
}
@@ -0,0 +1,23 @@
{
"db_name": "PostgreSQL",
"query": "select distinct counter_token from intents_trade where chain = $1 and asset = $2",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "counter_token",
"type_info": "Text"
}
],
"parameters": {
"Left": [
"Text",
"Text"
]
},
"nullable": [
false
]
},
"hash": "8753c8ef359a70cdb2954dca520f62fbe39893021d118be560c1986501ae0231"
}