Features
- Customer Deposits
- Escrow Service
- Withdawal/Payouts
What Doesn't Matter
For the sake of keeping this on track, we're going to completely disregard backend languages and frameworks. Whether you build your backend with Django, PHP, whatever - irrelevant. This conversation is focused on integrating monero at a design level and the implementation details of doing so.
Single vs. Multiple Wallets
First, let's figure out if we're going to hold a single wallet for the entire marketplace, or if we're are going to use multiple wallets. Using multiple wallets (ex: a wallet per customer?) sounds like a huge burden and, due to the nature of how Monero works, doesn't seem to provide any benefit given the options available through address types (more on this below). I'm going to go with the single wallet approach. Well, technically we'll use two wallets, but more on this later.
Utilizing Public Address Types
Monero utilizes three different types of public addresses for receiving funds that can be used in different ways. Let's go over some considerations, and see what seems to be the most logical way to structure this.
- Standard Address - basic address type, AKA raw address
- Sub-addresses
- Integrated Addresses
First, details on the standard addresses. Standard addresses are the building block to sub-addresses and integrated addresses. In other words, a standard address is required to generate sub-addresses and integrated addresses. In even more words, think of your sub-address/integrated address as a layer that sits on top of the standard address. We will not be using the standard address to send or receive funds to customers.
Next, we have the sub-address option. In short, sub-addresses are generally recommended for individuals - in our case, the buyers would be using new sub-addresses from their own wallets each time they transact with our market. According to the docs, for "businesses" it is recommended to use integrated addresses for the following reasons:
Individuals should prefer subaddresses to receive payments. This is to improve privacy in certain scenarios. See article on subaddresses for details.Businesses accepting payments in an automated way should prefer integrated addresses. The rationale is as follows:
- Scenario where subaddresses improve privacy is not applicable to businesses b/c businesses have the same identity over time. Consequently, subaddresses provide no benefits over integrated addresses.
- No private key is necessary to generate integrated address. This provides a strong security advantage because services that generate integrated addresses need no access to wallet. In contrast, to generate a subaddress, one needs a private view key.
- No shared counter is necessary to generate integrated address. This allows individual services to independently generate integrated addresses w/o synchronizing on a common sequence. In contrast, subaddresses are generated sequentially, and so the sequence (the counter or index) is a coupling point between the wallet and all services that need to generate the address. Back to integrated addresses, note that embedded payment IDs are 64-bit. This means the space is large enough that one can simply generate them randomly and reliably assume uniqueness.
- In very specific scenarios, preparation effort to monitor a very huge number of subaddresses, could became an issue. See this tforum thread for details.
And, of course, there are some caviats:
- Single transaction cannot pay to multiple integrated addresses.
- As individual running a wallet you should generally prefer subaddresses. However, if you happen to use integrated addresses, you should allow Monero software to generate integrated addresses for you (instead of forcing your own payment IDs).
All things considered, it seems the marketplace should be following this flow using integrated addresses:
DNM Wallet ---> Standard Address <---> Integrated Address (New for each user) <---> user's wallet
Users only ever deal with integrated addresses, and sub-addresses are used solely by admins to withdraw XMR to their own wallet(s). Escrow is accomplished via backend logic that keeps track of XMR amounts being held in escrow between the buyer and the vendor. Funds are released from DNM wallet via integrated address to vendor, either through FE or buyer release/escrow time-out.
Instead of using sub-addresses for admins to take their cut, it might be wise to manage a secondary, "Profits" wallet for admin payouts. Not only does this decouple activity further between the marketplace and admins, but it also allows for profits to be sent to a completely different wallet each time funds go into escrow - easy implementation
Integration & Code
Now that we have a rough road map of how we intend for things to work, we can start to work on the interaction part of the equation - i.e. what Monero code are we interacting with? Monero decouples network node logic and wallet logic, so we'll need to use a couple different executables to do what we need to do:
- Monero Node - monerod (also required for monero-wallet-rpc)
- Wallet/Network Interactions - monero-wallet-rpc
We won't go too much into detail, you can reference the documentation for that - they go into plenty of detail on this. But effectively, we would run monerod to spin up a full node and monero-wallet-rpc to handle all of our wallet logic. monero-wallet-rpc requires monerod, either locally or remote. The rest really comes down to mapping the interactions and writing some code.
Thanks for taking the time to read, and please do comment below if you have and experience, insight or issues with anything I've mentioned above. I'd be more than happy to make amendments where I am either incorrect, or if there's a better way to do it.