Skip to content

Connect mint to CLN#62

Closed
optout21 wants to merge 1 commit intovnprc:masterfrom
optout21:mint-cln
Closed

Connect mint to CLN#62
optout21 wants to merge 1 commit intovnprc:masterfrom
optout21:mint-cln

Conversation

@optout21
Copy link
Contributor

@optout21 optout21 commented Jun 17, 2025

Connect the Mint in the devenv to the already added CLN lightning node (#51).

Fixes #56

@optout21 optout21 marked this pull request as draft June 17, 2025 11:02
@optout21
Copy link
Contributor Author

optout21 commented Jun 17, 2025

Work in progress, things to figure out:

  • How to make the LN rpc_path in the mint.config.toml agnostic to the current path, and network-independent
  • How to test that the mint indeed uses the LN node
  • Figure out a way to conveniently send/receive payments to/from the LN node in the devenv

@optout21
Copy link
Contributor Author

I've realized that this is NOT needed.
The ehash mint works with ehash, which is not backed by bitcoin, only defined by this mint, so there cannot be a lightning node or lightning channel based on ehash. The ehash mint cannot and needs not be connected to a lightning node.
The 'other' bitcoin ecash mint, that will handle redemption is a differet story, but that will come later.

@vnprc , can you confirm?

@vnprc
Copy link
Owner

vnprc commented Jun 23, 2025

Ehash issuance does not require a lightning node. I've got a working prototype of issuance without lightning. But because cashu only operates on lightning you can't turn ehash tokens into bitcoin without lightning integration.

I suppose you could come up with a multi-mint model where one mint handles issuance and a separate one handles redemptions. I'm not sure how this would work because this was never my goal. Not saying it couldn't work that way.

I always intended for the same mint to handle redemptions. The simplest flow looks like this:

  1. block found!
  2. cashu mint rotates the keyset, closing out the epoch for that block
    1. ehash from the closed epoch now has a fixed value in sats
    2. ehash value = block reward / total issued ehash
  3. block reward funds flow to the lightning node wallet
  4. LN node opens a channel to a routing node
    1. or the node has already been capitalized and has lightning channels ready to go
    2. this saves miners from having to wait 100 blocks for the coinbase funds to be spendable
  5. ehash owners create swap requests to exchange ehash -> sats
  6. cashu mint redeems ehash in exchange for lightning payouts from the newly funded channel

If you wanted to split issuance and redemption across different mints how would the trust model work? The bitcoin needs to flow from the coinbase (or mining reward if the hashpool instance is running as a proxy pool) to a lightning node where it rests until users claim those sats. So there is a rug risk after the block is found while users are doing ehash redemptions. If the Hashpool instance doesn't custody these funds, who does? What leverage does Hashpool have to enforce these redemptions?

If Hashpool custodies the funds then they have a reputation to uphold and are accountable to the miners who trusted this mining pool. I'm not sure how the trust model works if you extend it to another party. What benefit does this have over the simplified single-mint model? It has a significantly more complicated trust model, so there should be commensurate benefits.

@optout21
Copy link
Contributor Author

Thanks for the write-up, some points are new to me!

What is a bit awkward to me, is that in the ehash mint there is a discrepancy in the denomination of the ehash values and the lightning values. At the time of creation of ehash tokens their final conversion ratio is not known, so therefore they will have a denomination different than the satoshis in the lightning backing. In fact the ehash is unbacked. Technically it is probably possible to implement, with some custom logic in the mint, I just found it a bit counterintuitive.

Based on my general (&limited) knowledge of the project goals, and mining, cashu, lightning, and bitcoin, what I had in mind is:

  • A mint for the ehash, which is unbacked and custodial. Ecash is used because of its privacy features and interoperability, but it even could be e simple database. Ehash is generated with each accepted work share, in a custodial way.
  • Another mint, based on real sats. Once an epoch is over, and the conversion is known (from the payout amount and the amount of outstanding ehash), ehash can be converted to 'real' ecash (can be done custodially as well). This is a 'regular' cashu mint, with regular lightning integration, and the users can keep their ecash there, remint it, or take it out through lightning.
  • With two mints the separation between unbacked and backed ecash is more clear.

I guess if one mint is used, very similar result can be achieved, if it is modified internally according to the needs.

For the specific questions on trust model, with two mints:

  • The unbacked mint has a number of issued ehashes
  • At the end of the epoch, the pool deposits the rewards into the backed mint, and mints ecash for itself.
  • The final conversions ratio is determined (ratio of amount of outstanding ehash / ecash)
  • For every ehash, the pool distributes the right amount of ecash to the owner. I think this step would require user interaction (to spend the ehash).
  • Users are free to use their ecash -- transfer out, hold, re-mint.
  • The actual swap of ehash to ecash technically can be done in an atomic way, but since there is trust involved with the pool/mint anyways, the extra tech is not justified.

In any case, the redemption cannot be done trust-minimized, since the mint is the one determining the payout ratio, and turning unbacked ehash into ecash. So I don't see much difference between the two cases.
The only way to the users to get out earlier from the trust needed in the mint, is to swap their ehash to ecash earlier, at a discount. Either through a marketplace, or through an early floor-price discount offer of the mint itself.

Further remarks:

  • Epoch based handling makes sense. Epoch closes when a block is found, or, in the proxy pool setup, when a payment arrives from the upstream pool. An epoch period is expected to be at least a few days long.
  • Ehash can be swapped to backed ecash, or, directly to lightning. The latter may be more efficient, since it skips one step (and a bit easier to implement)
  • I assume that ecash from a closed epoch can be 'spent' (melted), but no new one can be minted.
  • One idea: two epochs per payout period: one for the unbacked ehash, and a next epoch for the backed ecash / payouts (sg like odd/even epochs), for better separation.
  • The conversion from the reward to lightning -- onchain from coinbase in the case of real pool, onchain or lightning payout in the proxy pool case -- is an issue in itself. Direct swap to lightning is theoretcally possible, but requires obtaining a lightning invoice whenever a new block template is created, plus the invoices should live long enough. It is more practical to send to an intermediary address, and either open channels from there, or use a onchain-to-lightning swap (can be external service, or own-hosted to avoid fees.) Frequent rebalancing of lightning channels is also someghing to consider. Or with splicing (still early phase) it is possible to splice in the new reward into an existing channel.

@optout21
Copy link
Contributor Author

General discussion aside, I understand that for now the plan is to have the mint connected to the lightning node. I will continue on this.

@optout21
Copy link
Contributor Author

On further thought:

If a single mint is used, and ehash is swapped to lightning, then there is no need for the mint to be connected the lightning node.

Here's what I mean:
If a user has redeemable ehash:

  • his wallet shows the redeemable ehash and the post-coversion satoshi value
  • user can choose how much to redeem
  • user has to create a lightning invoice for the exact amount
  • user has to provide the lightning invoice
  • the wallet remints the ehash to be locked by the payment hash of the invoice
  • a timelocked refund path is also possible
  • the wallet sends the ehash and the invoice to the pool
  • the pool verifies that ehash is indeed locked to the invoice payment hash
  • the pool pays the invoice through its lighting node
  • the payment secret is obtained
  • the ehash is unlocked, melted, and burned, so noone else can redeem it
  • everybody is happy :)

