WIP add cosigners to wallet, print derived addresses for debugging

and upgrade bip48 to 0.0.4 so we can pass our custom Network
This commit is contained in:
sneurlax 2024-12-30 00:21:26 -06:00
parent 1e5236a8a4
commit 04816dc2ea
3 changed files with 58 additions and 25 deletions

View file

@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:bip48/bip48.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
@ -8,7 +9,10 @@ import '../../../../themes/stack_colors.dart';
import '../../../../utilities/text_styles.dart'; import '../../../../utilities/text_styles.dart';
import '../../../../widgets/background.dart'; import '../../../../widgets/background.dart';
import '../../../providers/global/wallets_provider.dart'; import '../../../providers/global/wallets_provider.dart';
import '../../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart'; import '../../../utilities/enums/derive_path_type_enum.dart';
import '../../../wallets/crypto_currency/coins/bip48_bitcoin.dart';
import '../../../wallets/crypto_currency/crypto_currency.dart';
import '../../../wallets/wallet/intermediate/bip39_hd_wallet.dart';
import '../../../widgets/custom_buttons/app_bar_icon_button.dart'; import '../../../widgets/custom_buttons/app_bar_icon_button.dart';
import '../../../widgets/desktop/primary_button.dart'; import '../../../widgets/desktop/primary_button.dart';
import '../../../widgets/desktop/secondary_button.dart'; import '../../../widgets/desktop/secondary_button.dart';
@ -70,6 +74,7 @@ class MultisigCoordinatorView extends ConsumerStatefulWidget {
class _MultisigSetupViewState extends ConsumerState<MultisigCoordinatorView> { class _MultisigSetupViewState extends ConsumerState<MultisigCoordinatorView> {
final List<TextEditingController> xpubControllers = []; final List<TextEditingController> xpubControllers = [];
late Bip48Wallet _multisigWallet;
String _myXpub = ""; String _myXpub = "";
// bool _isNfcAvailable = false; // bool _isNfcAvailable = false;
// String _nfcStatus = 'Checking NFC availability...'; // String _nfcStatus = 'Checking NFC availability...';
@ -83,21 +88,38 @@ class _MultisigSetupViewState extends ConsumerState<MultisigCoordinatorView> {
xpubControllers.add(TextEditingController()); xpubControllers.add(TextEditingController());
} }
// Get and set my xpub. // Initialize wallet and set xpub.
WidgetsBinding.instance.addPostFrameCallback((_) async { WidgetsBinding.instance.addPostFrameCallback((_) async {
final targetPath = _getTargetPathForScriptType(widget.scriptType); final wallet = await (ref.read(pWallets).getWallet(widget.walletId)
final xpubData = await (ref.read(pWallets).getWallet(widget.walletId) as Bip39HDWallet);
as ExtendedKeysInterface) final master = await wallet.getRootHDNode();
.getXPubs(bip48: true, account: widget.account);
print(xpubData);
final matchingPub = xpubData.xpubs.firstWhere( final node = master.derivePath(BIP48Bitcoin(wallet.cryptoCurrency.network)
(pub) => pub.path == targetPath, .constructDerivePath(
orElse: () => XPub(path: "", encoded: "xPub not found!"), derivePathType: widget.scriptType == MultisigScriptType.segwit
? DerivePathType.bip48p2shp2wsh
: DerivePathType.bip48p2wsh,
chain: wallet.cryptoCurrency.network == CryptoCurrencyNetwork.main
? 0
: 1, // TODO: Support coins other than Bitcoin.
index: widget.scriptType == MultisigScriptType.segwit ? 1 : 2));
_multisigWallet = Bip48Wallet(
accountXpub: node.hdPublicKey.encode(
wallet.cryptoCurrency.networkParams.pubHDPrefix,
),
coinType: wallet.cryptoCurrency.network == CryptoCurrencyNetwork.main
? 0
: 1, // TODO: Support coins other than Bitcoin.
account: widget.account,
scriptType: Bip48ScriptType.p2shMultisig,
threshold: widget.threshold,
totalKeys: widget.participants,
network: wallet.cryptoCurrency.networkParams,
); );
if (matchingPub.path.isNotEmpty && mounted) { if (mounted) {
setState(() => _myXpub = matchingPub.encoded); setState(() => _myXpub = _multisigWallet.accountXpub);
} }
}); });
@ -247,7 +269,7 @@ class _MultisigSetupViewState extends ConsumerState<MultisigCoordinatorView> {
text: _myXpub), text: _myXpub),
enabled: false, enabled: false,
decoration: InputDecoration( decoration: InputDecoration(
hintText: "xPub...", hintText: "Loading xPub...",
hintStyle: hintStyle:
STextStyles.fieldLabel(context), STextStyles.fieldLabel(context),
filled: true, filled: true,
@ -395,15 +417,25 @@ class _MultisigSetupViewState extends ConsumerState<MultisigCoordinatorView> {
label: "Create multisignature account", label: "Create multisignature account",
enabled: xpubControllers.every( enabled: xpubControllers.every(
(controller) => controller.text.isNotEmpty), (controller) => controller.text.isNotEmpty),
onPressed: () { onPressed: () async {
// final privWallet = Bip48Wallet( final _newWallet = _multisigWallet;
// masterKey: masterKey,
// coinType: 0, // Add cosigners.
// account: 0, for (final controller in xpubControllers) {
// scriptType: Bip48ScriptType.p2shMultisig, _newWallet.addCosignerXpub(controller.text);
// threshold: 2, // TODO: handle error on InvalidBase58Checksum.
// totalKeys: 3, }
// );
print(
'First receiving address: ${_newWallet.deriveMultisigAddress(0, isChange: false)}');
print(
'First change address: ${_newWallet.deriveMultisigAddress(0, isChange: true)}');
// TODO: Show multisig params (script type,
// threshold, participants, account index) for
// backup then create new wallet which is a copy
// of the current one with the additional multisig
// params as a BIP48BitcoinWallet.
}, },
), ),
], ],
@ -432,7 +464,7 @@ class MultisigCoordinatorData {
const MultisigCoordinatorData({ const MultisigCoordinatorData({
this.threshold = 2, this.threshold = 2,
this.participants = 3, this.participants = 3,
this.coinType = 0, // Bitcoin mainnet. this.coinType = 0, // Bitcoin mainnet by default, can be overridden.
this.account = 0, this.account = 0,
this.scriptType = MultisigScriptType.nativeSegwit, this.scriptType = MultisigScriptType.nativeSegwit,
this.cosignerXpubs = const [], this.cosignerXpubs = const [],

View file

@ -23,6 +23,7 @@ final multisigSetupStateProvider =
}); });
class MultisigSetupData { class MultisigSetupData {
// These default values are overridden by the inputs' onChanged methods.
const MultisigSetupData({ const MultisigSetupData({
this.threshold = 2, this.threshold = 2,
this.participants = 3, this.participants = 3,
@ -594,7 +595,7 @@ class _MultisigSetupViewState extends ConsumerState<MultisigSetupView> {
MaterialPageRoute<void>( MaterialPageRoute<void>(
builder: (context) => MultisigCoordinatorView( builder: (context) => MultisigCoordinatorView(
walletId: widget.walletId, walletId: widget.walletId,
scriptType: setupData.scriptType, // TODO, scriptType: setupData.scriptType,
participants: int.parse(_participantsController.text), participants: int.parse(_participantsController.text),
threshold: int.parse(_thresholdController.text), threshold: int.parse(_thresholdController.text),
account: int.parse(_accountController.text), account: int.parse(_accountController.text),

View file

@ -205,7 +205,7 @@ dependencies:
cs_monero: 1.0.0-pre.1 cs_monero: 1.0.0-pre.1
cs_monero_flutter_libs: 1.0.0-pre.0 cs_monero_flutter_libs: 1.0.0-pre.0
nfc_manager: ^3.5.0 nfc_manager: ^3.5.0
bip48: ^0.0.3 bip48: ^0.0.4
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: