@@ -43,14 +43,16 @@ object LiquidityAds {
4343 * The buyer refunds those on-chain fees for the given vbytes.
4444 * @param feeProportional proportional fee (expressed in basis points) based on the amount contributed by the seller.
4545 * @param feeBase flat fee that must be paid regardless of the amount contributed by the seller.
46+ * @param channelCreationFee flat fee that must be paid when a new channel is created.
4647 */
47- data class FundingRate (val minAmount : Satoshi , val maxAmount : Satoshi , val fundingWeight : Int , val feeProportional : Int , val feeBase : Satoshi ) {
48+ data class FundingRate (val minAmount : Satoshi , val maxAmount : Satoshi , val fundingWeight : Int , val feeProportional : Int , val feeBase : Satoshi , val channelCreationFee : Satoshi ) {
4849 /* * Fees paid by the liquidity buyer. */
49- fun fees (feerate : FeeratePerKw , requestedAmount : Satoshi , contributedAmount : Satoshi ): Fees {
50+ fun fees (feerate : FeeratePerKw , requestedAmount : Satoshi , contributedAmount : Satoshi , isChannelCreation : Boolean ): Fees {
5051 val onChainFees = Transactions .weight2fee(feerate, fundingWeight)
5152 // If the seller adds more liquidity than requested, the buyer doesn't pay for that extra liquidity.
5253 val proportionalFee = requestedAmount.min(contributedAmount) * feeProportional / 10_000
53- return Fees (onChainFees, feeBase + proportionalFee)
54+ val flatFee = if (isChannelCreation) channelCreationFee + feeBase else feeBase
55+ return Fees (onChainFees, flatFee + proportionalFee)
5456 }
5557
5658 /* * When liquidity is purchased, the seller provides a signature of the funding rate and funding script. */
@@ -68,6 +70,7 @@ object LiquidityAds {
6870 LightningCodecs .writeU16(fundingWeight, out )
6971 LightningCodecs .writeU16(feeProportional, out )
7072 LightningCodecs .writeU32(feeBase.sat.toInt(), out )
73+ LightningCodecs .writeU32(channelCreationFee.sat.toInt(), out )
7174 }
7275
7376 companion object {
@@ -77,6 +80,7 @@ object LiquidityAds {
7780 fundingWeight = LightningCodecs .u16(input),
7881 feeProportional = LightningCodecs .u16(input),
7982 feeBase = LightningCodecs .u32(input).sat,
83+ channelCreationFee = LightningCodecs .u32(input).sat,
8084 )
8185 }
8286 }
@@ -186,14 +190,14 @@ object LiquidityAds {
186190
187191 /* * Sellers offer various rates and payment options. */
188192 data class WillFundRates (val fundingRates : List <FundingRate >, val paymentTypes : Set <PaymentType >) {
189- fun validateRequest (nodeKey : PrivateKey , fundingScript : ByteVector , fundingFeerate : FeeratePerKw , request : RequestFunding ): WillFundPurchase ? {
193+ fun validateRequest (nodeKey : PrivateKey , fundingScript : ByteVector , fundingFeerate : FeeratePerKw , request : RequestFunding , isChannelCreation : Boolean ): WillFundPurchase ? {
190194 val paymentTypeOk = paymentTypes.contains(request.paymentDetails.paymentType)
191195 val rateOk = fundingRates.contains(request.fundingRate)
192196 val amountOk = request.fundingRate.minAmount <= request.requestedAmount && request.requestedAmount <= request.fundingRate.maxAmount
193197 return when {
194198 paymentTypeOk && rateOk && amountOk -> {
195199 val sig = Crypto .sign(request.fundingRate.signedData(fundingScript), nodeKey)
196- val purchase = Purchase .Standard (request.requestedAmount, request.fees(fundingFeerate), request.paymentDetails)
200+ val purchase = Purchase .Standard (request.requestedAmount, request.fees(fundingFeerate, isChannelCreation ), request.paymentDetails)
197201 WillFundPurchase (WillFund (request.fundingRate, fundingScript, sig), purchase)
198202 }
199203 else -> null
@@ -242,14 +246,15 @@ object LiquidityAds {
242246
243247 /* * Request inbound liquidity from a remote peer that supports liquidity ads. */
244248 data class RequestFunding (val requestedAmount : Satoshi , val fundingRate : FundingRate , val paymentDetails : PaymentDetails ) {
245- fun fees (feerate : FeeratePerKw ): Fees = fundingRate.fees(feerate, requestedAmount, requestedAmount)
249+ fun fees (feerate : FeeratePerKw , isChannelCreation : Boolean ): Fees = fundingRate.fees(feerate, requestedAmount, requestedAmount, isChannelCreation )
246250
247251 fun validateRemoteFunding (
248252 remoteNodeId : PublicKey ,
249253 channelId : ByteVector32 ,
250254 fundingScript : ByteVector ,
251255 remoteFundingAmount : Satoshi ,
252256 fundingFeerate : FeeratePerKw ,
257+ isChannelCreation : Boolean ,
253258 willFund : WillFund ?
254259 ): Either <ChannelException , Purchase > {
255260 return when (willFund) {
@@ -261,7 +266,7 @@ object LiquidityAds {
261266 remoteFundingAmount < requestedAmount -> Either .Left (InvalidLiquidityAdsAmount (channelId, remoteFundingAmount, requestedAmount))
262267 else -> {
263268 val purchasedAmount = requestedAmount.min(remoteFundingAmount)
264- val fees = fundingRate.fees(fundingFeerate, requestedAmount, remoteFundingAmount)
269+ val fees = fundingRate.fees(fundingFeerate, requestedAmount, remoteFundingAmount, isChannelCreation )
265270 Either .Right (Purchase .Standard (purchasedAmount, fees, paymentDetails))
266271 }
267272 }
@@ -295,11 +300,12 @@ object LiquidityAds {
295300 fundingScript : ByteVector ,
296301 remoteFundingAmount : Satoshi ,
297302 fundingFeerate : FeeratePerKw ,
303+ isChannelCreation : Boolean ,
298304 willFund : WillFund ? ,
299305 ): Either <ChannelException , Purchase ?> {
300306 return when (request) {
301307 null -> Either .Right (null )
302- else -> request.validateRemoteFunding(remoteNodeId, channelId, fundingScript, remoteFundingAmount, fundingFeerate, willFund)
308+ else -> request.validateRemoteFunding(remoteNodeId, channelId, fundingScript, remoteFundingAmount, fundingFeerate, isChannelCreation, willFund)
303309 }
304310 }
305311
0 commit comments