@vnprc
Copy link
Owner

vnprc commented Jun 25, 2025

An epoch period is expected to be at least a few days long.

If the epoch is tied directly to mining rewards then it could be very long or very short. Likely both at different times.

I think it will work like this. Hashpool will have two modes of operation: solo mode or proxy mode. In solo mode the pool mines blocks directly. In proxy mode the pool mines upstream to an aggregator pool. I like proportional payouts for their simplicity of design in both modes.

Proportional payouts let us do a very simple calculation once each epoch: simply divide the amount of ehash issued by the reward received to get a sat/difficulty value (the unit of ehash is called difficulty). It works the same in solo mode or proxy mode.

The unit conversion takes a little getting used to but I think this is the only way it works. You can't know the value of shares in bitcoin until you receive a mining reward.

@vnprc
Copy link
Owner

vnprc commented Jun 25, 2025

  • I assume that ecash from a closed epoch can be 'spent' (melted), but no new one can be minted.

Yep! That's the spec is written. Ecash from closed epochs can still be redeemed but no new ecash can be issued from that keyset.

  • One idea: two epochs per payout period: one for the unbacked ehash, and a next epoch for the backed ecash / payouts (sg like odd/even epochs), for better separation.

Yeah this is essentially how it will work. The mint will support two currency units: ehash and sats. They both have their own keyset and epochs. They basically operate like separate mints under the same service. This saves the mint operator a bunch of overhead that would be required to run two mints.

