Skip to content

Instantly share code, notes, and snippets.

Last active March 12, 2024 17:26
Show Gist options
  • Save m1sterc001guy/562d15fc995e45e6b7f10538c2a9dfe6 to your computer and use it in GitHub Desktop.
Save m1sterc001guy/562d15fc995e45e6b7f10538c2a9dfe6 to your computer and use it in GitHub Desktop.
Resolvr Fedimint Module


The goal of the Resolvr project is to enable an open-source dispute resolution system. We have discussed in the past that part of the solution could include a Fedimint module that orchestrated the unlocking of a "bounty". How to do this has remained an open question. In this post, I will propose two possible implementations. Both implementations use FROST/ROAST to produce a signature that allows the bounty to be unlocked.

Requirements and Assumptions

  • "Reviewers" can be assigned to a "bounty". This bounty is paid out in Bitcoin (on-chain, lightning, or ecash).
  • The "Reviewers" are assumed to have a Nostr Public Key (npub) associated with their identity. This proposal does not attempt to solve the problem of public key discovery or trustworthness of nostr npubs. It is assumed that reputation will be associated with npubs.
  • Only the reviewers should be able to "unlock" a bounty.
  • The reviewers should not be required to run server infrastructure, such as a Fedimint. A separate entity (i.e Resolvr team) can run a Fedimint.
  • The entity running the Fedimint "ideally" should not custody any funds.


There are two variants to this proposal. Both variants utilize Fedimint as a distributed database and do distributed key generation among the reviewers using Fedimint's consensus as their broadcast platform.

Variant 1 uses only on-chain Bitcoin transactions. The reviewers are in sole custody of the bounty while it is open, the operators of the Fedimint never custody funds. The downside is that funding/unlocking the bounty requires on-chain transactions, which could have expensive fees.

Variant 2 allows the Fedimint to custody the Bitcoin, and ecash is locked into a contract that can only be redeemed by the decision of the reviewers. This allows for cheap funding/unlocking of bounties, but at the expense of custody within the Fedimint. This is the same threat model as Fedimint's ecash (i.e the federation can rug you).

It is possible to implement and operate both variants, in parallel. In order to achieve the ability for the reviewers (who bring their own nostr keys) to unlock a bounty, both variants do FROST DKG over Fedimint consensus whenever a new bounty is created. More on that below.

Creating a Bounty

For both variants, the first step that a user takes is to create a bounty within the system. This user can be anybody, they do not need to be a reviewer or involved in the payout of the bounty. The creation of the bounty requires the user to specify the npubs of the reviewers (ex: 3 npubs). The creation of a bounty will also likely require some sort of payment to the operators of the Fedimint, to prevent DOS attacks.

Once the bounty has been created and the npubs specified, the system needs to run distributed key generation between the npubs that were specified in the bounty. Distributed key generation is a 2-round protocol: exchanging polynomials and exchaning shares/proof of possession. Round 2 cannot begin until round 1 has finished.

First, each reviewer would generate a polynomial and post it as a consensus item to the Fedimint. This consensus item must be signed by the reviewer's nostr private key, otherwise the other reviewers will not accept it. Posting it as a consensus item allows all of the reviewers to poll the Fedimint and listen for new polynomials that were broadcasted for this bounty from the other reviewers.

After all polynomials have been received by all clients, they can generate their shares and their proof of possession. Similar to round 1, each reviewer broadcasts this as a consensus item to the Fedimint, with a signature from the nostr key that proves it was generated by that reviewer. Other reviewers then poll the Fedimint and wait for all shares/pops to be known.

Once every reviewer has received all polynomials and all of the shares/pops, they each can independently generate the joint FROST key, in addition to their own secret share. The FROST key represents the public key that each reviewer can sign under. The secret share is their own private key that they use to produce a signature share, which can later be combined into a valid signature.

TLDR: To setup a join FROST key between the reviewers, we use Fedimint's consensus as a distributed database for distributing polynomials and shares/pops. Once everything is exchanged, the actual bounty funding process can begin.

All of this sounds technical, but from an end-user perspective it can be abstracted away. From a UX perspective, during the creation of a bounty, reviewers are required to click 2 buttons at a specific time. It could potentially be just one click as long as the user keeps their application open. All reviewers must do this, not just a threshold number of them. The bounty cannot be funded until this process is finished.

The main downside of setting up the bounty this way is that it requires interaction from the reviewers at creation time.

Variant 1

After DKG between all of the reviewers is finished, each reviewer has a secret share and can generate the joint public FROST key. For variant 1, the funding of the bounty is as simple as interpreting this public key as a Bitcoin address and sending Bitcoin to this address. Since this is a FROST key, on-chain it will look like a single-signature address, not a multi-sig.

To unlock the bounty, the reviewers will have the option of signing a set of Bitcoin transactions (likely provided during the creation of the bounty, but they could be provided later too). If a threshold number of the reviewers determine that the bounty has passed the criteria, they participate in the ROAST protocol to sign the appropriate Bitcoin transaction. Similar to DKG, the ROAST protocol can use Fedimint consensus to distribute nonces and ensure there is no nonce re-use. Signature shares can also be Fedimint consensus items, or they can be distributed out of band. If a threshold number of the reviewers have provided signature shares, anyone (reviewer, bounty created, the payee) can then construct the signature that can be attached to the Bitcoin transaction. This transaction can then be broadcated to the blockchain for payout.


  • Reviewers are in sole possession of the escrowed funds during the bounty. The operators of the Fedimint never have custody.
  • Private. On chain it is impossible to tell that this was a bounty or a collaborive spend. It looks like a normal Taproot address on-chain.


  • Requires on-chain transactions for funding/completion of the bounty (similar to an on-chain DLC).

Variant 2

To solve the issue of using on-chain payments for funding/completion of the bounty, it is possible to adopt Fedimint's threat model and have the Fedimint custody the Bitcoin, but have ecash locked into a smart contract that is enforced by the federation (this is similar to how lightning works in Fedimint today). Since this uses Fedimint's module system to, this contract can be arbitrarily complex. It can be locked by the public key of the joint FROST key and only unlocked if the reviewers execute the ROAST protocol (identical to variant 1) to construct a signature to unlock the ecash. The contract could also specify receipients, amounts, timelocks, etc. The payout in this case would be in ecash, which can then be sweeped over lightning using Fedimint's Lightning Gateway.


  • No on-chain footprint for funding or completion of bounties. Everything is done using ecash and users can exit using LN.
  • Private. Ecash is very private and there is no on-chain footprint at all.


  • An untrustworthy federation can rug the users by stealing the Bitcoin (same threat model as Fedimint).
  • The Fedimint operators (i.e the Resolvr team) custody the escrowed funds.


I think these would be fun Fedimint modules to build and could allow for open source dispute resolution, using Nostr as the identities of the reviewers.

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