BTCPayServer Multi-Account and 0conf Mempool Notifications

Project Summary

Implement 0conf mempool notifications and multi-account support for the BTCPayServer Zcash plugin.

Project Description

Implement a new Zcash wallet RPC server (zkool-walletd) using the Zkool GraphQL API backend for mempool and multi-account support, together with updating the BTCPayServer plugin to support separate wallets for multi-store instances.

This grant also includes some retroactive work for bug fixes, maintenance, Orchard/UA migration and payment updates on each new block.

Introducing multi-account support would allow Zcash ambassadors and communities to host a BTCPayServer instance and better onboard local merchants together with allowing existing BTCPay hosts to let merchants accept Zcash.

4 Likes

nice to see this, the multi-account pain is real and the 2.1 upgrade shipped clean. two questions on the 0conf side if useful.
on operator trust, how are you scoping the model for zkool-walletd itself? if the walletd operator drifts or gets compromised, mempool notifications become forgeable, which bounds how much a merchant can safely 0conf independent of the customer-side risk. the side-effects note covers the customer vector, curious how you’re handling the infra vector.
on double-spend and mempool semantics, what’s the planned accept threshold per tx size? expiry height and reorg can still pull a tx out of the mempool before a block, curious how you’re framing merchant exposure there.

2 Likes

zkool-walletd should run on the same machine as the BTCPayServer instance. The threat model would be roughly the same as trusting the integrity of the machine and the host itself. A malicious host could forge payments, I don’t see how 0conf would add extra risk on the server side since you already need to trust the operator, a zcash-walletd host could forge notify_block notifications, which is why it should run inside the same Docker or virtual network.

zkool-walletd is simply a wrapper around the Zkool client, which interacts with either a lightwalletd server or a Zebra node. Threshold per tx size should be handled on Zkool’s side I think? For online payments, at least 1 confirmation should be required, or 0conf should be tied to a user account that is limited to low value microtransactions and can be suspended in the case of a double-spend attack (the same as with a card chargeback).

To clarify, 0conf is more of a bonus for specific use cases and the main improvement is mempool notifications with 1+ confirmations that improve UX by notifying the user immediately that the payment has been received and is awaiting the necessary number of confirmations. Hope this answers your questions.

1 Like

makes senses, especially the UX reframe. mempool-seen + 1-conf notifications is honestly more useful for most merchants than actual 0conf accept, and the co-located walletd model closes the infra vector. the chargeback-analogue framing for the microtransaction 0conf carveout is a reasonable bound as well. thanks for the detailed reply, good luck with the grant.

1 Like

Thanks for your questions and feedback. Am thinking that displaying an estimated waiting time would be nice for UX also, based on heuristics analysing the confirmation times from the last 5 blocks.

Framing is important when onboarding merchants, they should be made aware of the pros and cons compared to accepting card: smaller transaction fees and the risk of a 0conf attack being considerably lower than that of a chargeback.

1 Like

Hey!

Honest question: since we can migrate open-source projects like that to Zcash and create a ZcashPay, and with other systems like CipherPay — Private Payments for the Internet already doing stuff, why is BTCpayserver still a deal ?

2 Likes

Hey! Thanks for your question. BTCPayServer is preferred by many merchants because they either already accept Bitcoin, Litecoin, Monero, Bitcoin Cash, etc or their first question during onboarding is likely to be “Will I be able to accept payments in Bitcoin also?” BTCPayServer is also a much more audited codebase and has good test coverage.

I would like to co-ordinate together with other payment processors such as ZGo and CipherPay to move towards standardising around the Bitcoin/Monero RPC to make adoption and interoperability easier on the merchant side. zcash-walletd and zkool-walletd should work as independent modules that can be used by merchants that have their own full node and payment processing infrastructure.

Sure, a Zcash maxi approach of having merchants only accept Zcash could be ideal in theory, but this is unlikely to lead to mass adoption when most crypto users already hold Bitcoin, USDT, Monero, etc and onboarding users who have not used crypto before will be significantly tougher. Especially as markets such as the EU are becoming increasingly hostile towards privacy, it’s easier for new users to swap their existing BTC to ZEC rather than exchange fiat to ZEC directly.

I believe that we should steer merchants away from the polarising “What is the best coin?” discourse and encourage them to accept many options and the end users can pick what best serves their needs and preserves their privacy.

5 Likes

Would like to raise some points from discussions that I’ve had with merchants:

0conf should not be used in online settings, unless a merchant has specifically decided that the risks can be mitigated with measures such as revoking access in the case of no confirmation being finalised, i.e. optimistic update for UX purposes, such as providing immediate access to a video stream.

