0xMiden / 0xMiden/rust-sdk

Counterparty privacy for the in-protocol DEX

Aperta
#2,305 16 commenti 0 reazioni 0 assegnatari Vedi su GitHub
enhancement
Lingua principale
Rust
Stelle
78
Fork
129
Merge medio
4g 14h
PR unite (30g)
52

Descrizione

## Summary

I want to open a discussion on adding **privacy to the in-protocol DEX**. Today it is fully public: a maker's PSWAP order is linkable to their main account, and the order contents are on-ledger. I think we should have a privacy story here, and I would like to figure out the right shape for it together.

I have one concrete approach I think we can easily implement, **self-owned, single-use burner accounts**, which I will lay out below because I think it is promising and mostly buildable on what the client already has. But I am raising this as a proposal to react to, so happy to hear any thoughts. Other people almost certainly have different ideas about how DEX privacy should be designed on Miden, and I would like this issue to be the place to compare them. So: first the goal, then my proposal, then an explicit invitation for alternatives.

## Current problem

Note metadata and attachments are always public regardless of note type, so on any PSWAP the maker's account is linkable to the order: the sender `AccountId` is in cleartext, the tag leaks the coarse asset pair, and for public orders the amounts and creator id are on-ledger too.

The realistic near-term target, in my view, is **Level 1: identity unlinkability**. Hide *who* is trading; the pair, amounts, and timing stay public. That is the same boundary Railgun, Aztec Connect, and live Penumbra ship. I want to be disciplined about calling this **counterparty privacy**, not a "private DEX", and about what it does and does not hide (see the threat model under the proposal).

## The design space

A few shapes are possible, and I would like input on which direction is worth pursuing:
- **Self-owned burner accounts** (the approach I detail below): the maker routes each order through a fresh account they own, funded over private notes. Self-custodial, no operator.
- **A shared shield / privacy-pool intermediary**: many users' orders flow through one account that mixes them. Either operator-run, or a trustless Railgun-style contract-shield with a shielded pool.
- Something else entirely. If people have approaches I have not considered, this is exactly what I want to hear.

I personally lean toward the burner approach for a first cut, since it does not need new shared infrastructure and no trusted operator.

## Self-owned burner accounts architecture

The client routes funds through a fresh, single-use account it owns, so the account that appears on-ledger as the order's creator is not linkable to the maker's main account:

```
maker main --[private P2ID: swap asset + native fee asset]--> burner B (private-mode, one per swap)
B emits PSWAP (sender = creator = B, type = Public) --> solver discovers + fills
B <--payback P2ID (public, to the disposable burner)
maker main <--[private P2ID sweep]-- B
```

The core protection is one-way: a Private note publishes its `NoteId` and `sender = main`, but the recipient and serial number stay in the hidden details, and `nullifier = hash(serial_num, ...)` cannot be derived from the public `NoteId`. So a chain observer cannot connect main's funding note to the nullifier the burner later publishes when it consumes it. The order stays `Public` so solver discovery is unchanged, and the payback stays public to the disposable burner (which sidesteps the private-payback discovery problem @bobbinth raised).

### Threat model

I want to be upfront about the boundaries, because they matter for whether this is worth building:
- **Chain observers (anyone reading committed blocks): protected**, with the caveats below.
- **The solver / counterparty: protected.** It only ever sees the burner as the order's creator; it never sees the funding chain.
- **Blocks do attribute the consumption to the burner.** A block carries per-transaction headers (account id plus that transaction's input-note nullifiers, output note headers, and fee), so an observer does see "burner B consumed some nullifier and created the PSWAP". What they cannot do is join that nullifier back to main's funding-note `NoteId`. So this severs the link but leaves a timing/count/fee correlation surface, which is the argument for randomized delays.
- **The remote prover operator: only if we force local proving.** The testnet/devnet presets default to a remote prover that receives the full witness, so burner flows must prove locally.

### What is reusable vs net-new

Reusable today: the multi-account client, the PSWAP API (#2162) and its lineage/observer machinery, discover-and-consume for a specific account, local-proving selection, and RNG plus block height for randomized height-gated actions.

Net-new: even without artificial delays, a private swap is an async, multi-block flow that must persist and resume (fund, wait for inclusion, publish, wait for an externally-timed fill, discover the payback, consume, sweep), and the client has no scheduler or auto-consume today, so a driver is net-new. Also net-new: decorrelated-tag notes (the current P2ID builder hardcodes an account-target tag, which would leak ~14 bits of the burner on the funding leg and of main on the sweep leg, so a non-targeting tag is required and not yet expressible through the high-level builder), per-burner fee funding (see below), optional sync isolation between main and burners, and burner retirement (there is no account-delete path today, so spent burners accumulate).

## Protocol dependency: fees

There is one piece the client cannot solve alone. Fees are auto-drawn from the executing account's own native-asset vault, and there is no way for one account to pay another's, so each burner must hold the native fee asset, and funding that is another edge. The private funding note breaks the on-chain link, but a protocol-level fee-sponsorship primitive would remove the edge entirely. There is already fee-note work in flight (0xMiden/protocol#2901, 0xMiden/protocol#3069, discussion [0xMiden/protocol#2968](https://github.com/0xMiden/protocol/discussions/2968)) that might be the right substrate.

## Standardized burner pattern feature for the SDK?

The bruner pattern is generic: route an interaction through a fresh, self-owned account funded over private notes, then sweep the result back. That applies to plenty of other client actions too, for example a payment or a faucet claim where you would rather not link it to your main account. So one direction worth exploring is making this a standard capability rather than a DEX-only helper: an opt-in on the base transaction model (roughly "run this interaction through a burner") that any flow could use, with the DEX as the first consumer.

Tagging @Dominik1999 @VAIBHAVJINDAL3012 @igamigo for comments and inputs

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

The issue discusses adding privacy to the in-protocol DEX using self-owned burner accounts. Start by reviewing the existing PSWAP API (#2162) and the multi-account client in the rust-sdk. Examine the protocol-level fee-sponsorship discussions (0xMiden/protocol#2901, #3069) and the note system for private funding. Understanding the current transaction model and the async, multi-block flow for swaps is key. 'Done' means a design proposal that integrates burner accounts, addresses fee funding, and defines the new scheduler or auto-consume driver.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
blockchain, rust
Ambito
backend-api-design, blockchain
Tipo di issue
Funzionalità
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Attiva
Chiarezza
Abbastanza chiara
Idoneità per principianti
25/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.