Multi-path payments
One payment. Several paths. Nobody knows which.
Bankhaus hides the figure, not the graph: who paid whom was always public. A multi-path payment cuts the figure at random across several legs to the payee and adds cover legs of zero to other handles. The chain settles them together or not at all, sees a set of recipients, and cannot tell which of them was paid or how the figure was cut. Each leg is a full confidential transfer with its own proof.
- confidentialTransferMulti: one to eight legs, atomic, each with its own Σ-Bullets proof
- A cover leg carries zero and still re-randomises the recipient's balance
- The payee gets one letter per leg in a bundle; the figures add up
gwen → bob Δs Δr amount: none · in the letter: 47.10
gwen → carol Δs Δr amount: none · in the letter: 0.00 cover
gwen → bob Δs Δr amount: none · in the letter: 31.85
gwen → dave Δs Δr amount: none · in the letter: 0.00 cover
gwen → bob Δs Δr amount: none · in the letter: 41.05
the chain: 5 transfers, 3 recipients, 0 figures
bob: three letters, 120.00 USDG · carol, dave: a leg that reads 0.00
Try one
Pay bob over several paths.
The figure is cut at random across the legs that go to bob; carol and dave get a leg of zero that re-randomises their balance. Every leg is a full transfer with its own proof, built here. On chain they settle together or not at all.
- The chain sees one transaction, several recipients, no figure
- Nobody can tell a cover leg from a paid one, nor how the figure was cut
- bob gets one letter per leg; they add up to the amount
Pay, and the legs appear here as the chain would hold them: from, to, four curve points each. Which of them carried value is only in the letters.
What changes for whom
The chain
Several transfers from one sender in one transaction. No figure, and no way to tell a cover leg from a paid one: a zero leg changes the recipient's ciphertext exactly as a paid leg does.
The payee
Several letters that add up. Each verifies on its own against its leg; together they are the invoice paid.
A cover recipient
A leg that reads 0.00 with their key. Their balance is re-randomised, nothing else; they learn only that someone named them.
On chain
struct Path { address to; Ciphertext senderDelta; Ciphertext recipientDelta; bytes proof; }
function confidentialTransferMulti(Path[] calldata paths) // 1–8 legs, all or nothing
// each leg is proven against the balance as it stands after the legs before it;
// the token builds every leg's public signals from its own storage, in order.From the terminal or an agent
bankhaus send bob 120 --paths 3 --cover carol,dave
send_multi({ recipient: "bob", amount: "120.00", paths: 3, cover: ["carol", "dave"] })Cover legs cost what any transfer costs, about 1.8M gas each, a fraction of a cent on Robinhood Chain. Mandates are not split: an agent paying from its vault is held to the per-payment cap on the whole figure.