Files
Danish Arora 3b8219026e feat(offer-publisher): select the maker's delivery fleet with SWAP_FLEET (default logos.dev) (#160)
* feat(maker): select the delivery fleet with SWAP_FLEET (default logos.dev)

* no-mistakes(document): docs(deploy): fleet is per-maker via SWAP_FLEET, not baked
2026-08-27 15:23:49 +05:30

108 lines
5.5 KiB
Bash

# Maker liquidity-bot environment — copy to deploy/maker.env and fill in.
# `deploy/maker.env` is gitignored; never commit real keys.
#
# HARD RULE: every distinct maker instance/deployment needs a DISTINCT
# ETH_RECIPIENT_ADDRESS. If two makers share one address, both match the
# same on-chain `Locked` event and race to lock the LEZ escrow; the loser
# ends up holding a journal entry for an escrow it cannot refund ("only
# maker can refund"), which `reconcile` retains forever as a quarantined
# entry. One address per maker, always.
# --- Ethereum (Sepolia) ---
ETH_RPC_URL=wss://ethereum-sepolia-rpc.publicnode.com
# Fresh key generated ONLY for this bot — never reuse a personal/dev key.
# Needs ~0.05 ETH: its only gas cost is the profitable ETH claim (~55k gas).
# Hex, no 0x prefix (see docs/testnet.md env template).
ETH_PRIVATE_KEY=REPLACE_ME_64_HEX_CHARS_NO_0x_PREFIX
# Canonical shared Sepolia EthHTLC (see docs/testnet.md / project memory).
# v2 (INTERFACE_VERSION=2, deployed 2026-08-04) — bound to the taker's LEZ
# account from PR #64/#76 (see docs/testnet.md). Supersedes the earlier
# 0x8636Fe66DFee166589a913140f14d5F57394834A deployment; a maker built
# before those PRs merged cannot talk to this address (ABI changed).
ETH_HTLC_ADDRESS=0x351B0EA07739FA9F6769213927D7836a790A5FAF
# MUST be unique per maker instance/deployment — see HARD RULE above.
ETH_RECIPIENT_ADDRESS=0x_REPLACE_ME
# --- LEZ (public testnet) ---
LEZ_SEQUENCER_URL=https://testnet.lez.logos.co
# Raw signing key for a native LEZ account created via `swap-cli` onboarding
# (src/lez/onboard.rs: Signer::generate + ensure_initialized + claim_to_target)
# — no scaffold wallet, no `wallet` binary required in this image.
LEZ_SIGNING_KEY=REPLACE_ME_64_HEX_CHARS
LEZ_HTLC_PROGRAM_ID=9eb88f51aae87a58fb74b8d2dc7327b39333585e63280e3f9cf8d86dac0ed702
# --- Swap parameters ---
LEZ_AMOUNT=1
ETH_AMOUNT=1
# Loop-mode defaults (20/40 min) already account for public-testnet LEZ lock
# confirmation taking up to ~300s; only override if you know why.
# LEZ_TIMELOCK_MINUTES=20
# ETH_TIMELOCK_MINUTES=40
# --- Counterparty ---
# DEFAULT / CURRENT MODE: PUBLIC. Serves any taker — each one publishes its
# own LEZ account in its ETH lock (PR #64/#76) and the maker binds the escrow
# to that. To restrict this maker to a single designated counterparty instead,
# set BOTH of the following (not just one — see the HARD RULE below):
# RESTRICT_COUNTERPARTY=true
# LEZ_TAKER_ACCOUNT_ID=<base58 account>
#LEZ_TAKER_ACCOUNT_ID=REPLACE_ME_64_HEX_CHARS
#
# HARD RULE: RESTRICT_COUNTERPARTY and LEZ_TAKER_ACCOUNT_ID must be changed
# TOGETHER, never just one. `classify_candidate`'s `designated_taker` is
# populated straight from LEZ_TAKER_ACCOUNT_ID whenever it is SET, regardless
# of RESTRICT_COUNTERPARTY's value — so a lingering LEZ_TAKER_ACCOUNT_ID left
# over from a previous restricted deployment silently turns back into an
# allowlist even with RESTRICT_COUNTERPARTY=false, quietly rejecting every
# other taker. For public mode, LEZ_TAKER_ACCOUNT_ID must be UNSET (commented
# out), not merely paired with RESTRICT_COUNTERPARTY=false. See README.md.
# --- Maker-loop tuning ---
# FALLBACK_HEARTBEAT_SECS is the SLOW, reliable baseline republish interval:
# with the RFQ on-demand model (feat/rfq-on-demand-offers) the offer-publisher
# now responds instantly when a taker asks, so the heartbeat only needs to
# cover takers who missed the response. Default 30s. The legacy
# OFFER_HEARTBEAT_SECS below is still honoured (swap-cli injects it) if
# FALLBACK_HEARTBEAT_SECS is unset — keep one of them, they mean the same slow
# baseline now.
FALLBACK_HEARTBEAT_SECS=30
OFFER_HEARTBEAT_SECS=45
# RFQ responder coalescing window: the maker answers at most one offer-request
# per RESPONSE_COOLDOWN_SECS regardless of how many arrive. This is the
# anti-amplification guard for the UNAUTHENTICATED requests topic (100 pings in
# a window -> 1 offer). Default 8s. Raise it to harden against a flood; lower
# it for a snappier board at the cost of more publishes under load.
RESPONSE_COOLDOWN_SECS=8
TIMELOCK_MARGIN_MINUTES=5
RESTRICT_COUNTERPARTY=false
# --- Background LEZ low-water top-up (issue #93 point 3) ---
# Every FUND_CHECK_SECS, check the LEZ balance and, if below
# FUND_LOW_WATER, claim from the pinata faucet up to that mark — independent
# of the swap-accept loop, so running dry mid-campaign no longer requires an
# operator to notice and restart the process by hand. Uncomment to override
# the defaults (300s / 3x LEZ_AMOUNT).
#FUND_CHECK_SECS=300
#FUND_LOW_WATER=30
# --- Delivery fleet (leave unset unless dual-homing; see README.md) ---
# Which fleet this maker's offer-publisher sidecar publishes on. Unset means
# logos.dev — where the live market and the shipped app are — so leave it
# alone for a normal maker. `logos.test` is the fleet the app migrates to in
# PR #125; pointing a maker there warms it ahead of the app-side switch.
# Anything else aborts the publisher at startup (no silent fallback).
#
# ONLY EFFECTIVE FOR THE BASE `maker` SERVICE (docker-compose.yml). The extra
# makers in docker-compose.multi.yml set SWAP_FLEET from `MAKER_<n>_FLEET` in
# `deploy/.env`, and compose `environment` overrides `env_file` — a line here
# would be silently ignored for those.
#SWAP_FLEET=logos.test
# --- Paths (already correct for the container image; do not change) ---
MAKER_STATE_FILE=/app/state/.maker-state.json
MAKER_STATUS_FILE=/app/state/maker-status.json
OFFER_PUBLISHER_SCRIPT=/app/offer-publisher/publish-offer.mjs
# --- Logging ---
RUST_LOG=info