@@ -90,12 +90,9 @@ change only the lines shown below.
9090network : mainnet
9191` ` `
9292
93- Caution: this is the live network. Two things to consider before exposing it:
94-
95- - Set ` merkle_service.url` and `callback_token` together if you want STUMP
96- callbacks. arcade refuses to start with one set and the other empty.
97- - Bind `api.host` to a private interface (or front it with auth) if the host is
98- reachable from the public internet.
93+ Caution: this is the live network. Bind ` api.host` to a private interface (or
94+ front it with auth) if the host is reachable from the public internet. See the
95+ [Merkle Service](#merkle-service) section below for the mainnet endpoint.
9996
10097# ## testnet — public BSV testnet
10198
@@ -129,6 +126,70 @@ Two regtest-specific constraints, enforced at config load:
129126- ` chaintracks_server` is auto-disabled regardless of what you set; the
130127 embedded chaintracks library has no regtest genesis header.
131128
129+ # # Merkle Service
130+
131+ Arcade delegates merkle-proof construction to a separate **Merkle Service**.
132+ The service watches the network for arcade's registered txids and drives the
133+ transaction lifecycle forward via callbacks
134+ (`SEEN_ON_NETWORK` → `MINED` → `IMMUTABLE`).
135+
136+ **If `merkle_service.url` is left empty, arcade still accepts and broadcasts
137+ transactions, but every row stays at `RECEIVED` forever** — no callback source
138+ means nothing advances the state machine. Configure Merkle Service whenever
139+ you want real status progression.
140+
141+ # ## Public Merkle Service endpoints
142+
143+ | Network | URL |
144+ | ------------- | --------------------------------------------------- |
145+ | `mainnet` | `https://merkle-service-us-1.bsvb.tech` |
146+ | `testnet` | `https://merkle-service-testnet-us-1.bsvb.tech` |
147+ | `teratestnet` | `https://merkle-service-ttn-us-1.bsvb.tech` |
148+ | `regtest` | bring your own — no public instance |
149+
150+ # ## Generate a callback auth token
151+
152+ Merkle Service authenticates its inbound callbacks to arcade with a bearer
153+ token. Generate a high-entropy value :
154+
155+ ` ` ` bash
156+ openssl rand -hex 32
157+ ` ` `
158+
159+ The same value must also be configured on the Merkle Service side so it can
160+ attach `Authorization : Bearer <token>` to its callback requests. Arcade
161+ **refuses to start** when `merkle_service.url` is set without `callback_token`
162+ — an unauthenticated callback receiver would accept forged status updates for
163+ any txid.
164+
165+ # ## Set `callback_url`
166+
167+ ` callback_url` is the **public URL at which Merkle Service can reach this
168+ arcade instance**, with path `/api/v1/merkle-service/callback`. Merkle
169+ Service POSTs status updates here, so it must be resolvable and routable
170+ *from Merkle Service*, not just from your laptop.
171+
172+ Examples :
173+
174+ - Public deployment : ` https://arcade.example.com/api/v1/merkle-service/callback`
175+ - Local dev with Merkle Service running in Docker on the same host :
176+ ` http://host.docker.internal:8080/api/v1/merkle-service/callback`
177+
178+ # ## Example config block
179+
180+ Append the following to your `config.yaml`. Note that `callback_url` and
181+ ` callback_token` are **top-level** keys; only `url` and `auth_token` live
182+ under `merkle_service:`.
183+
184+ ` ` ` yaml
185+ callback_url: "https://arcade.example.com/api/v1/merkle-service/callback"
186+ callback_token: "<output of openssl rand -hex 32>"
187+
188+ merkle_service:
189+ url: "https://merkle-service-ttn-us-1.bsvb.tech" # match your network
190+ auth_token: "" # only if your Merkle Service requires outbound auth from arcade
191+ ` ` `
192+
132193# # Verify it's running
133194
134195` ` ` bash
@@ -158,9 +219,8 @@ curl http://localhost:8080/tx/<txid>
158219
159220# # Common next steps
160221
161- - **Enable Merkle Service callbacks** — set `merkle_service.url` and
162- ` callback_token` in `config.yaml`. Both are required together. See
163- [`config.example.yaml`](../config.example.yaml).
222+ - **Enable Merkle Service callbacks** — without this, all transactions stay
223+ at `RECEIVED`. See the [Merkle Service](#merkle-service) section above.
164224- **Use embedded PostgreSQL instead of Pebble** — uncomment the alternative
165225 ` store:` block in [`config.example.standalone.yaml`](../config.example.standalone.yaml).
166226 The first run extracts the postgres binary, which takes a few seconds.
0 commit comments