diff --git a/README.md b/README.md index 29174858..a82034ce 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ To use the `bdk_flutter` package in your project, add it as a dependency in your ```dart dependencies: - bdk_flutter: ^0.27.1 + bdk_flutter: ^0.27.3 ``` ### Examples diff --git a/example/lib/main.dart b/example/lib/main.dart index 5f3fb8b2..98efb9aa 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -228,8 +228,8 @@ class _MyAppState extends State { final script = await address.scriptPubKey(); final feeRate = await estimateFeeRate(25); final txBuilderResult = await txBuilder - .addRecipient(script, 700) .feeRate(feeRate.asSatPerVb()) + .addRecipient(script, 1200) .finish(bdkWallet); getTransactionDetails(txBuilderResult); final sbt = await bdkWallet.sign(txBuilderResult.psbt); diff --git a/ios/bdk_flutter.podspec b/ios/bdk_flutter.podspec index fbaf6400..576836ab 100644 --- a/ios/bdk_flutter.podspec +++ b/ios/bdk_flutter.podspec @@ -4,7 +4,7 @@ # Pod::Spec.new do |s| s.name = 'bdk_flutter' - s.version = '0.27.1' + s.version = '0.27.3' s.summary = 'A Flutter library for the Bitcoin Development Kit (https://bitcoindevkit.org/)' s.description = <<-DESC A new Flutter project. diff --git a/lib/src/root.dart b/lib/src/root.dart index 7fdb2cc2..ebaccdad 100644 --- a/lib/src/root.dart +++ b/lib/src/root.dart @@ -880,7 +880,7 @@ class TxBuilder { /// Returns a [TxBuilderResult]. Future finish(Wallet wallet) async { - if (_recipients.isEmpty) { + if (_recipients.isEmpty && _drainTo == null) { throw const BdkException.unExpected("No Recipients Added"); } try { @@ -914,6 +914,7 @@ class TxBuilderResult { final PartiallySignedTransaction psbt; ///The transaction details. + /// final TransactionDetails txDetails; TxBuilderResult({required this.psbt, required this.txDetails}); diff --git a/pubspec.yaml b/pubspec.yaml index cdf179b3..d37f8391 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: bdk_flutter description: A Flutter library for the Bitcoin Development Kit(bdk) (https://bitcoindevkit.org/) -version: 0.27.2 +version: 0.27.3 homepage: https://github.com/LtbLightning/bdk-flutter environment: diff --git a/test/bdk_flutter_test.dart b/test/bdk_flutter_test.dart index 89cae6a3..d0735528 100644 --- a/test/bdk_flutter_test.dart +++ b/test/bdk_flutter_test.dart @@ -17,6 +17,7 @@ import 'bdk_flutter_test.mocks.dart'; @GenerateNiceMocks([MockSpec
()]) @GenerateNiceMocks([MockSpec()]) @GenerateNiceMocks([MockSpec()]) +@GenerateNiceMocks([MockSpec()]) void main() { final mockWallet = MockWallet(); final mockSDescriptorSecret = MockDescriptorSecretKey(); @@ -27,6 +28,7 @@ void main() { final mockAddress = MockAddress(); final mockBumpFeeTxBuilder = MockBumpFeeTxBuilder(); final mockScript = MockScript(); + final mockTxBuilderResult = MockTxBuilderResult(); group('Blockchain', () { test('verify getHeight', () async { @@ -157,7 +159,7 @@ void main() { expect(error, isA()); } }); - test('Should return aTxBuilderException when no recipients are added', + test('Should return a TxBuilderException when no recipients are added', () async { try { when(mockTxBuilder.finish(mockWallet)) @@ -168,6 +170,7 @@ void main() { expect(error, isA()); } }); + test('Verify addData() Exception', () async { try { when(mockTxBuilder.addData(data: List.empty())) @@ -185,22 +188,48 @@ void main() { vout: 1)); expect(res, isNot(mockTxBuilder)); }); - test('Create a proper psbt transaction ', () async { - const psbt = "cHNidP8BAHEBAAAAAfU6uDG8hNUox2Qw1nodiir" - "QhnLkDCYpTYfnY4+lUgjFAAAAAAD+////Ag5EAAAAAAAAFgAUxYD3fd+pId3hWxeuvuWmiUlS+1PoAwAAAAAAABYAFP+dpWfmLzDqhlT6HV+9R774474TxqQkAAABAN4" - "BAAAAAAEBViD1JkR+REQpHyOkKYkuVcOIiPzB0wUr8hFmrebQxe8AAAAAAP7///8ClEgAAAAAAAAWABTwV07KrKa1zWpwKzW+ve93pbQ4R+gDAAAAAAAAFgAU/52lZ+YvMOqGVPodX71Hv" - "vjjvhMCRzBEAiAa6a72jEfDuiyaNtlBYAxsc2oSruDWF2vuNQ3rJSshggIgLtJ/YuB8FmhjrPvTC9r2w9gpdfUNLuxw/C7oqo95cEIBIQM9XzutA2SgZFHjPDAATuWwHg19TTkb/NKZD/" - "hfN7fWP8akJAABAR+USAAAAAAAABYAFPBXTsqsprXNanArNb6973eltDhHIgYCHrxaLpnD4ed01bFHcixnAicv15oKiiVHrcVmxUWBW54Y2R5q3VQAAIABAACAAAAAgAEAAABbAAAAACICAqS" - "F0mhBBlgMe9OyICKlkhGHZfPjA0Q03I559ccj9x6oGNkeat1UAACAAQAAgAAAAIABAAAAXAAAAAAA"; + test( + 'Should not return a TxBuilderException when, a drainTo script address is added (with feeRate)', + () async { + when(mockTxBuilder.drainTo("mv4rnyY3Su5gjcDNzbMLKBQkBicCtHUtFB")) + .thenReturn(mockTxBuilder); + when(mockTxBuilder.drainTo("mv4rnyY3Su5gjcDNzbMLKBQkBicCtHUtFB")) + .thenReturn(mockTxBuilder); + when(mockTxBuilder.feeRate(any)).thenReturn(mockTxBuilder); + when(mockTxBuilder.finish(mockWallet)) + .thenAnswer((_) async => mockTxBuilderResult); + final txBuilder = mockTxBuilder + .drainTo("mv4rnyY3Su5gjcDNzbMLKBQkBicCtHUtFB") + .feeRate(25); + final res = await txBuilder.finish(mockWallet); + expect(res.psbt, isA()); + expect(res.txDetails, isA()); + }); + test( + 'Should not return a TxBuilderException when, a drainTo script address is added, instead of addRecipients', + () async { + when(mockTxBuilder.drainTo("mv4rnyY3Su5gjcDNzbMLKBQkBicCtHUtFB")) + .thenReturn(mockTxBuilder); + when(mockTxBuilder.finish(mockWallet)) + .thenAnswer((_) async => mockTxBuilderResult); + final txBuilder = + mockTxBuilder.drainTo("mv4rnyY3Su5gjcDNzbMLKBQkBicCtHUtFB"); + final res = await txBuilder.finish(mockWallet); + expect(res.psbt, isA()); + expect(res.txDetails, isA()); + }); + + test('Create a proper psbt transaction ', () async { when(mockAddress.scriptPubKey()).thenAnswer((_) async => mockScript); when(mockTxBuilder.addRecipient(mockScript, any)) .thenReturn(mockTxBuilder); - + when(mockTxBuilder.finish(mockWallet)) + .thenAnswer((_) async => mockTxBuilderResult); final script = await mockAddress.scriptPubKey(); final txBuilder = mockTxBuilder.addRecipient(script, 1200); final res = await txBuilder.finish(mockWallet); - expect(res.psbt, psbt); + expect(res, mockTxBuilderResult); }); }); group('Bump Fee Tx Builder', () { diff --git a/test/bdk_flutter_test.mocks.dart b/test/bdk_flutter_test.mocks.dart index c7475b80..6096ac28 100644 --- a/test/bdk_flutter_test.mocks.dart +++ b/test/bdk_flutter_test.mocks.dart @@ -1,5 +1,5 @@ -// Mocks generated by Mockito 5.3.2 from annotations -// in bdk_flutter/example/ios/.symlinks/plugins/bdk_flutter/test/bdk_flutter_test.dart. +// Mocks generated by Mockito 5.4.0 from annotations +// in bdk_flutter/test/bdk_flutter_test.dart. // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes @@ -135,6 +135,17 @@ class _FakeScript_10 extends _i1.SmartFake implements _i3.Script { ); } +class _FakeTransactionDetails_11 extends _i1.SmartFake + implements _i2.TransactionDetails { + _FakeTransactionDetails_11( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + /// A class which mocks [Wallet]. /// /// See the documentation for Mockito's code generation for more information. @@ -1114,3 +1125,33 @@ class MockFeeRate extends _i1.Mock implements _i3.FeeRate { returnValueForMissingStub: 0.0, ) as double); } + +/// A class which mocks [TxBuilderResult]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockTxBuilderResult extends _i1.Mock implements _i3.TxBuilderResult { + @override + _i3.PartiallySignedTransaction get psbt => (super.noSuchMethod( + Invocation.getter(#psbt), + returnValue: _FakePartiallySignedTransaction_2( + this, + Invocation.getter(#psbt), + ), + returnValueForMissingStub: _FakePartiallySignedTransaction_2( + this, + Invocation.getter(#psbt), + ), + ) as _i3.PartiallySignedTransaction); + @override + _i2.TransactionDetails get txDetails => (super.noSuchMethod( + Invocation.getter(#txDetails), + returnValue: _FakeTransactionDetails_11( + this, + Invocation.getter(#txDetails), + ), + returnValueForMissingStub: _FakeTransactionDetails_11( + this, + Invocation.getter(#txDetails), + ), + ) as _i2.TransactionDetails); +}