unrip/docs/operator-runbook.md
philipp 41b9ec680b
Some checks failed
deploy / deploy (push) Failing after 1m35s
Implement funded NEAR Intents trade loop
Proof: first non-mocked tradeable loop for one pair using funded NEAR Intents inventory, Kafka, and PostgreSQL.

Assumptions: solver-side execution is performed by signed token_diff quote responses over the Solver Relay; EURe is treated as 1:1 with EUR; k3s runtime uses unrip-dev.near as the named signer account.

Still fake: signer key is not yet registered on intents.near, strategy and executor remain disarmed by default, and no live mainnet quote response has been submitted from this repo yet.
2026-04-02 10:01:15 +02:00

131 lines
4.5 KiB
Markdown

# Operator Runbook
This turn implements the first funded market-maker loop for the active BTC/EURe pair on NEAR Intents.
## Verified venue flow
The implementation follows the official NEAR Intents market-maker path:
1. Funding handles come from the Passive Deposit/Withdrawal Service `deposit_address` RPC for the configured treasury chains.
2. Spendable inventory comes from the Verifier internal ledger on `intents.near` via `mt_batch_balance_of`.
3. Pending deposits remain non-spendable and are tracked from `recent_deposits`.
4. Real market-maker execution is a Solver Relay `quote_response` carrying a signed `token_diff`.
5. Named NEAR accounts need the executor public key registered on `intents.near` via `add_public_key` before live submission will succeed.
The Message Bus settles matched intents on-chain after a user accepts the quote. The executor therefore submits quote responses; it does not bridge or top up inventory on the hot path.
## Required env and secrets
Minimum required runtime values:
- `NEAR_INTENTS_API_KEY`
- `NEAR_INTENTS_ACCOUNT_ID`
- `NEAR_INTENTS_SIGNER_PRIVATE_KEY`
- `POSTGRES_URL`
Before the first live attempt on a named NEAR account, register the executor public key on `intents.near` from that named account:
```bash
near contract call-function as-transaction \
intents.near add_public_key json-args '{
"public_key": "ed25519:<executor-public-key>"
}' prepaid-gas '100.0 Tgas' attached-deposit '1 yoctoNEAR' \
sign-as <ACCOUNT_ID> network-config mainnet sign-with-keychain send
```
The executor stays disarmed by default even after the key is registered.
## Local bring-up
```bash
npm install
cp .env.example .env
# fill NEAR_INTENTS_API_KEY, NEAR_INTENTS_ACCOUNT_ID, NEAR_INTENTS_SIGNER_PRIVATE_KEY
docker compose up -d --build
```
Services:
- `near-intents-ingest`
- `market-reference-ingest`
- `liquidity-manager`
- `inventory-sync`
- `history-writer`
- `strategy-engine`
- `trade-executor`
## Control APIs
Default local ports:
- `8081` `near-intents-ingest`
- `8082` `market-reference-ingest`
- `8083` `inventory-sync`
- `8084` `liquidity-manager`
- `8085` `history-writer`
- `8086` `strategy-engine`
- `8087` `trade-executor`
Common inspection:
```bash
curl -s http://127.0.0.1:8081/healthz
curl -s http://127.0.0.1:8081/state
curl -s http://127.0.0.1:8086/state
curl -s http://127.0.0.1:8087/state
```
Useful controls:
```bash
curl -s -X POST http://127.0.0.1:8082/refresh
curl -s -X POST http://127.0.0.1:8083/refresh
curl -s -X POST http://127.0.0.1:8084/refresh
curl -s -X POST http://127.0.0.1:8086/arm
curl -s -X POST http://127.0.0.1:8086/disarm
curl -s -X PUT http://127.0.0.1:8086/limits \
-H 'content-type: application/json' \
-d '{"max_notional_eure":5}'
curl -s -X POST http://127.0.0.1:8087/arm
curl -s -X POST http://127.0.0.1:8087/disarm
```
Track a withdrawal so it stays visible in liquidity and inventory state:
```bash
curl -s -X POST http://127.0.0.1:8084/track-withdrawal \
-H 'content-type: application/json' \
-d '{"withdrawal_hash":"<near-burn-tx-hash>","asset_id":"nep141:btc.omft.near","chain":"btc:mainnet","amount":"1000"}'
```
## Safe arming sequence
1. Confirm `market-reference-ingest` is publishing fresh BTC/EUR data.
2. Confirm `inventory-sync` shows credited spendable balances on `intents.near`.
3. Confirm `liquidity-manager` shows the expected deposit handle and any pending funding separately from spendable inventory.
4. Confirm `history-writer` has PostgreSQL connectivity.
5. Keep `STRATEGY_MAX_NOTIONAL_EURE=5` for the first live test.
6. Arm `strategy-engine` first.
7. Observe actionable decisions without venue errors.
8. Arm `trade-executor` only when the signer key is registered and funded inventory is already credited.
## What to inspect after a live attempt
- `decision.trade_decision` for the reasoning chain.
- `cmd.execute_trade` for the emitted quote response command.
- `exec.trade_result` for submission outcome.
- PostgreSQL tables:
- `swap_demand_events`
- `market_price_events`
- `intent_inventory_snapshots`
- `liquidity_actions`
- `trade_decisions`
- `execute_trade_commands`
- `trade_execution_results`
## Still fake
- Settlement follow-up after user quote acceptance is only visible indirectly through Solver Relay quote-status observations; the repo records the live quote-response attempt, not an end-user acceptance flow it does not control.
- The executor checks signer registration best-effort. If the verifier key-check view surface changes, the live submission itself remains the definitive signal.