The problem sponsorship exists to solve
Midnight's fee model is built on a simple separation: NIGHT is a token you hold, DUST is a resource that token generates over time. Every transaction, public or shielded costs DUST to submit. You don't spend NIGHT directly; you spend the DUST it produces.
That design solves a lot of problems. It keeps fees predictable instead of tied to token price swings, and it means usage doesn't require giving anything up, registered NIGHT keeps generating DUST whether you spend it or not.
But it creates one obvious gap. A wallet that has never registered any NIGHT for DUST generation has never generated DUST. And a wallet with zero DUST cannot pay for a transaction, including the very first one someone would need to interact with your app at all. If you're building for people who've never touched crypto before, this isn't an edge case. It's the default state of every single visitor.
This is the cold-start problem, and sponsorship is the answer Midnight built for it. Official guide
What sponsorship actually is
DUST sponsorship means one wallet's DUST pays for another wallet's transaction fee. The user still proves and authorizes their own action with their own secret. The sponsor pays for it, and those two roles are kept deliberately separate, enforced by how the transaction is built, not just by convention.
Midnight's own guide puts the underlying principle in one line: who pays is not who is authorized. A table from the official docs makes this precise:

It's worth being precise about what this is not. It isn't a loan, the user doesn't owe the sponsor anything back. It isn't a transfer of DUST itself, because DUST can't be transferred between addresses at all. And it doesn't mean the sponsor is blind to what's happening. More on that below.
How the handoff actually works
This is the part worth getting exactly right, because getting it wrong is a real security mistake, not just a simplification.
The user does not hand the sponsor a half-built or unbalanced transaction. The official guide is explicit about the order: the user proves the circuit, balances their own side of the transaction, signs it, and finalizes it completely before anything leaves their machine. Only after that is a fully bound transaction sent to the sponsor.
Concretely, on the user's side, the wallet SDK calls balanceUnboundTransaction with tokenKindsToBalance: ['shielded', 'unshielded'] deliberately leaving DUST out, then signs and finalizes. What gets handed to the sponsor is this finished, bound transaction, serialized to a hex string. A wallet with zero DUST can run this entire sequence.
The sponsor then does its own, separate pass: it calls balanceFinalizedTransaction with tokenKindsToBalance: ['dust'] only DUST signs that addition, finalizes it, and submits the combined result to the network.
Why the order matters: because the transaction the sponsor receives is already bound, the network will reject it if anything about the user's side is altered afterward. The sponsor is structurally limited to adding a fee offer on top, it cannot reshape what the user already committed to. The guide states this directly: "If the user hands over an unbalanced or unsigned transaction, the receiving side could reshape it. Balance, sign, and finalize on the user's side before anything leaves the user's machine."
Why the sponsor can't act as the user
The deeper reason sponsorship is safe has nothing to do with who pays, it comes from how the contract itself authenticates a caller.
A well-built contract doesn't check "who is this fee being paid by." It checks whether the prover knows a specific secret. In Midnight's own reference example, a check-in circuit requires proving knowledge of a secret that matches a commitment already on the ledger. Only someone who holds that secret can produce a valid proof, the sponsor's DUST buys nothing but the fee, because the sponsor never has the secret and never needs it.
One thing worth flagging explicitly, because it's a mistake the official docs call out by name: don't build access control around ownPublicKey(). It's a witness, a value the prover's own machine supplies and the protocol never checks it against anything. Nothing stops a sponsor, or anyone else, from returning whatever value they like. Real authorization has to come from proving knowledge of a secret, the way the check-in example does, not from comparing a self-reported public key.
What sponsorship does and doesn't hide
It's tempting to describe sponsorship as fully invisible, and that's not quite accurate, it's worth separating two different things:
On-chain, nobody watching the ledger can link the sponsor to the user. DUST spends are built on the same commitment/nullifier model as shielded transactions, the spend proves validity without exposing who the spender is to an outside observer.
The sponsor's own backend is not blind, though. Whatever service is running the sponsor side necessarily receives the user's full finalized transaction in order to attach a fee to it, and can log that transaction if it chooses to. This is exactly why the official guide recommends running the sponsor as its own small backend service with its own acceptance policy, rate limits and allowlists applied before it spends anything on a given request. Sponsorship protects the user from the sponsor being able to act as them; it isn't a promise that the sponsor's own infrastructure can't observe what it's processing.
There's a separate kind of standing sponsorship worth knowing about too: a NIGHT holder can register their NIGHT to generate DUST directly into someone else's address, rather than covering individual transactions on demand. That registration, which NIGHT key is generating DUST for which DUST address is itself stored as ledger state, so it isn't private either. It's also a one-to-one mapping at any given time, which matters operationally: sponsoring many separate users this way means maintaining a separately registered NIGHT allocation per user, not one shared pool magically covering everyone.
The limits builders need to plan around
DUST isn't an unlimited tap, even for the sponsor, and a few specific numbers are worth knowing rather than approximating:
The cap is 5 DUST per NIGHT, reached gradually, about a week from zero to full capacity for any amount of NIGHT, since both the generation rate and the cap scale linearly with how much NIGHT backs it.
NIGHT only generates DUST once it's explicitly registered for generation. Holding NIGHT alone doesn't start the clock.
Registering NIGHT doesn't give it away. The NIGHT stays in the wallet and remains spendable, spending it is what stops that generation, which is effectively how a NIGHT holder reclaims control.
You can't buy DUST directly, since it isn't transferable, but that doesn't mean money is irrelevant, acquiring and registering more NIGHT increases both the generation rate and the cap proportionally.
Fees are collected during a transaction's guaranteed phase, which means a transaction that fails during its fallible phase still consumes the fee. Sponsors should budget for that, not assume failed attempts are free.
Timing on the DUST side is governed by a specific, named parameter: a three-hour DUST grace period, which accounts for the gap between when a shielded transaction is constructed and when it actually lands in a block. This is the real mechanism to build around, not a generic, made-up expiry window.
Why this matters if you're building on Midnight
If your target users are already comfortable holding tokens and paying fees, sponsorship is optional. If you're building for anyone else, which, realistically, is most real-world adoption, it's close to mandatory. Nobody downloads an app and expects to go acquire a token first just to click a button.
In practice, that means your backend takes on a real operational job: running a sponsor service that applies its own rate limits and allowlists, monitoring its DUST balance the way it would monitor any finite resource, and treating every request as something it screens before spending anything on it, not something it blindly forwards.
The mental model, in one picture
Think of NIGHT as a solar panel and DUST as the electricity it generates continuously. Sponsorship is one solar-panel owner letting someone else draw a specific, metered amount of power, not handing over the panel, and not losing the ability to see how that power is being drawn. Standing designation is like wiring someone else's address permanently into your panel's output. Per-transaction sponsorship is more like covering one specific bill as it comes in, request by request, with your own policy deciding which requests you'll cover.

Sources
This article is built directly on Midnight's official documentation rather than summarizing third-party tutorials. If anything here is unclear or you want to go deeper, these are the primary references:
Sponsor transaction fees with DUST : the official sponsorship guide, including the full code for both the user and sponsor sides
DUST architecture : the full technical reference on how DUST generates, caps, decays, and is spent
example-private-party : a runnable reference implementation of sponsorship, including the negative-case tests that prove a sponsor cannot act as the user (this repo is expected to be archived soon and moved into the midnight-examples monorepo under
examples/private-party; the sponsorship code itself isn't changing, just its location, this link will be updated once that move is live)SPONSORSHIP.md : the technical summary accompanying that reference implementation

Replies
Discussion
Join the discussion
Sign in with Google to reply. You stay on this article while you sign in.
No replies yet
Sign in with Google to start the discussion.