# Implementation Proof: NEAR Intents request creation and EURe-to-BTC taker flow Status: open Opened: 2026-04-12 ## Target outcome The repository must be able to create our own NEAR Intents EURe-to-BTC swap request from credited internal inventory, submit it through repo-owned code, and explain the full request lifecycle from preflight through settlement truth. For each repo-created request the operator must be able to answer: - which asset and amount we intended to spend - which asset and minimum amount we expected to receive - which signer, verifier contract, nonce, deadline, slippage, and idempotency key were used - whether the request was drafted, blocked, submitted, accepted by relay, failed, awaiting settlement, not filled, or completed - whether completed means durable inventory movement, not relay acceptance - how much BTC was received and how much EURe was spent, if settlement is proven ## Why this is the next architecture test The existing system can observe incoming NEAR Intents quote requests and respond as a solver or maker. That path has not produced fills at 1.49%, 0.99%, or 0.49% in recent live validation, and it cannot intentionally convert our EURe inventory into BTC. The next false path would be manually moving funds or adding a button that submits opaque live requests without durable preflight, request, and settlement evidence. This turn is successful only if the system can create requests as a first-class, auditable repo-owned flow instead of treating live fund movement as an off-system action. ## Scope - [I017] Repo-owned NEAR Intents request creation and EURe-to-BTC taker flow: create, sign, submit, and settle our own swap requests from credited inventory with truthful dashboard evidence. tags=intents,taker,execution,inventory,settlement - Active venue only: NEAR Intents. - Active direction: credited internal EURe to BTC. - Use credited spendable internal inventory only. Pending funding remains non-spendable. - Build the request path with dry-run/preflight first, then gated live submission. - Actual live submission requires explicit operator control and must be recorded durably. ## Assumptions - NEAR Intents exposes a supported request or quote publication method through the solver relay or another documented endpoint callable with our existing API key and verifier signer. - The correct taker intent can be represented as a signed verifier token_diff payload or a documented request envelope whose semantics can be proven before live submission. - Internal inventory snapshots are fresh enough to enforce spendable EURe and settlement deltas. - BTC minimum receive can be derived from reference price plus explicit slippage or minimum-out policy. - The user's intent is to build the capability to move EURe into BTC; live all-EURe execution remains behind an explicit final operator action in the repo-owned UI or API. ## Turn-shaping rules - Do not manually move funds. - Do not submit an all-EURe live request until repo-owned preflight, durable request logging, and settlement attribution are implemented and the operator explicitly triggers that live request. - Do not use pending or uncredited EURe. - Do not label relay acceptance as completed settlement. - Do not hide slippage, minimum receive, deadline, nonce, signer, or request id. - If the NEAR Intents request API cannot be verified from primary evidence or live dry-run behavior, stop and record the blocker instead of inventing a protocol. - Keep maker quote-response logic intact unless the new taker flow proves it should be paused or separated. ## Non-goals - No new venue. - No external wallet or manual bridge action. - No automatic recurring rebalancer. - No realized net PnL claim without fee and cost attribution. - No tax or accounting treatment. - No broad multi-asset request builder beyond EURe-to-BTC. ## Required operator behavior ### Request preflight truth Before submission, the operator must see: - spendable EURe available - requested EURe spend amount - BTC reference price - slippage or minimum-out rule - expected BTC receive and minimum BTC receive - deadline and nonce policy - exact signer account and verifier contract - whether this is dry-run only or live-submit capable ### Request lifecycle truth For each repo-created request, the dashboard must show: - request id, copyable - idempotency key, copyable - intent hash or relay request id if returned, copyable - created_at, submitted_at, resolved_at if known - state: draft, blocked, submitted, accepted_by_relay, failed, awaiting_settlement, not_filled, completed - decisive reason for blocks, failures, or no-fill - settlement evidence if completed ### Settlement truth Completed requires durable asset movement evidence: - EURe spend delta and BTC receive delta from inventory snapshots - attribution method and caveat if heuristic - submitted-only and relay-accepted rows remain separate from completed - portfolio-vs-hold movement remains separate from realized trade PnL ## Semantic invariants The implementation and tests must enforce at least: - request submitted != completed - relay accepted != settled inventory movement - pending EURe cannot be spent - insufficient spendable EURe blocks before signing or submission - slippage and minimum-out must be explicit and persisted - duplicate idempotency key cannot produce duplicate live submissions - dry-run request cannot accidentally submit - completed request rows require durable settlement evidence - request-creation flow is distinct from incoming quote-response flow ## Definition of done - The repo contains a verified NEAR Intents request-creation client or a recorded blocker proving the venue path is unavailable. - A request preflight API computes amount, min-out, deadline, nonce policy, signer, verifier, and inventory checks from durable/current data. - A gated live submission API exists only after preflight and records durable request, submission, and result events. - The dashboard shows repo-created request rows separately from incoming quote-response rows, with copyable ids and lifecycle reasons. - Settlement attribution handles repo-created requests without treating relay acceptance as completion. - Regression tests cover request signing/envelope semantics, inventory blocks, dry-run safety, idempotency, submission failure, submitted-not-completed, and completed-only-with-settlement. - The result is deployed through the repo workflow and validated against live service state. ## Validation evidence required - Unit tests for request preflight and minimum-out/slippage math. - Unit tests for signed request or request envelope construction using deterministic signer fixtures. - Unit tests proving insufficient EURe blocks before signing/submission. - Unit tests proving submitted/accepted requests do not count as completed without inventory deltas. - Live dry-run/preflight evidence for current credited EURe inventory. - If live submission is explicitly triggered, durable DB evidence for request, submission result, and later settlement or no-fill. - Dashboard bootstrap evidence showing the new request lifecycle row with copyable ids and truthful state. ## Failure conditions - Live funds are moved outside repo-owned code. - A request is submitted without durable preflight and request records. - The UI claims BTC was bought from relay acceptance alone. - A dry-run path can submit. - Pending funding is treated as spendable. - The implementation cannot prove the NEAR Intents request API shape and still proceeds. ## Current real before this turn - The repo has verifier signing for quote-response token_diff payloads. - The repo has a solver relay websocket client and quote-response submission path. - Credited internal BTC/EURe inventory is synced durably. - Quote, decision, command, submission result, and outcome attribution records exist for incoming quote-response flow. - The dashboard distinguishes submitted, not-filled, completed, rejected, and blocked rows for incoming quote responses. ## Deliberately not built by this proof - General portfolio optimizer. - Automatic all-in rebalancing loop. - Fee-complete realized PnL. - Venue-native terminal fill ingestion unless the request API provides it directly.