On NEAR Intents a price exists only when a solver chooses to quote, and nothing on-chain records a refusal. Every minute the observer now asks 1Click for a keyless dry quote on QTC pairs only, both ways, against native USDC and Ethereum USDC: the smallest size each minute and the full grid each quarter hour, averaging about 4 requests a minute against a published limit of 1,200. At the same moment it reads two things from its own nodes: the Ref pool's quote for the same input, and every solver's balance of the output token inside intents.near. So each "No liquidity available" is stored with whether one solver alone held enough to settle the trade. A probe that got no answer is recorded as `failed`, never as a refusal. Only our own observations are kept: the 1ClickSwap API Terms (s4.1(e)) forbid keeping API data past 24 hours, so a quote becomes a markup against the pool on arrival and raw responses are pruned hourly. The first live round, 2026-10-07: "No liquidity available" both ways. Selling 1 QTC, the pool would have paid 101.53 USDC and three solvers each held enough. Buying with 100 USDC, solver-ref-2.near held 2,308 QTC. The near-intents market page shows a strip per direction and counter token. It is an emphasis chart: the accent marks only "no quote while a solver could fill", the other states are quiet ink told apart by height, and the neutral token is validated against the accent in both themes. Beside it are a summary table and a list of the latest refusals. The pause log and the price-move statistics in #45 come later, once there is history to support them. Refs #45 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015tyzzRVjH9AdwGtYwsH5VC
54 lines
2.5 KiB
SQL
54 lines
2.5 KiB
SQL
-- Whether 1Click would quote the tracked asset, against whether it could have.
|
|
-- blackbeard/observer#45.
|
|
--
|
|
-- One row per probe: a keyless dry quote for one direction, size and counter
|
|
-- token, beside what this observer read for itself at the same moment, which
|
|
-- is what the pool would pay on-chain for the same trade and what the solvers
|
|
-- held of the output token inside intents.near.
|
|
--
|
|
-- Only our own observations are kept here. The 1ClickSwap API Terms (§4.1(e))
|
|
-- forbid storing API data for more than 24 hours, so a quoted amount is
|
|
-- reduced to `markup_bps` against the pool when it arrives, and the response
|
|
-- itself goes to `quote_probe_raw`, which is emptied after a day.
|
|
create table quote_probe (
|
|
chain text not null references chain (id) on delete cascade,
|
|
asset text not null,
|
|
at timestamptz not null,
|
|
-- `sell` gives the asset for the counter token; `buy` the reverse.
|
|
direction text not null check (direction in ('sell', 'buy')),
|
|
counter text not null,
|
|
-- The input, base units of whichever token is given.
|
|
size numeric not null,
|
|
-- `failed` is the probe not getting an answer (transport, 429, 5xx): a
|
|
-- fact about the probe, never about the solvers.
|
|
outcome text not null
|
|
check (outcome in ('quoted', 'no_liquidity', 'refused', 'failed')),
|
|
message text,
|
|
latency_ms integer,
|
|
-- What the reference pool's own `quote` view gives for the same input, read
|
|
-- from our node at the same moment. Null when no pool could be asked.
|
|
pool_out numeric,
|
|
-- For a quote: how much less than `pool_out` it paid, in basis points.
|
|
markup_bps integer,
|
|
-- The solver holding the most of the output token inside intents.near,
|
|
-- and how much. Solvers do not pool inventory, so one holder is the test.
|
|
best_solver text,
|
|
best_held numeric,
|
|
-- How many solvers each held at least `pool_out` of the output token.
|
|
solvers_able integer,
|
|
primary key (chain, asset, at, direction, counter, size)
|
|
);
|
|
create index quote_probe_recent on quote_probe (chain, asset, at desc);
|
|
|
|
-- The responses themselves, for a day, for debugging the probe. Deleted by
|
|
-- the probe loop; never read by the API.
|
|
create table quote_probe_raw (
|
|
at timestamptz not null,
|
|
direction text not null,
|
|
counter text not null,
|
|
size numeric not null,
|
|
status integer,
|
|
body jsonb not null,
|
|
primary key (at, direction, counter, size)
|
|
);
|