Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Post testing fixes #151

Merged
merged 6 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
## [0.31.3]

## [0.31.2]
Updated `flutter_rust_bridge` to `2.0.0`.
#### APIs added
Expand Down Expand Up @@ -174,4 +176,4 @@ Updated API to match bdk-ffi
- Create Transaction
- Sign Transaction
- Broadcast Transaction
- Quick Send
- Quick Send
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: ^0.31.3
```

### Examples
Expand Down
2 changes: 1 addition & 1 deletion analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
include: package:lints/recommended.yaml
include: package:lints/core.yaml
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

Expand Down
63 changes: 0 additions & 63 deletions example/integration_test /full_cycle_test.dart

This file was deleted.

167 changes: 167 additions & 0 deletions example/integration_test /multi_sig_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
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';

/// Derives extended descriptor keys (secret and public) based on the provided
/// hardened and unhardened derivation paths and mnemonic.
Future<(DescriptorSecretKey, DescriptorPublicKey)> deriveDescriptorKeys(
DerivationPath hardenedPath,
DerivationPath unHardenedPath,
Mnemonic mnemonic,
) async {
// Create the root secret key from the mnemonic
final secretKey = await DescriptorSecretKey.create(
mnemonic: mnemonic, network: Network.signet);

// Derive the key at the hardened path
final derivedSecretKey = await secretKey.derive(hardenedPath);

// Extend the derived secret key further using the unhardened path
final derivedExtendedSecretKey =
await derivedSecretKey.extend(unHardenedPath);

// Convert the derived secret key to its public counterpart
final publicKey = derivedSecretKey.toPublic();

// Extend the public key using the same unhardened path
final derivedExtendedPublicKey = await publicKey.extend(path: unHardenedPath);

return (derivedExtendedSecretKey, derivedExtendedPublicKey);
}

/// Constructs a wallet descriptor using timelock conditions and public keys.
String createWalletDescriptor(
String primaryReceivingSecret, // Alice's descriptor derived from m/0
String secondaryReceivingPublic, // Bob's public key derived from m/0
int primaryTimelock, // Alice's timelock
int secondaryTimelock, // Bob's timelock
String primaryChangePublic, // Alice's public key derived from m/1
String secondaryChangePublic, // Bob's public key derived from m/1
) {
// Define the multi-sig condition based on timelock priority
String multi = (primaryTimelock < secondaryTimelock)
? 'multi(2,$primaryReceivingSecret,$secondaryReceivingPublic)'
: 'multi(2,$secondaryReceivingPublic,$primaryReceivingSecret)';

// Define the timelock conditions for Bob and Alice
String timelockBob =
'and_v(v:older($secondaryTimelock),pk($secondaryChangePublic))';
String timelockAlice =
'and_v(v:older($primaryTimelock),pk($primaryChangePublic))';

// Combine the timelock conditions
String timelockCondition = (primaryTimelock < secondaryTimelock)
? 'or_i($timelockAlice,$timelockBob)'
: 'or_i($timelockBob,$timelockAlice)';

// Return the final wallet descriptor
return 'wsh(or_d($multi,$timelockCondition))';
}

void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

group('Time-locked multi-sig wallet synchronization', () {
setUp(() async {
// Setup for test group
});

test("Alice and Bob should have the same initial address and balance",
() async {
// Define mnemonics for Alice and Bob
final alice = await Mnemonic.fromString(
'thumb member wage display inherit music elevator need side setup tube panther broom giant auction banner split potato');
final bob = await Mnemonic.fromString(
'tired shine hat tired hover timber reward bridge verb aerobic safe economy');

// Define timelocks for Alice and Bob
const aliceTimelock = 25;
const bobTimeLock = 35;

// Define derivation paths
final hardenedDerivationPath =
await DerivationPath.create(path: "m/84h/1h/0h");
final receivingDerivationPath = await DerivationPath.create(path: "m/0");
final changeDerivationPath = await DerivationPath.create(path: "m/1");

// Derive keys for Alice
final (aliceReceivingSecretKey, aliceReceivingPublicKey) =
await deriveDescriptorKeys(
hardenedDerivationPath, receivingDerivationPath, alice);
final (aliceChangeSecretKey, aliceChangePublicKey) =
await deriveDescriptorKeys(
hardenedDerivationPath, changeDerivationPath, alice);

// Derive keys for Bob
final (bobReceivingSecretKey, bobReceivingPublicKey) =
await deriveDescriptorKeys(
hardenedDerivationPath, receivingDerivationPath, bob);
final (bobChangeSecretKey, bobChangePublicKey) =
await deriveDescriptorKeys(
hardenedDerivationPath, changeDerivationPath, bob);

// Create wallet descriptors for Alice and Bob
final aliceDescriptor = createWalletDescriptor(
aliceReceivingSecretKey.toString(),
bobReceivingPublicKey.toString(),
aliceTimelock,
bobTimeLock,
aliceChangePublicKey.toString(),
bobChangePublicKey.toString());
final bobDescriptor = createWalletDescriptor(
bobReceivingSecretKey.toString(),
aliceReceivingPublicKey.toString(),
bobTimeLock,
aliceTimelock,
bobChangePublicKey.toString(),
aliceChangePublicKey.toString());

// Debug print descriptors
debugPrint("Alice's descriptor: $aliceDescriptor");
debugPrint("Bob's descriptor: $bobDescriptor");

// Create wallets
final aliceWallet = await Wallet.create(
descriptor: await Descriptor.create(
descriptor: aliceDescriptor, network: Network.signet),
network: Network.signet,
databaseConfig: const DatabaseConfig.memory());
final bobWallet = await Wallet.create(
descriptor: await Descriptor.create(
descriptor: bobDescriptor, network: Network.signet),
network: Network.signet,
databaseConfig: const DatabaseConfig.memory());

// Get initial addresses
final aliceAddress = aliceWallet
.getAddress(addressIndex: const AddressIndex.peek(index: 0))
.address
.toString();
final bobAddress = bobWallet
.getAddress(addressIndex: const AddressIndex.peek(index: 0))
.address
.toString();
assert(aliceAddress == bobAddress, "Addresses should match");

debugPrint("Alice's receiving address: $aliceAddress");
debugPrint("Bob's receiving address: $bobAddress");

// Sync wallets
final blockchain = await Blockchain.createMutinynet();
debugPrint("Syncing Bob's wallet...");
await bobWallet.sync(blockchain: blockchain);
debugPrint("Syncing Alice's wallet...");
await aliceWallet.sync(blockchain: blockchain);
debugPrint("Synchronization complete");

// Check balances
final bobBalance = bobWallet.getBalance().total.toInt();
final aliceBalance = aliceWallet.getBalance().total.toInt();
assert(bobBalance == aliceBalance, "Balances should match");

debugPrint("Alice's balance: $aliceBalance");
debugPrint("Bob's balance: $bobBalance");
});
});
}
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 ExampleWallet());
}
97 changes: 0 additions & 97 deletions example/lib/multi_sig_wallet.dart

This file was deleted.

8 changes: 4 additions & 4 deletions example/lib/simple_wallet.dart → example/lib/wallet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import 'package:flutter/material.dart';

import 'bdk_library.dart';

class SimpleWallet extends StatefulWidget {
const SimpleWallet({super.key});
class ExampleWallet extends StatefulWidget {
const ExampleWallet({super.key});

@override
State<SimpleWallet> createState() => _SimpleWalletState();
State<ExampleWallet> createState() => _ExampleWalletState();
}

class _SimpleWalletState extends State<SimpleWallet> {
class _ExampleWalletState extends State<ExampleWallet> {
String displayText = "";
BigInt balance = BigInt.zero;
late Wallet wallet;
Expand Down
2 changes: 1 addition & 1 deletion example/macos/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
PODS:
- bdk_flutter (0.31.2):
- bdk_flutter (0.31.3):
- FlutterMacOS
- FlutterMacOS (1.0.0)

Expand Down
Loading
Loading