mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2024-11-19 01:40:55 +01:00
Add raw funding of psbt to LndRpc (#4235)
This commit is contained in:
parent
b0e849c233
commit
5856745398
@ -5,15 +5,19 @@ import org.bitcoins.asyncutil.AsyncUtil
|
||||
import org.bitcoins.core.currency.{currencyUnitNumeric, Bitcoins, Satoshis}
|
||||
import org.bitcoins.core.number.{Int32, UInt32}
|
||||
import org.bitcoins.core.protocol.BigSizeUInt
|
||||
import org.bitcoins.core.protocol.script.EmptyScriptSignature
|
||||
import org.bitcoins.core.protocol.script.{
|
||||
EmptyScriptSignature,
|
||||
P2WPKHWitnessSPKV0
|
||||
}
|
||||
import org.bitcoins.core.protocol.tlv.UnknownTLV
|
||||
import org.bitcoins.core.protocol.transaction._
|
||||
import org.bitcoins.core.psbt.PSBT
|
||||
import org.bitcoins.core.wallet.fee.SatoshisPerKW
|
||||
import org.bitcoins.core.wallet.fee.{SatoshisPerKW, SatoshisPerVirtualByte}
|
||||
import org.bitcoins.crypto._
|
||||
import org.bitcoins.testkit.fixtures.DualLndFixture
|
||||
import scodec.bits.HexStringSyntax
|
||||
|
||||
import scala.concurrent.Future
|
||||
import scala.concurrent.duration.DurationInt
|
||||
import scala.util.{Failure, Success}
|
||||
|
||||
@ -153,6 +157,26 @@ class LndRpcClientPairTest extends DualLndFixture {
|
||||
}
|
||||
}
|
||||
|
||||
it must "fund from an no input psbt" in { params =>
|
||||
val (_, lnd, _) = params
|
||||
|
||||
val spk = P2WPKHWitnessSPKV0(ECPublicKey.freshPublicKey)
|
||||
val output = TransactionOutput(Satoshis(10000), spk)
|
||||
val unsignedTx = BaseTransaction(version = Int32.one,
|
||||
inputs = Vector.empty,
|
||||
outputs = Vector(output),
|
||||
lockTime = UInt32.zero)
|
||||
|
||||
for {
|
||||
unsignedPsbt <- lnd.fundPSBT(PSBT.fromUnsignedTx(unsignedTx),
|
||||
SatoshisPerVirtualByte.one,
|
||||
spendUnconfirmed = true)
|
||||
signed <- lnd.finalizePSBT(unsignedPsbt)
|
||||
transaction <- Future.fromTry(signed.extractTransactionAndValidate)
|
||||
errorOpt <- lnd.publishTransaction(transaction)
|
||||
} yield assert(errorOpt.isEmpty)
|
||||
}
|
||||
|
||||
it must "send and receive a custom message" in { params =>
|
||||
val (_, lndA, lndB) = params
|
||||
|
||||
|
@ -564,6 +564,59 @@ class LndRpcClient(val instance: LndInstance, binaryOpt: Option[File] = None)(
|
||||
.map(res => Tx(res.rawTx))
|
||||
}
|
||||
|
||||
def fundPSBT(
|
||||
inputs: Vector[TransactionOutPoint],
|
||||
outputs: Map[BitcoinAddress, CurrencyUnit],
|
||||
feeRate: SatoshisPerVirtualByte,
|
||||
spendUnconfirmed: Boolean): Future[PSBT] = {
|
||||
val outputMap = outputs.map { case (addr, amt) =>
|
||||
addr.toString -> amt.satoshis.toLong
|
||||
}
|
||||
val template = TxTemplate(inputs, outputMap)
|
||||
val rawTemplate = FundPsbtRequest.Template.Raw(template)
|
||||
val fees = SatPerVbyte(feeRate.toLong)
|
||||
val request = FundPsbtRequest(template = rawTemplate,
|
||||
fees = fees,
|
||||
spendUnconfirmed = spendUnconfirmed)
|
||||
|
||||
fundPSBT(request)
|
||||
}
|
||||
|
||||
def fundPSBT(
|
||||
inputs: Vector[TransactionOutPoint],
|
||||
outputs: Map[BitcoinAddress, CurrencyUnit],
|
||||
feeRate: SatoshisPerVirtualByte,
|
||||
account: String,
|
||||
spendUnconfirmed: Boolean): Future[PSBT] = {
|
||||
val outputMap = outputs.map { case (addr, amt) =>
|
||||
addr.toString -> amt.satoshis.toLong
|
||||
}
|
||||
val template = TxTemplate(inputs, outputMap)
|
||||
val rawTemplate = FundPsbtRequest.Template.Raw(template)
|
||||
val fees = SatPerVbyte(feeRate.toLong)
|
||||
val request = FundPsbtRequest(template = rawTemplate,
|
||||
fees = fees,
|
||||
account = account,
|
||||
spendUnconfirmed = spendUnconfirmed)
|
||||
|
||||
fundPSBT(request)
|
||||
}
|
||||
|
||||
def fundPSBT(
|
||||
psbt: PSBT,
|
||||
feeRate: SatoshisPerVirtualByte,
|
||||
account: String,
|
||||
spendUnconfirmed: Boolean): Future[PSBT] = {
|
||||
val template = Psbt(psbt.bytes)
|
||||
val fees = SatPerVbyte(feeRate.toLong)
|
||||
val request = FundPsbtRequest(template = template,
|
||||
fees = fees,
|
||||
account = account,
|
||||
spendUnconfirmed = spendUnconfirmed)
|
||||
|
||||
fundPSBT(request)
|
||||
}
|
||||
|
||||
def fundPSBT(
|
||||
psbt: PSBT,
|
||||
feeRate: SatoshisPerVirtualByte,
|
||||
|
@ -1,8 +1,8 @@
|
||||
package org.bitcoins.lnd.rpc
|
||||
|
||||
import com.google.protobuf.ByteString
|
||||
import lnrpc.ChannelPoint
|
||||
import lnrpc.ChannelPoint.FundingTxid.FundingTxidBytes
|
||||
import lnrpc.{ChannelPoint, OutPoint}
|
||||
import org.bitcoins.commons.jsonmodels.lnd.TxDetails
|
||||
import org.bitcoins.core.currency.Satoshis
|
||||
import org.bitcoins.core.number.UInt32
|
||||
@ -30,12 +30,27 @@ trait LndUtils {
|
||||
TransactionOutput(Satoshis(txOut.value),
|
||||
ScriptPubKey.fromAsmBytes(txOut.pkScript))
|
||||
|
||||
implicit def outpointToTxOutPoint(op: OutPoint): TransactionOutPoint =
|
||||
TransactionOutPoint(DoubleSha256DigestBE(op.txidStr),
|
||||
UInt32(op.outputIndex))
|
||||
|
||||
implicit def txOutpointToOutpoint(outpoint: TransactionOutPoint): OutPoint =
|
||||
OutPoint(outpoint.txId.bytes, outpoint.txIdBE.hex, outpoint.vout.toInt)
|
||||
|
||||
// If other kinds of Iterables are needed, there's a fancy thing to do
|
||||
// that is done all over the Seq code using params and an implicit CanBuildFrom
|
||||
implicit def outputVecToTxOuts(
|
||||
outputs: Vector[TransactionOutput]): Vector[TxOut] =
|
||||
outputs.map(outputToTxOut)
|
||||
|
||||
implicit def outpointVecToTxOutPointVec(
|
||||
ops: Vector[OutPoint]): Vector[TransactionOutPoint] =
|
||||
ops.map(outpointToTxOutPoint)
|
||||
|
||||
implicit def txOutpointToOutpointVec(
|
||||
ops: Vector[TransactionOutPoint]): Vector[OutPoint] =
|
||||
ops.map(txOutpointToOutpoint)
|
||||
|
||||
implicit def byteStringVecToByteVecs(
|
||||
byteStrings: Vector[ByteString]): Vector[ByteVector] =
|
||||
byteStrings.map(byteStringToByteVec)
|
||||
|
Loading…
Reference in New Issue
Block a user