@@ -571,6 +571,7 @@ func (m *Mint) RequestMeltQuote(meltQuoteRequest nut05.PostMeltQuoteBolt11Reques
571571 return storage.MeltQuote {}, cashu .BuildCashuError (errmsg , cashu .UnitErrCode )
572572 }
573573
574+ var quoteAmount uint64
574575 // check invoice passed is valid
575576 request := meltQuoteRequest .Request
576577 bolt11 , err := decodepay .Decodepay (request )
@@ -579,10 +580,23 @@ func (m *Mint) RequestMeltQuote(meltQuoteRequest nut05.PostMeltQuoteBolt11Reques
579580 return storage.MeltQuote {}, cashu .BuildCashuError (errmsg , cashu .MeltQuoteErrCode )
580581 }
581582 if bolt11 .MSatoshi == 0 {
582- return storage.MeltQuote {}, cashu .BuildCashuError ("invoice has no amount" , cashu .MeltQuoteErrCode )
583+ // if amountless invoice, check amount specified in options
584+ if meltQuoteRequest .Options .AmountlessOption == nil {
585+ return storage.MeltQuote {}, cashu .InvoiceAmountMissingErr
586+ } else {
587+ amountless := meltQuoteRequest .Options .AmountlessOption
588+ quoteAmount = amountless .AmountMsat / 1000
589+ }
590+ } else {
591+ quoteAmount = uint64 (bolt11 .MSatoshi ) / 1000
592+
593+ // if amountless option passed, check that amounts matched
594+ if meltQuoteRequest .Options .AmountlessOption != nil {
595+ if meltQuoteRequest .Options .AmountlessOption .AmountMsat != uint64 (bolt11 .MSatoshi ) {
596+ return storage.MeltQuote {}, cashu .MeltAmountlessMismatchErr
597+ }
598+ }
583599 }
584- invoiceSatAmount := uint64 (bolt11 .MSatoshi ) / 1000
585- quoteAmount := invoiceSatAmount
586600
587601 // check if a mint quote exists with the same invoice.
588602 _ , err = m .db .GetMintQuoteByPaymentHash (bolt11 .PaymentHash )
@@ -594,31 +608,31 @@ func (m *Mint) RequestMeltQuote(meltQuoteRequest nut05.PostMeltQuoteBolt11Reques
594608 isMpp := false
595609 var amountMsat uint64 = 0
596610 // check mpp option
597- if len (meltQuoteRequest .Options ) > 0 {
598- mpp , ok := meltQuoteRequest .Options ["mpp" ]
599- if ok {
600- if m .mppEnabled {
601- // if this is an internal invoice, reject MPP request
602- if isInternal {
603- return storage.MeltQuote {},
604- cashu .BuildCashuError ("mpp for internal invoice is not allowed" , cashu .MeltQuoteErrCode )
605- }
611+ if meltQuoteRequest .Options .MppOption != nil {
612+ if m .mppEnabled {
613+ // if this is an internal invoice, reject MPP request
614+ if isInternal {
615+ return storage.MeltQuote {},
616+ cashu .BuildCashuError ("mpp for internal invoice is not allowed" , cashu .MeltQuoteErrCode )
617+ }
606618
607- // check mpp msat amount is less than invoice amount
608- if mpp .AmountMsat >= uint64 (bolt11 .MSatoshi ) {
609- return storage.MeltQuote {},
610- cashu .BuildCashuError ("mpp amount is not less than amount in invoice" ,
611- cashu .MeltQuoteErrCode )
612- }
613- isMpp = true
614- amountMsat = mpp .AmountMsat
615- quoteAmount = amountMsat / 1000
616- m .logInfof ("got melt quote request to pay partial amount '%v' of invoice with amount '%v'" ,
617- quoteAmount , invoiceSatAmount )
618- } else {
619+ // check mpp msat amount is less than invoice amount
620+ mppAmount := meltQuoteRequest .Options .MppOption .Amount
621+ if mppAmount >= uint64 (bolt11 .MSatoshi ) {
619622 return storage.MeltQuote {},
620- cashu .BuildCashuError ("MPP is not supported" , cashu .MeltQuoteErrCode )
623+ cashu .BuildCashuError ("mpp amount is not less than amount in invoice" , cashu .MeltQuoteErrCode )
624+ }
625+ if mppAmount > 0 && bolt11 .MSatoshi == 0 {
626+ return storage.MeltQuote {}, cashu .BuildCashuError ("invalid invoice for MPP option" , cashu .MeltQuoteErrCode )
621627 }
628+ isMpp = true
629+ amountMsat = mppAmount
630+ quoteAmount = amountMsat / 1000
631+ m .logInfof ("got melt quote request to pay partial amount '%v' of invoice with amount '%v'" ,
632+ quoteAmount , bolt11 .MSatoshi / 1000 )
633+ } else {
634+ return storage.MeltQuote {},
635+ cashu .BuildCashuError ("MPP is not supported" , cashu .MeltQuoteErrCode )
622636 }
623637 }
624638
@@ -661,8 +675,8 @@ func (m *Mint) RequestMeltQuote(meltQuoteRequest nut05.PostMeltQuoteBolt11Reques
661675 AmountMsat : amountMsat ,
662676 }
663677
664- m .logInfof ("got melt quote request for invoice of amount '%v'. Setting fee reserve to %v" ,
665- invoiceSatAmount , meltQuote .FeeReserve )
678+ m .logInfof ("got melt quote request for amount '%v'. Setting fee reserve to %v" ,
679+ quoteAmount , meltQuote .FeeReserve )
666680
667681 if err := m .db .SaveMeltQuote (meltQuote ); err != nil {
668682 errmsg := fmt .Sprintf ("error saving melt quote to db: %v" , err )
@@ -861,7 +875,12 @@ func (m *Mint) MeltTokens(ctx context.Context, meltTokensRequest nut05.PostMeltB
861875 )
862876 } else {
863877 m .logInfof ("attempting to pay invoice: %v" , meltQuote .InvoiceRequest )
864- sendPaymentResponse , err = m .lightningClient .SendPayment (ctx , meltQuote .InvoiceRequest , meltQuote .Amount )
878+ sendPaymentResponse , err = m .lightningClient .SendPayment (
879+ ctx ,
880+ meltQuote .InvoiceRequest ,
881+ meltQuote .Amount ,
882+ meltQuote .FeeReserve ,
883+ )
865884 }
866885 if err != nil {
867886 // if SendPayment failed do not return yet, an extra check will be done
@@ -1625,10 +1644,11 @@ func (m *Mint) SetMintInfo(mintInfo MintInfo) {
16251644 Nut05 : nut06.NutSetting {
16261645 Methods : []nut06.MethodSetting {
16271646 {
1628- Method : cashu .BOLT11_METHOD ,
1629- Unit : cashu .Sat .String (),
1630- MinAmount : m .limits .MeltingSettings .MinAmount ,
1631- MaxAmount : m .limits .MeltingSettings .MaxAmount ,
1647+ Method : cashu .BOLT11_METHOD ,
1648+ Unit : cashu .Sat .String (),
1649+ MinAmount : m .limits .MeltingSettings .MinAmount ,
1650+ MaxAmount : m .limits .MeltingSettings .MaxAmount ,
1651+ Amountless : true ,
16321652 },
16331653 },
16341654 Disabled : false ,
0 commit comments