Skip to content

Commit

Permalink
Merge branch 'main' into v1.0.0-alpha.11
Browse files Browse the repository at this point in the history
  • Loading branch information
BitcoinZavior committed Nov 8, 2024
1 parent 2fbb172 commit 8f01157
Show file tree
Hide file tree
Showing 59 changed files with 73,327 additions and 45,817 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
## [1.0.0-alpha.11]

## [0.31.2]
Updated `flutter_rust_bridge` to `2.0.0`.
#### APIs added
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ To use the `bdk_flutter` package in your project, add it as a dependency in your

```dart
dependencies:
bdk_flutter: ^0.31.2
bdk_flutter: "1.0.0-alpha.11"
```

### Examples
Expand Down
48 changes: 48 additions & 0 deletions example/integration_test/full_cycle_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import 'package:bdk_flutter/bdk_flutter.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';

void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
group('Descriptor & Keys', () {
setUp(() async {});
testWidgets('Muti-sig wallet generation', (_) async {
final descriptor = await Descriptor.create(
descriptor:
"wsh(or_d(pk([24d87569/84'/1'/0'/0/0]tpubDHebJGZWZaZ3JkhwTx5DytaRpFhK9ffFaN9PMBm7m63bdkdxqKgXkSPMzYzfDAGStx8LWt4b2CgGm86BwtNuG6PdsxsLVmuf6EjREX3oHjL/0/0/*),and_v(v:older(12),pk([24d87569/84'/1'/0'/0/0]tpubDHebJGZWZaZ3JkhwTx5DytaRpFhK9ffFaN9PMBm7m63bdkdxqKgXkSPMzYzfDAGStx8LWt4b2CgGm86BwtNuG6PdsxsLVmuf6EjREX3oHjL/0/1/*))))",
network: Network.testnet);
final changeDescriptor = await Descriptor.create(
descriptor:
"wsh(or_d(pk([24d87569/84'/1'/0'/1/0]tpubDHebJGZWZaZ3JkhwTx5DytaRpFhK9ffFaN9PMBm7m63bdkdxqKgXkSPMzYzfDAGStx8LWt4b2CgGm86BwtNuG6PdsxsLVmuf6EjREX3oHjL/1/0/*),and_v(v:older(12),pk([24d87569/84'/1'/0'/1/0]tpubDHebJGZWZaZ3JkhwTx5DytaRpFhK9ffFaN9PMBm7m63bdkdxqKgXkSPMzYzfDAGStx8LWt4b2CgGm86BwtNuG6PdsxsLVmuf6EjREX3oHjL/1/1/*))))",
network: Network.testnet);

final wallet = await Wallet.create(
descriptor: descriptor,
changeDescriptor: changeDescriptor,
network: Network.testnet,
connection: await Connection.createInMemory());
debugPrint(wallet.network().toString());
});
testWidgets('Derive descriptorSecretKey Manually', (_) async {
final mnemonic = await Mnemonic.create(WordCount.words12);
final descriptorSecretKey = await DescriptorSecretKey.create(
network: Network.testnet, mnemonic: mnemonic);
debugPrint(descriptorSecretKey.toString());

for (var e in [0, 1]) {
final derivationPath =
await DerivationPath.create(path: "m/84'/1'/0'/$e");
final derivedDescriptorSecretKey =
await descriptorSecretKey.derive(derivationPath);
debugPrint(derivedDescriptorSecretKey.toString());
debugPrint(derivedDescriptorSecretKey.toPublic().toString());
final descriptor = await Descriptor.create(
descriptor: "wpkh($derivedDescriptorSecretKey)",
network: Network.testnet);

debugPrint(descriptor.toString());
}
});
});
}
2 changes: 1 addition & 1 deletion example/ios/Runner/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import UIKit
import Flutter

@UIApplicationMain
@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
Expand Down
138 changes: 82 additions & 56 deletions example/lib/bdk_library.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,70 +7,105 @@ class BdkLibrary {
return res;
}

