mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2024-11-19 01:40:55 +01:00
2024 08 07 createnewaccount
rpc (#5638)
* Implement creatnewaccount rpc * Get WalletRoutesSpec createnewaccount unit test passing * Rename HDPurposes -> HDPurpose * Fix docs * Implement ConsoleCli arg, change HDPurpose json serialization to be a json string instead of a num
This commit is contained in:
parent
9c25209198
commit
41fab3dfd2
@ -2,26 +2,26 @@ package org.bitcoins.commons.rpc
|
||||
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.LockUnspentOutputParameter
|
||||
import org.bitcoins.commons.jsonmodels.cli.ContractDescriptorParser
|
||||
import org.bitcoins.commons.serializers.JsonReaders
|
||||
import org.bitcoins.commons.serializers.{JsonReaders, Picklers}
|
||||
import org.bitcoins.commons.util.{BitcoinSLogger, WalletNames}
|
||||
import org.bitcoins.core.api.dlc.wallet.db.DLCContactDb
|
||||
import org.bitcoins.core.api.wallet.CoinSelectionAlgo
|
||||
import org.bitcoins.core.crypto.{ExtPrivateKey, MnemonicCode}
|
||||
import org.bitcoins.core.currency.{Bitcoins, Satoshis}
|
||||
import org.bitcoins.core.hd.AddressType
|
||||
import org.bitcoins.core.hd.{AddressType, HDPurpose}
|
||||
import org.bitcoins.core.hd.AddressType.SegWit
|
||||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.core.protocol.BlockStamp.BlockHeight
|
||||
import org.bitcoins.core.protocol.dlc.models.ContractDescriptor
|
||||
import org.bitcoins.core.protocol.tlv._
|
||||
import org.bitcoins.core.protocol.tlv.*
|
||||
import org.bitcoins.core.protocol.transaction.{Transaction, TransactionOutPoint}
|
||||
import org.bitcoins.core.protocol.{BitcoinAddress, BlockStamp}
|
||||
import org.bitcoins.core.psbt.PSBT
|
||||
import org.bitcoins.core.wallet.fee.SatoshisPerVirtualByte
|
||||
import org.bitcoins.core.wallet.utxo.AddressLabelTag
|
||||
import org.bitcoins.crypto._
|
||||
import org.bitcoins.crypto.*
|
||||
import scodec.bits.ByteVector
|
||||
import ujson._
|
||||
import ujson.*
|
||||
|
||||
import java.net.{InetSocketAddress, URI}
|
||||
import java.nio.file.Path
|
||||
@ -1803,6 +1803,25 @@ object LoadWallet extends ServerJsonModels with BitcoinSLogger {
|
||||
}
|
||||
}
|
||||
|
||||
case class CreateNewAccount(purpose: HDPurpose)
|
||||
extends CommandRpc
|
||||
with AppServerCliCommand
|
||||
|
||||
object CreateNewAccount {
|
||||
|
||||
def fromJsArr(arr: ujson.Arr): Try[CreateNewAccount] = {
|
||||
arr.arr.toVector match {
|
||||
case purposeJs +: _ =>
|
||||
Try(upickle.default.read(purposeJs)(Picklers.hdPurpose))
|
||||
.map(CreateNewAccount.apply)
|
||||
case _ =>
|
||||
val exn = new IllegalArgumentException(
|
||||
s"Invalid input for createnewaccount rpc, got=$arr")
|
||||
Failure(exn)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait ServerJsonModels {
|
||||
|
||||
def jsToOracleAnnouncementTLV(js: Value): OracleAnnouncementTLV =
|
||||
|
@ -9,22 +9,22 @@ import org.bitcoins.core.api.dlc.wallet.db.{DLCContactDb, IncomingDLCOfferDb}
|
||||
import org.bitcoins.core.api.wallet.CoinSelectionAlgo
|
||||
import org.bitcoins.core.api.wallet.db.SpendingInfoDb
|
||||
import org.bitcoins.core.config.DLC
|
||||
import org.bitcoins.core.crypto._
|
||||
import org.bitcoins.core.crypto.*
|
||||
import org.bitcoins.core.currency.{Bitcoins, Satoshis}
|
||||
import org.bitcoins.core.dlc.accounting.DLCWalletAccounting
|
||||
import org.bitcoins.core.gcs.FilterType
|
||||
import org.bitcoins.core.hd.{AddressType, HDPath}
|
||||
import org.bitcoins.core.hd.{AddressType, HDPath, HDPurpose}
|
||||
import org.bitcoins.core.number.{Int32, UInt16, UInt32, UInt64}
|
||||
import org.bitcoins.core.protocol.blockchain.Block
|
||||
import org.bitcoins.core.protocol.dlc.models.DLCStatus._
|
||||
import org.bitcoins.core.protocol.dlc.models._
|
||||
import org.bitcoins.core.protocol.dlc.models.DLCStatus.*
|
||||
import org.bitcoins.core.protocol.dlc.models.*
|
||||
import org.bitcoins.core.protocol.script.{
|
||||
ScriptPubKey,
|
||||
ScriptWitness,
|
||||
ScriptWitnessV0,
|
||||
WitnessScriptPubKey
|
||||
}
|
||||
import org.bitcoins.core.protocol.tlv._
|
||||
import org.bitcoins.core.protocol.tlv.*
|
||||
import org.bitcoins.core.protocol.transaction.{
|
||||
Transaction,
|
||||
TransactionOutPoint,
|
||||
@ -35,14 +35,14 @@ import org.bitcoins.core.psbt.InputPSBTRecord.PartialSignature
|
||||
import org.bitcoins.core.psbt.PSBT
|
||||
import org.bitcoins.core.serializers.PicklerKeys
|
||||
import org.bitcoins.core.util.{NetworkUtil, TimeUtil}
|
||||
import org.bitcoins.core.util.TimeUtil._
|
||||
import org.bitcoins.core.util.TimeUtil.*
|
||||
import org.bitcoins.core.util.sorted.OrderedSchnorrSignatures
|
||||
import org.bitcoins.core.wallet.fee.{FeeUnit, SatoshisPerVirtualByte}
|
||||
import org.bitcoins.core.wallet.utxo.{AddressLabelTag, TxoState}
|
||||
import org.bitcoins.crypto._
|
||||
import org.bitcoins.crypto.*
|
||||
import scodec.bits.ByteVector
|
||||
import ujson._
|
||||
import upickle.default._
|
||||
import ujson.*
|
||||
import upickle.default.*
|
||||
|
||||
import java.io.File
|
||||
import java.net.{InetSocketAddress, URI}
|
||||
@ -1767,4 +1767,9 @@ object Picklers {
|
||||
SatoshisPerVirtualByte.fromLong(value.num.toLong)
|
||||
}
|
||||
|
||||
implicit val hdPurpose: ReadWriter[HDPurpose] = {
|
||||
readwriter[ujson.Str]
|
||||
.bimap(_.toString, str => HDPurpose.fromString(str.str))
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,20 +1,20 @@
|
||||
package org.bitcoins.cli
|
||||
|
||||
import org.bitcoins.cli.CliCommand._
|
||||
import org.bitcoins.cli.CliReaders._
|
||||
import org.bitcoins.cli.CliCommand.*
|
||||
import org.bitcoins.cli.CliReaders.*
|
||||
import org.bitcoins.cli.ConsoleCli.RequestParam
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.LockUnspentOutputParameter
|
||||
import org.bitcoins.commons.rpc._
|
||||
import org.bitcoins.commons.serializers.Picklers._
|
||||
import org.bitcoins.commons.rpc.*
|
||||
import org.bitcoins.commons.serializers.Picklers.*
|
||||
import org.bitcoins.commons.util.BitcoinSLogger
|
||||
import org.bitcoins.core.api.wallet.CoinSelectionAlgo
|
||||
import org.bitcoins.core.config.NetworkParameters
|
||||
import org.bitcoins.core.crypto._
|
||||
import org.bitcoins.core.currency._
|
||||
import org.bitcoins.core.hd.AddressType
|
||||
import org.bitcoins.core.crypto.*
|
||||
import org.bitcoins.core.currency.*
|
||||
import org.bitcoins.core.hd.{AddressType, HDPurpose}
|
||||
import org.bitcoins.core.hd.AddressType.SegWit
|
||||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.core.protocol.tlv._
|
||||
import org.bitcoins.core.protocol.tlv.*
|
||||
import org.bitcoins.core.protocol.transaction.{
|
||||
EmptyTransaction,
|
||||
Transaction,
|
||||
@ -24,15 +24,15 @@ import org.bitcoins.core.protocol.{BitcoinAddress, BlockStamp}
|
||||
import org.bitcoins.core.psbt.PSBT
|
||||
import org.bitcoins.core.wallet.fee.SatoshisPerVirtualByte
|
||||
import org.bitcoins.core.wallet.utxo.AddressLabelTag
|
||||
import org.bitcoins.crypto._
|
||||
import org.bitcoins.crypto.*
|
||||
import scodec.bits.ByteVector
|
||||
import scopt.OParser
|
||||
import sttp.client3.logging.LogLevel
|
||||
import sttp.client3.logging.slf4j.Slf4jLoggingBackend
|
||||
import sttp.client3.{Identity, SttpBackend}
|
||||
import sttp.model.StatusCode
|
||||
import ujson._
|
||||
import upickle.{default => up}
|
||||
import ujson.*
|
||||
import upickle.default as up
|
||||
|
||||
import java.io.File
|
||||
import java.net.InetSocketAddress
|
||||
@ -267,8 +267,19 @@ object ConsoleCli extends BitcoinSLogger {
|
||||
.action((_, conf) => conf.copy(command = GetAccounts))
|
||||
.text("Returns list of all wallet accounts"),
|
||||
cmd("createnewaccount")
|
||||
.action((_, conf) => conf.copy(command = CreateNewAccount))
|
||||
.text("Creates a new wallet account"),
|
||||
.action((_, conf) => conf.copy(command = CreateNewAccount(null)))
|
||||
.text("Creates a new wallet account")
|
||||
.children(
|
||||
arg[String]("hd_purpose")
|
||||
.text("hd_purpose according to BIP43")
|
||||
.required()
|
||||
.action((purpose, conf) =>
|
||||
conf.copy(command = conf.command match {
|
||||
case c: CreateNewAccount =>
|
||||
c.copy(purpose = HDPurpose.fromString(purpose))
|
||||
case other => other
|
||||
}))
|
||||
),
|
||||
cmd("getaddressinfo")
|
||||
.action((_, conf) => conf.copy(command = GetAddressInfo(null)))
|
||||
.text("Returns list of all wallet accounts")
|
||||
@ -2160,8 +2171,8 @@ object CliCommand {
|
||||
RequestParam("getunusedaddresses")
|
||||
case GetAccounts =>
|
||||
RequestParam("getaccounts")
|
||||
case CreateNewAccount =>
|
||||
RequestParam("createnewaccount")
|
||||
case CreateNewAccount(purpose) =>
|
||||
RequestParam("createnewaccount", Seq(up.writeJs(purpose)))
|
||||
case IsEmpty =>
|
||||
RequestParam("isempty")
|
||||
case WalletInfo =>
|
||||
@ -2668,7 +2679,6 @@ object CliCommand {
|
||||
case object GetFundedAddresses extends AppServerCliCommand
|
||||
case object GetUnusedAddresses extends AppServerCliCommand
|
||||
case object GetAccounts extends AppServerCliCommand
|
||||
case object CreateNewAccount extends AppServerCliCommand
|
||||
case object IsEmpty extends AppServerCliCommand
|
||||
case object WalletInfo extends AppServerCliCommand
|
||||
case object ListWallets extends AppServerCliCommand
|
||||
|
@ -647,8 +647,7 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
|
||||
val accountDb =
|
||||
AccountDb(
|
||||
xpub = xpub,
|
||||
hdAccount =
|
||||
HDAccount(HDCoin(HDPurposes.Legacy, HDCoinType.Testnet), 0)
|
||||
hdAccount = HDAccount(HDCoin(HDPurpose.Legacy, HDCoinType.Testnet), 0)
|
||||
)
|
||||
|
||||
(() => mockWalletApi.listAccounts())
|
||||
|
@ -1,13 +1,18 @@
|
||||
package org.bitcoins.server
|
||||
|
||||
import org.apache.pekko.http.scaladsl.model.ContentTypes._
|
||||
import org.apache.pekko.http.scaladsl.model.ContentTypes.*
|
||||
import org.apache.pekko.http.scaladsl.testkit.ScalatestRouteTest
|
||||
import org.bitcoins.commons.serializers.Picklers
|
||||
import org.bitcoins.core.api.chain.ChainApi
|
||||
import org.bitcoins.core.api.wallet.db.AccountDb
|
||||
import org.bitcoins.core.crypto.ExtKeyVersion.SegWitMainNetPriv
|
||||
import org.bitcoins.core.crypto.ExtPrivateKey
|
||||
import org.bitcoins.core.hd.{HDAccount, HDPurpose}
|
||||
import org.bitcoins.core.protocol.BitcoinAddress
|
||||
import org.bitcoins.core.protocol.dlc.models.DLCMessage.{DLCAccept, DLCOffer}
|
||||
import org.bitcoins.core.protocol.dlc.models.DLCStatus
|
||||
import org.bitcoins.core.protocol.tlv.{DLCOfferTLV, LnMessage, LnMessageFactory}
|
||||
import org.bitcoins.core.wallet.fee.{SatoshisPerVirtualByte}
|
||||
import org.bitcoins.core.wallet.fee.SatoshisPerVirtualByte
|
||||
import org.bitcoins.crypto.Sha256Digest
|
||||
import org.bitcoins.feeprovider.ConstantFeeRateProvider
|
||||
import org.bitcoins.node.Node
|
||||
@ -155,6 +160,37 @@ class WalletRoutesSpec
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
"createnewaccount" in {
|
||||
val keyVersion = SegWitMainNetPriv
|
||||
val extPrivKey = ExtPrivateKey.freshRootKey(keyVersion)
|
||||
val extPubKey = extPrivKey.extPublicKey
|
||||
val hdAccount = HDAccount.fromExtKeyVersion(version = keyVersion, idx = 0)
|
||||
val accountDb = AccountDb(extPubKey, hdAccount = hdAccount)
|
||||
(mockWalletApi
|
||||
.createNewAccount(_: HDPurpose))
|
||||
.expects(HDPurpose.default)
|
||||
.returning(Future.successful(mockWalletApi))
|
||||
|
||||
(() => mockWalletApi.listAccounts())
|
||||
.expects()
|
||||
.returning(Future.successful(Vector(accountDb)))
|
||||
|
||||
val cmd = ServerCommand(
|
||||
"createnewaccount",
|
||||
ujson.Arr(
|
||||
upickle.default.writeJs(HDPurpose.default)(Picklers.hdPurpose))
|
||||
)
|
||||
val route = walletRoutes.handleCommand(cmd)
|
||||
|
||||
Get() ~> route ~> check {
|
||||
assert(contentType == `application/json`)
|
||||
val response = responseAs[String]
|
||||
assert(
|
||||
response == s"""{"result":["${extPubKey.toString}"],"error":null}"""
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,12 +5,13 @@ import org.apache.pekko.http.scaladsl.model.HttpEntity
|
||||
import org.apache.pekko.http.scaladsl.server.Directives.complete
|
||||
import org.apache.pekko.http.scaladsl.server.Route
|
||||
import org.apache.pekko.stream.Materializer
|
||||
import org.bitcoins.commons.rpc._
|
||||
import org.bitcoins.commons.serializers.Picklers._
|
||||
import org.bitcoins.commons.rpc.*
|
||||
import org.bitcoins.commons.serializers.Picklers
|
||||
import org.bitcoins.commons.serializers.Picklers.*
|
||||
import org.bitcoins.commons.util.BitcoinSLogger
|
||||
import org.bitcoins.core.api.wallet.db.SpendingInfoDb
|
||||
import org.bitcoins.core.currency._
|
||||
import org.bitcoins.core.protocol.tlv._
|
||||
import org.bitcoins.core.currency.*
|
||||
import org.bitcoins.core.protocol.tlv.*
|
||||
import org.bitcoins.core.protocol.transaction.Transaction
|
||||
import org.bitcoins.core.wallet.fee.{FeeUnit, SatoshisPerVirtualByte}
|
||||
import org.bitcoins.core.wallet.rescan.RescanState
|
||||
@ -21,13 +22,13 @@ import org.bitcoins.core.wallet.utxo.{
|
||||
TxoState
|
||||
}
|
||||
import org.bitcoins.crypto.NetworkElement
|
||||
import org.bitcoins.keymanager._
|
||||
import org.bitcoins.keymanager.*
|
||||
import org.bitcoins.keymanager.config.KeyManagerAppConfig
|
||||
import org.bitcoins.server.routes.{Server, ServerCommand, ServerRoute}
|
||||
import org.bitcoins.wallet.WalletHolder
|
||||
import org.bitcoins.wallet.config.WalletAppConfig
|
||||
import ujson._
|
||||
import upickle.default._
|
||||
import ujson.*
|
||||
import upickle.default.*
|
||||
|
||||
import java.nio.file.{Files, Path}
|
||||
import java.time.Instant
|
||||
@ -861,16 +862,20 @@ case class WalletRoutes(loadWalletApi: DLCWalletLoaderApi)(implicit
|
||||
}
|
||||
}
|
||||
|
||||
case ServerCommand("createnewaccount", _) =>
|
||||
complete {
|
||||
for {
|
||||
newWallet <- wallet.createNewAccount(
|
||||
wallet.keyManager.kmParams.purpose)
|
||||
accounts <- newWallet.listAccounts()
|
||||
} yield {
|
||||
val xpubs = accounts.map(_.xpub)
|
||||
Server.httpSuccess(xpubs)
|
||||
}
|
||||
case ServerCommand("createnewaccount", arr) =>
|
||||
withValidServerCommand(CreateNewAccount.fromJsArr(arr)) {
|
||||
case CreateNewAccount(purpose) =>
|
||||
complete {
|
||||
for {
|
||||
newWallet <- wallet.createNewAccount(purpose)
|
||||
accounts <- newWallet.listAccounts()
|
||||
} yield {
|
||||
val xpubs = accounts.map(_.xpub)
|
||||
val json =
|
||||
xpubs.map(upickle.default.writeJs(_)(Picklers.extPubKeyPickler))
|
||||
Server.httpSuccess(Arr.from(json))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case ServerCommand("keymanagerpassphrasechange", arr) =>
|
||||
|
@ -692,6 +692,7 @@ lazy val testkit = project
|
||||
coreJVM % testAndCompile,
|
||||
appServer,
|
||||
chain,
|
||||
cli,
|
||||
bitcoindRpc,
|
||||
eclairRpc,
|
||||
lndRpc,
|
||||
|
@ -1,7 +1,7 @@
|
||||
package org.bitcoins.core.crypto.bip32
|
||||
|
||||
import org.bitcoins.core.crypto.{ExtKey, ExtPublicKey}
|
||||
import org.bitcoins.core.hd.{BIP32Node, BIP32Path, HardenedType}
|
||||
import org.bitcoins.core.hd.{BIP32Node, BIP32Path, HDPurpose, HardenedType}
|
||||
import org.bitcoins.testkitcore.gen.{
|
||||
CryptoGenerators,
|
||||
HDGenerators,
|
||||
@ -9,7 +9,7 @@ import org.bitcoins.testkitcore.gen.{
|
||||
}
|
||||
import org.bitcoins.testkitcore.util.BitcoinSUnitTest
|
||||
import org.scalacheck.Gen
|
||||
import scodec.bits._
|
||||
import scodec.bits.*
|
||||
|
||||
import scala.util.{Success, Try}
|
||||
|
||||
@ -287,4 +287,12 @@ class BIP32PathTest extends BitcoinSUnitTest {
|
||||
BIP32Path.fromHardenedString(badPath4)
|
||||
}
|
||||
}
|
||||
|
||||
it must "have serialization symmetry for HDPurpose" in {
|
||||
for (p <- HDPurpose.all) {
|
||||
val fromString = HDPurpose.fromString(p.toString)
|
||||
assert(fromString == p)
|
||||
assert(p.toString == fromString.toString)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ class HDPathTest extends BitcoinSUnitTest {
|
||||
|
||||
val firstString = " m / 44' / 0' / 0' / 0 / 0 "
|
||||
val first = LegacyHDPath.fromString(firstString)
|
||||
assert(first.purpose == HDPurposes.Legacy)
|
||||
assert(first.purpose == HDPurpose.Legacy)
|
||||
assert(first.coin.coinType == HDCoinType.Bitcoin)
|
||||
assert(first.account.index == 0)
|
||||
assert(first.chain.chainType == HDChainType.External)
|
||||
@ -207,7 +207,7 @@ class HDPathTest extends BitcoinSUnitTest {
|
||||
|
||||
val secondString = " m / 44' / 0' / 0' / 0 / 1 "
|
||||
val second = LegacyHDPath.fromString(secondString)
|
||||
assert(second.purpose == HDPurposes.Legacy)
|
||||
assert(second.purpose == HDPurpose.Legacy)
|
||||
assert(second.coin.coinType == HDCoinType.Bitcoin)
|
||||
assert(second.account.index == 0)
|
||||
assert(second.chain.chainType == HDChainType.External)
|
||||
@ -216,7 +216,7 @@ class HDPathTest extends BitcoinSUnitTest {
|
||||
|
||||
val thirdString = " m / 44' / 0' / 0' / 1 / 0 "
|
||||
val third = LegacyHDPath.fromString(thirdString)
|
||||
assert(third.purpose == HDPurposes.Legacy)
|
||||
assert(third.purpose == HDPurpose.Legacy)
|
||||
assert(third.coin.coinType == HDCoinType.Bitcoin)
|
||||
assert(third.account.index == 0)
|
||||
assert(third.chain.chainType == HDChainType.Change)
|
||||
@ -225,7 +225,7 @@ class HDPathTest extends BitcoinSUnitTest {
|
||||
|
||||
val fourthString = " m / 44' / 0' / 0' / 1 / 1 "
|
||||
val fourth = LegacyHDPath.fromString(fourthString)
|
||||
assert(fourth.purpose == HDPurposes.Legacy)
|
||||
assert(fourth.purpose == HDPurpose.Legacy)
|
||||
assert(fourth.coin.coinType == HDCoinType.Bitcoin)
|
||||
assert(fourth.account.index == 0)
|
||||
assert(fourth.chain.chainType == HDChainType.Change)
|
||||
@ -234,7 +234,7 @@ class HDPathTest extends BitcoinSUnitTest {
|
||||
|
||||
val fifthString = " m / 44' / 0' / 1' / 0 / 0 "
|
||||
val fifth = LegacyHDPath.fromString(fifthString)
|
||||
assert(fifth.purpose == HDPurposes.Legacy)
|
||||
assert(fifth.purpose == HDPurpose.Legacy)
|
||||
assert(fifth.coin.coinType == HDCoinType.Bitcoin)
|
||||
assert(fifth.account.index == 1)
|
||||
assert(fifth.chain.chainType == HDChainType.External)
|
||||
@ -243,7 +243,7 @@ class HDPathTest extends BitcoinSUnitTest {
|
||||
|
||||
val sixthString = " m / 44' / 0' / 1' / 0 / 1 "
|
||||
val sixth = LegacyHDPath.fromString(sixthString)
|
||||
assert(sixth.purpose == HDPurposes.Legacy)
|
||||
assert(sixth.purpose == HDPurpose.Legacy)
|
||||
assert(sixth.coin.coinType == HDCoinType.Bitcoin)
|
||||
assert(sixth.account.index == 1)
|
||||
assert(sixth.chain.chainType == HDChainType.External)
|
||||
@ -252,7 +252,7 @@ class HDPathTest extends BitcoinSUnitTest {
|
||||
|
||||
val seventhString = " m / 44' / 0' / 1' / 1 / 0 "
|
||||
val seventh = LegacyHDPath.fromString(seventhString)
|
||||
assert(seventh.purpose == HDPurposes.Legacy)
|
||||
assert(seventh.purpose == HDPurpose.Legacy)
|
||||
assert(seventh.coin.coinType == HDCoinType.Bitcoin)
|
||||
assert(seventh.account.index == 1)
|
||||
assert(seventh.chain.chainType == HDChainType.Change)
|
||||
@ -261,7 +261,7 @@ class HDPathTest extends BitcoinSUnitTest {
|
||||
|
||||
val eightString = " m / 44' / 0' / 1' / 1 / 1 "
|
||||
val eigth = LegacyHDPath.fromString(eightString)
|
||||
assert(eigth.purpose == HDPurposes.Legacy)
|
||||
assert(eigth.purpose == HDPurpose.Legacy)
|
||||
assert(eigth.coin.coinType == HDCoinType.Bitcoin)
|
||||
assert(eigth.account.index == 1)
|
||||
assert(eigth.chain.chainType == HDChainType.Change)
|
||||
@ -270,7 +270,7 @@ class HDPathTest extends BitcoinSUnitTest {
|
||||
|
||||
val ninthString = " m / 44' / 1' / 0' / 0 / 1 "
|
||||
val ninth = LegacyHDPath.fromString(ninthString)
|
||||
assert(ninth.purpose == HDPurposes.Legacy)
|
||||
assert(ninth.purpose == HDPurpose.Legacy)
|
||||
assert(ninth.coin.coinType == HDCoinType.Testnet)
|
||||
assert(ninth.account.index == 0)
|
||||
assert(ninth.chain.chainType == HDChainType.External)
|
||||
@ -279,7 +279,7 @@ class HDPathTest extends BitcoinSUnitTest {
|
||||
|
||||
val tenthString = " m / 44' / 1' / 0' / 0 / 1 "
|
||||
val tenth = LegacyHDPath.fromString(tenthString)
|
||||
assert(tenth.purpose == HDPurposes.Legacy)
|
||||
assert(tenth.purpose == HDPurpose.Legacy)
|
||||
assert(tenth.coin.coinType == HDCoinType.Testnet)
|
||||
assert(tenth.account.index == 0)
|
||||
assert(tenth.chain.chainType == HDChainType.External)
|
||||
@ -288,7 +288,7 @@ class HDPathTest extends BitcoinSUnitTest {
|
||||
|
||||
val eleventhString = " m / 44' / 1' / 0' / 1 / 0 "
|
||||
val eleventh = LegacyHDPath.fromString(eleventhString)
|
||||
assert(eleventh.purpose == HDPurposes.Legacy)
|
||||
assert(eleventh.purpose == HDPurpose.Legacy)
|
||||
assert(eleventh.coin.coinType == HDCoinType.Testnet)
|
||||
assert(eleventh.account.index == 0)
|
||||
assert(eleventh.chain.chainType == HDChainType.Change)
|
||||
@ -297,7 +297,7 @@ class HDPathTest extends BitcoinSUnitTest {
|
||||
|
||||
val twelfthString = " m / 44' / 1' / 0' / 1 / 1 "
|
||||
val twelfth = LegacyHDPath.fromString(twelfthString)
|
||||
assert(twelfth.purpose == HDPurposes.Legacy)
|
||||
assert(twelfth.purpose == HDPurpose.Legacy)
|
||||
assert(twelfth.coin.coinType == HDCoinType.Testnet)
|
||||
assert(twelfth.account.index == 0)
|
||||
assert(twelfth.chain.chainType == HDChainType.Change)
|
||||
@ -306,7 +306,7 @@ class HDPathTest extends BitcoinSUnitTest {
|
||||
|
||||
val thirteenthString = " m / 44' / 1' / 1' / 0 / 0 "
|
||||
val thirteenth = LegacyHDPath.fromString(thirteenthString)
|
||||
assert(thirteenth.purpose == HDPurposes.Legacy)
|
||||
assert(thirteenth.purpose == HDPurpose.Legacy)
|
||||
assert(thirteenth.coin.coinType == HDCoinType.Testnet)
|
||||
assert(thirteenth.account.index == 1)
|
||||
assert(thirteenth.chain.chainType == HDChainType.External)
|
||||
@ -315,7 +315,7 @@ class HDPathTest extends BitcoinSUnitTest {
|
||||
|
||||
val fourteenthString = " m / 44' / 1' / 1' / 0 / 1 "
|
||||
val fourteenth = LegacyHDPath.fromString(fourteenthString)
|
||||
assert(fourteenth.purpose == HDPurposes.Legacy)
|
||||
assert(fourteenth.purpose == HDPurpose.Legacy)
|
||||
assert(fourteenth.coin.coinType == HDCoinType.Testnet)
|
||||
assert(fourteenth.account.index == 1)
|
||||
assert(fourteenth.chain.chainType == HDChainType.External)
|
||||
@ -324,7 +324,7 @@ class HDPathTest extends BitcoinSUnitTest {
|
||||
|
||||
val fifteenthString = " m / 44' / 1' / 1' / 1 / 0 "
|
||||
val fifteenth = LegacyHDPath.fromString(fifteenthString)
|
||||
assert(fifteenth.purpose == HDPurposes.Legacy)
|
||||
assert(fifteenth.purpose == HDPurpose.Legacy)
|
||||
assert(fifteenth.coin.coinType == HDCoinType.Testnet)
|
||||
assert(fifteenth.account.index == 1)
|
||||
assert(fifteenth.chain.chainType == HDChainType.Change)
|
||||
@ -333,7 +333,7 @@ class HDPathTest extends BitcoinSUnitTest {
|
||||
|
||||
val sixteenthString = " m / 44' / 1' / 1' / 1 / 1 "
|
||||
val sixteenth = LegacyHDPath.fromString(sixteenthString)
|
||||
assert(sixteenth.purpose == HDPurposes.Legacy)
|
||||
assert(sixteenth.purpose == HDPurpose.Legacy)
|
||||
assert(sixteenth.coin.coinType == HDCoinType.Testnet)
|
||||
assert(sixteenth.account.index == 1)
|
||||
assert(sixteenth.chain.chainType == HDChainType.Change)
|
||||
|
@ -25,7 +25,7 @@ case class AddressRecord(
|
||||
|
||||
def toAddressDb(scriptPubKey: ScriptPubKey): AddressDb = {
|
||||
(purpose, address, scriptWitnessOpt) match {
|
||||
case (HDPurposes.SegWit, bechAddr: Bech32Address, Some(scriptWitness)) =>
|
||||
case (HDPurpose.SegWit, bechAddr: Bech32Address, Some(scriptWitness)) =>
|
||||
val path =
|
||||
SegWitHDPath(coinType = accountCoin,
|
||||
accountIndex = accountIndex,
|
||||
@ -39,7 +39,7 @@ case class AddressRecord(
|
||||
witnessScript = scriptWitness,
|
||||
scriptPubKey = scriptPubKey)
|
||||
|
||||
case (HDPurposes.Legacy, legacyAddr: P2PKHAddress, None) =>
|
||||
case (HDPurpose.Legacy, legacyAddr: P2PKHAddress, None) =>
|
||||
val path = LegacyHDPath(coinType = accountCoin,
|
||||
accountIndex = accountIndex,
|
||||
chainType = accountChain,
|
||||
@ -50,7 +50,7 @@ case class AddressRecord(
|
||||
legacyAddr,
|
||||
scriptPubKey = scriptPubKey)
|
||||
|
||||
case (HDPurposes.NestedSegWit,
|
||||
case (HDPurpose.NestedSegWit,
|
||||
address: P2SHAddress,
|
||||
Some(scriptWitness)) =>
|
||||
val path = NestedSegWitHDPath(coinType = accountCoin,
|
||||
|
@ -1,9 +1,12 @@
|
||||
package org.bitcoins.core.crypto
|
||||
|
||||
import org.bitcoins.core.hd.HDCoinType
|
||||
import org.bitcoins.crypto.{Factory, NetworkElement}
|
||||
import scodec.bits._
|
||||
import scodec.bits.*
|
||||
|
||||
sealed abstract class ExtKeyVersion extends NetworkElement
|
||||
sealed abstract class ExtKeyVersion extends NetworkElement {
|
||||
def hdCoinType: HDCoinType
|
||||
}
|
||||
|
||||
sealed abstract class ExtKeyPrivVersion extends ExtKeyVersion
|
||||
|
||||
@ -43,6 +46,8 @@ object ExtKeyVersion extends Factory[ExtKeyVersion] {
|
||||
*/
|
||||
case object LegacyMainNetPriv extends ExtKeyPrivVersion {
|
||||
override val bytes = hex"0x0488ADE4"
|
||||
|
||||
override def hdCoinType: HDCoinType = HDCoinType.Bitcoin
|
||||
}
|
||||
|
||||
/** Generating a [[org.bitcoins.core.crypto.ExtPrivateKey ExtPrivateKey]] with
|
||||
@ -50,6 +55,7 @@ object ExtKeyVersion extends Factory[ExtKeyVersion] {
|
||||
*/
|
||||
case object LegacyTestNet3Priv extends ExtKeyPrivVersion {
|
||||
override val bytes = hex"0x04358394"
|
||||
override def hdCoinType: HDCoinType = HDCoinType.Testnet
|
||||
}
|
||||
|
||||
/** Generating a [[org.bitcoins.core.crypto.ExtPrivateKey ExtPrivateKey]] with
|
||||
@ -57,6 +63,7 @@ object ExtKeyVersion extends Factory[ExtKeyVersion] {
|
||||
*/
|
||||
case object SegWitMainNetPriv extends ExtKeyPrivVersion {
|
||||
override val bytes = hex"0x04b2430c"
|
||||
override def hdCoinType: HDCoinType = HDCoinType.Bitcoin
|
||||
}
|
||||
|
||||
/** Generating a [[org.bitcoins.core.crypto.ExtPrivateKey ExtPrivateKey]] with
|
||||
@ -64,6 +71,7 @@ object ExtKeyVersion extends Factory[ExtKeyVersion] {
|
||||
*/
|
||||
case object SegWitTestNet3Priv extends ExtKeyPrivVersion {
|
||||
override val bytes = hex"0x045f18bc"
|
||||
override def hdCoinType: HDCoinType = HDCoinType.Testnet
|
||||
}
|
||||
|
||||
/** Generating a [[org.bitcoins.core.crypto.ExtPrivateKey ExtPrivateKey]] with
|
||||
@ -74,6 +82,7 @@ object ExtKeyVersion extends Factory[ExtKeyVersion] {
|
||||
*/
|
||||
case object NestedSegWitMainNetPriv extends ExtKeyPrivVersion {
|
||||
override val bytes = hex"0x049D7878"
|
||||
override def hdCoinType: HDCoinType = HDCoinType.Bitcoin
|
||||
}
|
||||
|
||||
/** Generating a [[org.bitcoins.core.crypto.ExtPrivateKey ExtPrivateKey]] with
|
||||
@ -84,6 +93,7 @@ object ExtKeyVersion extends Factory[ExtKeyVersion] {
|
||||
*/
|
||||
case object NestedSegWitTestNet3Priv extends ExtKeyPrivVersion {
|
||||
override val bytes = hex"0x044a4e28"
|
||||
override def hdCoinType: HDCoinType = HDCoinType.Testnet
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,6 +113,7 @@ object ExtKeyPubVersion extends Factory[ExtKeyPubVersion] {
|
||||
*/
|
||||
case object LegacyMainNetPub extends ExtKeyPubVersion {
|
||||
override val bytes = hex"0x0488b21E"
|
||||
override def hdCoinType: HDCoinType = HDCoinType.Bitcoin
|
||||
}
|
||||
|
||||
/** Generating a [[org.bitcoins.core.crypto.ExtPublicKey ExtPublicKey]] with
|
||||
@ -117,6 +128,7 @@ object ExtKeyPubVersion extends Factory[ExtKeyPubVersion] {
|
||||
// Value stolen from Trezor lib, see link above
|
||||
// ByteVector.fromLong(71979618).toHex = 00000000044a5262
|
||||
override val bytes = hex"0x044a5262"
|
||||
override def hdCoinType: HDCoinType = HDCoinType.Testnet
|
||||
}
|
||||
|
||||
/** Generating a [[org.bitcoins.core.crypto.ExtPublicKey ExtPublicKey]] with
|
||||
@ -127,6 +139,7 @@ object ExtKeyPubVersion extends Factory[ExtKeyPubVersion] {
|
||||
*/
|
||||
case object NestedSegWitMainNetPub extends ExtKeyPubVersion {
|
||||
override val bytes = hex"0x049D7CB2"
|
||||
override def hdCoinType: HDCoinType = HDCoinType.Bitcoin
|
||||
}
|
||||
|
||||
/** Generating a [[org.bitcoins.core.crypto.ExtPublicKey ExtPublicKey]] with
|
||||
@ -134,6 +147,7 @@ object ExtKeyPubVersion extends Factory[ExtKeyPubVersion] {
|
||||
*/
|
||||
case object SegWitTestNet3Pub extends ExtKeyPubVersion {
|
||||
override val bytes = hex"0x045f1cf6"
|
||||
override def hdCoinType: HDCoinType = HDCoinType.Testnet
|
||||
}
|
||||
|
||||
/** Generating a [[org.bitcoins.core.crypto.ExtPublicKey ExtPublicKey]] with
|
||||
@ -141,6 +155,7 @@ object ExtKeyPubVersion extends Factory[ExtKeyPubVersion] {
|
||||
*/
|
||||
case object LegacyTestNet3Pub extends ExtKeyPubVersion {
|
||||
override val bytes = hex"0x043587CF"
|
||||
override def hdCoinType: HDCoinType = HDCoinType.Testnet
|
||||
}
|
||||
|
||||
/** Generating a [[org.bitcoins.core.crypto.ExtPublicKey ExtPublicKey]] with
|
||||
@ -148,6 +163,7 @@ object ExtKeyPubVersion extends Factory[ExtKeyPubVersion] {
|
||||
*/
|
||||
case object SegWitMainNetPub extends ExtKeyPubVersion {
|
||||
override val bytes = hex"0x04b24746"
|
||||
override def hdCoinType: HDCoinType = HDCoinType.Bitcoin
|
||||
}
|
||||
|
||||
override def fromBytes(bytes: ByteVector): ExtKeyPubVersion = {
|
||||
|
@ -201,6 +201,15 @@ case class BIP32Node(index: Int, hardenedOpt: Option[HardenedType]) {
|
||||
else UInt32(index)
|
||||
}
|
||||
|
||||
object BIP32Node extends StringFactory[BIP32Node] {
|
||||
override def fromString(string: String): BIP32Node = {
|
||||
val path = BIP32Path.fromString(string)
|
||||
require(path.length == 1,
|
||||
s"BIP32Node can only have one element in the path, got=$path")
|
||||
BIP32Node(path.head.index, path.head.hardenedOpt)
|
||||
}
|
||||
}
|
||||
|
||||
sealed abstract class HardenedType
|
||||
|
||||
object HardenedType extends StringFactory[HardenedType] {
|
||||
|
@ -1,5 +1,7 @@
|
||||
package org.bitcoins.core.hd
|
||||
|
||||
import org.bitcoins.core.crypto.ExtKeyVersion
|
||||
|
||||
/** Represents a
|
||||
* [[https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#Account BIP44]],
|
||||
* [[https://github.com/bitcoin/bips/blob/master/bip-0084.mediawiki BIP84]] and
|
||||
@ -63,4 +65,9 @@ object HDAccount {
|
||||
def isSameAccount(bip32Path: BIP32Path, account: HDAccount): Boolean = {
|
||||
isSameAccount(bip32Path.toVector, account)
|
||||
}
|
||||
|
||||
def fromExtKeyVersion(version: ExtKeyVersion, idx: Int): HDAccount = {
|
||||
val coin = HDCoin.fromExtKeyVersion(version)
|
||||
HDAccount(coin, idx)
|
||||
}
|
||||
}
|
||||
|
@ -19,9 +19,9 @@ sealed abstract class HDAddress extends BIP32Path {
|
||||
|
||||
def toPath: HDPath =
|
||||
purpose match {
|
||||
case HDPurposes.Legacy => LegacyHDPath(this)
|
||||
case HDPurposes.SegWit => SegWitHDPath(this)
|
||||
case HDPurposes.NestedSegWit => NestedSegWitHDPath(this)
|
||||
case HDPurpose.Legacy => LegacyHDPath(this)
|
||||
case HDPurpose.SegWit => SegWitHDPath(this)
|
||||
case HDPurpose.NestedSegWit => NestedSegWitHDPath(this)
|
||||
case unknown: HDPurpose =>
|
||||
throw new IllegalArgumentException(s"Unknown HD purpose $unknown")
|
||||
}
|
||||
|
@ -1,6 +1,25 @@
|
||||
package org.bitcoins.core.hd
|
||||
|
||||
import org.bitcoins.core.crypto.ExtKeyPubVersion.{
|
||||
LegacyMainNetPub,
|
||||
LegacyTestNet3Pub,
|
||||
NestedSegWitMainNetPub,
|
||||
NestedSegWitTestNet3Pub,
|
||||
SegWitMainNetPub,
|
||||
SegWitTestNet3Pub
|
||||
}
|
||||
import org.bitcoins.core.crypto.ExtKeyVersion
|
||||
import org.bitcoins.core.crypto.ExtKeyVersion.{
|
||||
LegacyMainNetPriv,
|
||||
LegacyTestNet3Priv,
|
||||
NestedSegWitMainNetPriv,
|
||||
NestedSegWitTestNet3Priv,
|
||||
SegWitMainNetPriv,
|
||||
SegWitTestNet3Priv
|
||||
}
|
||||
|
||||
/** Contains the path m / purpose' / coin_type' /
|
||||
*
|
||||
* @see
|
||||
* https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#path-levels
|
||||
*/
|
||||
@ -16,7 +35,7 @@ object HDCoin {
|
||||
|
||||
def fromPath(path: BIP32Path): Option[HDCoin] = {
|
||||
if (path.path.length == 2) {
|
||||
HDPurposes.fromNode(path.path.head).map { purpose =>
|
||||
HDPurpose.fromNode(path.path.head).map { purpose =>
|
||||
val coinType = HDCoinType.fromInt(path.path.last.index)
|
||||
|
||||
HDCoin(purpose, coinType)
|
||||
@ -25,4 +44,18 @@ object HDCoin {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
def fromExtKeyVersion(version: ExtKeyVersion): HDCoin = {
|
||||
version match {
|
||||
case SegWitMainNetPriv | SegWitMainNetPub | SegWitTestNet3Priv |
|
||||
SegWitTestNet3Pub =>
|
||||
HDCoin(HDPurpose.SegWit, version.hdCoinType)
|
||||
case NestedSegWitMainNetPriv | NestedSegWitMainNetPub |
|
||||
NestedSegWitTestNet3Priv | NestedSegWitTestNet3Pub =>
|
||||
HDCoin(HDPurpose.NestedSegWit, version.hdCoinType)
|
||||
case LegacyMainNetPriv | LegacyMainNetPub | LegacyTestNet3Priv |
|
||||
LegacyTestNet3Pub =>
|
||||
HDCoin(HDPurpose.Legacy, version.hdCoinType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,12 +44,12 @@ private[hd] trait HDPathFactory[PathType <: BIP32Path]
|
||||
case BIP32Node(_, None) =>
|
||||
throw new IllegalArgumentException(
|
||||
"The first child in a HD path must be hardened")
|
||||
case BIP32Node(HDPurposes.Legacy.constant, Some(_)) => HDPurposes.Legacy
|
||||
case BIP32Node(HDPurposes.SegWit.constant, Some(_)) => HDPurposes.SegWit
|
||||
case BIP32Node(HDPurposes.NestedSegWit.constant, Some(_)) =>
|
||||
HDPurposes.NestedSegWit
|
||||
case BIP32Node(HDPurposes.Multisig.constant, Some(_)) =>
|
||||
HDPurposes.Multisig
|
||||
case BIP32Node(HDPurpose.Legacy.constant, Some(_)) => HDPurpose.Legacy
|
||||
case BIP32Node(HDPurpose.SegWit.constant, Some(_)) => HDPurpose.SegWit
|
||||
case BIP32Node(HDPurpose.NestedSegWit.constant, Some(_)) =>
|
||||
HDPurpose.NestedSegWit
|
||||
case BIP32Node(HDPurpose.Multisig.constant, Some(_)) =>
|
||||
HDPurpose.Multisig
|
||||
case BIP32Node(unknown, Some(_)) =>
|
||||
throw new IllegalArgumentException(
|
||||
s"Purpose constant ($unknown) is not a known purpose constant")
|
||||
@ -103,7 +103,7 @@ private[hd] trait HDPathFactory[PathType <: BIP32Path]
|
||||
def PURPOSE: Int
|
||||
|
||||
protected lazy val hdPurpose: HDPurpose =
|
||||
HDPurposes.fromConstant(PURPOSE).get // todo
|
||||
HDPurpose.fromConstant(PURPOSE).get // todo
|
||||
|
||||
lazy val purposeChild: BIP32Node = BIP32Node(PURPOSE, HardenedType.defaultOpt)
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package org.bitcoins.core.hd
|
||||
|
||||
import org.bitcoins.crypto.StringFactory
|
||||
|
||||
/** This is a field that is used in conjunction with BIP44 to indicate what the
|
||||
* purpose of this [[org.bitcoins.core.crypto.ExtKey ExtKey]] is.
|
||||
*
|
||||
@ -25,12 +27,14 @@ case class HDPurpose(constant: Int) extends BIP32Path {
|
||||
BIP32Node(constant, HardenedType.defaultOpt))
|
||||
}
|
||||
|
||||
object HDPurposes {
|
||||
object HDPurpose extends StringFactory[HDPurpose] {
|
||||
final val Legacy = HDPurpose(LegacyHDPath.PURPOSE)
|
||||
final val Multisig = HDPurpose(MultisigHDPath.PURPOSE)
|
||||
final val SegWit = HDPurpose(SegWitHDPath.PURPOSE)
|
||||
final val NestedSegWit = HDPurpose(NestedSegWitHDPath.PURPOSE)
|
||||
|
||||
final val default: HDPurpose = SegWit
|
||||
|
||||
lazy val singleSigPurposes = Vector(Legacy, SegWit, NestedSegWit)
|
||||
|
||||
lazy val all: Vector[HDPurpose] =
|
||||
@ -44,4 +48,11 @@ object HDPurposes {
|
||||
s"Cannot construct HDPurpose from un-hardened node: $node")
|
||||
fromConstant(node.index)
|
||||
}
|
||||
|
||||
override def fromString(string: String): HDPurpose = {
|
||||
val node = BIP32Node.fromString(string)
|
||||
fromNode(node).getOrElse {
|
||||
sys.error(s"Cannot create HDPurpose from string=$string")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ object HDUtil {
|
||||
hdPurpose: HDPurpose,
|
||||
network: NetworkParameters): ExtKeyPrivVersion = {
|
||||
import org.bitcoins.core.crypto.ExtKeyVersion._
|
||||
import org.bitcoins.core.hd.HDPurposes._
|
||||
import org.bitcoins.core.hd.HDPurpose._
|
||||
|
||||
(hdPurpose, network) match {
|
||||
case (SegWit, MainNet) => SegWitMainNetPriv
|
||||
@ -35,7 +35,7 @@ object HDUtil {
|
||||
def getXpubVersion(
|
||||
hdPurpose: HDPurpose,
|
||||
network: NetworkParameters): ExtKeyPubVersion = {
|
||||
import org.bitcoins.core.hd.HDPurposes._
|
||||
import org.bitcoins.core.hd.HDPurpose._
|
||||
|
||||
(hdPurpose, network) match {
|
||||
case (SegWit, MainNet | SigNet) => ExtKeyPubVersion.SegWitMainNetPub
|
||||
|
@ -248,8 +248,7 @@ class DbCommonsColumnMappers(val profile: JdbcProfile) {
|
||||
MappedColumnType
|
||||
.base[HDPurpose, Int](
|
||||
_.constant,
|
||||
purpose =>
|
||||
HDPurposes.fromConstant(purpose).getOrElse(HDPurpose(purpose))
|
||||
purpose => HDPurpose.fromConstant(purpose).getOrElse(HDPurpose(purpose))
|
||||
)
|
||||
|
||||
implicit val bitcoinAddressMapper: BaseColumnType[BitcoinAddress] =
|
||||
|
@ -71,7 +71,7 @@ case class DLCOracle()(implicit val conf: DLCOracleAppConfig)
|
||||
def getRootXpub: ExtPublicKey = extPrivateKey.extPublicKey
|
||||
|
||||
private def signingKey: ECPrivateKey = {
|
||||
val coin = HDCoin(HDPurposes.SegWit, coinType)
|
||||
val coin = HDCoin(HDPurpose.SegWit, coinType)
|
||||
val account = HDAccount(coin, 0)
|
||||
val purpose = coin.purpose
|
||||
val chain = HDChainType.External
|
||||
|
@ -185,7 +185,7 @@ the `-p 9999:9999` port mapping on the docker container to adjust for this.
|
||||
- `getunusedaddresses` - Returns list of all wallet addresses that have not been used
|
||||
- `getaccounts` - Returns list of all wallet accounts
|
||||
- `walletinfo` - Returns meta information about the wallet
|
||||
- `createnewaccount` - Creates a new wallet account
|
||||
- `createnewaccount` `purpose` - Creates a new wallet account with the given HD purpose from [BIP43](https://github.com/bitcoin/bips/blob/master/bip-0043.mediawiki)
|
||||
- `getaddressinfo` `address` - Returns list of all wallet accounts
|
||||
- `address` - Address to get information about
|
||||
- `getnewaddress` - Get a new address
|
||||
|
@ -79,7 +79,7 @@ import java.nio.file._
|
||||
val seedPath = Files.createTempDirectory("key-manager-example").resolve(WalletStorage.ENCRYPTED_SEED_FILE_NAME)
|
||||
|
||||
//let's create a native segwit key manager
|
||||
val purpose = HDPurposes.SegWit
|
||||
val purpose = HDPurpose.SegWit
|
||||
|
||||
//let's choose regtest as our network
|
||||
val network = RegTest
|
||||
@ -107,7 +107,7 @@ again after initializing it once. You can use the same `mnemonic` for different
|
||||
```scala mdoc:to-string
|
||||
|
||||
//let's create a nested segwit key manager for mainnet
|
||||
val mainnetKmParams = KeyManagerParams(seedPath, HDPurposes.SegWit, MainNet)
|
||||
val mainnetKmParams = KeyManagerParams(seedPath, HDPurpose.SegWit, MainNet)
|
||||
|
||||
//we do not need to all `initializeWithMnemonic()` again as we have saved the seed to dis
|
||||
val mainnetKeyManager = BIP39KeyManager.fromMnemonic(mnemonic, mainnetKmParams, None, Instant.now, false)
|
||||
|
@ -23,7 +23,7 @@ import scodec.bits.BitVector
|
||||
import java.nio.file.Files
|
||||
|
||||
class BIP39KeyManagerApiTest extends KeyManagerApiUnitTest {
|
||||
val purpose = HDPurposes.Legacy
|
||||
val purpose = HDPurpose.Legacy
|
||||
|
||||
// this is taken from 'trezor-addresses.json' which give us test cases that conform with trezor
|
||||
val mnemonicStr =
|
||||
@ -339,7 +339,7 @@ class BIP39KeyManagerApiTest extends KeyManagerApiUnitTest {
|
||||
val seedPath = KeyManagerTestUtil.tmpSeedPath
|
||||
val aesPasswordOpt = KeyManagerTestUtil.aesPasswordOpt
|
||||
val kmParams =
|
||||
keymanagement.KeyManagerParams(seedPath, HDPurposes.SegWit, RegTest)
|
||||
keymanagement.KeyManagerParams(seedPath, HDPurpose.SegWit, RegTest)
|
||||
val entropy = MnemonicCode.getEntropy256Bits
|
||||
val passwordOpt = Some(KeyManagerTestUtil.bip39Password)
|
||||
val keyManager = withInitializedKeyManager(
|
||||
@ -376,7 +376,7 @@ class BIP39KeyManagerApiTest extends KeyManagerApiUnitTest {
|
||||
val seedPath = KeyManagerTestUtil.tmpSeedPath
|
||||
val aesPasswordOpt = KeyManagerTestUtil.aesPasswordOpt
|
||||
val kmParams =
|
||||
keymanagement.KeyManagerParams(seedPath, HDPurposes.SegWit, RegTest)
|
||||
keymanagement.KeyManagerParams(seedPath, HDPurpose.SegWit, RegTest)
|
||||
val entropy = MnemonicCode.getEntropy256Bits
|
||||
val passwordOpt = Some(KeyManagerTestUtil.bip39Password)
|
||||
val keyManager = withInitializedKeyManager(
|
||||
|
@ -17,7 +17,7 @@ import org.bitcoins.core.crypto.ExtKeyVersion.{
|
||||
SegWitMainNetPriv,
|
||||
SegWitTestNet3Priv
|
||||
}
|
||||
import org.bitcoins.core.hd.{HDCoinType, HDPurpose, HDPurposes}
|
||||
import org.bitcoins.core.hd.{HDCoinType, HDPurpose}
|
||||
import org.bitcoins.core.util.HDUtil
|
||||
import org.bitcoins.testkit.keymanager.KeyManagerApiUnitTest
|
||||
|
||||
@ -25,26 +25,26 @@ class HdUtilTest extends KeyManagerApiUnitTest {
|
||||
|
||||
it must "get the correct version for a public key" in {
|
||||
assert(
|
||||
HDUtil.getXpubVersion(HDPurposes.Legacy, MainNet) == LegacyMainNetPub
|
||||
HDUtil.getXpubVersion(HDPurpose.Legacy, MainNet) == LegacyMainNetPub
|
||||
)
|
||||
assert(
|
||||
HDUtil.getXpubVersion(HDPurposes.Legacy, TestNet3) == LegacyTestNet3Pub
|
||||
HDUtil.getXpubVersion(HDPurpose.Legacy, TestNet3) == LegacyTestNet3Pub
|
||||
)
|
||||
assert(
|
||||
HDUtil.getXpubVersion(HDPurposes.SegWit, MainNet) == SegWitMainNetPub
|
||||
HDUtil.getXpubVersion(HDPurpose.SegWit, MainNet) == SegWitMainNetPub
|
||||
)
|
||||
assert(
|
||||
HDUtil.getXpubVersion(HDPurposes.SegWit, TestNet3) == SegWitTestNet3Pub
|
||||
HDUtil.getXpubVersion(HDPurpose.SegWit, TestNet3) == SegWitTestNet3Pub
|
||||
)
|
||||
assert(
|
||||
HDUtil.getXpubVersion(
|
||||
HDPurposes.NestedSegWit,
|
||||
HDPurpose.NestedSegWit,
|
||||
MainNet
|
||||
) == NestedSegWitMainNetPub
|
||||
)
|
||||
assert(
|
||||
HDUtil.getXpubVersion(
|
||||
HDPurposes.NestedSegWit,
|
||||
HDPurpose.NestedSegWit,
|
||||
TestNet3
|
||||
) == NestedSegWitTestNet3Pub
|
||||
)
|
||||
@ -56,26 +56,26 @@ class HdUtilTest extends KeyManagerApiUnitTest {
|
||||
|
||||
it must "get the correct version for a private key" in {
|
||||
assert(
|
||||
HDUtil.getXprivVersion(HDPurposes.Legacy, MainNet) == LegacyMainNetPriv
|
||||
HDUtil.getXprivVersion(HDPurpose.Legacy, MainNet) == LegacyMainNetPriv
|
||||
)
|
||||
assert(
|
||||
HDUtil.getXprivVersion(HDPurposes.Legacy, TestNet3) == LegacyTestNet3Priv
|
||||
HDUtil.getXprivVersion(HDPurpose.Legacy, TestNet3) == LegacyTestNet3Priv
|
||||
)
|
||||
assert(
|
||||
HDUtil.getXprivVersion(HDPurposes.SegWit, MainNet) == SegWitMainNetPriv
|
||||
HDUtil.getXprivVersion(HDPurpose.SegWit, MainNet) == SegWitMainNetPriv
|
||||
)
|
||||
assert(
|
||||
HDUtil.getXprivVersion(HDPurposes.SegWit, TestNet3) == SegWitTestNet3Priv
|
||||
HDUtil.getXprivVersion(HDPurpose.SegWit, TestNet3) == SegWitTestNet3Priv
|
||||
)
|
||||
assert(
|
||||
HDUtil.getXprivVersion(
|
||||
HDPurposes.NestedSegWit,
|
||||
HDPurpose.NestedSegWit,
|
||||
MainNet
|
||||
) == NestedSegWitMainNetPriv
|
||||
)
|
||||
assert(
|
||||
HDUtil.getXprivVersion(
|
||||
HDPurposes.NestedSegWit,
|
||||
HDPurpose.NestedSegWit,
|
||||
TestNet3
|
||||
) == NestedSegWitTestNet3Priv
|
||||
)
|
||||
|
@ -6,7 +6,7 @@ import org.bitcoins.commons.util.WalletNames
|
||||
import org.bitcoins.core.api.commons.ArgumentSource
|
||||
import org.bitcoins.core.config.NetworkParameters
|
||||
import org.bitcoins.core.crypto.MnemonicCode
|
||||
import org.bitcoins.core.hd.{HDPurpose, HDPurposes}
|
||||
import org.bitcoins.core.hd.HDPurpose
|
||||
import org.bitcoins.core.wallet.keymanagement.KeyManagerParams
|
||||
import org.bitcoins.crypto.{AesPassword, CryptoUtil}
|
||||
import org.bitcoins.keymanager.bip39.BIP39KeyManager
|
||||
@ -70,9 +70,9 @@ case class KeyManagerAppConfig(
|
||||
|
||||
private lazy val defaultAccountKind: HDPurpose =
|
||||
config.getString("bitcoin-s.wallet.defaultAccountType") match {
|
||||
case "legacy" => HDPurposes.Legacy
|
||||
case "segwit" => HDPurposes.SegWit
|
||||
case "nested-segwit" => HDPurposes.NestedSegWit
|
||||
case "legacy" => HDPurpose.Legacy
|
||||
case "segwit" => HDPurpose.SegWit
|
||||
case "nested-segwit" => HDPurpose.NestedSegWit
|
||||
// todo: validate this pre-app startup
|
||||
case other: String =>
|
||||
throw new RuntimeException(s"$other is not a valid account type!")
|
||||
|
@ -63,7 +63,7 @@ object HDGenerators {
|
||||
|
||||
/** Generates a valid HD purpose path */
|
||||
def hdPurpose: Gen[HDPurpose] =
|
||||
Gen.oneOf(HDPurposes.Legacy, HDPurposes.NestedSegWit, HDPurposes.SegWit)
|
||||
Gen.oneOf(HDPurpose.Legacy, HDPurpose.NestedSegWit, HDPurpose.SegWit)
|
||||
|
||||
def hdCoin: Gen[HDCoin] =
|
||||
for {
|
||||
@ -92,7 +92,7 @@ object HDGenerators {
|
||||
def legacyHdPath: Gen[LegacyHDPath] =
|
||||
for {
|
||||
coinType <- hdCoinType
|
||||
purpose = HDPurposes.Legacy
|
||||
purpose = HDPurpose.Legacy
|
||||
accountIndex <- NumberGenerator.positiveInts
|
||||
addressIndex <- NumberGenerator.positiveInts
|
||||
chainType <- hdChainType
|
||||
|
@ -7,7 +7,7 @@ import org.bitcoins.core.hd.{
|
||||
HDChainType,
|
||||
HDCoin,
|
||||
HDCoinType,
|
||||
HDPurposes,
|
||||
HDPurpose,
|
||||
LegacyHDPath,
|
||||
NestedSegWitHDPath,
|
||||
SegWitHDPath
|
||||
@ -73,5 +73,5 @@ object WalletTestUtil {
|
||||
)
|
||||
|
||||
val defaultHdAccount: HDAccount =
|
||||
HDAccount(HDCoin(HDPurposes.SegWit, hdCoinType), 0)
|
||||
HDAccount(HDCoin(HDPurpose.SegWit, hdCoinType), 0)
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package org.bitcoins.testkit.keymanager
|
||||
import java.nio.file.Path
|
||||
|
||||
import org.bitcoins.core.config.Networks
|
||||
import org.bitcoins.core.hd.HDPurposes
|
||||
import org.bitcoins.core.hd.HDPurpose
|
||||
import org.bitcoins.core.wallet.keymanagement.KeyManagerParams
|
||||
import org.bitcoins.crypto.AesPassword
|
||||
import org.bitcoins.keymanager.WalletStorage
|
||||
@ -27,7 +27,7 @@ object KeyManagerTestUtil {
|
||||
val seedPath = KeyManagerTestUtil.tmpSeedPath
|
||||
KeyManagerParams(
|
||||
seedPath = seedPath,
|
||||
purpose = Gen.oneOf(HDPurposes.all).sample.get,
|
||||
purpose = Gen.oneOf(HDPurpose.all).sample.get,
|
||||
network = Gen.oneOf(Networks.knownNetworks).sample.get
|
||||
)
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ object WalletTestUtil {
|
||||
}
|
||||
|
||||
val defaultHdAccount: HDAccount =
|
||||
HDAccount(HDCoin(HDPurposes.SegWit, hdCoinType), 0)
|
||||
HDAccount(HDCoin(HDPurpose.SegWit, hdCoinType), 0)
|
||||
|
||||
def getHdAccount1(walletAppConfig: WalletAppConfig): HDAccount = {
|
||||
val purpose = walletAppConfig.defaultAccountKind
|
||||
@ -117,7 +117,7 @@ object WalletTestUtil {
|
||||
def nestedSegWitAccountDb: AccountDb =
|
||||
AccountDb(
|
||||
freshXpub(),
|
||||
HDAccount(HDCoin(HDPurposes.NestedSegWit, hdCoinType), 0)
|
||||
HDAccount(HDCoin(HDPurpose.NestedSegWit, hdCoinType), 0)
|
||||
)
|
||||
|
||||
private def randomScriptWitness: ScriptWitness =
|
||||
|
@ -1,6 +1,6 @@
|
||||
package org.bitcoins.wallet
|
||||
|
||||
import org.bitcoins.core.hd.{AddressType, HDPurposes}
|
||||
import org.bitcoins.core.hd.{AddressType, HDPurpose}
|
||||
import org.bitcoins.core.protocol.{Bech32Address, P2PKHAddress, P2SHAddress}
|
||||
import org.bitcoins.testkit.wallet.BitcoinSWalletTest
|
||||
import org.scalatest.FutureOutcome
|
||||
@ -20,7 +20,7 @@ class LegacyWalletTest extends BitcoinSWalletTest {
|
||||
thirdAddr <- wallet.getNewAddress(AddressType.Legacy)
|
||||
allAddrs <- wallet.listAddresses()
|
||||
} yield {
|
||||
assert(account.hdAccount.purpose == HDPurposes.Legacy)
|
||||
assert(account.hdAccount.purpose == HDPurpose.Legacy)
|
||||
assert(allAddrs.forall(_.address.isInstanceOf[P2PKHAddress]))
|
||||
assert(allAddrs.length == 3)
|
||||
assert(allAddrs.exists(_.address == addr))
|
||||
@ -34,7 +34,7 @@ class LegacyWalletTest extends BitcoinSWalletTest {
|
||||
account <- wallet.getDefaultAccountForType(AddressType.SegWit)
|
||||
addr <- wallet.getNewAddress(AddressType.SegWit)
|
||||
} yield {
|
||||
assert(account.hdAccount.purpose == HDPurposes.SegWit)
|
||||
assert(account.hdAccount.purpose == HDPurpose.SegWit)
|
||||
assert(addr.isInstanceOf[Bech32Address])
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package org.bitcoins.wallet
|
||||
|
||||
import org.bitcoins.core.hd.{AddressType, HDPurposes}
|
||||
import org.bitcoins.core.hd.{AddressType, HDPurpose}
|
||||
import org.bitcoins.core.protocol.{Bech32Address, P2PKHAddress, P2SHAddress}
|
||||
import org.bitcoins.testkit.wallet.BitcoinSWalletTest
|
||||
import org.scalatest.FutureOutcome
|
||||
@ -21,7 +21,7 @@ class SegwitWalletTest extends BitcoinSWalletTest {
|
||||
thirdAddr <- wallet.getNewAddress(AddressType.SegWit)
|
||||
allAddrs <- wallet.listAddresses()
|
||||
} yield {
|
||||
assert(account.hdAccount.purpose == HDPurposes.SegWit)
|
||||
assert(account.hdAccount.purpose == HDPurpose.SegWit)
|
||||
assert(allAddrs.forall(_.address.isInstanceOf[Bech32Address]))
|
||||
assert(allAddrs.length == 3)
|
||||
assert(allAddrs.exists(_.address == addr))
|
||||
@ -35,7 +35,7 @@ class SegwitWalletTest extends BitcoinSWalletTest {
|
||||
account <- wallet.getDefaultAccountForType(AddressType.Legacy)
|
||||
addr <- wallet.getNewAddress(AddressType.Legacy)
|
||||
} yield {
|
||||
assert(account.hdAccount.purpose == HDPurposes.Legacy)
|
||||
assert(account.hdAccount.purpose == HDPurpose.Legacy)
|
||||
assert(addr.isInstanceOf[P2PKHAddress])
|
||||
}
|
||||
}
|
||||
|
@ -78,9 +78,9 @@ class TrezorAddressTest extends BitcoinSWalletTest with EmptyFixture {
|
||||
|
||||
override def reads(json: JsValue): JsResult[HDPurpose] =
|
||||
json.validate[String].map {
|
||||
case "legacy" => HDPurposes.Legacy
|
||||
case "segwit" => HDPurposes.SegWit
|
||||
case "p2sh-segwit" => HDPurposes.NestedSegWit
|
||||
case "legacy" => HDPurpose.Legacy
|
||||
case "segwit" => HDPurpose.SegWit
|
||||
case "p2sh-segwit" => HDPurpose.NestedSegWit
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,20 +122,20 @@ class TrezorAddressTest extends BitcoinSWalletTest with EmptyFixture {
|
||||
}
|
||||
|
||||
lazy val legacyVectors =
|
||||
vectors.filter(_.pathType == HDPurposes.Legacy)
|
||||
vectors.filter(_.pathType == HDPurpose.Legacy)
|
||||
|
||||
lazy val segwitVectors =
|
||||
vectors.filter(_.pathType == HDPurposes.SegWit)
|
||||
vectors.filter(_.pathType == HDPurpose.SegWit)
|
||||
|
||||
lazy val nestedVectors =
|
||||
vectors.filter(_.pathType == HDPurposes.NestedSegWit)
|
||||
vectors.filter(_.pathType == HDPurpose.NestedSegWit)
|
||||
|
||||
def configForPurposeAndSeed(purpose: HDPurpose): Config = {
|
||||
val purposeStr = purpose match {
|
||||
case HDPurposes.Legacy => "legacy"
|
||||
case HDPurposes.SegWit => "segwit"
|
||||
case HDPurposes.NestedSegWit => "nested-segwit"
|
||||
case other => fail(s"unexpected purpose: $other")
|
||||
case HDPurpose.Legacy => "legacy"
|
||||
case HDPurpose.SegWit => "segwit"
|
||||
case HDPurpose.NestedSegWit => "nested-segwit"
|
||||
case other => fail(s"unexpected purpose: $other")
|
||||
}
|
||||
val entropy = mnemonic.toEntropy.toHex
|
||||
val confStr = s"""bitcoin-s.wallet.defaultAccountType = $purposeStr
|
||||
@ -236,10 +236,10 @@ class TrezorAddressTest extends BitcoinSWalletTest with EmptyFixture {
|
||||
.walletConf
|
||||
|
||||
val testVectors = purpose match {
|
||||
case HDPurposes.Legacy => legacyVectors
|
||||
case HDPurposes.SegWit => segwitVectors
|
||||
case HDPurposes.NestedSegWit => nestedVectors
|
||||
case other => fail(s"unknown purpose: $other")
|
||||
case HDPurpose.Legacy => legacyVectors
|
||||
case HDPurpose.SegWit => segwitVectors
|
||||
case HDPurpose.NestedSegWit => nestedVectors
|
||||
case other => fail(s"unknown purpose: $other")
|
||||
}
|
||||
|
||||
val assertionsF: Future[Seq[Assertion]] = for {
|
||||
@ -306,14 +306,14 @@ class TrezorAddressTest extends BitcoinSWalletTest with EmptyFixture {
|
||||
}
|
||||
|
||||
it must "act the same way as Trezor for legacy accounts" in { _ =>
|
||||
testAccountType(HDPurposes.Legacy)
|
||||
testAccountType(HDPurpose.Legacy)
|
||||
}
|
||||
|
||||
it must "act the same way as Trezor for segwit accounts" in { _ =>
|
||||
testAccountType(HDPurposes.SegWit)
|
||||
testAccountType(HDPurpose.SegWit)
|
||||
}
|
||||
|
||||
it must "act the same way as Trezor for nested segwit accounts" in { _ =>
|
||||
testAccountType(HDPurposes.NestedSegWit)
|
||||
testAccountType(HDPurpose.NestedSegWit)
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import java.nio.file.Files
|
||||
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import org.bitcoins.core.config.{MainNet, RegTest, TestNet3}
|
||||
import org.bitcoins.core.hd.HDPurposes
|
||||
import org.bitcoins.core.hd.HDPurpose
|
||||
import org.bitcoins.testkit.util.BitcoinSAsyncTest
|
||||
import org.bitcoins.wallet.config.WalletAppConfig
|
||||
|
||||
@ -61,8 +61,8 @@ class WalletAppConfigTest extends BitcoinSAsyncTest {
|
||||
|
||||
val twiceOverriden = overriden.withOverrides(thirdConf)
|
||||
|
||||
assert(overriden.defaultAccountKind == HDPurposes.SegWit)
|
||||
assert(twiceOverriden.defaultAccountKind == HDPurposes.NestedSegWit)
|
||||
assert(overriden.defaultAccountKind == HDPurpose.SegWit)
|
||||
assert(twiceOverriden.defaultAccountKind == HDPurpose.NestedSegWit)
|
||||
|
||||
assert(config.datadir == overriden.datadir)
|
||||
assert(twiceOverriden.datadir == overriden.datadir)
|
||||
|
@ -29,7 +29,7 @@ object GetAddresses extends App {
|
||||
def printerr(x: Any): Unit = System.err.println(x.toString())
|
||||
|
||||
val accountInfo = for {
|
||||
constant <- HDPurposes.singleSigPurposes
|
||||
constant <- HDPurpose.singleSigPurposes
|
||||
coin <- List(HDCoinType.Bitcoin /*, HDCoinType.Testnet*/ )
|
||||
accountIndex <- 0 until 3
|
||||
} yield {
|
||||
@ -41,17 +41,17 @@ object GetAddresses extends App {
|
||||
|
||||
val pathType =
|
||||
constant match {
|
||||
case HDPurposes.Legacy => "legacy"
|
||||
case HDPurposes.NestedSegWit => "p2sh-segwit"
|
||||
case HDPurposes.SegWit => "segwit"
|
||||
case HDPurpose.Legacy => "legacy"
|
||||
case HDPurpose.NestedSegWit => "p2sh-segwit"
|
||||
case HDPurpose.SegWit => "segwit"
|
||||
case other => throw new RuntimeException(s"Unexpected purpose $other")
|
||||
}
|
||||
|
||||
val trezorPathType =
|
||||
constant match {
|
||||
case HDPurposes.Legacy => "address"
|
||||
case HDPurposes.NestedSegWit => "p2shsegwit"
|
||||
case HDPurposes.SegWit => "segwit"
|
||||
case HDPurpose.Legacy => "address"
|
||||
case HDPurpose.NestedSegWit => "p2shsegwit"
|
||||
case HDPurpose.SegWit => "segwit"
|
||||
case other => throw new RuntimeException(s"Unexpected purpose $other")
|
||||
}
|
||||
|
||||
|
@ -1143,7 +1143,7 @@ object Wallet extends WalletLogger {
|
||||
val createAccountActions: Vector[
|
||||
DBIOAction[AccountDb, NoStream, Effect.Read with Effect.Write]
|
||||
] = {
|
||||
val accounts = HDPurposes.singleSigPurposes.map { purpose =>
|
||||
val accounts = HDPurpose.singleSigPurposes.map { purpose =>
|
||||
// we need to create key manager params for each purpose
|
||||
// and then initialize a key manager to derive the correct xpub
|
||||
val kmParams = wallet.keyManager.kmParams.copy(purpose = purpose)
|
||||
|
@ -98,9 +98,9 @@ case class WalletAppConfig(
|
||||
|
||||
lazy val defaultAccountKind: HDPurpose =
|
||||
config.getString("bitcoin-s.wallet.defaultAccountType") match {
|
||||
case "legacy" => HDPurposes.Legacy
|
||||
case "segwit" => HDPurposes.SegWit
|
||||
case "nested-segwit" => HDPurposes.NestedSegWit
|
||||
case "legacy" => HDPurpose.Legacy
|
||||
case "segwit" => HDPurpose.SegWit
|
||||
case "nested-segwit" => HDPurpose.NestedSegWit
|
||||
// todo: validate this pre-app startup
|
||||
case other: String =>
|
||||
throw new RuntimeException(s"$other is not a valid account type!")
|
||||
@ -108,9 +108,9 @@ case class WalletAppConfig(
|
||||
|
||||
lazy val defaultAddressType: AddressType = {
|
||||
defaultAccountKind match {
|
||||
case HDPurposes.Legacy => AddressType.Legacy
|
||||
case HDPurposes.NestedSegWit => AddressType.NestedSegWit
|
||||
case HDPurposes.SegWit => AddressType.SegWit
|
||||
case HDPurpose.Legacy => AddressType.Legacy
|
||||
case HDPurpose.NestedSegWit => AddressType.NestedSegWit
|
||||
case HDPurpose.SegWit => AddressType.SegWit
|
||||
// todo: validate this pre-app startup
|
||||
case other =>
|
||||
throw new RuntimeException(s"$other is not a valid account type!")
|
||||
|
@ -51,9 +51,9 @@ private[wallet] trait AccountHandling { self: Wallet =>
|
||||
addressType: AddressType
|
||||
): Future[AccountDb] = {
|
||||
val hdCoin = addressType match {
|
||||
case Legacy => HDCoin(HDPurposes.Legacy, DEFAULT_HD_COIN_TYPE)
|
||||
case NestedSegWit => HDCoin(HDPurposes.NestedSegWit, DEFAULT_HD_COIN_TYPE)
|
||||
case SegWit => HDCoin(HDPurposes.SegWit, DEFAULT_HD_COIN_TYPE)
|
||||
case Legacy => HDCoin(HDPurpose.Legacy, DEFAULT_HD_COIN_TYPE)
|
||||
case NestedSegWit => HDCoin(HDPurpose.NestedSegWit, DEFAULT_HD_COIN_TYPE)
|
||||
case SegWit => HDCoin(HDPurpose.SegWit, DEFAULT_HD_COIN_TYPE)
|
||||
case P2TR =>
|
||||
throw new UnsupportedOperationException(
|
||||
s"Taproot not supported in wallet")
|
||||
|
@ -368,11 +368,11 @@ private[wallet] trait AddressHandling extends WalletLogger {
|
||||
val accountIndex = account.hdAccount.index
|
||||
|
||||
val path = account.hdAccount.purpose match {
|
||||
case HDPurposes.Legacy =>
|
||||
case HDPurpose.Legacy =>
|
||||
LegacyHDPath(coinType, accountIndex, chainType, addressIndex)
|
||||
case HDPurposes.NestedSegWit =>
|
||||
case HDPurpose.NestedSegWit =>
|
||||
NestedSegWitHDPath(coinType, accountIndex, chainType, addressIndex)
|
||||
case HDPurposes.SegWit =>
|
||||
case HDPurpose.SegWit =>
|
||||
SegWitHDPath(coinType, accountIndex, chainType, addressIndex)
|
||||
|
||||
case invalid: HDPurpose =>
|
||||
@ -396,19 +396,19 @@ private[wallet] trait AddressHandling extends WalletLogger {
|
||||
}
|
||||
|
||||
val addressDb = account.hdAccount.purpose match {
|
||||
case HDPurposes.SegWit =>
|
||||
case HDPurpose.SegWit =>
|
||||
AddressDbHelper.getSegwitAddress(
|
||||
pubkey,
|
||||
SegWitHDPath(coinType, accountIndex, chainType, addressIndex),
|
||||
networkParameters
|
||||
)
|
||||
case HDPurposes.NestedSegWit =>
|
||||
case HDPurpose.NestedSegWit =>
|
||||
AddressDbHelper.getNestedSegwitAddress(
|
||||
pubkey,
|
||||
NestedSegWitHDPath(coinType, accountIndex, chainType, addressIndex),
|
||||
networkParameters
|
||||
)
|
||||
case HDPurposes.Legacy =>
|
||||
case HDPurpose.Legacy =>
|
||||
AddressDbHelper.getLegacyAddress(
|
||||
pubkey,
|
||||
LegacyHDPath(coinType, accountIndex, chainType, addressIndex),
|
||||
|
Loading…
Reference in New Issue
Block a user