mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2024-11-19 09:52:09 +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.asyncutil.AsyncUtil
|
||||||
import org.bitcoins.core.currency.Satoshis
|
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 org.bitcoins.testkit.fixtures.DualLndFixture
|
||||||
|
|
||||||
import scala.concurrent.duration.DurationInt
|
import scala.concurrent.duration.DurationInt
|
||||||
@ -49,4 +51,30 @@ class LndRpcClientPairTest extends DualLndFixture {
|
|||||||
_ <- lndA.monitorInvoice(invoice.rHash)
|
_ <- lndA.monitorInvoice(invoice.rHash)
|
||||||
} yield succeed
|
} 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.commons.jsonmodels.lnd._
|
||||||
import org.bitcoins.core.currency._
|
import org.bitcoins.core.currency._
|
||||||
import org.bitcoins.core.number.UInt32
|
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.LnInvoice
|
||||||
import org.bitcoins.core.protocol.ln.currency.MilliSatoshis
|
import org.bitcoins.core.protocol.ln.currency.MilliSatoshis
|
||||||
import org.bitcoins.core.protocol.ln.node.NodeId
|
import org.bitcoins.core.protocol.ln.node.NodeId
|
||||||
import org.bitcoins.core.protocol.script.ScriptPubKey
|
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.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.crypto.DoubleSha256DigestBE
|
||||||
import org.bitcoins.lnd.rpc.LndRpcClient._
|
import org.bitcoins.lnd.rpc.LndRpcClient._
|
||||||
import org.bitcoins.lnd.rpc.config.LndInstance
|
import org.bitcoins.lnd.rpc.config.LndInstance
|
||||||
import org.bitcoins.rpc.util.NativeProcessFactory
|
import org.bitcoins.rpc.util.NativeProcessFactory
|
||||||
import scodec.bits.ByteVector
|
import scodec.bits.ByteVector
|
||||||
import walletrpc.WalletKitClient
|
import signrpc.TxOut
|
||||||
|
import walletrpc.{SendOutputsRequest, WalletKitClient}
|
||||||
|
|
||||||
import java.io.{File, FileInputStream}
|
import java.io.{File, FileInputStream}
|
||||||
import java.net.InetSocketAddress
|
import java.net.InetSocketAddress
|
||||||
@ -386,6 +394,61 @@ class LndRpcClient(val instance: LndInstance, binary: Option[File] = None)(
|
|||||||
.invoke(request)
|
.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(
|
def monitorInvoice(
|
||||||
rHash: ByteVector,
|
rHash: ByteVector,
|
||||||
interval: FiniteDuration = 1.second,
|
interval: FiniteDuration = 1.second,
|
||||||
|
Loading…
Reference in New Issue
Block a user