@vnprc
Copy link
Owner

vnprc commented Jun 25, 2025

Direct swap to lightning is theoretcally possible, but requires obtaining a lightning invoice whenever a new block template is created, plus the invoices should live long enough.

I think the ehash->lightning flow will be substantially more complicated than ehash->ecash because the user and mint first need to exchange a bunch of information. The user knows how much ehash they have. The mint knows the conversion ratio. For bolt11 the user needs to create the payment invoice. For bolt12 the mint can attempt a payment directly. But in either case we need to wait for the payment to confirm before expiring the ehash tokens. So we need to build an API flow where this information can be exchanged and failure cases handled correctly. That's gonna be a lot of work.

The flow for ehash -> ecash should be a lot simpler because the mint just handles everything and delivers the ecash tokens in the API response. It's all atomic and synchronous, no payment failures, invoice timeouts, or privacy leaks to worry about. (BOLT12 is a big privacy leak, unfortunately, because it associates all your ehash tokens to a static payment address). We can also leverage all the work that has already been done to make ecash->lightning flows work. It's just one more step for the user to redeem their ecash through already existing flows.

@vnprc
Copy link
Owner

vnprc commented Jun 25, 2025

If a single mint is used, and ehash is swapped to lightning, then there is no need for the mint to be connected the lightning node.

Oh that is interesting. I haven't thought of that flow before. I assumed the mint and lightning node would be tightly integrated because this is how cashu already works. Is there a benefit to tightly coupling the pool and LN node instead? I'll have to think about that. Off the top of my head it seems like we'd be reinventing the wheel since the cashu community has already solved most of the problems with lightning integration. Pool-lightning integrations are not widely deployed and AFAIK there is not a well supported FOSS project to support this flow.

@optout21
Copy link
Contributor Author

The mint will support two currency units: ehash and sats. They both have their own keyset and epochs. They basically operate like separate mints under the same service. This saves the mint operator a bunch of overhead that would be required to run two mints.

Exactly. As I said, this is more of an implementation-level issue: two mints or one mint supporting the two kinds of ecash both achieve the same things. My thinking was that the ecash part can be an unmodified cashu implementation, hence it makes sense to have it separately, while the ehash part needs to have internal logic customization. But one mint customized implementation is almost the same, I'm fine with that approach too.

@optout21
Copy link
Contributor Author

I think the ehash->lightning flow will be substantially more complicated than ehash->ecash

I see these alternatives:

  1. ehash->ecash swap done custodially, then regular ecash->lightning (as done by a typical cashu mint)
  2. ehash->ecash swap done atomically, then regular ecash->lightning (as done by a typical cashu mint)
  3. ehash->lightning swap, done atomically

Of these, 1 is the simplest for sure. I was brainstorming about the other options as I got the feeling that you have a preference for atomic swaps.
However, for a 3rd party redeem service (at a discount) or marketplace, atomic swap may be more appropriate, as it minimizes trust needed in the 3rd party. But that is a bit later stage.

@optout21
Copy link
Contributor Author

optout21 commented Jul 4, 2025

Played around a bit with these, but struggled with "Unit unsupported". It looks like CDK with CLN backend defaults to Msat.

@vnprc
Copy link
Owner

vnprc commented Jul 15, 2025

Did you try adding the supported_units field to the cln config block? https://github.com/optout21/hashpool/blob/mint-cln/config/mint.config.toml#L24

If you give me more info on what you're trying to accomplish I might can help.

@vnprc
Copy link
Owner

vnprc commented Sep 25, 2025

cdk supports a built-in ldk node since version 0.15 so CLN is no longer necessary. closing this issue

@vnprc vnprc closed this Sep 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Integrate cln with mintd

2 participants

Comments