The main purpose of “0conf” support is to enable mempool payment notifications for purchases that require at least 1 confirmation. A physical merchant may decide to let a customer leave a store the moment the mempool payment update has occurred for example, or may choose to enable 0conf for low value purchases.

Existing merchants will automatically benefit from mempool notifications for 1+ confirmation, providing enhanced UX.

Multi-account support is more likely to bring in new merchants rather than be adopted by existing merchants. Existing merchants are mainly using one store and have the technical knowledge and experience to run their own BTCPayServer instance.

A potential future grant application would be to create documentation and a framework for merchant onboarding, both for those already familiar with crypto and who are new to crypto. This would expand on the work done with multi-account support by allowing local ambassadors to host their own instance and potentially receive a monthly fee or commission. This would include recommendations around accountancy for example and physical merchants would be featured on a searchable map.

1 Like

I have restructured the milestones for this grant, with the total amount remaining the same:

Startup funding has been moved over to the first milestone and milestone 1 is now milestone 2 (and 2 is 3). I have added some more details to the first milestone including the .NET 10 migration for BTCPay version 2.3.7.

The last milestone now additionally includes releasing some proof of concept prototypes (mainly designs/demos for future development) that align with my vision for creating a Zcash first payment experience while accommodating for merchants’ needs:

    - publish initial proof of concepts:
      - Merchant Working Group – specification to standardise modular APIs and libraries for easier merchant adoption into existing stacks
      - paywithzec merchant map and onboarding resources
        - zcash ambassador merchant onboarding proposal for multi-account Point of Sale maintenance
      - Point of Sale wallet app design/prototype
      - daily scheduled NEAR Intents stablecoin settlement layer (automatic swap to USDT) design and potentially prototype
2 Likes

Good work on this. Multi-account and mempool notifications are the right priorities, we went through the same UX pain early on with CipherPay.

Interested in the Merchant Working Group idea. Standardizing the interface between payment processors and merchant stacks would help the whole ecosystem. Happy to contribute from our side if that takes shape.

2 Likes

Thanks! Look forward to hopefully collaborating on the Merchant Working Group idea :slight_smile:.

Once multi-account support is ready, I plan to reach out to existing BTCPayServer hosts on the directory. As already mentioned, this would be a great way to provide a source of revenue for Zcash ambassadors with a monthly fee via BTCPay subscriptions and to onboard existing BTCPay merchants with less technical skill.

If anyone would be interested in running a hosted instance with the BTCPay plugin please reach out! Any feedback would be appreciated. While cross-pay is great, BTCPayServer allows merchants to avoid the 1-2% slippage fee if they would like to also accept Bitcoin, USDT, etc. A CipherPay and BTCPayServer integration would be interesting to explore also for “native” multi-coin support.

Switching to the Zkool GraphQL API should reduce the reliance on active maintenance of zcash-walletd when it comes to Zcash upgrades, requiring less overall work in the long-term to keep the plugin maintained.

1 Like

@1337bytes at the most recent meeting, ZCG voted to approve this proposal. Congratulations!

To keep the community informed, ZCG requests that you provide monthly updates via the forum in this thread.

Please check your forum inbox for a direct message from FPF with important next steps, including a link to the Milestone Payment Request Form and your unique validation code for submitting payment requests.

1 Like

Milestone 1 is complete, this includes:

A plugin update will be published once zkool-walletd is ready.

The last milestone for multi-account support was removed from this proposal. The underlying zkool-walletd implementation will still support multi-account, but I hope to work on the plugin side of the integration when the current grant is complete and possibly apply for retroactive funding for it.

Could you clarify the purpose of zkool-walletd ?

For now, it’s a drop-in replacement for zcash-walletd that implements the same RPC APIs, together with multi-account support (with account_index passed in as a request body parameter). It wraps the Zkool GraphQL API using Express.js and maintains a mempool watcher WebSocket connection for notify_tx and notify_block. Will push the progress so far to GitHub in the coming week.

It would be much cleaner to use zkool directly from the btcpay server plugin. c# can use graphql. Going through a wrapper is really unnecessary.

I’d like to avoid diverging too far from the Monero plugin codebase and there is quite a bit of logic that I’d feel more comfortable and confident implementing and testing in Node.js such as combining note amounts, keeping track of diversifier indexes, etc, rather than using the .NET SQL database. A large rewrite, together with full integrated test coverage would be required for the plugin, which would add a lot of work.

Well, regardless of the location of the logic, you would have to write integrated test coverage. Now the BTCPay has c# → js → rust. It’s more code to write/test/maintain.

I appreciate your feedback and am happy to reevaluate if it proves to be more work compared to using GraphQL with .NET. My past experience working with GraphQL in Java wasn’t great with the level of boilerplate and codegen tooling required. I’ve already written over half of the JS layer. Would like to explore rewriting it in Rust later on.