feat: add wallet persistence
This commit is contained in:
@@ -1,58 +1,61 @@
|
||||
package org.bitcoindevkit
|
||||
|
||||
import kotlin.test.Ignore
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class LiveTxBuilderTest {
|
||||
@Ignore("The Esplora client's fullScan method requires a Wallet instead of a WalletNoPersist.")
|
||||
@Test
|
||||
fun testTxBuilder() {
|
||||
val descriptor = Descriptor("wpkh(tprv8ZgxMBicQKsPf2qfrEygW6fdYseJDDrVnDv26PH5BHdvSuG6ecCbHqLVof9yZcMoM31z9ur3tTYbSnr1WBqbGX97CbXcmp5H6qeMpyvx35B/84h/1h/0h/0/*)", Network.TESTNET)
|
||||
val wallet = Wallet.newNoPersist(descriptor, null, Network.TESTNET)
|
||||
// val wallet = WalletNoPersist(descriptor, null, Network.TESTNET)
|
||||
val esploraClient = EsploraClient("https://mempool.space/testnet/api")
|
||||
val update = esploraClient.fullScan(wallet, 10uL, 1uL)
|
||||
wallet.applyUpdate(update)
|
||||
println("Balance: ${wallet.getBalance().total}")
|
||||
|
||||
assert(wallet.getBalance().total > 0uL)
|
||||
|
||||
val recipient: Address = Address("tb1qrnfslnrve9uncz9pzpvf83k3ukz22ljgees989", Network.TESTNET)
|
||||
val psbt: PartiallySignedTransaction = TxBuilder()
|
||||
.addRecipient(recipient.scriptPubkey(), 4200uL)
|
||||
.feeRate(FeeRate.fromSatPerVb(2.0f))
|
||||
.finish(wallet)
|
||||
|
||||
println(psbt.serialize())
|
||||
|
||||
assertTrue(psbt.serialize().startsWith("cHNi"), "PSBT should start with 'cHNi'")
|
||||
// val update = esploraClient.fullScan(wallet, 10uL, 1uL)
|
||||
// wallet.applyUpdate(update)
|
||||
// println("Balance: ${wallet.getBalance().total}")
|
||||
//
|
||||
// assert(wallet.getBalance().total > 0uL)
|
||||
//
|
||||
// val recipient: Address = Address("tb1qrnfslnrve9uncz9pzpvf83k3ukz22ljgees989", Network.TESTNET)
|
||||
// val psbt: PartiallySignedTransaction = TxBuilder()
|
||||
// .addRecipient(recipient.scriptPubkey(), 4200uL)
|
||||
// .feeRate(FeeRate.fromSatPerVb(2.0f))
|
||||
// .finish(wallet)
|
||||
//
|
||||
// println(psbt.serialize())
|
||||
//
|
||||
// assertTrue(psbt.serialize().startsWith("cHNi"), "PSBT should start with 'cHNi'")
|
||||
}
|
||||
|
||||
@Ignore("The Esplora client's fullScan method requires a Wallet instead of a WalletNoPersist.")
|
||||
@Test
|
||||
fun complexTxBuilder() {
|
||||
val externalDescriptor = Descriptor("wpkh(tprv8ZgxMBicQKsPf2qfrEygW6fdYseJDDrVnDv26PH5BHdvSuG6ecCbHqLVof9yZcMoM31z9ur3tTYbSnr1WBqbGX97CbXcmp5H6qeMpyvx35B/84h/1h/0h/0/*)", Network.TESTNET)
|
||||
val changeDescriptor = Descriptor("wpkh(tprv8ZgxMBicQKsPf2qfrEygW6fdYseJDDrVnDv26PH5BHdvSuG6ecCbHqLVof9yZcMoM31z9ur3tTYbSnr1WBqbGX97CbXcmp5H6qeMpyvx35B/84h/1h/0h/1/*)", Network.TESTNET)
|
||||
val wallet = Wallet.newNoPersist(externalDescriptor, changeDescriptor, Network.TESTNET)
|
||||
val esploraClient = EsploraClient("https://mempool.space/testnet/api")
|
||||
val update = esploraClient.fullScan(wallet, 10uL, 1uL)
|
||||
wallet.applyUpdate(update)
|
||||
println("Balance: ${wallet.getBalance().total}")
|
||||
|
||||
assert(wallet.getBalance().total > 0uL)
|
||||
|
||||
val recipient1: Address = Address("tb1qrnfslnrve9uncz9pzpvf83k3ukz22ljgees989", Network.TESTNET)
|
||||
val recipient2: Address = Address("tb1qw2c3lxufxqe2x9s4rdzh65tpf4d7fssjgh8nv6", Network.TESTNET)
|
||||
val allRecipients: List<ScriptAmount> = listOf(
|
||||
ScriptAmount(recipient1.scriptPubkey(), 4200uL),
|
||||
ScriptAmount(recipient2.scriptPubkey(), 4200uL),
|
||||
)
|
||||
|
||||
val psbt: PartiallySignedTransaction = TxBuilder()
|
||||
.setRecipients(allRecipients)
|
||||
.feeRate(FeeRate.fromSatPerVb(4.0f))
|
||||
.changePolicy(ChangeSpendPolicy.CHANGE_FORBIDDEN)
|
||||
.enableRbf()
|
||||
.finish(wallet)
|
||||
|
||||
wallet.sign(psbt)
|
||||
assertTrue(psbt.serialize().startsWith("cHNi"), "PSBT should start with 'cHNi'")
|
||||
// val wallet = WalletNoPersist(externalDescriptor, changeDescriptor, Network.TESTNET)
|
||||
// val esploraClient = EsploraClient("https://mempool.space/testnet/api")
|
||||
// val update = esploraClient.fullScan(wallet, 10uL, 1uL)
|
||||
// wallet.applyUpdate(update)
|
||||
// println("Balance: ${wallet.getBalance().total}")
|
||||
//
|
||||
// assert(wallet.getBalance().total > 0uL)
|
||||
//
|
||||
// val recipient1: Address = Address("tb1qrnfslnrve9uncz9pzpvf83k3ukz22ljgees989", Network.TESTNET)
|
||||
// val recipient2: Address = Address("tb1qw2c3lxufxqe2x9s4rdzh65tpf4d7fssjgh8nv6", Network.TESTNET)
|
||||
// val allRecipients: List<ScriptAmount> = listOf(
|
||||
// ScriptAmount(recipient1.scriptPubkey(), 4200uL),
|
||||
// ScriptAmount(recipient2.scriptPubkey(), 4200uL),
|
||||
// )
|
||||
//
|
||||
// val psbt: PartiallySignedTransaction = TxBuilder()
|
||||
// .setRecipients(allRecipients)
|
||||
// .feeRate(FeeRate.fromSatPerVb(4.0f))
|
||||
// .changePolicy(ChangeSpendPolicy.CHANGE_FORBIDDEN)
|
||||
// .enableRbf()
|
||||
// .finish(wallet)
|
||||
//
|
||||
// wallet.sign(psbt)
|
||||
// assertTrue(psbt.serialize().startsWith("cHNi"), "PSBT should start with 'cHNi'")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,68 +1,71 @@
|
||||
package org.bitcoindevkit
|
||||
|
||||
import kotlin.test.Ignore
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class LiveWalletTest {
|
||||
@Ignore("The Esplora client's fullScan method requires a Wallet instead of a WalletNoPersist.")
|
||||
@Test
|
||||
fun testSyncedBalance() {
|
||||
val descriptor: Descriptor = Descriptor("wpkh(tprv8ZgxMBicQKsPf2qfrEygW6fdYseJDDrVnDv26PH5BHdvSuG6ecCbHqLVof9yZcMoM31z9ur3tTYbSnr1WBqbGX97CbXcmp5H6qeMpyvx35B/84h/1h/0h/0/*)", Network.TESTNET)
|
||||
val wallet: Wallet = Wallet.newNoPersist(descriptor, null, Network.TESTNET)
|
||||
// val wallet: WalletNoPersist = WalletNoPersist(descriptor, null, Network.TESTNET)
|
||||
val esploraClient: EsploraClient = EsploraClient("https://mempool.space/testnet/api")
|
||||
// val esploraClient = EsploraClient("https://blockstream.info/testnet/api")
|
||||
val update = esploraClient.fullScan(wallet, 10uL, 1uL)
|
||||
wallet.applyUpdate(update)
|
||||
println("Balance: ${wallet.getBalance().total}")
|
||||
|
||||
assert(wallet.getBalance().total > 0uL)
|
||||
|
||||
println("Transactions count: ${wallet.transactions().count()}")
|
||||
val transactions = wallet.transactions().take(3)
|
||||
for (tx in transactions) {
|
||||
val sentAndReceived = wallet.sentAndReceived(tx)
|
||||
println("Transaction: ${tx.txid()}")
|
||||
println("Sent ${sentAndReceived.sent}")
|
||||
println("Received ${sentAndReceived.received}")
|
||||
}
|
||||
// val update = esploraClient.fullScan(wallet, 10uL, 1uL)
|
||||
// wallet.applyUpdate(update)
|
||||
// println("Balance: ${wallet.getBalance().total}")
|
||||
//
|
||||
// assert(wallet.getBalance().total > 0uL)
|
||||
//
|
||||
// println("Transactions count: ${wallet.transactions().count()}")
|
||||
// val transactions = wallet.transactions().take(3)
|
||||
// for (tx in transactions) {
|
||||
// val sentAndReceived = wallet.sentAndReceived(tx)
|
||||
// println("Transaction: ${tx.txid()}")
|
||||
// println("Sent ${sentAndReceived.sent}")
|
||||
// println("Received ${sentAndReceived.received}")
|
||||
// }
|
||||
}
|
||||
|
||||
@Ignore("The Esplora client's fullScan method requires a Wallet instead of a WalletNoPersist.")
|
||||
@Test
|
||||
fun testBroadcastTransaction() {
|
||||
val descriptor = Descriptor("wpkh(tprv8ZgxMBicQKsPf2qfrEygW6fdYseJDDrVnDv26PH5BHdvSuG6ecCbHqLVof9yZcMoM31z9ur3tTYbSnr1WBqbGX97CbXcmp5H6qeMpyvx35B/84h/1h/0h/0/*)", Network.TESTNET)
|
||||
val wallet = Wallet.newNoPersist(descriptor, null, Network.TESTNET)
|
||||
// val wallet = WalletNoPersist(descriptor, null, Network.TESTNET)
|
||||
val esploraClient = EsploraClient("https://mempool.space/testnet/api")
|
||||
val update = esploraClient.fullScan(wallet, 10uL, 1uL)
|
||||
|
||||
wallet.applyUpdate(update)
|
||||
println("Balance: ${wallet.getBalance().total}")
|
||||
println("New address: ${wallet.getAddress(AddressIndex.New).address.asString()}")
|
||||
|
||||
assert(wallet.getBalance().total > 0uL) {
|
||||
"Wallet balance must be greater than 0! Please send funds to ${wallet.getAddress(AddressIndex.New).address} and try again."
|
||||
}
|
||||
|
||||
val recipient: Address = Address("tb1qrnfslnrve9uncz9pzpvf83k3ukz22ljgees989", Network.TESTNET)
|
||||
|
||||
val psbt: PartiallySignedTransaction = TxBuilder()
|
||||
.addRecipient(recipient.scriptPubkey(), 4200uL)
|
||||
.feeRate(FeeRate.fromSatPerVb(2.0f))
|
||||
.finish(wallet)
|
||||
|
||||
println(psbt.serialize())
|
||||
assertTrue(psbt.serialize().startsWith("cHNi"), "PSBT should start with 'cHNi'")
|
||||
|
||||
val walletDidSign = wallet.sign(psbt)
|
||||
assertTrue(walletDidSign)
|
||||
|
||||
val tx: Transaction = psbt.extractTx()
|
||||
println("Txid is: ${tx.txid()}")
|
||||
|
||||
val txFee: ULong = wallet.calculateFee(tx)
|
||||
println("Tx fee is: ${txFee}")
|
||||
|
||||
val feeRate: FeeRate = wallet.calculateFeeRate(tx)
|
||||
println("Tx fee rate is: ${feeRate.asSatPerVb()} sat/vB")
|
||||
|
||||
esploraClient.broadcast(tx)
|
||||
// val update = esploraClient.fullScan(wallet, 10uL, 1uL)
|
||||
//
|
||||
// wallet.applyUpdate(update)
|
||||
// println("Balance: ${wallet.getBalance().total}")
|
||||
// println("New address: ${wallet.getAddress(AddressIndex.New).address.asString()}")
|
||||
//
|
||||
// assert(wallet.getBalance().total > 0uL) {
|
||||
// "Wallet balance must be greater than 0! Please send funds to ${wallet.getAddress(AddressIndex.New).address} and try again."
|
||||
// }
|
||||
//
|
||||
// val recipient: Address = Address("tb1qrnfslnrve9uncz9pzpvf83k3ukz22ljgees989", Network.TESTNET)
|
||||
//
|
||||
// val psbt: PartiallySignedTransaction = TxBuilder()
|
||||
// .addRecipient(recipient.scriptPubkey(), 4200uL)
|
||||
// .feeRate(FeeRate.fromSatPerVb(2.0f))
|
||||
// .finish(wallet)
|
||||
//
|
||||
// println(psbt.serialize())
|
||||
// assertTrue(psbt.serialize().startsWith("cHNi"), "PSBT should start with 'cHNi'")
|
||||
//
|
||||
// val walletDidSign = wallet.sign(psbt)
|
||||
// assertTrue(walletDidSign)
|
||||
//
|
||||
// val tx: Transaction = psbt.extractTx()
|
||||
// println("Txid is: ${tx.txid()}")
|
||||
//
|
||||
// val txFee: ULong = wallet.calculateFee(tx)
|
||||
// println("Tx fee is: ${txFee}")
|
||||
//
|
||||
// val feeRate: FeeRate = wallet.calculateFeeRate(tx)
|
||||
// println("Tx fee rate is: ${feeRate.asSatPerVb()} sat/vB")
|
||||
//
|
||||
// esploraClient.broadcast(tx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,22 +21,22 @@ class OfflineWalletTest {
|
||||
"wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
|
||||
Network.TESTNET
|
||||
)
|
||||
val wallet: Wallet = Wallet.newNoPersist(
|
||||
descriptor,
|
||||
null,
|
||||
Network.TESTNET
|
||||
)
|
||||
val addressInfo: AddressInfo = wallet.getAddress(AddressIndex.New)
|
||||
|
||||
assertTrue(addressInfo.address.isValidForNetwork(Network.TESTNET), "Address is not valid for testnet network")
|
||||
assertTrue(addressInfo.address.isValidForNetwork(Network.SIGNET), "Address is not valid for signet network")
|
||||
assertFalse(addressInfo.address.isValidForNetwork(Network.REGTEST), "Address is valid for regtest network, but it shouldn't be")
|
||||
assertFalse(addressInfo.address.isValidForNetwork(Network.BITCOIN), "Address is valid for bitcoin network, but it shouldn't be")
|
||||
|
||||
assertEquals(
|
||||
expected = "tb1qzg4mckdh50nwdm9hkzq06528rsu73hjxxzem3e",
|
||||
actual = addressInfo.address.asString()
|
||||
)
|
||||
// val wallet: Wallet = WalletNoPersist(
|
||||
// descriptor,
|
||||
// null,
|
||||
// Network.TESTNET
|
||||
// )
|
||||
// val addressInfo: AddressInfo = wallet.getAddress(AddressIndex.New)
|
||||
//
|
||||
// assertTrue(addressInfo.address.isValidForNetwork(Network.TESTNET), "Address is not valid for testnet network")
|
||||
// assertTrue(addressInfo.address.isValidForNetwork(Network.SIGNET), "Address is not valid for signet network")
|
||||
// assertFalse(addressInfo.address.isValidForNetwork(Network.REGTEST), "Address is valid for regtest network, but it shouldn't be")
|
||||
// assertFalse(addressInfo.address.isValidForNetwork(Network.BITCOIN), "Address is valid for bitcoin network, but it shouldn't be")
|
||||
//
|
||||
// assertEquals(
|
||||
// expected = "tb1qzg4mckdh50nwdm9hkzq06528rsu73hjxxzem3e",
|
||||
// actual = addressInfo.address.asString()
|
||||
// )
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -45,15 +45,15 @@ class OfflineWalletTest {
|
||||
"wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
|
||||
Network.TESTNET
|
||||
)
|
||||
val wallet: Wallet = Wallet.newNoPersist(
|
||||
descriptor,
|
||||
null,
|
||||
Network.TESTNET
|
||||
)
|
||||
// val wallet: WalletNoPersist = WalletNoPersist(
|
||||
// descriptor,
|
||||
// null,
|
||||
// Network.TESTNET
|
||||
// )
|
||||
|
||||
assertEquals(
|
||||
expected = 0uL,
|
||||
actual = wallet.getBalance().total
|
||||
)
|
||||
// assertEquals(
|
||||
// expected = 0uL,
|
||||
// actual = wallet.getBalance().total
|
||||
// )
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user