Adds a second downstream lane to /apis/btcmaps/v1/submit that forwards
the merchant payload to teambtcmap/btcmap-api's submit_place RPC
(merged 2026-05-24 in teambtcmap/btcmap-api#91).
Request schema:
- New fields Lat, Lon, Category, ExternalId on BtcMapsSubmitRequest,
required iff SubmitToBtcMap=true. Validator enforces lat/lon
ranges, lowercase-identifier category, and 1-200 char external_id.
Plugin side (rollforsats/BTCPayServerPlugins) composes external_id
as hostname:storeId so the namespace stays unique per BTCPay
instance.
- New SubmitToDirectory + SubmitToBtcMap routing flags. The
directory flag defaults true to preserve existing callers; btcmap
defaults false so new callers must opt in.
- New Phone field forwarded as OSM Key:phone in extra_fields.
Service layer:
- BtcMapsService.SubmitToBtcMapAsync POSTs a JSON-RPC 2.0 envelope
({jsonrpc, method, params, id}) to BTCMAPS:BtcMapImportEndpoint
(default https://api.btcmap.org/rpc) with method=submit_place,
origin=btcpayserver, and the merchant payload mapped to the
documented param shape. Bearer auth from BTCMAPS:BtcMapImportToken.
- Optional fields (website, description, twitter, github, onion,
phone, country) ride along in extra_fields using OSM tag keys
(contact:twitter, addr:country, etc.) plus the implicit
payment:bitcoin=yes marker.
- New BtcMapTokenMissingException parallels the existing
DirectoryTokenMissingException so the controller can return 503
with a distinct error code when ops haven't provisioned the
scoped token yet.
Controller:
- /apis/btcmaps/v1/submit branches on SubmitToDirectory +
SubmitToBtcMap. At least one must be true (rejected 400 otherwise).
- Each lane has its own exception ladder symmetric to the existing
directory path: token-missing 503 (directory-not-configured /
btcmap-not-configured), caller-cancel rethrow, upstream-timeout
504, generic-failure 502 - error codes namespaced by lane so ops
can tell them apart.
HttpClient registration:
- New HttpClientNames.BtcMap named client registered with 15s
per-call timeout and JSON Accept header, matching the
BtcMapsDirectory budget for bounded worst-case behavior.
Tests:
- 12 new validation tests in BtcMapsServiceTests covering the
SubmitToBtcMap=true required-field paths (Lat / Lon / Category /
ExternalId; range checks; lowercase-identifier policy; overlong
external_id) plus the default-false directory-only-still-works
baseline. 37/37 BtcMapsServiceTests passing.