Future<Descriptor> createDescriptor(Mnemonic mnemonic) async {
Future<List<Descriptor>> createDescriptor(Mnemonic mnemonic) async {
final descriptorSecretKey = await DescriptorSecretKey.create(
network: Network.signet,
mnemonic: mnemonic,
);
if (kDebugMode) {
print(descriptorSecretKey.toPublic());
print(descriptorSecretKey.secretBytes());
print(descriptorSecretKey);
}

final descriptor = await Descriptor.newBip84(
secretKey: descriptorSecretKey,
network: Network.signet,
keychain: KeychainKind.externalChain);
return descriptor;
}

Future<Blockchain> initializeBlockchain() async {
return Blockchain.createMutinynet();
final changeDescriptor = await Descriptor.newBip84(
secretKey: descriptorSecretKey,
network: Network.signet,
keychain: KeychainKind.internalChain);
return [descriptor, changeDescriptor];
}

Future<Wallet> restoreWallet(Descriptor descriptor) async {
final wallet = await Wallet.create(
descriptor: descriptor,
network: Network.testnet,
databaseConfig: const DatabaseConfig.memory());
return wallet;
Future<EsploraClient> initializeBlockchain() async {
return EsploraClient.createMutinynet();
}

Future<void> sync(Blockchain blockchain, Wallet wallet) async {
Future<Wallet> crateOrLoadWallet(Descriptor descriptor,
Descriptor changeDescriptor, Connection connection) async {
try {
await wallet.sync(blockchain: blockchain);
} on FormatException catch (e) {
debugPrint(e.message);
final wallet = await Wallet.create(
descriptor: descriptor,
changeDescriptor: changeDescriptor,
network: Network.signet,
connection: connection);
return wallet;
} on CreateWithPersistException catch (e) {
if (e.code == "DatabaseExists") {
final res = await Wallet.load(
descriptor: descriptor,
changeDescriptor: changeDescriptor,
connection: connection);
return res;
} else {
rethrow;
}
}
}

AddressInfo getAddressInfo(Wallet wallet) {
return wallet.getAddress(addressIndex: const AddressIndex.increase());
Future<void> sync(
EsploraClient esploraClient, Wallet wallet, bool fullScan) async {
try {
if (fullScan) {
final fullScanRequestBuilder = await wallet.startFullScan();
final fullScanRequest = await (await fullScanRequestBuilder
.inspectSpksForAllKeychains(inspector: (e, f, g) {
debugPrint(
"Syncing: index: ${f.toString()}, script: ${g.toString()}");
}))
.build();
final update = await esploraClient.fullScan(
request: fullScanRequest,
stopGap: BigInt.from(1),
parallelRequests: BigInt.from(1));
await wallet.applyUpdate(update: update);
} else {
final syncRequestBuilder = await wallet.startSyncWithRevealedSpks();
final syncRequest = await (await syncRequestBuilder.inspectSpks(
inspector: (script, progress) {
debugPrint(
"syncing spk: ${(progress.spksConsumed / (progress.spksConsumed + progress.spksRemaining)) * 100} %");
}))
.build();
final update = await esploraClient.sync(
request: syncRequest, parallelRequests: BigInt.from(1));
await wallet.applyUpdate(update: update);
}
} on Exception catch (e) {
debugPrint(e.toString());
}
}

Future<Input> getPsbtInput(
Wallet wallet, LocalUtxo utxo, bool onlyWitnessUtxo) async {
final input =
await wallet.getPsbtInput(utxo: utxo, onlyWitnessUtxo: onlyWitnessUtxo);
return input;
AddressInfo revealNextAddress(Wallet wallet) {
return wallet.revealNextAddress(keychainKind: KeychainKind.externalChain);
}

List<TransactionDetails> getUnConfirmedTransactions(Wallet wallet) {
List<TransactionDetails> unConfirmed = [];
final res = wallet.listTransactions(includeRaw: true);
List<CanonicalTx> getUnConfirmedTransactions(Wallet wallet) {
List<CanonicalTx> unConfirmed = [];
final res = wallet.transactions();
for (var e in res) {
if (e.confirmationTime == null) unConfirmed.add(e);
if (e.chainPosition
.maybeMap(orElse: () => false, unconfirmed: (_) => true)) {
unConfirmed.add(e);
}
}
return unConfirmed;
}

List<TransactionDetails> getConfirmedTransactions(Wallet wallet) {
List<TransactionDetails> confirmed = [];
final res = wallet.listTransactions(includeRaw: true);

List<CanonicalTx> getConfirmedTransactions(Wallet wallet) {
List<CanonicalTx> confirmed = [];
final res = wallet.transactions();
for (var e in res) {
if (e.confirmationTime != null) confirmed.add(e);
if (e.chainPosition
.maybeMap(orElse: () => false, confirmed: (_) => true)) {
confirmed.add(e);
}
}
return confirmed;
}
Expand All @@ -79,39 +114,30 @@ class BdkLibrary {
return wallet.getBalance();
}

List<LocalUtxo> listUnspent(Wallet wallet) {
List<LocalOutput> listUnspent(Wallet wallet) {
return wallet.listUnspent();
}

Future<FeeRate> estimateFeeRate(
int blocks,
Blockchain blockchain,
) async {
final feeRate = await blockchain.estimateFee(target: BigInt.from(blocks));
return feeRate;
}

sendBitcoin(Blockchain blockchain, Wallet wallet, String receiverAddress,
sendBitcoin(EsploraClient blockchain, Wallet wallet, String receiverAddress,
int amountSat) async {
try {
final txBuilder = TxBuilder();
final address = await Address.fromString(
s: receiverAddress, network: wallet.network());
final script = address.scriptPubkey();
final feeRate = await estimateFeeRate(25, blockchain);
final (psbt, _) = await txBuilder
.addRecipient(script, BigInt.from(amountSat))
.feeRate(feeRate.satPerVb)
final unspentUtxo =
wallet.listUnspent().firstWhere((e) => e.isSpent == false);
final psbt = await txBuilder
.addRecipient(address.script(), BigInt.from(amountSat))
.addUtxo(unspentUtxo.outpoint)
.finish(wallet);
final isFinalized = await wallet.sign(psbt: psbt);
if (isFinalized) {
final tx = psbt.extractTx();
final res = await blockchain.broadcast(transaction: tx);
debugPrint(res);
await blockchain.broadcast(transaction: tx);
debugPrint(tx.computeTxid());
} else {
debugPrint("psbt not finalized!");
}
// Isolate.run(() async => {});
} on Exception catch (_) {
rethrow;
}
Expand Down
4 changes: 2 additions & 2 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:bdk_flutter_example/simple_wallet.dart';
import 'package:bdk_flutter_example/wallet.dart';
import 'package:flutter/material.dart';

void main() {
runApp(const SimpleWallet());
runApp(const BdkWallet());
}
97 changes: 0 additions & 97 deletions example/lib/multi_sig_wallet.dart

This file was deleted.

Loading

0 comments on commit 8f01157

Please sign in to comment.