test: add excluded-in-CI live tests
This commit is contained in:
parent
13c751cebc
commit
d37b2f37b5
11
.github/workflows/test-android.yaml
vendored
11
.github/workflows/test-android.yaml
vendored
@ -55,11 +55,12 @@ jobs:
|
|||||||
- name: "Build Android library"
|
- name: "Build Android library"
|
||||||
run: |
|
run: |
|
||||||
cd bdk-android
|
cd bdk-android
|
||||||
./gradlew buildAndroidLib
|
./gradlew buildAndroidLib --console=plain
|
||||||
|
|
||||||
# There are currently no unit tests for bdk-android and the integration tests require the macOS image
|
# There are currently no unit tests for bdk-android (see the tests in bdk-jvm instead) and the
|
||||||
# which is not working with the older NDK version we are using, so for now we just make sure that the library builds.
|
# integration tests require the macOS image which is not working with the older NDK version we
|
||||||
# - name: "Run Android unit tests"
|
# are using, so for now we just make sure that the library builds and omit the connectedTest
|
||||||
|
# - name: "Run Android connected tests"
|
||||||
# run: |
|
# run: |
|
||||||
# cd bdk-android
|
# cd bdk-android
|
||||||
# ./gradlew test --console=rich
|
# ./gradlew connectedAndroidTest --console=plain
|
||||||
|
2
.github/workflows/test-jvm.yaml
vendored
2
.github/workflows/test-jvm.yaml
vendored
@ -38,4 +38,4 @@ jobs:
|
|||||||
- name: "Run JVM tests"
|
- name: "Run JVM tests"
|
||||||
run: |
|
run: |
|
||||||
cd bdk-jvm
|
cd bdk-jvm
|
||||||
./gradlew test
|
./gradlew test -P excludeConnectedTests
|
||||||
|
8
.github/workflows/test-python.yaml
vendored
8
.github/workflows/test-python.yaml
vendored
@ -54,7 +54,7 @@ jobs:
|
|||||||
run: ${PYBIN}/pip install ./dist/*.whl
|
run: ${PYBIN}/pip install ./dist/*.whl
|
||||||
|
|
||||||
- name: "Run tests"
|
- name: "Run tests"
|
||||||
run: ${PYBIN}/python -m unittest tests/test_bdk.py --verbose
|
run: ${PYBIN}/python -m unittest discover --start "./tests/" --pattern "test_offline_*.py" --verbose
|
||||||
|
|
||||||
- name: "Upload artifact test"
|
- name: "Upload artifact test"
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
@ -97,7 +97,7 @@ jobs:
|
|||||||
# - name: "Install wheel and run tests"
|
# - name: "Install wheel and run tests"
|
||||||
# run: |
|
# run: |
|
||||||
# pip3 install ./dist/*.whl
|
# pip3 install ./dist/*.whl
|
||||||
# python3 -m unittest tests/test_bdk.py --verbose
|
# python3 -m unittest discover --start "./tests/" --pattern "test_offline_*.py" --verbose
|
||||||
|
|
||||||
- name: "Upload artifact test"
|
- name: "Upload artifact test"
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
@ -138,7 +138,7 @@ jobs:
|
|||||||
run: pip3 install ./dist/*.whl
|
run: pip3 install ./dist/*.whl
|
||||||
|
|
||||||
- name: "Run tests"
|
- name: "Run tests"
|
||||||
run: python3 -m unittest tests/test_bdk.py --verbose
|
run: python3 -m unittest discover --start "./tests/" --pattern "test_offline_*.py" --verbose
|
||||||
|
|
||||||
- name: "Upload artifact test"
|
- name: "Upload artifact test"
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
@ -186,4 +186,4 @@ jobs:
|
|||||||
shell: powershell
|
shell: powershell
|
||||||
|
|
||||||
- name: "Run tests"
|
- name: "Run tests"
|
||||||
run: python -m unittest tests/test_bdk.py --verbose
|
run: python -m unittest discover --start "./tests/" --pattern "test_offline_*.py" --verbose
|
||||||
|
2
.github/workflows/test-swift.yaml
vendored
2
.github/workflows/test-swift.yaml
vendored
@ -23,4 +23,4 @@ jobs:
|
|||||||
|
|
||||||
- name: "Run Swift tests"
|
- name: "Run Swift tests"
|
||||||
working-directory: bdk-swift
|
working-directory: bdk-swift
|
||||||
run: swift test
|
run: swift test --skip LiveWalletTests --skip LiveTxBuilderTests
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
package org.bitcoindevkit
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class LiveTxBuilderTest {
|
||||||
|
@Test
|
||||||
|
fun testTxBuilder() {
|
||||||
|
val descriptor = Descriptor("wpkh(tprv8ZgxMBicQKsPf2qfrEygW6fdYseJDDrVnDv26PH5BHdvSuG6ecCbHqLVof9yZcMoM31z9ur3tTYbSnr1WBqbGX97CbXcmp5H6qeMpyvx35B/84h/1h/0h/0/*)", Network.TESTNET)
|
||||||
|
val wallet = Wallet.newNoPersist(descriptor, null, Network.TESTNET)
|
||||||
|
val esploraClient = EsploraClient("https://mempool.space/testnet/api")
|
||||||
|
val update = esploraClient.scan(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(2.0f)
|
||||||
|
.finish(wallet)
|
||||||
|
|
||||||
|
println(psbt.serialize())
|
||||||
|
assertTrue(psbt.serialize().startsWith("cHNi"), "PSBT should start with 'cHNi'")
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package org.bitcoindevkit
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class LiveWalletTest {
|
||||||
|
@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 esploraClient: EsploraClient = EsploraClient("https://mempool.space/testnet/api")
|
||||||
|
// val esploraClient = EsploraClient("https://blockstream.info/testnet/api")
|
||||||
|
val update = esploraClient.scan(wallet, 10uL, 1uL)
|
||||||
|
wallet.applyUpdate(update)
|
||||||
|
println("Balance: ${wallet.getBalance().total()}")
|
||||||
|
|
||||||
|
assert(wallet.getBalance().total() > 0uL)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package org.bitcoindevkit
|
||||||
|
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class OfflineDescriptorTest {
|
||||||
|
@Test
|
||||||
|
fun testDescriptorBip86() {
|
||||||
|
val mnemonic: Mnemonic = Mnemonic.fromString("space echo position wrist orient erupt relief museum myself grain wisdom tumble")
|
||||||
|
val descriptorSecretKey: DescriptorSecretKey = DescriptorSecretKey(Network.TESTNET, mnemonic, null)
|
||||||
|
val descriptor: Descriptor = Descriptor.newBip86(descriptorSecretKey, KeychainKind.EXTERNAL, Network.TESTNET)
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
expected = "tr([be1eec8f/86'/1'/0']tpubDCTtszwSxPx3tATqDrsSyqScPNnUChwQAVAkanuDUCJQESGBbkt68nXXKRDifYSDbeMa2Xg2euKbXaU3YphvGWftDE7ozRKPriT6vAo3xsc/0/*)#m7puekcx",
|
||||||
|
actual = descriptor.asString()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -1,19 +1,13 @@
|
|||||||
package org.bitcoindevkit
|
package org.bitcoindevkit
|
||||||
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
|
||||||
import org.junit.runner.RunWith
|
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
/**
|
|
||||||
* Instrumented test, which will execute on an Android device.
|
|
||||||
*
|
|
||||||
* See [testing documentation](http://d.android.com/tools/testing).
|
|
||||||
*/
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
class WalletTest {
|
class OfflineWalletTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testDescriptorBip86() {
|
fun testDescriptorBip86() {
|
||||||
val mnemonic: Mnemonic = Mnemonic(WordCount.WORDS12)
|
val mnemonic: Mnemonic = Mnemonic(WordCount.WORDS12)
|
||||||
@ -36,7 +30,10 @@ class WalletTest {
|
|||||||
)
|
)
|
||||||
val addressInfo: AddressInfo = wallet.getAddress(AddressIndex.New)
|
val addressInfo: AddressInfo = wallet.getAddress(AddressIndex.New)
|
||||||
|
|
||||||
assertEquals("tb1qzg4mckdh50nwdm9hkzq06528rsu73hjxxzem3e", addressInfo.address.asString())
|
assertEquals(
|
||||||
|
expected = "tb1qzg4mckdh50nwdm9hkzq06528rsu73hjxxzem3e",
|
||||||
|
actual = addressInfo.address.asString()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -51,7 +48,9 @@ class WalletTest {
|
|||||||
Network.TESTNET
|
Network.TESTNET
|
||||||
)
|
)
|
||||||
|
|
||||||
assertEquals(0uL, wallet.getBalance().total())
|
assertEquals(
|
||||||
|
expected = 0uL,
|
||||||
|
actual = wallet.getBalance().total()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -76,10 +76,14 @@ interface Wallet {
|
|||||||
|
|
||||||
AddressInfo get_address(AddressIndex address_index);
|
AddressInfo get_address(AddressIndex address_index);
|
||||||
|
|
||||||
|
AddressInfo get_internal_address(AddressIndex address_index);
|
||||||
|
|
||||||
Network network();
|
Network network();
|
||||||
|
|
||||||
Balance get_balance();
|
Balance get_balance();
|
||||||
|
|
||||||
|
boolean is_mine(Script script);
|
||||||
|
|
||||||
[Throws=BdkError]
|
[Throws=BdkError]
|
||||||
void apply_update(Update update);
|
void apply_update(Update update);
|
||||||
};
|
};
|
||||||
|
@ -38,28 +38,22 @@ impl Wallet {
|
|||||||
self.inner_mutex.lock().expect("wallet")
|
self.inner_mutex.lock().expect("wallet")
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn get_address(&self, address_index: AddressIndex) -> Result<AddressInfo, BdkError> {
|
|
||||||
pub fn get_address(&self, address_index: AddressIndex) -> AddressInfo {
|
pub fn get_address(&self, address_index: AddressIndex) -> AddressInfo {
|
||||||
self.get_wallet().get_address(address_index.into()).into()
|
self.get_wallet().get_address(address_index.into()).into()
|
||||||
// NOTE: I prefer this:
|
|
||||||
// AddressInfo::from(
|
|
||||||
// self.get_wallet().get_address(address_index.into())
|
|
||||||
// )
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn network(&self) -> Network {
|
pub fn network(&self) -> Network {
|
||||||
self.get_wallet().network().into()
|
self.get_wallet().network().into()
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn get_internal_address(&mut self, address_index: AddressIndex) -> AddressInfo {
|
pub fn get_internal_address(&self, address_index: AddressIndex) -> AddressInfo {
|
||||||
// self.get_wallet()
|
self.get_wallet()
|
||||||
// .get_internal_address(address_index.into())
|
.get_internal_address(address_index.into())
|
||||||
// .into()
|
.into()
|
||||||
// }
|
}
|
||||||
|
|
||||||
// TODO 16: Why is the Arc required here?
|
// TODO 16: Why is the Arc required here?
|
||||||
pub fn get_balance(&self) -> Arc<Balance> {
|
pub fn get_balance(&self) -> Arc<Balance> {
|
||||||
// Arc::new(self.get_wallet().get_balance().into())
|
|
||||||
let bdk_balance = self.get_wallet().get_balance();
|
let bdk_balance = self.get_wallet().get_balance();
|
||||||
let balance = Balance { inner: bdk_balance };
|
let balance = Balance { inner: bdk_balance };
|
||||||
Arc::new(balance)
|
Arc::new(balance)
|
||||||
@ -71,11 +65,11 @@ impl Wallet {
|
|||||||
.map_err(|e| BdkError::Generic(e.to_string()))
|
.map_err(|e| BdkError::Generic(e.to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn commit(&self) -> Result<(), BdkError> {}
|
pub fn is_mine(&self, script: Arc<Script>) -> bool {
|
||||||
|
// TODO: Both of the following lines work. Which is better?
|
||||||
// fn is_mine(&self, script: Arc<Script>) -> bool {
|
self.get_wallet().is_mine(&script.0)
|
||||||
// self.get_wallet().is_mine(&script.inner)
|
// self.get_wallet().is_mine(script.0.clone().as_script())
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Update(pub(crate) BdkUpdate);
|
pub struct Update(pub(crate) BdkUpdate);
|
||||||
@ -98,63 +92,6 @@ pub struct Update(pub(crate) BdkUpdate);
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// impl Wallet {
|
|
||||||
// // pub(crate) fn new(
|
|
||||||
// // descriptor: Arc<Descriptor>,
|
|
||||||
// // change_descriptor: Option<Arc<Descriptor>>,
|
|
||||||
// // db: PersistBackend<ChangeSet>,
|
|
||||||
// // network: Network,
|
|
||||||
// // ) -> Result<Self, BdkError> {
|
|
||||||
// // let any_database_config = match database_config {
|
|
||||||
// // DatabaseConfig::Memory => AnyDatabaseConfig::Memory(()),
|
|
||||||
// // DatabaseConfig::Sled { config } => AnyDatabaseConfig::Sled(config),
|
|
||||||
// // DatabaseConfig::Sqlite { config } => AnyDatabaseConfig::Sqlite(config),
|
|
||||||
// // };
|
|
||||||
// // let database = AnyDatabase::from_config(&any_database_config)?;
|
|
||||||
// // let descriptor: String = descriptor.as_string_private();
|
|
||||||
// // let change_descriptor: Option<String> = change_descriptor.map(|d| d.as_string_private());
|
|
||||||
// //
|
|
||||||
// // let wallet_mutex = Mutex::new(BdkWallet::new(
|
|
||||||
// // &descriptor,
|
|
||||||
// // change_descriptor.as_ref(),
|
|
||||||
// // network,
|
|
||||||
// // database,
|
|
||||||
// // )?);
|
|
||||||
// // Ok(Wallet {
|
|
||||||
// // inner_mutex: wallet_mutex,
|
|
||||||
// // })
|
|
||||||
// // }
|
|
||||||
//
|
|
||||||
// pub(crate) fn new_no_persist(
|
|
||||||
// descriptor: Arc<Descriptor>,
|
|
||||||
// change_descriptor: Option<Arc<Descriptor>>,
|
|
||||||
// network: Network,
|
|
||||||
// ) -> Result<Self, BdkError> {
|
|
||||||
// let descriptor: String = descriptor.as_string_private();
|
|
||||||
// let change_descriptor: Option<String> = change_descriptor.map(|d| d.as_string_private());
|
|
||||||
//
|
|
||||||
// let wallet = BdkWallet::new_no_persist(
|
|
||||||
// &descriptor,
|
|
||||||
// change_descriptor.as_ref(),
|
|
||||||
// network,
|
|
||||||
// )?;
|
|
||||||
//
|
|
||||||
// Ok(Wallet {
|
|
||||||
// inner: wallet,
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // MIGRATION 1.0: This function is no longer needed right? If I remove the mutex on the wallet,
|
|
||||||
// // I can just access the wallet directly without causing trouble me thinks.
|
|
||||||
// pub(crate) fn get_wallet(&self) -> MutexGuard<BdkWallet<AnyDatabase>> {
|
|
||||||
// self.inner_mutex.lock().expect("wallet")
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /// Get the Bitcoin network the wallet is using.
|
|
||||||
// pub(crate) fn network(&self) -> Network {
|
|
||||||
// self.inner.network()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /// Return whether or not a script is part of this wallet (either internal or external).
|
// /// Return whether or not a script is part of this wallet (either internal or external).
|
||||||
// pub(crate) fn is_mine(&self, script: Arc<Script>) -> bool {
|
// pub(crate) fn is_mine(&self, script: Arc<Script>) -> bool {
|
||||||
// self.inner.is_mine(&script.inner)
|
// self.inner.is_mine(&script.inner)
|
||||||
|
@ -26,6 +26,18 @@ java {
|
|||||||
withJavadocJar()
|
withJavadocJar()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This block ensures that the tests that require access to a blockchain are not
|
||||||
|
// run if the -P excludeConnectedTests flag is passed to gradle.
|
||||||
|
// This ensures our CI runs are not fickle by not requiring access to testnet.
|
||||||
|
// This is a workaround until we have a proper regtest setup for the CI.
|
||||||
|
// Note that the command in the CI is ./gradlew test -P excludeConnectedTests
|
||||||
|
tasks.test {
|
||||||
|
if (project.hasProperty("excludeConnectedTests")) {
|
||||||
|
exclude("**/LiveWalletTest.class")
|
||||||
|
exclude("**/LiveTxBuilderTest.class")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
testing {
|
testing {
|
||||||
suites {
|
suites {
|
||||||
val test by getting(JvmTestSuite::class) {
|
val test by getting(JvmTestSuite::class) {
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package org.bitcoindevkit
|
||||||
|
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
class LiveTxBuilderTest {
|
||||||
|
@Test
|
||||||
|
fun testTxBuilder() {
|
||||||
|
val descriptor = Descriptor("wpkh(tprv8ZgxMBicQKsPf2qfrEygW6fdYseJDDrVnDv26PH5BHdvSuG6ecCbHqLVof9yZcMoM31z9ur3tTYbSnr1WBqbGX97CbXcmp5H6qeMpyvx35B/84h/1h/0h/0/*)", Network.TESTNET)
|
||||||
|
val wallet = Wallet.newNoPersist(descriptor, null, Network.TESTNET)
|
||||||
|
val esploraClient = EsploraClient("https://mempool.space/testnet/api")
|
||||||
|
val update = esploraClient.scan(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(2.0f)
|
||||||
|
.finish(wallet)
|
||||||
|
|
||||||
|
println(psbt.serialize())
|
||||||
|
|
||||||
|
assertTrue(psbt.serialize().startsWith("cHNi"), "PSBT should start with 'cHNi'")
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package org.bitcoindevkit
|
||||||
|
|
||||||
|
import kotlin.test.Test
|
||||||
|
|
||||||
|
class LiveWalletTest {
|
||||||
|
@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 esploraClient: EsploraClient = EsploraClient("https://mempool.space/testnet/api")
|
||||||
|
// val esploraClient = EsploraClient("https://blockstream.info/testnet/api")
|
||||||
|
val update = esploraClient.scan(wallet, 10uL, 1uL)
|
||||||
|
wallet.applyUpdate(update)
|
||||||
|
println("Balance: ${wallet.getBalance().total()}")
|
||||||
|
|
||||||
|
assert(wallet.getBalance().total() > 0uL)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package org.bitcoindevkit
|
||||||
|
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class OfflineDescriptorTest {
|
||||||
|
@Test
|
||||||
|
fun testDescriptorBip86() {
|
||||||
|
val mnemonic: Mnemonic = Mnemonic.fromString("space echo position wrist orient erupt relief museum myself grain wisdom tumble")
|
||||||
|
val descriptorSecretKey: DescriptorSecretKey = DescriptorSecretKey(Network.TESTNET, mnemonic, null)
|
||||||
|
val descriptor: Descriptor = Descriptor.newBip86(descriptorSecretKey, KeychainKind.EXTERNAL, Network.TESTNET)
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
expected = "tr([be1eec8f/86'/1'/0']tpubDCTtszwSxPx3tATqDrsSyqScPNnUChwQAVAkanuDUCJQESGBbkt68nXXKRDifYSDbeMa2Xg2euKbXaU3YphvGWftDE7ozRKPriT6vAo3xsc/0/*)#m7puekcx",
|
||||||
|
actual = descriptor.asString()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -4,8 +4,7 @@ import kotlin.test.Test
|
|||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
class WalletTest {
|
class OfflineWalletTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testDescriptorBip86() {
|
fun testDescriptorBip86() {
|
||||||
val mnemonic: Mnemonic = Mnemonic(WordCount.WORDS12)
|
val mnemonic: Mnemonic = Mnemonic(WordCount.WORDS12)
|
||||||
@ -28,7 +27,10 @@ class WalletTest {
|
|||||||
)
|
)
|
||||||
val addressInfo: AddressInfo = wallet.getAddress(AddressIndex.New)
|
val addressInfo: AddressInfo = wallet.getAddress(AddressIndex.New)
|
||||||
|
|
||||||
assertEquals("tb1qzg4mckdh50nwdm9hkzq06528rsu73hjxxzem3e", addressInfo.address.asString())
|
assertEquals(
|
||||||
|
expected = "tb1qzg4mckdh50nwdm9hkzq06528rsu73hjxxzem3e",
|
||||||
|
actual = addressInfo.address.asString()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -43,18 +45,9 @@ class WalletTest {
|
|||||||
Network.TESTNET
|
Network.TESTNET
|
||||||
)
|
)
|
||||||
|
|
||||||
assertEquals(0uL, wallet.getBalance().total())
|
assertEquals(
|
||||||
|
expected = 0uL,
|
||||||
|
actual = wallet.getBalance().total()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Test
|
|
||||||
// fun testSyncedBalance() {
|
|
||||||
// val descriptor = Descriptor("wpkh(tprv8ZgxMBicQKsPf2qfrEygW6fdYseJDDrVnDv26PH5BHdvSuG6ecCbHqLVof9yZcMoM31z9ur3tTYbSnr1WBqbGX97CbXcmp5H6qeMpyvx35B/84h/1h/0h/0/*)", Network.TESTNET)
|
|
||||||
// val wallet = Wallet.newNoPersist(descriptor, null, Network.TESTNET)
|
|
||||||
// val esploraClient = EsploraClient("https://mempool.space/testnet/api")
|
|
||||||
// // val esploraClient = EsploraClient("https://blockstream.info/testnet/api")
|
|
||||||
// val update = esploraClient.scan(wallet, 10uL, 1uL)
|
|
||||||
// wallet.applyUpdate(update)
|
|
||||||
// println("Balance: ${wallet.getBalance().total()}")
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
38
bdk-python/tests/test_live_tx_builder.py
Normal file
38
bdk-python/tests/test_live_tx_builder.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import bdkpython as bdk
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class TestLiveTxBuilder(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_tx_builder(self):
|
||||||
|
descriptor: bdk.Descriptor = bdk.Descriptor(
|
||||||
|
"wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
|
||||||
|
bdk.Network.TESTNET
|
||||||
|
)
|
||||||
|
wallet: bdk.Wallet = bdk.Wallet.new_no_persist(
|
||||||
|
descriptor,
|
||||||
|
None,
|
||||||
|
bdk.Network.TESTNET
|
||||||
|
)
|
||||||
|
esploraClient: bdk.EsploraClient = bdk.EsploraClient(url = "https://mempool.space/testnet/api")
|
||||||
|
update = esploraClient.scan(
|
||||||
|
wallet = wallet,
|
||||||
|
stop_gap = 10,
|
||||||
|
parallel_requests = 1
|
||||||
|
)
|
||||||
|
wallet.apply_update(update)
|
||||||
|
|
||||||
|
self.assertGreater(wallet.get_balance().total(), 0)
|
||||||
|
|
||||||
|
recipient = bdk.Address(
|
||||||
|
address = "tb1qrnfslnrve9uncz9pzpvf83k3ukz22ljgees989",
|
||||||
|
network = bdk.Network.TESTNET
|
||||||
|
)
|
||||||
|
|
||||||
|
psbt = bdk.TxBuilder().add_recipient(script=recipient.script_pubkey(), amount=4200).fee_rate(2.0).finish(wallet)
|
||||||
|
# print(psbt.serialize())
|
||||||
|
|
||||||
|
self.assertTrue(psbt.serialize().startswith("cHNi"), "The PSBT should start with cHNi")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
28
bdk-python/tests/test_live_wallet.py
Normal file
28
bdk-python/tests/test_live_wallet.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import bdkpython as bdk
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class TestLiveWallet(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_synced_balance(self):
|
||||||
|
descriptor: bdk.Descriptor = bdk.Descriptor(
|
||||||
|
"wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
|
||||||
|
bdk.Network.TESTNET
|
||||||
|
)
|
||||||
|
wallet: bdk.Wallet = bdk.Wallet.new_no_persist(
|
||||||
|
descriptor,
|
||||||
|
None,
|
||||||
|
bdk.Network.TESTNET
|
||||||
|
)
|
||||||
|
esploraClient: bdk.EsploraClient = bdk.EsploraClient(url = "https://mempool.space/testnet/api")
|
||||||
|
update = esploraClient.scan(
|
||||||
|
wallet = wallet,
|
||||||
|
stop_gap = 10,
|
||||||
|
parallel_requests = 1
|
||||||
|
)
|
||||||
|
wallet.apply_update(update)
|
||||||
|
|
||||||
|
self.assertGreater(wallet.get_balance().total(), 0)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
18
bdk-python/tests/test_offline_descriptor.py
Normal file
18
bdk-python/tests/test_offline_descriptor.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import bdkpython as bdk
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class TestSimpleWallet(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_descriptor_bip86(self):
|
||||||
|
mnemonic: bdk.Mnemonic = bdk.Mnemonic.from_string("space echo position wrist orient erupt relief museum myself grain wisdom tumble")
|
||||||
|
descriptor_secret_key: bdk.DescriptorSecretKey = bdk.DescriptorSecretKey(bdk.Network.TESTNET, mnemonic, None)
|
||||||
|
descriptor: bdk.Descriptor = bdk.Descriptor.new_bip86(descriptor_secret_key, bdk.KeychainKind.EXTERNAL, bdk.Network.TESTNET)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
"tr([be1eec8f/86'/1'/0']tpubDCTtszwSxPx3tATqDrsSyqScPNnUChwQAVAkanuDUCJQESGBbkt68nXXKRDifYSDbeMa2Xg2euKbXaU3YphvGWftDE7ozRKPriT6vAo3xsc/0/*)#m7puekcx",
|
||||||
|
descriptor.as_string()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
@ -3,13 +3,6 @@ import unittest
|
|||||||
|
|
||||||
class TestSimpleWallet(unittest.TestCase):
|
class TestSimpleWallet(unittest.TestCase):
|
||||||
|
|
||||||
def test_descriptor_bip86(self):
|
|
||||||
mnemonic: bdk.Mnemonic = bdk.Mnemonic(bdk.WordCount.WORDS12)
|
|
||||||
descriptor_secret_key: bdk.DescriptorSecretKey = bdk.DescriptorSecretKey(bdk.Network.TESTNET, mnemonic, None)
|
|
||||||
descriptor: bdk.Descriptor = bdk.Descriptor.new_bip86(descriptor_secret_key, bdk.KeychainKind.EXTERNAL, bdk.Network.TESTNET)
|
|
||||||
|
|
||||||
self.assertTrue(descriptor.as_string().startswith("tr"), "Bip86 Descriptor does not start with 'tr'")
|
|
||||||
|
|
||||||
def test_new_address(self):
|
def test_new_address(self):
|
||||||
descriptor: bdk.Descriptor = bdk.Descriptor(
|
descriptor: bdk.Descriptor = bdk.Descriptor(
|
||||||
"wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
|
"wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
|
||||||
@ -29,7 +22,7 @@ class TestSimpleWallet(unittest.TestCase):
|
|||||||
"wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
|
"wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
|
||||||
bdk.Network.TESTNET
|
bdk.Network.TESTNET
|
||||||
)
|
)
|
||||||
wallet: Wallet = bdk.Wallet.new_no_persist(
|
wallet: bdk.Wallet = bdk.Wallet.new_no_persist(
|
||||||
descriptor,
|
descriptor,
|
||||||
None,
|
None,
|
||||||
bdk.Network.TESTNET
|
bdk.Network.TESTNET
|
@ -1,68 +0,0 @@
|
|||||||
import XCTest
|
|
||||||
@testable import BitcoinDevKit
|
|
||||||
|
|
||||||
final class BitcoinDevKitTests: XCTestCase {
|
|
||||||
|
|
||||||
func testDescriptorBip86() {
|
|
||||||
let mnemonic: Mnemonic = Mnemonic(wordCount: WordCount.words12)
|
|
||||||
let descriptorSecretKey: DescriptorSecretKey = DescriptorSecretKey(
|
|
||||||
network: Network.testnet,
|
|
||||||
mnemonic: mnemonic,
|
|
||||||
password: nil
|
|
||||||
)
|
|
||||||
let descriptor: Descriptor = Descriptor.newBip86(
|
|
||||||
secretKey: descriptorSecretKey,
|
|
||||||
keychain: KeychainKind.external,
|
|
||||||
network: Network.testnet
|
|
||||||
)
|
|
||||||
|
|
||||||
XCTAssertTrue(descriptor.asString().hasPrefix("tr"), "Bip86 Descriptor does not start with 'tr'")
|
|
||||||
}
|
|
||||||
|
|
||||||
func testNewAddress() throws {
|
|
||||||
let descriptor: Descriptor = try Descriptor(
|
|
||||||
descriptor: "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
|
|
||||||
network: Network.testnet
|
|
||||||
)
|
|
||||||
let wallet: Wallet = try Wallet.newNoPersist(
|
|
||||||
descriptor: descriptor,
|
|
||||||
changeDescriptor: nil,
|
|
||||||
network: .testnet
|
|
||||||
)
|
|
||||||
let addressInfo: AddressInfo = wallet.getAddress(addressIndex: AddressIndex.new)
|
|
||||||
|
|
||||||
XCTAssertEqual(addressInfo.address.asString(), "tb1qzg4mckdh50nwdm9hkzq06528rsu73hjxxzem3e")
|
|
||||||
}
|
|
||||||
|
|
||||||
func testBalance() throws {
|
|
||||||
let descriptor: Descriptor = try Descriptor(
|
|
||||||
descriptor: "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
|
|
||||||
network: Network.testnet
|
|
||||||
)
|
|
||||||
let wallet: Wallet = try Wallet.newNoPersist(
|
|
||||||
descriptor: descriptor,
|
|
||||||
changeDescriptor: nil,
|
|
||||||
network: .testnet
|
|
||||||
)
|
|
||||||
|
|
||||||
XCTAssertEqual(wallet.getBalance().total(), 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// func testSyncedBalance() throws {
|
|
||||||
// let descriptor = try Descriptor(
|
|
||||||
// descriptor: "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
|
|
||||||
// network: Network.testnet
|
|
||||||
// )
|
|
||||||
// let wallet = try Wallet.newNoPersist(
|
|
||||||
// descriptor: descriptor,
|
|
||||||
// changeDescriptor: nil,
|
|
||||||
// network: .testnet
|
|
||||||
// )
|
|
||||||
// let esploraClient = EsploraClient("https://mempool.space/testnet/api")
|
|
||||||
// let update = esploraClient.scan(wallet, 10, 1)
|
|
||||||
// wallet.applyUpdate(update)
|
|
||||||
//
|
|
||||||
// XCTAssertEqual(wallet.getBalance().total(), 0)
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
34
bdk-swift/Tests/BitcoinDevKitTests/LiveTxBuilderTests.swift
Normal file
34
bdk-swift/Tests/BitcoinDevKitTests/LiveTxBuilderTests.swift
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import XCTest
|
||||||
|
@testable import BitcoinDevKit
|
||||||
|
|
||||||
|
final class LiveTxBuilderTests: XCTestCase {
|
||||||
|
func testTxBuilder() throws {
|
||||||
|
let descriptor = try Descriptor(
|
||||||
|
descriptor: "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
|
||||||
|
network: Network.testnet
|
||||||
|
)
|
||||||
|
let wallet = try Wallet.newNoPersist(
|
||||||
|
descriptor: descriptor,
|
||||||
|
changeDescriptor: nil,
|
||||||
|
network: .testnet
|
||||||
|
)
|
||||||
|
let esploraClient = EsploraClient(url: "https://mempool.space/testnet/api")
|
||||||
|
let update = try esploraClient.scan(
|
||||||
|
wallet: wallet,
|
||||||
|
stopGap: 10,
|
||||||
|
parallelRequests: 1
|
||||||
|
)
|
||||||
|
try wallet.applyUpdate(update: update)
|
||||||
|
|
||||||
|
XCTAssertGreaterThan(wallet.getBalance().total(), UInt64(0), "Wallet must have positive balance, please add funds")
|
||||||
|
|
||||||
|
let recipient: Address = try Address(address: "tb1qrnfslnrve9uncz9pzpvf83k3ukz22ljgees989", network: .testnet)
|
||||||
|
let psbt: PartiallySignedTransaction = try TxBuilder()
|
||||||
|
.addRecipient(script: recipient.scriptPubkey(), amount: 4200)
|
||||||
|
.feeRate(satPerVbyte: 2.0)
|
||||||
|
.finish(wallet: wallet)
|
||||||
|
|
||||||
|
print(psbt.serialize())
|
||||||
|
XCTAssertTrue(psbt.serialize().hasPrefix("cHNi"), "PSBT should start with cHNI")
|
||||||
|
}
|
||||||
|
}
|
25
bdk-swift/Tests/BitcoinDevKitTests/LiveWalletTests.swift
Normal file
25
bdk-swift/Tests/BitcoinDevKitTests/LiveWalletTests.swift
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import XCTest
|
||||||
|
@testable import BitcoinDevKit
|
||||||
|
|
||||||
|
final class LiveWalletTests: XCTestCase {
|
||||||
|
func testSyncedBalance() throws {
|
||||||
|
let descriptor = try Descriptor(
|
||||||
|
descriptor: "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
|
||||||
|
network: Network.testnet
|
||||||
|
)
|
||||||
|
let wallet = try Wallet.newNoPersist(
|
||||||
|
descriptor: descriptor,
|
||||||
|
changeDescriptor: nil,
|
||||||
|
network: .testnet
|
||||||
|
)
|
||||||
|
let esploraClient = EsploraClient(url: "https://mempool.space/testnet/api")
|
||||||
|
let update = try esploraClient.scan(
|
||||||
|
wallet: wallet,
|
||||||
|
stopGap: 10,
|
||||||
|
parallelRequests: 1
|
||||||
|
)
|
||||||
|
try wallet.applyUpdate(update: update)
|
||||||
|
|
||||||
|
XCTAssertGreaterThan(wallet.getBalance().total(), UInt64(0))
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
import XCTest
|
||||||
|
@testable import BitcoinDevKit
|
||||||
|
|
||||||
|
final class OfflineDescriptorTests: XCTestCase {
|
||||||
|
func testDescriptorBip86() throws {
|
||||||
|
let mnemonic: Mnemonic = try Mnemonic.fromString(mnemonic: "space echo position wrist orient erupt relief museum myself grain wisdom tumble")
|
||||||
|
let descriptorSecretKey: DescriptorSecretKey = DescriptorSecretKey(
|
||||||
|
network: Network.testnet,
|
||||||
|
mnemonic: mnemonic,
|
||||||
|
password: nil
|
||||||
|
)
|
||||||
|
let descriptor: Descriptor = Descriptor.newBip86(
|
||||||
|
secretKey: descriptorSecretKey,
|
||||||
|
keychain: KeychainKind.external,
|
||||||
|
network: Network.testnet
|
||||||
|
)
|
||||||
|
|
||||||
|
XCTAssertEqual(descriptor.asString(), "tr([be1eec8f/86'/1'/0']tpubDCTtszwSxPx3tATqDrsSyqScPNnUChwQAVAkanuDUCJQESGBbkt68nXXKRDifYSDbeMa2Xg2euKbXaU3YphvGWftDE7ozRKPriT6vAo3xsc/0/*)#m7puekcx")
|
||||||
|
}
|
||||||
|
}
|
33
bdk-swift/Tests/BitcoinDevKitTests/OfflineWalletTests.swift
Normal file
33
bdk-swift/Tests/BitcoinDevKitTests/OfflineWalletTests.swift
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import XCTest
|
||||||
|
@testable import BitcoinDevKit
|
||||||
|
|
||||||
|
final class OfflineWalletTests: XCTestCase {
|
||||||
|
func testNewAddress() throws {
|
||||||
|
let descriptor: Descriptor = try Descriptor(
|
||||||
|
descriptor: "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
|
||||||
|
network: Network.testnet
|
||||||
|
)
|
||||||
|
let wallet: Wallet = try Wallet.newNoPersist(
|
||||||
|
descriptor: descriptor,
|
||||||
|
changeDescriptor: nil,
|
||||||
|
network: .testnet
|
||||||
|
)
|
||||||
|
let addressInfo: AddressInfo = wallet.getAddress(addressIndex: AddressIndex.new)
|
||||||
|
|
||||||
|
XCTAssertEqual(addressInfo.address.asString(), "tb1qzg4mckdh50nwdm9hkzq06528rsu73hjxxzem3e")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testBalance() throws {
|
||||||
|
let descriptor: Descriptor = try Descriptor(
|
||||||
|
descriptor: "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
|
||||||
|
network: Network.testnet
|
||||||
|
)
|
||||||
|
let wallet: Wallet = try Wallet.newNoPersist(
|
||||||
|
descriptor: descriptor,
|
||||||
|
changeDescriptor: nil,
|
||||||
|
network: .testnet
|
||||||
|
)
|
||||||
|
|
||||||
|
XCTAssertEqual(wallet.getBalance().total(), 0)
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user