mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2024-11-19 01:40:55 +01:00
Add sendouputs function to lnd rpc (#2858)
This commit is contained in:
parent
d726c498d0
commit
825024fa1a
@ -2,6 +2,8 @@ package org.bitcoins.lnd.rpc
|
||||
|
||||
import org.bitcoins.asyncutil.AsyncUtil
|
||||
import org.bitcoins.core.currency.Satoshis
|
||||
import org.bitcoins.core.protocol.transaction.TransactionOutput
|
||||
import org.bitcoins.core.wallet.fee.SatoshisPerKW
|
||||
import org.bitcoins.testkit.fixtures.DualLndFixture
|
||||
|
||||
import scala.concurrent.duration.DurationInt
|
||||
@ -49,4 +51,30 @@ class LndRpcClientPairTest extends DualLndFixture {
|
||||
_ <- lndA.monitorInvoice(invoice.rHash)
|
||||
} yield succeed
|
||||
}
|
||||
|
||||
it must "send outputs from one node to another" in { params =>
|
||||
val (bitcoind, lndA, lndB) = params
|
||||
|
||||
val sendAmt = Satoshis(10000)
|
||||
val feeRate = SatoshisPerKW.fromLong(1000)
|
||||
|
||||
for {
|
||||
oldBalA <- lndA.walletBalance().map(_.balance)
|
||||
oldBalB <- lndB.walletBalance().map(_.balance)
|
||||
|
||||
addr <- lndB.getNewAddress
|
||||
output = TransactionOutput(sendAmt, addr.scriptPubKey)
|
||||
|
||||
tx <- lndA.sendOutputs(Vector(output), feeRate, spendUnconfirmed = false)
|
||||
_ <- lndA.publishTransaction(tx)
|
||||
_ <- bitcoind.getNewAddress.flatMap(bitcoind.generateToAddress(6, _))
|
||||
|
||||
newBalA <- lndA.walletBalance().map(_.balance)
|
||||
newBalB <- lndB.walletBalance().map(_.balance)
|
||||
} yield {
|
||||
assert(newBalB == oldBalB + sendAmt)
|
||||
// account for variance in fees
|
||||
assert(newBalA === oldBalA - sendAmt - feeRate.calc(tx) +- Satoshis(6))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,20 +8,28 @@ import lnrpc._
|
||||
import org.bitcoins.commons.jsonmodels.lnd._
|
||||
import org.bitcoins.core.currency._
|
||||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.core.protocol.BitcoinAddress
|
||||
import org.bitcoins.core.protocol.ln.LnInvoice
|
||||
import org.bitcoins.core.protocol.ln.currency.MilliSatoshis
|
||||
import org.bitcoins.core.protocol.ln.node.NodeId
|
||||
import org.bitcoins.core.protocol.script.ScriptPubKey
|
||||
import org.bitcoins.core.protocol.transaction.TransactionOutPoint
|
||||
import org.bitcoins.core.protocol.transaction.{
|
||||
TransactionOutPoint,
|
||||
TransactionOutput
|
||||
}
|
||||
import org.bitcoins.core.protocol.{transaction, BitcoinAddress}
|
||||
import org.bitcoins.core.util.StartStopAsync
|
||||
import org.bitcoins.core.wallet.fee.SatoshisPerByte
|
||||
import org.bitcoins.core.wallet.fee.{
|
||||
SatoshisPerByte,
|
||||
SatoshisPerKW,
|
||||
SatoshisPerVirtualByte
|
||||
}
|
||||
import org.bitcoins.crypto.DoubleSha256DigestBE
|
||||
import org.bitcoins.lnd.rpc.LndRpcClient._
|
||||
import org.bitcoins.lnd.rpc.config.LndInstance
|
||||
import org.bitcoins.rpc.util.NativeProcessFactory
|
||||
import scodec.bits.ByteVector
|
||||
import walletrpc.WalletKitClient
|
||||
import signrpc.TxOut
|
||||
import walletrpc.{SendOutputsRequest, WalletKitClient}
|
||||
|
||||
import java.io.{File, FileInputStream}
|
||||
import java.net.InetSocketAddress
|
||||
@ -386,6 +394,61 @@ class LndRpcClient(val instance: LndInstance, binary: Option[File] = None)(
|
||||
.invoke(request)
|
||||
}
|
||||
|
||||
def sendOutputs(
|
||||
outputs: Vector[TransactionOutput],
|
||||
feeRate: SatoshisPerVirtualByte,
|
||||
spendUnconfirmed: Boolean): Future[transaction.Transaction] = {
|
||||
sendOutputs(outputs, feeRate.toSatoshisPerKW, spendUnconfirmed)
|
||||
}
|
||||
|
||||
def sendOutputs(
|
||||
outputs: Vector[TransactionOutput],
|
||||
feeRate: SatoshisPerKW,
|
||||
spendUnconfirmed: Boolean): Future[transaction.Transaction] = {
|
||||
|
||||
val txOuts = outputs.map(out =>
|
||||
TxOut(out.value.satoshis.toLong,
|
||||
ByteString.copyFrom(out.scriptPubKey.asmBytes.toArray)))
|
||||
|
||||
val request = SendOutputsRequest(satPerKw = feeRate.toLong,
|
||||
outputs = txOuts,
|
||||
spendUnconfirmed = spendUnconfirmed)
|
||||
sendOutputs(request)
|
||||
}
|
||||
|
||||
def sendOutputs(
|
||||
request: SendOutputsRequest): Future[transaction.Transaction] = {
|
||||
logger.trace("lnd calling sendoutputs")
|
||||
|
||||
wallet
|
||||
.sendOutputs()
|
||||
.addHeader(macaroonKey, instance.macaroon)
|
||||
.invoke(request)
|
||||
.map { res =>
|
||||
val bytes = ByteVector(res.rawTx.toByteArray)
|
||||
transaction.Transaction(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
/** Broadcasts the given transaction
|
||||
* @return None if no error, otherwise the error string
|
||||
*/
|
||||
def publishTransaction(
|
||||
tx: transaction.Transaction): Future[Option[String]] = {
|
||||
logger.trace("lnd calling publishtransaction")
|
||||
|
||||
val request = walletrpc.Transaction(ByteString.copyFrom(tx.bytes.toArray))
|
||||
|
||||
wallet
|
||||
.publishTransaction()
|
||||
.addHeader(macaroonKey, instance.macaroon)
|
||||
.invoke(request)
|
||||
.map { res =>
|
||||
if (res.publishError.isEmpty) None
|
||||
else Some(res.publishError)
|
||||
}
|
||||
}
|
||||
|
||||
def monitorInvoice(
|
||||
rHash: ByteVector,
|
||||
interval: FiniteDuration = 1.second,
|
||||
|
Loading…
Reference in New Issue
Block a user