From b8c8473459c518be99836ab3a1153916884f5787 Mon Sep 17 00:00:00 2001 From: Jeremiah Jacob Date: Tue, 23 Jun 2026 02:27:49 +0100 Subject: [PATCH 1/7] test: cover wallet creation SQLite lifecycle --- test/integration/wallet_creation_test.dart | 121 +++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 test/integration/wallet_creation_test.dart diff --git a/test/integration/wallet_creation_test.dart b/test/integration/wallet_creation_test.dart new file mode 100644 index 0000000..8784673 --- /dev/null +++ b/test/integration/wallet_creation_test.dart @@ -0,0 +1,121 @@ +// @Tags(['integration']) + +import 'dart:io'; + +import 'package:bdk_dart/bdk.dart'; +import 'package:test/test.dart'; + +import '../test_constants.dart'; + +Future _deleteDirectoryWithRetry(Directory directory) async { + for (var attempt = 0; attempt < 10; attempt++) { + try { + if (directory.existsSync()) { + await directory.delete(recursive: true); + } + return; + } on PathAccessException { + await Future.delayed(const Duration(milliseconds: 100)); + } + } + + if (directory.existsSync()) { + await directory.delete(recursive: true); + } +} + +void main() { + group('Wallet creation integration', () { + test('persists derivation state across a SQLite reopen', () { + final tempDir = Directory.systemTemp.createTempSync( + 'bdk_dart_wallet_creation_', + ); + addTearDown(() => _deleteDirectoryWithRetry(tempDir)); + + final dbPath = '${tempDir.path}/wallet.sqlite'; + final descriptor = buildBip84Descriptor(Network.testnet); + final changeDescriptor = buildBip84ChangeDescriptor(Network.testnet); + Persister? persister; + Wallet? wallet; + Persister? reopenedPersister; + Wallet? reopenedWallet; + + try { + expect(File(dbPath).existsSync(), isFalse); + + final initialPersister = Persister.newSqlite(path: dbPath); + persister = initialPersister; + + wallet = Wallet( + descriptor: descriptor, + changeDescriptor: changeDescriptor, + network: Network.testnet, + persister: initialPersister, + lookahead: defaultLookahead, + ); + + final externalAddress = wallet.revealNextAddress( + keychain: KeychainKind.external_, + ); + final internalAddress = wallet.revealNextAddress( + keychain: KeychainKind.internal, + ); + + expect(externalAddress.index, equals(0)); + expect(internalAddress.index, equals(0)); + expect(wallet.persist(persister: initialPersister), isTrue); + + wallet.dispose(); + wallet = null; + persister.dispose(); + persister = null; + + expect(File(dbPath).existsSync(), isTrue); + + reopenedPersister = Persister.newSqlite(path: dbPath); + reopenedWallet = Wallet.load( + descriptor: descriptor, + changeDescriptor: changeDescriptor, + persister: reopenedPersister, + lookahead: defaultLookahead, + ); + + expect(reopenedWallet.network(), equals(Network.testnet)); + expect(reopenedWallet.balance().total.toSat(), equals(0)); + expect( + reopenedWallet.nextDerivationIndex(keychain: KeychainKind.external_), + equals(1), + ); + expect( + reopenedWallet.nextDerivationIndex(keychain: KeychainKind.internal), + equals(1), + ); + + final reopenedExternalAddress = reopenedWallet.peekAddress( + keychain: KeychainKind.external_, + index: externalAddress.index, + ); + final reopenedInternalAddress = reopenedWallet.peekAddress( + keychain: KeychainKind.internal, + index: internalAddress.index, + ); + + expect( + reopenedExternalAddress.address.scriptPubkey().toBytes(), + orderedEquals(externalAddress.address.scriptPubkey().toBytes()), + ); + expect( + reopenedInternalAddress.address.scriptPubkey().toBytes(), + orderedEquals(internalAddress.address.scriptPubkey().toBytes()), + ); + } finally { + reopenedWallet?.dispose(); + reopenedPersister?.dispose(); + wallet?.dispose(); + persister?.dispose(); + descriptor.dispose(); + changeDescriptor.dispose(); + } + }); + }); +} From df2299d6c9939dedabc4fd199a7eaa6509e887c4 Mon Sep 17 00:00:00 2001 From: Jeremiah Jacob Date: Fri, 26 Jun 2026 12:12:51 +0100 Subject: [PATCH 2/7] test: cover multiple SQLite wallet address reveals --- test/integration/wallet_creation_test.dart | 103 +++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/test/integration/wallet_creation_test.dart b/test/integration/wallet_creation_test.dart index 8784673..334501e 100644 --- a/test/integration/wallet_creation_test.dart +++ b/test/integration/wallet_creation_test.dart @@ -117,5 +117,108 @@ void main() { changeDescriptor.dispose(); } }); + + test('cover multiple SQLite wallet address reveals', () { + final tempDir = Directory.systemTemp.createTempSync( + 'bdk_dart_wallet_creation_test1_', + ); + addTearDown(() => _deleteDirectoryWithRetry(tempDir)); + + final dbPath = '${tempDir.path}/wallet.sqlite'; + final descriptor = buildBip84Descriptor(Network.testnet); + final changeDescriptor = buildBip84ChangeDescriptor(Network.testnet); + Persister? persister; + Wallet? wallet; + Persister? reopenedPersister; + Wallet? reopenedWallet; + + try { + final initialPersister = Persister.newSqlite(path: dbPath); + persister = initialPersister; + + wallet = Wallet( + descriptor: descriptor, + changeDescriptor: changeDescriptor, + network: Network.testnet, + persister: initialPersister, + lookahead: defaultLookahead, + ); + + final ext0 = wallet.revealNextAddress(keychain: KeychainKind.external_); + final ext1 = wallet.revealNextAddress(keychain: KeychainKind.external_); + final ext2 = wallet.revealNextAddress(keychain: KeychainKind.external_); + final int0 = wallet.revealNextAddress(keychain: KeychainKind.internal); + + expect(ext0.index, equals(0)); + expect(ext1.index, equals(1)); + expect(ext2.index, equals(2)); + expect(int0.index, equals(0)); + + expect(wallet.persist(persister: initialPersister), isTrue); + + wallet.dispose(); + wallet = null; + persister.dispose(); + persister = null; + + reopenedPersister = Persister.newSqlite(path: dbPath); + reopenedWallet = Wallet.load( + descriptor: descriptor, + changeDescriptor: changeDescriptor, + persister: reopenedPersister, + lookahead: defaultLookahead, + ); + + expect( + reopenedWallet.nextDerivationIndex(keychain: KeychainKind.external_), + equals(3), + ); + expect( + reopenedWallet.nextDerivationIndex(keychain: KeychainKind.internal), + equals(1), + ); + + final reopenedExt0 = reopenedWallet.peekAddress( + keychain: KeychainKind.external_, + index: 0, + ); + final reopenedExt1 = reopenedWallet.peekAddress( + keychain: KeychainKind.external_, + index: 1, + ); + final reopenedExt2 = reopenedWallet.peekAddress( + keychain: KeychainKind.external_, + index: 2, + ); + final reopenedInt0 = reopenedWallet.peekAddress( + keychain: KeychainKind.internal, + index: 0, + ); + + expect( + reopenedExt0.address.scriptPubkey().toBytes(), + orderedEquals(ext0.address.scriptPubkey().toBytes()), + ); + expect( + reopenedExt1.address.scriptPubkey().toBytes(), + orderedEquals(ext1.address.scriptPubkey().toBytes()), + ); + expect( + reopenedExt2.address.scriptPubkey().toBytes(), + orderedEquals(ext2.address.scriptPubkey().toBytes()), + ); + expect( + reopenedInt0.address.scriptPubkey().toBytes(), + orderedEquals(int0.address.scriptPubkey().toBytes()), + ); + } finally { + reopenedWallet?.dispose(); + reopenedPersister?.dispose(); + wallet?.dispose(); + persister?.dispose(); + descriptor.dispose(); + changeDescriptor.dispose(); + } + }); }); } From 75c360f3b7d7a6d9a53cf96c959286daf336267a Mon Sep 17 00:00:00 2001 From: Jeremiah Jacob Date: Fri, 26 Jun 2026 12:13:04 +0100 Subject: [PATCH 3/7] test: cover explicit SQLite wallet persist contract --- test/integration/wallet_creation_test.dart | 61 ++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/test/integration/wallet_creation_test.dart b/test/integration/wallet_creation_test.dart index 334501e..dc3e7c3 100644 --- a/test/integration/wallet_creation_test.dart +++ b/test/integration/wallet_creation_test.dart @@ -220,5 +220,66 @@ void main() { changeDescriptor.dispose(); } }); + + test('cover explicit SQLite wallet persist contract', () { + final tempDir = Directory.systemTemp.createTempSync( + 'bdk_dart_wallet_creation_test2_', + ); + addTearDown(() => _deleteDirectoryWithRetry(tempDir)); + + final dbPath = '${tempDir.path}/wallet.sqlite'; + final descriptor = buildBip84Descriptor(Network.testnet); + final changeDescriptor = buildBip84ChangeDescriptor(Network.testnet); + Persister? persister; + Wallet? wallet; + Persister? reopenedPersister; + Wallet? reopenedWallet; + + try { + final initialPersister = Persister.newSqlite(path: dbPath); + persister = initialPersister; + + wallet = Wallet( + descriptor: descriptor, + changeDescriptor: changeDescriptor, + network: Network.testnet, + persister: initialPersister, + lookahead: defaultLookahead, + ); + + final ext0 = wallet.revealNextAddress(keychain: KeychainKind.external_); + expect(ext0.index, equals(0)); + + expect(wallet.persist(persister: initialPersister), isTrue); + + final ext1 = wallet.revealNextAddress(keychain: KeychainKind.external_); + expect(ext1.index, equals(1)); + + wallet.dispose(); + wallet = null; + persister.dispose(); + persister = null; + + reopenedPersister = Persister.newSqlite(path: dbPath); + reopenedWallet = Wallet.load( + descriptor: descriptor, + changeDescriptor: changeDescriptor, + persister: reopenedPersister, + lookahead: defaultLookahead, + ); + + expect( + reopenedWallet.nextDerivationIndex(keychain: KeychainKind.external_), + equals(1), + ); + } finally { + reopenedWallet?.dispose(); + reopenedPersister?.dispose(); + wallet?.dispose(); + persister?.dispose(); + descriptor.dispose(); + changeDescriptor.dispose(); + } + }); }); } From f483bb530befc6137d8c2eabc5751c825a21bd04 Mon Sep 17 00:00:00 2001 From: Jeremiah Jacob Date: Fri, 26 Jun 2026 12:13:18 +0100 Subject: [PATCH 4/7] test: cover independent SQLite keychain indexes --- test/integration/wallet_creation_test.dart | 91 ++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/test/integration/wallet_creation_test.dart b/test/integration/wallet_creation_test.dart index dc3e7c3..36ad054 100644 --- a/test/integration/wallet_creation_test.dart +++ b/test/integration/wallet_creation_test.dart @@ -281,5 +281,96 @@ void main() { changeDescriptor.dispose(); } }); + + test('cover independent SQLite keychain indexes', () { + final tempDir = Directory.systemTemp.createTempSync( + 'bdk_dart_wallet_creation_test3_', + ); + addTearDown(() => _deleteDirectoryWithRetry(tempDir)); + + final dbPath = '${tempDir.path}/wallet.sqlite'; + final descriptor = buildBip84Descriptor(Network.testnet); + final changeDescriptor = buildBip84ChangeDescriptor(Network.testnet); + Persister? persister; + Wallet? wallet; + Persister? reopenedPersister; + Wallet? reopenedWallet; + + try { + final initialPersister = Persister.newSqlite(path: dbPath); + persister = initialPersister; + + wallet = Wallet( + descriptor: descriptor, + changeDescriptor: changeDescriptor, + network: Network.testnet, + persister: initialPersister, + lookahead: defaultLookahead, + ); + + final ext0 = wallet.revealNextAddress(keychain: KeychainKind.external_); + final ext1 = wallet.revealNextAddress(keychain: KeychainKind.external_); + final ext2 = wallet.revealNextAddress(keychain: KeychainKind.external_); + + final int0 = wallet.revealNextAddress(keychain: KeychainKind.internal); + final int1 = wallet.revealNextAddress(keychain: KeychainKind.internal); + + expect(ext0.index, equals(0)); + expect(ext1.index, equals(1)); + expect(ext2.index, equals(2)); + + expect(int0.index, equals(0)); + expect(int1.index, equals(1)); + + expect(wallet.persist(persister: initialPersister), isTrue); + + wallet.dispose(); + wallet = null; + persister.dispose(); + persister = null; + + reopenedPersister = Persister.newSqlite(path: dbPath); + reopenedWallet = Wallet.load( + descriptor: descriptor, + changeDescriptor: changeDescriptor, + persister: reopenedPersister, + lookahead: defaultLookahead, + ); + + expect( + reopenedWallet.nextDerivationIndex(keychain: KeychainKind.external_), + equals(3), + ); + expect( + reopenedWallet.nextDerivationIndex(keychain: KeychainKind.internal), + equals(2), + ); + + final reopenedExt1 = reopenedWallet.peekAddress( + keychain: KeychainKind.external_, + index: 1, + ); + final reopenedInt0 = reopenedWallet.peekAddress( + keychain: KeychainKind.internal, + index: 0, + ); + + expect( + reopenedExt1.address.scriptPubkey().toBytes(), + orderedEquals(ext1.address.scriptPubkey().toBytes()), + ); + expect( + reopenedInt0.address.scriptPubkey().toBytes(), + orderedEquals(int0.address.scriptPubkey().toBytes()), + ); + } finally { + reopenedWallet?.dispose(); + reopenedPersister?.dispose(); + wallet?.dispose(); + persister?.dispose(); + descriptor.dispose(); + changeDescriptor.dispose(); + } + }); }); } From 22670a298fb1a2bcd51d006140f9ecdf18495d04 Mon Sep 17 00:00:00 2001 From: Jeremiah Jacob Date: Mon, 13 Jul 2026 17:57:35 +0100 Subject: [PATCH 5/7] test: move SQLite lifecycle coverage to offline suite --- ...test.dart => wallet_creation_sqlite_lifecycle_test.dart} | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) rename test/{integration/wallet_creation_test.dart => wallet_creation_sqlite_lifecycle_test.dart} (99%) diff --git a/test/integration/wallet_creation_test.dart b/test/wallet_creation_sqlite_lifecycle_test.dart similarity index 99% rename from test/integration/wallet_creation_test.dart rename to test/wallet_creation_sqlite_lifecycle_test.dart index 36ad054..7c99cff 100644 --- a/test/integration/wallet_creation_test.dart +++ b/test/wallet_creation_sqlite_lifecycle_test.dart @@ -1,11 +1,9 @@ -// @Tags(['integration']) - import 'dart:io'; import 'package:bdk_dart/bdk.dart'; import 'package:test/test.dart'; -import '../test_constants.dart'; +import 'test_constants.dart'; Future _deleteDirectoryWithRetry(Directory directory) async { for (var attempt = 0; attempt < 10; attempt++) { @@ -25,7 +23,7 @@ Future _deleteDirectoryWithRetry(Directory directory) async { } void main() { - group('Wallet creation integration', () { + group('Wallet creation SQLite lifecycle', () { test('persists derivation state across a SQLite reopen', () { final tempDir = Directory.systemTemp.createTempSync( 'bdk_dart_wallet_creation_', From cb61e9e07597b9fb97bf1b70341547f906d3d188 Mon Sep 17 00:00:00 2001 From: Jeremiah Jacob Date: Mon, 13 Jul 2026 18:06:10 +0100 Subject: [PATCH 6/7] style: format generated bindings --- lib/bdk.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/bdk.dart b/lib/bdk.dart index b17e358..5f03221 100644 --- a/lib/bdk.dart +++ b/lib/bdk.dart @@ -26231,6 +26231,7 @@ mixin FfiConverterPrimitive on FfiConverter { @override T lower(T value) => value; } + Uint8List createUint8ListFromInt(int value) { int length = value.bitLength ~/ 8 + 1; if (length != 4 && length != 8) { From f364f5b594da6c42bdc0fb67d0738705006fcea7 Mon Sep 17 00:00:00 2001 From: Jeremiah Jacob Date: Tue, 14 Jul 2026 11:34:32 +0100 Subject: [PATCH 7/7] test: refine SQLite wallet lifecycle coverage --- lib/bdk.dart | 1 - ...wallet_creation_sqlite_lifecycle_test.dart | 456 +++++++----------- 2 files changed, 164 insertions(+), 293 deletions(-) diff --git a/lib/bdk.dart b/lib/bdk.dart index 5f03221..b17e358 100644 --- a/lib/bdk.dart +++ b/lib/bdk.dart @@ -26231,7 +26231,6 @@ mixin FfiConverterPrimitive on FfiConverter { @override T lower(T value) => value; } - Uint8List createUint8ListFromInt(int value) { int length = value.bitLength ~/ 8 + 1; if (length != 4 && length != 8) { diff --git a/test/wallet_creation_sqlite_lifecycle_test.dart b/test/wallet_creation_sqlite_lifecycle_test.dart index 7c99cff..19b3b43 100644 --- a/test/wallet_creation_sqlite_lifecycle_test.dart +++ b/test/wallet_creation_sqlite_lifecycle_test.dart @@ -24,9 +24,153 @@ Future _deleteDirectoryWithRetry(Directory directory) async { void main() { group('Wallet creation SQLite lifecycle', () { - test('persists derivation state across a SQLite reopen', () { + test( + 'persists external and internal derivation state across SQLite reopen', + () { + final tempDir = Directory.systemTemp.createTempSync( + 'bdk_dart_wallet_creation_', + ); + addTearDown(() => _deleteDirectoryWithRetry(tempDir)); + + final dbPath = '${tempDir.path}/wallet.sqlite'; + final descriptor = buildBip84Descriptor(Network.testnet); + final changeDescriptor = buildBip84ChangeDescriptor(Network.testnet); + Persister? persister; + Wallet? wallet; + Address? externalAddress; + Address? internalAddress; + Script? externalScript; + Script? internalScript; + Persister? reopenedPersister; + Wallet? reopenedWallet; + Address? reopenedExternalAddress; + Address? reopenedInternalAddress; + Script? reopenedExternalScript; + Script? reopenedInternalScript; + + try { + expect(File(dbPath).existsSync(), isFalse); + + persister = Persister.newSqlite(path: dbPath); + wallet = Wallet( + descriptor: descriptor, + changeDescriptor: changeDescriptor, + network: Network.testnet, + persister: persister, + lookahead: defaultLookahead, + ); + + final extAddressInfo = wallet.revealNextAddress( + keychain: KeychainKind.external_, + ); + externalAddress = extAddressInfo.address; + + final intAddressInfo = wallet.revealNextAddress( + keychain: KeychainKind.internal, + ); + internalAddress = intAddressInfo.address; + + expect(extAddressInfo.index, equals(0)); + expect(intAddressInfo.index, equals(0)); + expect(wallet.persist(persister: persister), isTrue); + + externalScript = externalAddress.scriptPubkey(); + final extBytes = externalScript.toBytes(); + + internalScript = internalAddress.scriptPubkey(); + final intBytes = internalScript.toBytes(); + + // Dispose temporary address and script objects + externalScript.dispose(); + externalScript = null; + externalAddress.dispose(); + externalAddress = null; + + internalScript.dispose(); + internalScript = null; + internalAddress.dispose(); + internalAddress = null; + + wallet.dispose(); + wallet = null; + persister.dispose(); + persister = null; + + expect(File(dbPath).existsSync(), isTrue); + + reopenedPersister = Persister.newSqlite(path: dbPath); + reopenedWallet = Wallet.load( + descriptor: descriptor, + changeDescriptor: changeDescriptor, + persister: reopenedPersister, + lookahead: defaultLookahead, + ); + + expect(reopenedWallet.network(), equals(Network.testnet)); + + final balance = reopenedWallet.balance(); + final balanceSat = balance.total.toSat(); + balance.immature.dispose(); + balance.trustedPending.dispose(); + balance.untrustedPending.dispose(); + balance.confirmed.dispose(); + balance.trustedSpendable.dispose(); + balance.total.dispose(); + + expect(balanceSat, equals(0)); + expect( + reopenedWallet.nextDerivationIndex( + keychain: KeychainKind.external_, + ), + equals(1), + ); + expect( + reopenedWallet.nextDerivationIndex(keychain: KeychainKind.internal), + equals(1), + ); + + final reopenedExtAddressInfo = reopenedWallet.peekAddress( + keychain: KeychainKind.external_, + index: 0, + ); + reopenedExternalAddress = reopenedExtAddressInfo.address; + + final reopenedIntAddressInfo = reopenedWallet.peekAddress( + keychain: KeychainKind.internal, + index: 0, + ); + reopenedInternalAddress = reopenedIntAddressInfo.address; + + reopenedExternalScript = reopenedExternalAddress.scriptPubkey(); + final reopenedExtBytes = reopenedExternalScript.toBytes(); + + reopenedInternalScript = reopenedInternalAddress.scriptPubkey(); + final reopenedIntBytes = reopenedInternalScript.toBytes(); + + expect(reopenedExtBytes, orderedEquals(extBytes)); + expect(reopenedIntBytes, orderedEquals(intBytes)); + } finally { + reopenedInternalScript?.dispose(); + reopenedExternalScript?.dispose(); + reopenedInternalAddress?.dispose(); + reopenedExternalAddress?.dispose(); + reopenedWallet?.dispose(); + reopenedPersister?.dispose(); + internalScript?.dispose(); + externalScript?.dispose(); + internalAddress?.dispose(); + externalAddress?.dispose(); + wallet?.dispose(); + persister?.dispose(); + descriptor.dispose(); + changeDescriptor.dispose(); + } + }, + ); + + test('does not restore derivation changes made after the last persist', () { final tempDir = Directory.systemTemp.createTempSync( - 'bdk_dart_wallet_creation_', + 'bdk_dart_wallet_creation_test2_', ); addTearDown(() => _deleteDirectoryWithRetry(tempDir)); @@ -35,223 +179,40 @@ void main() { final changeDescriptor = buildBip84ChangeDescriptor(Network.testnet); Persister? persister; Wallet? wallet; + Address? externalAddress0; + Address? externalAddress1; Persister? reopenedPersister; Wallet? reopenedWallet; try { - expect(File(dbPath).existsSync(), isFalse); - - final initialPersister = Persister.newSqlite(path: dbPath); - persister = initialPersister; - + persister = Persister.newSqlite(path: dbPath); wallet = Wallet( descriptor: descriptor, changeDescriptor: changeDescriptor, network: Network.testnet, - persister: initialPersister, + persister: persister, lookahead: defaultLookahead, ); - final externalAddress = wallet.revealNextAddress( + final extAddressInfo0 = wallet.revealNextAddress( keychain: KeychainKind.external_, ); - final internalAddress = wallet.revealNextAddress( - keychain: KeychainKind.internal, - ); + externalAddress0 = extAddressInfo0.address; + expect(extAddressInfo0.index, equals(0)); - expect(externalAddress.index, equals(0)); - expect(internalAddress.index, equals(0)); - expect(wallet.persist(persister: initialPersister), isTrue); - - wallet.dispose(); - wallet = null; - persister.dispose(); - persister = null; - - expect(File(dbPath).existsSync(), isTrue); - - reopenedPersister = Persister.newSqlite(path: dbPath); - reopenedWallet = Wallet.load( - descriptor: descriptor, - changeDescriptor: changeDescriptor, - persister: reopenedPersister, - lookahead: defaultLookahead, - ); - - expect(reopenedWallet.network(), equals(Network.testnet)); - expect(reopenedWallet.balance().total.toSat(), equals(0)); - expect( - reopenedWallet.nextDerivationIndex(keychain: KeychainKind.external_), - equals(1), - ); - expect( - reopenedWallet.nextDerivationIndex(keychain: KeychainKind.internal), - equals(1), - ); + expect(wallet.persist(persister: persister), isTrue); - final reopenedExternalAddress = reopenedWallet.peekAddress( + final extAddressInfo1 = wallet.revealNextAddress( keychain: KeychainKind.external_, - index: externalAddress.index, - ); - final reopenedInternalAddress = reopenedWallet.peekAddress( - keychain: KeychainKind.internal, - index: internalAddress.index, - ); - - expect( - reopenedExternalAddress.address.scriptPubkey().toBytes(), - orderedEquals(externalAddress.address.scriptPubkey().toBytes()), - ); - expect( - reopenedInternalAddress.address.scriptPubkey().toBytes(), - orderedEquals(internalAddress.address.scriptPubkey().toBytes()), - ); - } finally { - reopenedWallet?.dispose(); - reopenedPersister?.dispose(); - wallet?.dispose(); - persister?.dispose(); - descriptor.dispose(); - changeDescriptor.dispose(); - } - }); - - test('cover multiple SQLite wallet address reveals', () { - final tempDir = Directory.systemTemp.createTempSync( - 'bdk_dart_wallet_creation_test1_', - ); - addTearDown(() => _deleteDirectoryWithRetry(tempDir)); - - final dbPath = '${tempDir.path}/wallet.sqlite'; - final descriptor = buildBip84Descriptor(Network.testnet); - final changeDescriptor = buildBip84ChangeDescriptor(Network.testnet); - Persister? persister; - Wallet? wallet; - Persister? reopenedPersister; - Wallet? reopenedWallet; - - try { - final initialPersister = Persister.newSqlite(path: dbPath); - persister = initialPersister; - - wallet = Wallet( - descriptor: descriptor, - changeDescriptor: changeDescriptor, - network: Network.testnet, - persister: initialPersister, - lookahead: defaultLookahead, - ); - - final ext0 = wallet.revealNextAddress(keychain: KeychainKind.external_); - final ext1 = wallet.revealNextAddress(keychain: KeychainKind.external_); - final ext2 = wallet.revealNextAddress(keychain: KeychainKind.external_); - final int0 = wallet.revealNextAddress(keychain: KeychainKind.internal); - - expect(ext0.index, equals(0)); - expect(ext1.index, equals(1)); - expect(ext2.index, equals(2)); - expect(int0.index, equals(0)); - - expect(wallet.persist(persister: initialPersister), isTrue); - - wallet.dispose(); - wallet = null; - persister.dispose(); - persister = null; - - reopenedPersister = Persister.newSqlite(path: dbPath); - reopenedWallet = Wallet.load( - descriptor: descriptor, - changeDescriptor: changeDescriptor, - persister: reopenedPersister, - lookahead: defaultLookahead, - ); - - expect( - reopenedWallet.nextDerivationIndex(keychain: KeychainKind.external_), - equals(3), - ); - expect( - reopenedWallet.nextDerivationIndex(keychain: KeychainKind.internal), - equals(1), - ); - - final reopenedExt0 = reopenedWallet.peekAddress( - keychain: KeychainKind.external_, - index: 0, - ); - final reopenedExt1 = reopenedWallet.peekAddress( - keychain: KeychainKind.external_, - index: 1, - ); - final reopenedExt2 = reopenedWallet.peekAddress( - keychain: KeychainKind.external_, - index: 2, - ); - final reopenedInt0 = reopenedWallet.peekAddress( - keychain: KeychainKind.internal, - index: 0, - ); - - expect( - reopenedExt0.address.scriptPubkey().toBytes(), - orderedEquals(ext0.address.scriptPubkey().toBytes()), - ); - expect( - reopenedExt1.address.scriptPubkey().toBytes(), - orderedEquals(ext1.address.scriptPubkey().toBytes()), - ); - expect( - reopenedExt2.address.scriptPubkey().toBytes(), - orderedEquals(ext2.address.scriptPubkey().toBytes()), - ); - expect( - reopenedInt0.address.scriptPubkey().toBytes(), - orderedEquals(int0.address.scriptPubkey().toBytes()), - ); - } finally { - reopenedWallet?.dispose(); - reopenedPersister?.dispose(); - wallet?.dispose(); - persister?.dispose(); - descriptor.dispose(); - changeDescriptor.dispose(); - } - }); - - test('cover explicit SQLite wallet persist contract', () { - final tempDir = Directory.systemTemp.createTempSync( - 'bdk_dart_wallet_creation_test2_', - ); - addTearDown(() => _deleteDirectoryWithRetry(tempDir)); - - final dbPath = '${tempDir.path}/wallet.sqlite'; - final descriptor = buildBip84Descriptor(Network.testnet); - final changeDescriptor = buildBip84ChangeDescriptor(Network.testnet); - Persister? persister; - Wallet? wallet; - Persister? reopenedPersister; - Wallet? reopenedWallet; - - try { - final initialPersister = Persister.newSqlite(path: dbPath); - persister = initialPersister; - - wallet = Wallet( - descriptor: descriptor, - changeDescriptor: changeDescriptor, - network: Network.testnet, - persister: initialPersister, - lookahead: defaultLookahead, ); + externalAddress1 = extAddressInfo1.address; + expect(extAddressInfo1.index, equals(1)); - final ext0 = wallet.revealNextAddress(keychain: KeychainKind.external_); - expect(ext0.index, equals(0)); - - expect(wallet.persist(persister: initialPersister), isTrue); - - final ext1 = wallet.revealNextAddress(keychain: KeychainKind.external_); - expect(ext1.index, equals(1)); + // Dispose original wallet and persister before reopening + externalAddress0.dispose(); + externalAddress0 = null; + externalAddress1.dispose(); + externalAddress1 = null; wallet.dispose(); wallet = null; @@ -273,97 +234,8 @@ void main() { } finally { reopenedWallet?.dispose(); reopenedPersister?.dispose(); - wallet?.dispose(); - persister?.dispose(); - descriptor.dispose(); - changeDescriptor.dispose(); - } - }); - - test('cover independent SQLite keychain indexes', () { - final tempDir = Directory.systemTemp.createTempSync( - 'bdk_dart_wallet_creation_test3_', - ); - addTearDown(() => _deleteDirectoryWithRetry(tempDir)); - - final dbPath = '${tempDir.path}/wallet.sqlite'; - final descriptor = buildBip84Descriptor(Network.testnet); - final changeDescriptor = buildBip84ChangeDescriptor(Network.testnet); - Persister? persister; - Wallet? wallet; - Persister? reopenedPersister; - Wallet? reopenedWallet; - - try { - final initialPersister = Persister.newSqlite(path: dbPath); - persister = initialPersister; - - wallet = Wallet( - descriptor: descriptor, - changeDescriptor: changeDescriptor, - network: Network.testnet, - persister: initialPersister, - lookahead: defaultLookahead, - ); - - final ext0 = wallet.revealNextAddress(keychain: KeychainKind.external_); - final ext1 = wallet.revealNextAddress(keychain: KeychainKind.external_); - final ext2 = wallet.revealNextAddress(keychain: KeychainKind.external_); - - final int0 = wallet.revealNextAddress(keychain: KeychainKind.internal); - final int1 = wallet.revealNextAddress(keychain: KeychainKind.internal); - - expect(ext0.index, equals(0)); - expect(ext1.index, equals(1)); - expect(ext2.index, equals(2)); - - expect(int0.index, equals(0)); - expect(int1.index, equals(1)); - - expect(wallet.persist(persister: initialPersister), isTrue); - - wallet.dispose(); - wallet = null; - persister.dispose(); - persister = null; - - reopenedPersister = Persister.newSqlite(path: dbPath); - reopenedWallet = Wallet.load( - descriptor: descriptor, - changeDescriptor: changeDescriptor, - persister: reopenedPersister, - lookahead: defaultLookahead, - ); - - expect( - reopenedWallet.nextDerivationIndex(keychain: KeychainKind.external_), - equals(3), - ); - expect( - reopenedWallet.nextDerivationIndex(keychain: KeychainKind.internal), - equals(2), - ); - - final reopenedExt1 = reopenedWallet.peekAddress( - keychain: KeychainKind.external_, - index: 1, - ); - final reopenedInt0 = reopenedWallet.peekAddress( - keychain: KeychainKind.internal, - index: 0, - ); - - expect( - reopenedExt1.address.scriptPubkey().toBytes(), - orderedEquals(ext1.address.scriptPubkey().toBytes()), - ); - expect( - reopenedInt0.address.scriptPubkey().toBytes(), - orderedEquals(int0.address.scriptPubkey().toBytes()), - ); - } finally { - reopenedWallet?.dispose(); - reopenedPersister?.dispose(); + externalAddress1?.dispose(); + externalAddress0?.dispose(); wallet?.dispose(); persister?.dispose(); descriptor.dispose();