Gnosis VPN routes your traffic through the HOPR mixnet to an exit node, which then talks to the internet for you. Exit operators are paid for the traffic they carry, and those payments settle on Gnosis Chain.
We’ve spent the last few months working with the HOPR team on that payment step. The mixnet already hides who is talking to whom from the nodes relaying the traffic. Payments are a separate matter, since anything settled on a public chain is visible by default, and the plan from the start was to give the payment side the same treatment as the traffic. Curvy provides that piece: clients pay into its shielded pool and exits get paid out of it.

Curvy, briefly
Curvy is a privacy protocol for public blockchains. You deposit funds into a pool contract, and they turn into notes. A note is a record that a certain amount of a token belongs to a certain key, and once it’s inside the pool, the chain only holds a commitment to it plus encrypted data that lets the owner find and read it. To spend a note, you make a zero-knowledge proof that you own one of the notes in the pool and that the new notes you create add up to what you spent. The proof doesn’t say which note. Recipients find their notes by scanning the pool’s announcements with a private view key.
Paying for traffic that hasn’t been delivered yet
Gnosis VPN uses a payment protocol called PIX. For each chunk of traffic, the client and the exit create a one-time key together, and at first neither of them has the whole private key. A piece of it travels with every reply packet the exit delivers. When the chunk is done, the exit has the full key.
On the Curvy side, that one-time key becomes the owner of a note. The client creates a note for the agreed amount at the start, and the exit spends it at the end with the key it collected along the way.
Normally, a Curvy recipient discovers a note and spends it using keys derived from the same secret. Here the exit has to notice the payment right away, while it’s still serving the traffic, and it won’t have the spending key until later. We ended up giving every payment two keys. The exit makes a fresh scan key pair and sends the public half to the client. The client encrypts the note to that scan key and sets the one-time key as the owner. From then on, the exit can see the note and check the amount, and it still needs the one-time key to move it.
Getting funds into the pool
A Gnosis VPN client keeps its funds in a Safe, which is a smart-contract wallet, and the VPN software is only allowed to make the Safe call a few specific contracts. Curvy’s pool isn’t one of them, and we didn’t want users to have to approve anything extra before their first payment.
The payment token, wxHOPR, has receive hooks: a contract can run code at the moment tokens arrive. We wrote a small router contract that uses this. The Safe sends tokens to the router with a note attached, the router’s hook deposits them into the pool, and it all happens in one transaction. If the deposit fails, the transfer fails with it, and the tokens never leave the Safe. The router is around a hundred lines of Solidity. It has no owner and stores nothing.
The client does this once, to load a prepaid balance into the pool.
Proofs and the relayer
Every payment is a proof, generated by the VPN software on the user’s own machine. Curvy’s cryptography and Groth16 prover are written in Rust and compiled into the node software, with proving keys from a trusted-setup ceremony.
Our usual transfer circuit produces three notes per proof. For Gnosis VPN, we built a larger one with nine outputs. One proof can cover up to seven payments, plus the change going back to the client and a small note that repays the relayer. As with every Curvy transfer, it also carries a protocol fee note, covering Curvy’s fee and the cost of writing the new notes into the tree.
The client hands the finished proof to Curvy’s relayer, which submits the transaction and pays the gas, so the client’s own address isn’t the sender. The outputs are fixed inside the proof, and the relayer just carries it to the chain.
The exit’s side
The exit reads the pool’s public stream of new notes and tries each one against its scan keys. When it finds its note, it waits until the note is in Curvy’s Merkle tree and final. After the traffic is delivered and the one-time key is complete, the exit makes its own proof and withdraws to its wallet. A second new circuit lets it withdraw up to ten notes with different owner keys in one proof.
One payment, start to finish:

On chain
A client shows up on chain when it loads its balance into Curvy, a round sum chosen in advance that says nothing about what it goes on to spend. The payments themselves stay inside the pool as commitments and encrypted records, each for the standard price of a chunk of traffic. An exit withdraws only after delivering the whole chunk, whenever that happens to be. The usual way of tracing funds through a pool, matching an amount going in with the same amount coming out soon after, has very little to work with here. A busier pool still helps, as with any shielded pool.
The Curvy pool is in the HOPR node software now, and the Gnosis VPN client is being moved onto it. The code on our side is on GitHub: the SDK (rs-sdk), the cryptography and prover (rs-core), and the router (CurvyShieldRouter).

