mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-02-23 14:50:42 +01:00
Fixed getAddressInfo for versions 18 and 19 (#1679)
This commit is contained in:
parent
4935b513c7
commit
714d5a06fd
4 changed files with 166 additions and 137 deletions
|
@ -204,7 +204,30 @@ case class UnspentOutput(
|
||||||
reused: Option[Boolean])
|
reused: Option[Boolean])
|
||||||
extends WalletResult
|
extends WalletResult
|
||||||
|
|
||||||
case class AddressInfoResult(
|
sealed trait AddressInfoResult extends WalletResult {
|
||||||
|
def address: BitcoinAddress
|
||||||
|
def scriptPubKey: ScriptPubKey
|
||||||
|
def ismine: Boolean
|
||||||
|
def iswatchonly: Boolean
|
||||||
|
def isscript: Boolean
|
||||||
|
def iswitness: Boolean
|
||||||
|
def iscompressed: Option[Boolean]
|
||||||
|
def witness_version: Option[WitnessVersion]
|
||||||
|
def witness_program: Option[String] // todo what's the correct type here?
|
||||||
|
def script: Option[ScriptType]
|
||||||
|
def hex: Option[ScriptPubKey]
|
||||||
|
def pubkeys: Option[Vector[ECPublicKey]]
|
||||||
|
def sigsrequired: Option[Int]
|
||||||
|
def pubkey: Option[ECPublicKey]
|
||||||
|
def embedded: Option[EmbeddedResult]
|
||||||
|
def label: String
|
||||||
|
def timestamp: Option[ZonedDateTime]
|
||||||
|
def hdkeypath: Option[BIP32Path]
|
||||||
|
def hdseedid: Option[RipeMd160Digest]
|
||||||
|
def labels: Vector[LabelResult]
|
||||||
|
}
|
||||||
|
|
||||||
|
case class AddressInfoResultPreV18(
|
||||||
address: BitcoinAddress,
|
address: BitcoinAddress,
|
||||||
scriptPubKey: ScriptPubKey,
|
scriptPubKey: ScriptPubKey,
|
||||||
ismine: Boolean,
|
ismine: Boolean,
|
||||||
|
@ -213,7 +236,7 @@ case class AddressInfoResult(
|
||||||
iswitness: Boolean,
|
iswitness: Boolean,
|
||||||
iscompressed: Option[Boolean],
|
iscompressed: Option[Boolean],
|
||||||
witness_version: Option[WitnessVersion],
|
witness_version: Option[WitnessVersion],
|
||||||
witness_program: Option[String], // todo what's the correct type here?
|
witness_program: Option[String],
|
||||||
script: Option[ScriptType],
|
script: Option[ScriptType],
|
||||||
hex: Option[ScriptPubKey],
|
hex: Option[ScriptPubKey],
|
||||||
pubkeys: Option[Vector[ECPublicKey]],
|
pubkeys: Option[Vector[ECPublicKey]],
|
||||||
|
@ -226,7 +249,94 @@ case class AddressInfoResult(
|
||||||
hdseedid: Option[RipeMd160Digest],
|
hdseedid: Option[RipeMd160Digest],
|
||||||
hdmasterkeyid: Option[RipeMd160Digest],
|
hdmasterkeyid: Option[RipeMd160Digest],
|
||||||
labels: Vector[LabelResult])
|
labels: Vector[LabelResult])
|
||||||
extends WalletResult
|
extends AddressInfoResult
|
||||||
|
|
||||||
|
// The split into two case classes is to deal with the 22 param limit for case classes
|
||||||
|
case class AddressInfoResultPostV18(
|
||||||
|
address: BitcoinAddress,
|
||||||
|
scriptPubKey: ScriptPubKey,
|
||||||
|
isProps: AddressInfoResultPostV18.AddressInfoIsProps,
|
||||||
|
desc: String,
|
||||||
|
witness_version: Option[WitnessVersion],
|
||||||
|
witness_program: Option[String],
|
||||||
|
script: Option[ScriptType],
|
||||||
|
hex: Option[ScriptPubKey],
|
||||||
|
pubkeys: Option[Vector[ECPublicKey]],
|
||||||
|
sigsrequired: Option[Int],
|
||||||
|
pubkey: Option[ECPublicKey],
|
||||||
|
embedded: Option[EmbeddedResult],
|
||||||
|
label: String,
|
||||||
|
ischange: Boolean,
|
||||||
|
timestamp: Option[ZonedDateTime],
|
||||||
|
hdkeypath: Option[BIP32Path],
|
||||||
|
hdseedid: Option[RipeMd160Digest],
|
||||||
|
hdmasterfingerprint: Option[String],
|
||||||
|
labels: Vector[LabelResult])
|
||||||
|
extends AddressInfoResult {
|
||||||
|
override def ismine: Boolean = isProps.ismine
|
||||||
|
def solvable: Boolean = isProps.solvable
|
||||||
|
override def iswatchonly: Boolean = isProps.iswatchonly
|
||||||
|
override def isscript: Boolean = isProps.isscript
|
||||||
|
override def iswitness: Boolean = isProps.iswitness
|
||||||
|
override def iscompressed: Option[Boolean] = isProps.iscompressed
|
||||||
|
}
|
||||||
|
|
||||||
|
object AddressInfoResultPostV18 {
|
||||||
|
|
||||||
|
case class AddressInfoIsProps(
|
||||||
|
ismine: Boolean,
|
||||||
|
solvable: Boolean,
|
||||||
|
iswatchonly: Boolean,
|
||||||
|
isscript: Boolean,
|
||||||
|
iswitness: Boolean,
|
||||||
|
iscompressed: Option[Boolean])
|
||||||
|
|
||||||
|
case class AddressInfoResultPostV18WithoutIsProps(
|
||||||
|
address: BitcoinAddress,
|
||||||
|
scriptPubKey: ScriptPubKey,
|
||||||
|
desc: String,
|
||||||
|
witness_version: Option[WitnessVersion],
|
||||||
|
witness_program: Option[String],
|
||||||
|
script: Option[ScriptType],
|
||||||
|
hex: Option[ScriptPubKey],
|
||||||
|
pubkeys: Option[Vector[ECPublicKey]],
|
||||||
|
sigsrequired: Option[Int],
|
||||||
|
pubkey: Option[ECPublicKey],
|
||||||
|
embedded: Option[EmbeddedResult],
|
||||||
|
label: String,
|
||||||
|
ischange: Boolean,
|
||||||
|
timestamp: Option[ZonedDateTime],
|
||||||
|
hdkeypath: Option[BIP32Path],
|
||||||
|
hdseedid: Option[RipeMd160Digest],
|
||||||
|
hdmasterfingerprint: Option[String],
|
||||||
|
labels: Vector[LabelResult])
|
||||||
|
|
||||||
|
def apply(
|
||||||
|
info: AddressInfoResultPostV18WithoutIsProps,
|
||||||
|
isProps: AddressInfoIsProps): AddressInfoResultPostV18 = {
|
||||||
|
AddressInfoResultPostV18(
|
||||||
|
address = info.address,
|
||||||
|
scriptPubKey = info.scriptPubKey,
|
||||||
|
isProps = isProps,
|
||||||
|
desc = info.desc,
|
||||||
|
witness_version = info.witness_version,
|
||||||
|
witness_program = info.witness_program,
|
||||||
|
script = info.script,
|
||||||
|
hex = info.hex,
|
||||||
|
pubkeys = info.pubkeys,
|
||||||
|
sigsrequired = info.sigsrequired,
|
||||||
|
pubkey = info.pubkey,
|
||||||
|
embedded = info.embedded,
|
||||||
|
label = info.label,
|
||||||
|
ischange = info.ischange,
|
||||||
|
timestamp = info.timestamp,
|
||||||
|
hdkeypath = info.hdkeypath,
|
||||||
|
hdseedid = info.hdseedid,
|
||||||
|
hdmasterfingerprint = info.hdmasterfingerprint,
|
||||||
|
labels = info.labels
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case class EmbeddedResult(
|
case class EmbeddedResult(
|
||||||
isscript: Boolean,
|
isscript: Boolean,
|
||||||
|
|
|
@ -8,142 +8,19 @@ import org.bitcoins.core.currency.{Bitcoins, Satoshis}
|
||||||
import org.bitcoins.core.hd.BIP32Path
|
import org.bitcoins.core.hd.BIP32Path
|
||||||
import org.bitcoins.core.number.{Int32, UInt32, UInt64}
|
import org.bitcoins.core.number.{Int32, UInt32, UInt64}
|
||||||
import org.bitcoins.core.protocol.blockchain.{Block, BlockHeader, MerkleBlock}
|
import org.bitcoins.core.protocol.blockchain.{Block, BlockHeader, MerkleBlock}
|
||||||
import org.bitcoins.core.protocol.script.{
|
import org.bitcoins.core.protocol.script._
|
||||||
ScriptPubKey,
|
import org.bitcoins.core.protocol.transaction._
|
||||||
ScriptSignature,
|
import org.bitcoins.core.protocol._
|
||||||
WitnessScriptPubKey
|
|
||||||
}
|
|
||||||
import org.bitcoins.core.protocol.transaction.{
|
|
||||||
Transaction,
|
|
||||||
TransactionInput,
|
|
||||||
TransactionOutPoint
|
|
||||||
}
|
|
||||||
import org.bitcoins.core.protocol.{
|
|
||||||
Address,
|
|
||||||
BitcoinAddress,
|
|
||||||
P2PKHAddress,
|
|
||||||
P2SHAddress
|
|
||||||
}
|
|
||||||
import org.bitcoins.core.script.ScriptType
|
import org.bitcoins.core.script.ScriptType
|
||||||
import org.bitcoins.core.wallet.fee.{
|
import org.bitcoins.core.wallet.fee._
|
||||||
BitcoinFeeUnit,
|
|
||||||
SatoshisPerKiloByte,
|
|
||||||
SatoshisPerVirtualByte
|
|
||||||
}
|
|
||||||
import org.bitcoins.commons.serializers.JsonReaders._
|
import org.bitcoins.commons.serializers.JsonReaders._
|
||||||
import org.bitcoins.commons.serializers.JsonWriters._
|
import org.bitcoins.commons.serializers.JsonWriters._
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.AddressType
|
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.AddressType
|
||||||
import org.bitcoins.commons.jsonmodels.bitcoind.{
|
import org.bitcoins.commons.jsonmodels.bitcoind._
|
||||||
AddressInfoResult,
|
import org.bitcoins.commons.jsonmodels.wallet._
|
||||||
AnalyzePsbtInput,
|
import org.bitcoins.crypto._
|
||||||
AnalyzePsbtResult,
|
|
||||||
ArrayOfWalletsInput,
|
|
||||||
BalanceInfo,
|
|
||||||
Bip9Softfork,
|
|
||||||
BlockTransaction,
|
|
||||||
BumpFeeResult,
|
|
||||||
ChainTip,
|
|
||||||
CreateWalletResult,
|
|
||||||
DecodePsbtResult,
|
|
||||||
DecodeScriptResult,
|
|
||||||
DeriveAddressesResult,
|
|
||||||
DumpWalletResult,
|
|
||||||
EmbeddedResult,
|
|
||||||
EstimateSmartFeeResult,
|
|
||||||
FeeInfo,
|
|
||||||
FinalizePsbtResult,
|
|
||||||
FinalizedPsbt,
|
|
||||||
FundRawTransactionResult,
|
|
||||||
GetBalancesResult,
|
|
||||||
GetBlockChainInfoResult,
|
|
||||||
GetBlockHeaderResult,
|
|
||||||
GetBlockResult,
|
|
||||||
GetBlockTemplateResult,
|
|
||||||
GetBlockWithTransactionsResult,
|
|
||||||
GetChainTxStatsResult,
|
|
||||||
GetDescriptorInfoResult,
|
|
||||||
GetMemPoolEntryResultPostV19,
|
|
||||||
GetMemPoolEntryResultPreV19,
|
|
||||||
GetMemPoolInfoResult,
|
|
||||||
GetMemPoolResultPostV19,
|
|
||||||
GetMemPoolResultPreV19,
|
|
||||||
GetMemoryInfoResult,
|
|
||||||
GetMiningInfoResult,
|
|
||||||
GetNetTotalsResult,
|
|
||||||
GetNetworkInfoResult,
|
|
||||||
GetNodeAddressesResult,
|
|
||||||
GetRawTransactionResult,
|
|
||||||
GetRawTransactionScriptSig,
|
|
||||||
GetRawTransactionVin,
|
|
||||||
GetRpcInfoResult,
|
|
||||||
GetTransactionResult,
|
|
||||||
GetTxOutResult,
|
|
||||||
GetTxOutSetInfoResult,
|
|
||||||
GetWalletInfoResult,
|
|
||||||
ImportMultiError,
|
|
||||||
ImportMultiResult,
|
|
||||||
LabelResult,
|
|
||||||
ListSinceBlockResult,
|
|
||||||
ListTransactionsResult,
|
|
||||||
ListWalletDirResult,
|
|
||||||
MemoryManager,
|
|
||||||
MultiSigResult,
|
|
||||||
NetTarget,
|
|
||||||
Network,
|
|
||||||
NetworkAddress,
|
|
||||||
Node,
|
|
||||||
NodeAddress,
|
|
||||||
NodeBan,
|
|
||||||
NonFinalizedPsbt,
|
|
||||||
Payment,
|
|
||||||
Peer,
|
|
||||||
PeerNetworkInfo,
|
|
||||||
PsbtBIP32Deriv,
|
|
||||||
PsbtMissingData,
|
|
||||||
PsbtWitnessUtxoInput,
|
|
||||||
ReceivedAccount,
|
|
||||||
ReceivedAddress,
|
|
||||||
ReceivedLabel,
|
|
||||||
RescanBlockChainResult,
|
|
||||||
RpcAccount,
|
|
||||||
RpcAddress,
|
|
||||||
RpcCommands,
|
|
||||||
RpcPsbtInput,
|
|
||||||
RpcPsbtOutput,
|
|
||||||
RpcPsbtScript,
|
|
||||||
RpcScriptPubKey,
|
|
||||||
RpcTransaction,
|
|
||||||
RpcTransactionOutput,
|
|
||||||
SetWalletFlagResult,
|
|
||||||
SignRawTransactionError,
|
|
||||||
SignRawTransactionResult,
|
|
||||||
SignRawTransactionWithWalletResult,
|
|
||||||
Softfork,
|
|
||||||
SoftforkProgress,
|
|
||||||
SubmitHeaderResult,
|
|
||||||
TestMempoolAcceptResult,
|
|
||||||
TransactionDetails,
|
|
||||||
UnspentOutput,
|
|
||||||
ValidateAddressResultImpl,
|
|
||||||
WalletCreateFundedPsbtResult,
|
|
||||||
WalletProcessPsbtResult
|
|
||||||
}
|
|
||||||
import org.bitcoins.commons.jsonmodels.wallet.{
|
|
||||||
BitGoResult,
|
|
||||||
BitcoinerLiveEstimate,
|
|
||||||
BitcoinerLiveResult
|
|
||||||
}
|
|
||||||
import org.bitcoins.crypto.{
|
|
||||||
DoubleSha256Digest,
|
|
||||||
DoubleSha256DigestBE,
|
|
||||||
ECDigitalSignature,
|
|
||||||
ECPublicKey,
|
|
||||||
RipeMd160Digest,
|
|
||||||
RipeMd160DigestBE,
|
|
||||||
Sha256Hash160Digest
|
|
||||||
}
|
|
||||||
import play.api.libs.functional.syntax._
|
import play.api.libs.functional.syntax._
|
||||||
import play.api.libs.json._
|
import play.api.libs.json._
|
||||||
|
|
||||||
|
@ -525,8 +402,25 @@ object JsonSerializers {
|
||||||
implicit val embeddedResultReads: Reads[EmbeddedResult] =
|
implicit val embeddedResultReads: Reads[EmbeddedResult] =
|
||||||
Json.reads[EmbeddedResult]
|
Json.reads[EmbeddedResult]
|
||||||
|
|
||||||
implicit val addressInfoResultReads: Reads[AddressInfoResult] =
|
implicit val addressInfoResultPreV18Reads: Reads[AddressInfoResultPreV18] =
|
||||||
Json.reads[AddressInfoResult]
|
Json.reads[AddressInfoResultPreV18]
|
||||||
|
|
||||||
|
implicit val addressInfoResultPostV18Reads: Reads[
|
||||||
|
AddressInfoResultPostV18] = {
|
||||||
|
Reads[AddressInfoResultPostV18] { json =>
|
||||||
|
for {
|
||||||
|
isProps <-
|
||||||
|
Json.reads[AddressInfoResultPostV18.AddressInfoIsProps].reads(json)
|
||||||
|
infoWithoutProps <-
|
||||||
|
Json
|
||||||
|
.reads[
|
||||||
|
AddressInfoResultPostV18.AddressInfoResultPostV18WithoutIsProps]
|
||||||
|
.reads(json)
|
||||||
|
} yield {
|
||||||
|
AddressInfoResultPostV18(infoWithoutProps, isProps)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
implicit val receivedLabelReads: Reads[ReceivedLabel] =
|
implicit val receivedLabelReads: Reads[ReceivedLabel] =
|
||||||
Json.reads[ReceivedLabel]
|
Json.reads[ReceivedLabel]
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
package org.bitcoins.rpc.v18
|
package org.bitcoins.rpc.v18
|
||||||
|
|
||||||
import org.bitcoins.chain.models.BlockHeaderDbHelper
|
import org.bitcoins.chain.models.BlockHeaderDbHelper
|
||||||
|
import org.bitcoins.commons.jsonmodels.bitcoind.{
|
||||||
|
AddressInfoResultPostV18,
|
||||||
|
AddressInfoResultPreV18
|
||||||
|
}
|
||||||
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.AddNodeArgument
|
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.AddNodeArgument
|
||||||
import org.bitcoins.core.protocol.blockchain.RegTestNetChainParams
|
import org.bitcoins.core.protocol.blockchain.RegTestNetChainParams
|
||||||
import org.bitcoins.rpc.client.common.BitcoindVersion
|
import org.bitcoins.rpc.client.common.BitcoindVersion
|
||||||
|
@ -109,4 +113,19 @@ class BitcoindV18RpcClientTest extends BitcoindRpcTest {
|
||||||
client.submitHeader(nextHeader.blockHeader).map(_ => succeed))
|
client.submitHeader(nextHeader.blockHeader).map(_ => succeed))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
it should "have extra address information" in {
|
||||||
|
for {
|
||||||
|
(client, _) <- clientPairF
|
||||||
|
address <- client.getNewAddress
|
||||||
|
info <- client.getAddressInfo(address)
|
||||||
|
} yield {
|
||||||
|
info match {
|
||||||
|
case _: AddressInfoResultPreV18 =>
|
||||||
|
fail("Was expecting AddressInfoResultPostV18")
|
||||||
|
case postV18Info: AddressInfoResultPostV18 =>
|
||||||
|
assert(postV18Info.address == address)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,7 +223,13 @@ trait WalletRpc { self: Client =>
|
||||||
}
|
}
|
||||||
|
|
||||||
def getAddressInfo(address: BitcoinAddress): Future[AddressInfoResult] = {
|
def getAddressInfo(address: BitcoinAddress): Future[AddressInfoResult] = {
|
||||||
bitcoindCall[AddressInfoResult]("getaddressinfo",
|
self.version match {
|
||||||
List(JsString(address.value)))
|
case V16 | V17 =>
|
||||||
|
bitcoindCall[AddressInfoResultPreV18]("getaddressinfo",
|
||||||
|
List(JsString(address.value)))
|
||||||
|
case V18 | V19 | Experimental | Unknown =>
|
||||||
|
bitcoindCall[AddressInfoResultPostV18]("getaddressinfo",
|
||||||
|
List(JsString(address.value)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue