Skip to content

Arkade Market Discovery Protocol v0 — solver side#10

Draft
tiero wants to merge 6 commits into
masterfrom
claude/draft-pr-qa-fixes-n06k24
Draft

Arkade Market Discovery Protocol v0 — solver side#10
tiero wants to merge 6 commits into
masterfrom
claude/draft-pr-qa-fixes-n06k24

Conversation

@tiero

@tiero tiero commented Jul 9, 2026

Copy link
Copy Markdown
Member

Implements the solver side of the Arkade Market Discovery Protocol v0 (per arkade-discovery-spec.md): pair configuration gains the fields the discovery card needs, and the solver can emit its own solvers/<network>/<name>.json card for the registry repo. Discovery is additive and advisory — the covenant, TLV offer format and fill-path semantics are untouched.

What's here

  • Pair model: rename slippage_bpstolerance_bps (internal fill band, default 100, never published), add fee_bps (published spread, default 0); validate tolerance_bps > fee_bps on add/update — a market whose internal band is narrower than its published fee cannot fill
  • Base-denominated limits: min_base_amount/max_base_amount bound the base side of the trade (the maker's deposit) in base-asset atomic units. Previously bounds were checked against WantAmount (quote side). ⚠️ Values are not converted by the migration — operators must review bounds after upgrading
  • Per-side asset metadata: base/quote name/ticker on the Pair (BTC side auto-fills Bitcoin/BTC/8; asset sides fall back to indexer metadata, operator flags win) + price_decimals (feed normalization, also applied at fill time so the published normalization mirrors what the solver enforces)
  • pkg/discovery: BuildCard (spec-exact card, deterministic market ordering by id pair, optional BIP340 signing over sha256 of the canonical serialization — sig removed, keys sorted, no whitespace) and ValidateCard (registry-CI-equivalent checks incl. strict schema + signature verification); golden tests pin unsigned/signed/canonical bytes, fixtures reusable by the registry repo CI
  • Wiring: SOLVER_NAME / SOLVER_DISCOVERY_SECRET_KEY envs (fallback: key derived from wallet seed at m/38173'/0'), GET /v1/discovery/card returning raw card bytes (+X-Registry-Path header hint, network from arkd's config), solver card [--sign] printing byte-identical output
  • QA round 1: consolidated the schema change into one 20260709 migration, made pair get --json carry all fields, dashboard edits preserve CLI-set card metadata, acceptance tests per the spec's criteria
  • QA round 2: multi-angle adversarial review in progress

Notes

  • make proto regen done offline with local plugins pinned to the same versions as buf.gen.yaml's remote ones (buf.build unreachable from the sandbox); make sqlc regen included.
  • Existing --slippage-bps CLI flag kept as an alias of --tolerance-bps.
  • /v1/discovery/card is HTTP-only (no proto RPC): the response is the raw registry document, not a JSON envelope, so curl output is PR-ready. Happy to lift it into the proto if gRPC parity is wanted.

🤖 Generated with Claude Code

https://claude.ai/code/session_016yemf5rGd6Y4By6dHXb7Ny

claude added 6 commits July 9, 2026 23:07
Adopt the discovery-protocol vocabulary: the internal fill-time price
band is the pair's tolerance_bps (default 100, never published), while
fee_bps is the published spread promised to makers. Validate
tolerance_bps > fee_bps on add/update — a market whose internal band is
narrower than its published fee cannot fill.

Renames the column/proto field/CLI flag (--slippage-bps kept as an
alias) and threads fee_bps through sqlite, the API, the CLI and the
dashboard.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_016yemf5rGd6Y4By6dHXb7Ny
Per the discovery spec, min/max bound the base side of the trade in
base-asset atomic units, applied to the maker's deposit (the pair's
base is always the deposit side). Previously the bounds were checked
against WantAmount — the quote side in quote units — which breaks for
asset-to-asset pairs and contradicts the published card semantics.

Renames min_amount/max_amount to min_base_amount/max_base_amount across
the schema (values are not converted — operators must review bounds
after upgrading), API, CLI (--min/--max keep their names, help text now
states base-side semantics) and dashboard. Adds Match tests covering a
tightened tolerance_bps and base-unit limits on a non-BTC-base pair.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_016yemf5rGd6Y4By6dHXb7Ny
The discovery card needs asset descriptors (id/name/ticker/precision)
and the feed's decimal encoding. Pairs gain base/quote name+ticker —
auto-filled with Bitcoin/BTC on the BTC side and from the indexer's
asset metadata otherwise, operator flags win — and price_decimals
(price = feed value / 10^n, default 0). The plugin now applies
price_decimals when normalizing the feed at fill time so the published
normalization always mirrors what the solver enforces.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_016yemf5rGd6Y4By6dHXb7Ny
Implements the solver card of the Arkade Market Discovery Protocol v0.
BuildCard renders one market per configured pair — asset descriptors
with canonical ids ('btc' or the lowercase hex AssetId), the pair label
derived from the tickers, feed/price_decimals/invert, fee_bps and the
base-denominated limits — sorted by id pair for deterministic,
registry-reviewable output. tolerance_bps never appears in a card.

Signing is optional and off by default per spec: with a key, the card
carries the x-only discovery_pubkey and a BIP340 signature over
sha256 of the canonical serialization (sig removed, keys sorted, no
whitespace, no HTML escaping). ValidateCard mirrors the registry CI:
strict schema, version/name checks, per-market rules, id-pair dedupe
and signature verification. Golden tests pin the unsigned, signed and
canonical bytes; the fixtures are plain files for reuse by the
registry repo's CI.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_016yemf5rGd6Y4By6dHXb7Ny
BuildDiscoveryCard on the application service renders the card from
the configured pairs — named by SOLVER_NAME, optionally signed with
SOLVER_DISCOVERY_SECRET_KEY or a key derived from the wallet seed at
the dedicated discovery path — plus the registry path hint
solvers/<network>/<name>.json (network from arkd's config, 'bitcoin'
maps to 'mainnet').

GET /v1/discovery/card serves the raw document bytes with the hint in
an X-Registry-Path header, so curl and the new 'solver card [--sign]'
command (card to stdout, hint to stderr) emit identical, PR-ready
bytes. Both are operator tooling: the solver stays unreachable from
the outside.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_016yemf5rGd6Y4By6dHXb7Ny
…e tests

- Collapse the three branch-local migrations into one 20260709 file:
  10-digit versions would have sorted after future 8-digit date-only
  migrations, breaking the repo's migration ordering convention.
- solver pair get --json now carries all pair fields (asset metadata
  and price_decimals were silently dropped); pair detail shows the
  card label and price decimals.
- Dashboard edits preserve card metadata set via the CLI instead of
  resetting it (the form has no inputs for those fields).
- Acceptance tests per the spec: BuildDiscoveryCard output validates,
  reflects fee/limits/feed, contains no tolerance, changes with the
  pair, maps arkd networks onto registry directories, and signs with
  the env key or seed-derived key; 'solver card' emits byte-identical
  output to the endpoint.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_016yemf5rGd6Y4By6dHXb7Ny
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants