pull down to refresh
Good point. Sampled manual verification does not scale: a compromised host can serve correct addresses for the ones a merchant checks and substitute the rest.
The mitigation I am implementing is per invoice verification that runs on the merchant's side, against a key the server never provides. For each invoice the server returns only the derivation index and the issued address. A verifier the merchant runs re-derives m/0/index from their own zpub and confirms the match before the payment link is shared. Because the derivation code ships from the public repo and the key comes from the merchant, the server cannot satisfy the check with a substituted address.
Two forms, identical logic: a single self contained HTML file for users who would rather not run code, and a CLI script that can run on a schedule and exit nonzero on a mismatch for alerting. Neither sends the key anywhere.
This is additive. Derivation and settlement are unchanged; the verifier is an independent check on top, not a change to the flow.
On VLS and Greenlight: on chain receiving takes no signature, so there is no direct analogue to a signer that must co approve each invoice. The equivalent here is independent per address verification against the merchant's own key rather than protocol level approval. Useful framing though.
Both fair, and worth separating.
You are right that derivation is not the service. The verifier exists to make that explicit: it is a commodity you can and should reproduce yourself. What the hosted side does is the operational layer around it, a checkout page the customer sees, fiat to BTC pricing locked at invoice time, per invoice index allocation with no reuse or races, reorg and underpayment handling, and signed webhooks for fulfilment. None of that is cryptographic magic. It is the usual reason people use hosted anything over rolling their own, with the difference that here hosted costs you neither custody nor KYC, and every address it hands out is verifiable.
On the server lying about payment: correct, a paid notification is not proof, and the verifier does not cover it. But the blast radius is bounded, because the coins land in the merchant's own wallet, never ours. We cannot fake money arriving in your wallet. A merchant who wants zero trust confirms receipt in their own wallet or node before fulfilling; the webhook is a convenience signal, not the source of truth. The same tool should let you watch your own derived addresses for the actual funds, so the payment signal becomes something you check too, and I am going to add that.
And yes, a technical merchant can derive from their ZPUB and poll an explorer themselves. That is the self host path and it is legitimate, the same way BTCPay is. BoreLine is for the ones who do not want to run, secure, and keep that service up, and who still refuse to hand over custody or identity to avoid running it. If someone would rather run the script, they should. The point of publishing the verifier is that choosing hosted no longer means trusting us on the thing that matters.