Skip to content

Instantly share code, notes, and snippets.

@lukechilds
Last active June 3, 2026 11:16
Show Gist options
  • Select an option

  • Save lukechilds/302e7fa04b09d6e4568bdcd64cb43356 to your computer and use it in GitHub Desktop.

Select an option

Save lukechilds/302e7fa04b09d6e4568bdcd64cb43356 to your computer and use it in GitHub Desktop.
Nimdolf: Non-interactive Mint Delegation on Liveness Failure

nimdolf

Nimdolf: Non-interactive Mint Delegation on Liveness Failure

This proposal improves liveness guarantees for custodial ecash mints with on-chain reserves. It allows a mint operator to delegate control of mint reserves to third-party mint operators in a non-interactive way.

While the mint is in operation, it maintains unilateral control over the mint reserves. However, if the mint becomes unresponsive, the delegate mint can take over control of the funds and process withdrawals for the original mint's users.

A mint can delegate to multiple other mints. If a set of mints all act as delegates for eachother, they collectively inherit 1-of-n liveness properties. As long as one mint in the set is able to remain online, the users of all mints in the set are able to redeem their funds.

This pairs especially well with recent work on running mints inside TEEs. A TEE can reduce custody trust in the mint operator by keeping reserve keys inside attested code, shifting part of the trust assumption to the TEE implementation, hardware vendor, and attestation process. The tradeoff is increased liveness risk: if access to the TEE or its sealed key material is lost, reserve funds may become inaccessible. Pairing TEE-based mints with this proposal can preserve the custody-security benefits of TEEs while improving, rather than weakening, liveness guarantees.

Reserve construction

A mint holds its reserves in a Taproot output that is spendable immediately by itself in the key path, or by delegate mints in the script path. The delegate script paths are timelocked relative to UTXO age with OP_CHECKSEQUENCEVERIFY. The first delegate mint can spend after 7 days, the second delegate mint after 8, etc.

Example:

Mint A reserve:
  key path:
    immediate:    Mint A (custodian)
  script path:
    after 7 days: Mint B (delegate mint)
    after 8 days: Mint C (delegate mint)

While Mint A is live, it performs regular consolidations, rolling reserve funds over to the same script. This cleans up deposits into a single reserve UTXO and rearms the delegation timelock in the process. This prevents delegate mints from ever having access to the mint's reserves during normal operation.

If Mint A disappears, loses its reserve key, or stops operating, it can no longer roll the reserve. After 7 days, Mint B can claim the funds. If Mint B fails to act within 24 hours, Mint C can claim them.

This allows supporting a large number of delegate mints with various levels of trust. You can order delegate mints from most trusted to least trusted. Adding later delegate mints does not weaken security during earlier delegate time windows: later delegate mints can only act if earlier delegate mints fail to act before the later timelocks mature.

Ecash state

The delegate mint needs the original mint's spent-proof state to be able to issue redemptions without accepting tokens that have already been redeemed.

This is solved by Mint A publishing its internal feed of spent proof identifiers. Delegate mints watch this feed all the time and keep a local copy. This ensures that if Mint A disappears, the delegate mints already have an up-to-date copy of the mint state to be able to safely take over operation of the mint.

On failover, Mint B accepts old Mint A proofs only if:

- the proof belongs to an old Mint A keyset
- the proof is valid for that keyset's amount public key
- the spent proof identifier is not in Mint B's local spent set for Mint A
- recovered reserve funds remain

Mint B then marks the spent proof identifier as spent and either:

- melts the proof to Bitcoin/Lightning, or
- swaps it into fresh Mint B ecash

Normally, to verify a proof, the mint's private key is needed. This will not work in this case since, if Mint A is in operation, it is not safe to share its key with delegate mints. And if it is no longer in operation, we cannot rely on it to be able to share its key. We need the delegation process to be non-interactive between mints.

This requires an ecash scheme that supports public verification of proofs against mint public keys. DLEQ proofs, as described in NUT-12, can provide this, but full third-party verification requires revealing the blinding factor, which weakens privacy. A BLS-based ecash scheme with public verification avoids this tradeoff. Cashu is moving in this direction, which would make this delegation flow cleaner.

Circular delegation

A set of mints can act as delegate mints for all other mints in the set. An example with three mints would be:

Mint A (custodian) -> Mint B (delegate mint) -> Mint C (delegate mint)
Mint B (custodian) -> Mint C (delegate mint) -> Mint A (delegate mint)
Mint C (custodian) -> Mint A (delegate mint) -> Mint B (delegate mint)

If one mint dies, another mint can take over its reserve. If two die, the remaining mint can eventually take over both reserves.

This gives a 1-of-n liveness property for the set of mints. As long as one mint in the set remains online, the users of all mints can redeem funds.

Consistency model

The delegate mint's local copy of the spent-proof feed does not need perfect consistency.

If the delegate mint is slightly behind, it may accept some proofs that were already redeemed shortly before Mint A failed. That can create more claims than recovered funds.

If the delegate mint is doing the job it was trusted to do and staying correctly synced with the original mint, this should not happen. However, if it does, this is acceptable for disaster recovery mode. The delegate mint can simply stop processing withdrawals once the recovered reserve is exhausted. It's better that 99% of users can redeem than that all users lose their money.

Summary

Non-interactive mint delegation is ordered custodial failover, not trustless unilateral exit for ecash mints. If a mint goes offline, Bitcoin consensus rules move reserve control to the first eligible delegate mint, which can process withdrawals using mirrored spent-proof state. Users inherit all usual ecash trust assumptions under the new mint operator.

The live mint keeps control by refreshing its timelocked reserve output. The construction depends on the original mint keeping reserve funds in the delegated Taproot structure and refreshing reserve UTXOs before the earliest delegate timelock matures. Delegate mints must keep a sufficiently up-to-date, authenticated copy of the original mint's spent-proof state. The ecash scheme must support public proof verification, ideally without revealing blinding data that weakens privacy.

It does not remove custodial trust. It improves recovery from liveness failures, not from malicious custody: users' funds are not automatically lost just because their original mint disappeared, but users are not protected if the original mint steals reserves before failure or becomes insolvent, and delegate mints are trusted after failover not to censor, steal, or misallocate recovered funds.

Mints have an incentive to cooperate in these arrangements. A mint that supports delegation is less risky for users than a mint that does not support delegation, so it makes the mint more attractive to users. A mint that processes redemptions for another mint can profit from transaction fees on those redemptions. So a mint is both incentivized to delegate to other mints and to act as a delegate for other mints.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment