mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-08 19:59:29 +00:00
display xprivs along side mnemonic on backup screen
This commit is contained in:
parent
f22f34904a
commit
cae27b3835
13 changed files with 326 additions and 91 deletions
|
@ -105,6 +105,7 @@ class _UnlockWalletKeysDesktopState
|
|||
WalletKeysDesktopPopup.routeName,
|
||||
arguments: (
|
||||
mnemonic: words ?? [],
|
||||
walletId: widget.walletId,
|
||||
frostData: frostData,
|
||||
),
|
||||
);
|
||||
|
@ -344,6 +345,7 @@ class _UnlockWalletKeysDesktopState
|
|||
WalletKeysDesktopPopup.routeName,
|
||||
arguments: (
|
||||
mnemonic: words ?? [],
|
||||
walletId: widget.walletId,
|
||||
frostData: frostData,
|
||||
),
|
||||
);
|
||||
|
|
|
@ -12,38 +12,46 @@ import 'dart:async';
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import '../../../../notifications/show_flush_bar.dart';
|
||||
import '../../../../pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart';
|
||||
import '../../../../pages/wallet_view/transaction_views/transaction_details_view.dart';
|
||||
import '../../../../providers/providers.dart';
|
||||
import '../../../../themes/stack_colors.dart';
|
||||
import '../../../../utilities/address_utils.dart';
|
||||
import '../../../../utilities/assets.dart';
|
||||
import '../../../../utilities/clipboard_interface.dart';
|
||||
import '../../../../utilities/text_styles.dart';
|
||||
import '../../../../wallets/wallet/wallet_mixin_interfaces/extended_keys_interface.dart';
|
||||
import '../../../../widgets/custom_tab_view.dart';
|
||||
import '../../../../widgets/desktop/desktop_dialog.dart';
|
||||
import '../../../../widgets/desktop/desktop_dialog_close_button.dart';
|
||||
import '../../../../widgets/desktop/primary_button.dart';
|
||||
import '../../../../widgets/desktop/secondary_button.dart';
|
||||
import '../../../../widgets/detail_item.dart';
|
||||
import '../../../../widgets/loading_indicator.dart';
|
||||
import '../../../../widgets/rounded_white_container.dart';
|
||||
import 'qr_code_desktop_popup_content.dart';
|
||||
|
||||
class WalletKeysDesktopPopup extends StatelessWidget {
|
||||
class WalletKeysDesktopPopup extends ConsumerWidget {
|
||||
const WalletKeysDesktopPopup({
|
||||
super.key,
|
||||
required this.words,
|
||||
required this.walletId,
|
||||
this.frostData,
|
||||
this.clipboardInterface = const ClipboardWrapper(),
|
||||
});
|
||||
|
||||
final List<String> words;
|
||||
final String walletId;
|
||||
final ({String keys, String config})? frostData;
|
||||
final ClipboardInterface clipboardInterface;
|
||||
|
||||
static const String routeName = "walletKeysDesktopPopup";
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return DesktopDialog(
|
||||
maxWidth: 614,
|
||||
maxHeight: double.infinity,
|
||||
|
@ -168,94 +176,26 @@ class WalletKeysDesktopPopup extends StatelessWidget {
|
|||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
Text(
|
||||
"Recovery phrase",
|
||||
style: STextStyles.desktopTextMedium(context),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 32,
|
||||
: (ref.watch(pWallets).getWallet(walletId)
|
||||
is ExtendedKeysInterface)
|
||||
? CustomTabView(
|
||||
titles: const ["Mnemonic", "XPriv(s)"],
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 16),
|
||||
child: _Mnemonic(
|
||||
words: words,
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
"Please write down your recovery phrase in the correct order and save it to keep your funds secure. You will also be asked to verify the words on the next screen.",
|
||||
style:
|
||||
STextStyles.desktopTextExtraExtraSmall(context),
|
||||
textAlign: TextAlign.center,
|
||||
_MasterSeedPrivateKey(
|
||||
words: words,
|
||||
walletId: walletId,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: _Mnemonic(
|
||||
words: words,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 32,
|
||||
),
|
||||
child: MnemonicTable(
|
||||
words: words,
|
||||
isDesktop: true,
|
||||
itemBorderColor: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.buttonBackSecondary,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 32,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SecondaryButton(
|
||||
label: "Show QR code",
|
||||
onPressed: () {
|
||||
// TODO: address utils
|
||||
final String value =
|
||||
AddressUtils.encodeQRSeedData(words);
|
||||
Navigator.of(context).pushNamed(
|
||||
QRCodeDesktopPopupContent.routeName,
|
||||
arguments: value,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 16,
|
||||
),
|
||||
Expanded(
|
||||
child: PrimaryButton(
|
||||
label: "Copy",
|
||||
onPressed: () async {
|
||||
await clipboardInterface.setData(
|
||||
ClipboardData(text: words.join(" ")),
|
||||
);
|
||||
if (context.mounted) {
|
||||
unawaited(
|
||||
showFloatingFlushBar(
|
||||
type: FlushBarType.info,
|
||||
message: "Copied to clipboard",
|
||||
iconAsset: Assets.svg.copy,
|
||||
context: context,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 32,
|
||||
),
|
||||
|
@ -264,3 +204,193 @@ class WalletKeysDesktopPopup extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _Mnemonic extends StatelessWidget {
|
||||
const _Mnemonic({
|
||||
super.key,
|
||||
required this.words,
|
||||
this.clipboardInterface = const ClipboardWrapper(),
|
||||
});
|
||||
|
||||
final List<String> words;
|
||||
final ClipboardInterface clipboardInterface;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
"Recovery phrase",
|
||||
style: STextStyles.desktopTextMedium(context),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 32,
|
||||
),
|
||||
child: Text(
|
||||
"Please write down your recovery phrase in the correct order and "
|
||||
"save it to keep your funds secure. You will also be asked to"
|
||||
" verify the words on the next screen.",
|
||||
style: STextStyles.desktopTextExtraExtraSmall(context),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 32,
|
||||
),
|
||||
child: MnemonicTable(
|
||||
words: words,
|
||||
isDesktop: true,
|
||||
itemBorderColor:
|
||||
Theme.of(context).extension<StackColors>()!.buttonBackSecondary,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 32,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SecondaryButton(
|
||||
label: "Show QR code",
|
||||
onPressed: () {
|
||||
// TODO: address utils
|
||||
final String value = AddressUtils.encodeQRSeedData(words);
|
||||
Navigator.of(context).pushNamed(
|
||||
QRCodeDesktopPopupContent.routeName,
|
||||
arguments: value,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 16,
|
||||
),
|
||||
Expanded(
|
||||
child: PrimaryButton(
|
||||
label: "Copy",
|
||||
onPressed: () async {
|
||||
await clipboardInterface.setData(
|
||||
ClipboardData(text: words.join(" ")),
|
||||
);
|
||||
if (context.mounted) {
|
||||
unawaited(
|
||||
showFloatingFlushBar(
|
||||
type: FlushBarType.info,
|
||||
message: "Copied to clipboard",
|
||||
iconAsset: Assets.svg.copy,
|
||||
context: context,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _MasterSeedPrivateKey extends ConsumerStatefulWidget {
|
||||
const _MasterSeedPrivateKey({
|
||||
super.key,
|
||||
required this.words,
|
||||
required this.walletId,
|
||||
this.clipboardInterface = const ClipboardWrapper(),
|
||||
});
|
||||
|
||||
final List<String> words;
|
||||
final String walletId;
|
||||
final ClipboardInterface clipboardInterface;
|
||||
|
||||
@override
|
||||
ConsumerState<_MasterSeedPrivateKey> createState() =>
|
||||
_MasterSeedPrivateKeyState();
|
||||
}
|
||||
|
||||
class _MasterSeedPrivateKeyState extends ConsumerState<_MasterSeedPrivateKey> {
|
||||
final controller = TextEditingController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
FutureBuilder(
|
||||
future: (ref.read(pWallets).getWallet(widget.walletId)
|
||||
as ExtendedKeysInterface)
|
||||
.getXPrivs(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.done &&
|
||||
snapshot.hasData) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
DetailItem(
|
||||
title: "Master fingerprint",
|
||||
detail: snapshot.data!.fingerprint,
|
||||
),
|
||||
...snapshot.data!.xprivs.map(
|
||||
(e) => Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
DetailItem(
|
||||
title: "Derivation",
|
||||
detail: e.path,
|
||||
),
|
||||
DetailItem(
|
||||
title: "xpriv",
|
||||
detail: e.xpriv,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return const LoadingIndicator(
|
||||
width: 100,
|
||||
height: 100,
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2293,11 +2293,13 @@ class RouteGenerator {
|
|||
case WalletKeysDesktopPopup.routeName:
|
||||
if (args is ({
|
||||
List<String> mnemonic,
|
||||
String walletId,
|
||||
({String keys, String config})? frostData
|
||||
})) {
|
||||
return FadePageRoute(
|
||||
WalletKeysDesktopPopup(
|
||||
words: args.mnemonic,
|
||||
walletId: args.walletId,
|
||||
frostData: args.frostData,
|
||||
),
|
||||
RouteSettings(
|
||||
|
|
|
@ -8,12 +8,14 @@ import '../intermediate/bip39_hd_wallet.dart';
|
|||
import '../wallet_mixin_interfaces/coin_control_interface.dart';
|
||||
import '../wallet_mixin_interfaces/cpfp_interface.dart';
|
||||
import '../wallet_mixin_interfaces/electrumx_interface.dart';
|
||||
import '../wallet_mixin_interfaces/extended_keys_interface.dart';
|
||||
import '../wallet_mixin_interfaces/paynym_interface.dart';
|
||||
import '../wallet_mixin_interfaces/rbf_interface.dart';
|
||||
|
||||
class BitcoinWallet<T extends PaynymCurrencyInterface> extends Bip39HDWallet<T>
|
||||
with
|
||||
ElectrumXInterface<T>,
|
||||
ExtendedKeysInterface<T>,
|
||||
CoinControlInterface,
|
||||
PaynymInterface<T>,
|
||||
RbfInterface<T>,
|
||||
|
|
|
@ -19,11 +19,13 @@ import '../wallet_mixin_interfaces/bcash_interface.dart';
|
|||
import '../wallet_mixin_interfaces/cash_fusion_interface.dart';
|
||||
import '../wallet_mixin_interfaces/coin_control_interface.dart';
|
||||
import '../wallet_mixin_interfaces/electrumx_interface.dart';
|
||||
import '../wallet_mixin_interfaces/extended_keys_interface.dart';
|
||||
|
||||
class BitcoincashWallet<T extends ElectrumXCurrencyInterface>
|
||||
extends Bip39HDWallet<T>
|
||||
with
|
||||
ElectrumXInterface<T>,
|
||||
ExtendedKeysInterface<T>,
|
||||
BCashInterface<T>,
|
||||
CoinControlInterface<T>,
|
||||
CashFusionInterface<T> {
|
||||
|
|
|
@ -12,9 +12,10 @@ import '../../crypto_currency/interfaces/electrumx_currency_interface.dart';
|
|||
import '../intermediate/bip39_hd_wallet.dart';
|
||||
import '../wallet_mixin_interfaces/coin_control_interface.dart';
|
||||
import '../wallet_mixin_interfaces/electrumx_interface.dart';
|
||||
import '../wallet_mixin_interfaces/extended_keys_interface.dart';
|
||||
|
||||
class DashWallet<T extends ElectrumXCurrencyInterface> extends Bip39HDWallet<T>
|
||||
with ElectrumXInterface<T>, CoinControlInterface {
|
||||
with ElectrumXInterface<T>, ExtendedKeysInterface<T>, CoinControlInterface {
|
||||
DashWallet(CryptoCurrencyNetwork network) : super(Dash(network) as T);
|
||||
|
||||
@override
|
||||
|
|
|
@ -13,9 +13,11 @@ import '../../crypto_currency/interfaces/electrumx_currency_interface.dart';
|
|||
import '../intermediate/bip39_hd_wallet.dart';
|
||||
import '../wallet_mixin_interfaces/coin_control_interface.dart';
|
||||
import '../wallet_mixin_interfaces/electrumx_interface.dart';
|
||||
import '../wallet_mixin_interfaces/extended_keys_interface.dart';
|
||||
|
||||
class DogecoinWallet<T extends ElectrumXCurrencyInterface>
|
||||
extends Bip39HDWallet<T> with ElectrumXInterface<T>, CoinControlInterface {
|
||||
extends Bip39HDWallet<T>
|
||||
with ElectrumXInterface<T>, ExtendedKeysInterface<T>, CoinControlInterface {
|
||||
DogecoinWallet(CryptoCurrencyNetwork network) : super(Dogecoin(network) as T);
|
||||
|
||||
@override
|
||||
|
|
|
@ -19,10 +19,12 @@ import '../wallet_mixin_interfaces/bcash_interface.dart';
|
|||
import '../wallet_mixin_interfaces/cash_fusion_interface.dart';
|
||||
import '../wallet_mixin_interfaces/coin_control_interface.dart';
|
||||
import '../wallet_mixin_interfaces/electrumx_interface.dart';
|
||||
import '../wallet_mixin_interfaces/extended_keys_interface.dart';
|
||||
|
||||
class EcashWallet<T extends ElectrumXCurrencyInterface> extends Bip39HDWallet<T>
|
||||
with
|
||||
ElectrumXInterface<T>,
|
||||
ExtendedKeysInterface<T>,
|
||||
BCashInterface<T>,
|
||||
CoinControlInterface<T>,
|
||||
CashFusionInterface<T> {
|
||||
|
|
|
@ -22,6 +22,7 @@ import '../../models/tx_data.dart';
|
|||
import '../intermediate/bip39_hd_wallet.dart';
|
||||
import '../wallet_mixin_interfaces/coin_control_interface.dart';
|
||||
import '../wallet_mixin_interfaces/electrumx_interface.dart';
|
||||
import '../wallet_mixin_interfaces/extended_keys_interface.dart';
|
||||
import '../wallet_mixin_interfaces/lelantus_interface.dart';
|
||||
import '../wallet_mixin_interfaces/spark_interface.dart';
|
||||
|
||||
|
@ -30,6 +31,7 @@ const sparkStartBlock = 819300; // (approx 18 Jan 2024)
|
|||
class FiroWallet<T extends ElectrumXCurrencyInterface> extends Bip39HDWallet<T>
|
||||
with
|
||||
ElectrumXInterface<T>,
|
||||
ExtendedKeysInterface<T>,
|
||||
LelantusInterface<T>,
|
||||
SparkInterface<T>,
|
||||
CoinControlInterface<T> {
|
||||
|
|
|
@ -15,6 +15,7 @@ import '../../crypto_currency/interfaces/electrumx_currency_interface.dart';
|
|||
import '../intermediate/bip39_hd_wallet.dart';
|
||||
import '../wallet_mixin_interfaces/coin_control_interface.dart';
|
||||
import '../wallet_mixin_interfaces/electrumx_interface.dart';
|
||||
import '../wallet_mixin_interfaces/extended_keys_interface.dart';
|
||||
import '../wallet_mixin_interfaces/ordinals_interface.dart';
|
||||
import '../wallet_mixin_interfaces/rbf_interface.dart';
|
||||
|
||||
|
@ -22,6 +23,7 @@ class LitecoinWallet<T extends ElectrumXCurrencyInterface>
|
|||
extends Bip39HDWallet<T>
|
||||
with
|
||||
ElectrumXInterface<T>,
|
||||
ExtendedKeysInterface<T>,
|
||||
CoinControlInterface<T>,
|
||||
RbfInterface<T>,
|
||||
OrdinalsInterface<T> {
|
||||
|
|
|
@ -19,10 +19,14 @@ import '../../models/tx_data.dart';
|
|||
import '../intermediate/bip39_hd_wallet.dart';
|
||||
import '../wallet_mixin_interfaces/coin_control_interface.dart';
|
||||
import '../wallet_mixin_interfaces/electrumx_interface.dart';
|
||||
import '../wallet_mixin_interfaces/extended_keys_interface.dart';
|
||||
|
||||
class ParticlWallet<T extends ElectrumXCurrencyInterface>
|
||||
extends Bip39HDWallet<T>
|
||||
with ElectrumXInterface<T>, CoinControlInterface<T> {
|
||||
with
|
||||
ElectrumXInterface<T>,
|
||||
ExtendedKeysInterface<T>,
|
||||
CoinControlInterface<T> {
|
||||
@override
|
||||
int get isarTransactionVersion => 2;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:isar/isar.dart';
|
||||
|
||||
import '../../../models/isar/models/blockchain_data/address.dart';
|
||||
import '../../../models/isar/models/blockchain_data/transaction.dart';
|
||||
import '../../../models/isar/models/blockchain_data/v2/input_v2.dart';
|
||||
|
@ -11,10 +12,14 @@ import '../../crypto_currency/interfaces/electrumx_currency_interface.dart';
|
|||
import '../intermediate/bip39_hd_wallet.dart';
|
||||
import '../wallet_mixin_interfaces/coin_control_interface.dart';
|
||||
import '../wallet_mixin_interfaces/electrumx_interface.dart';
|
||||
import '../wallet_mixin_interfaces/extended_keys_interface.dart';
|
||||
|
||||
class PeercoinWallet<T extends ElectrumXCurrencyInterface>
|
||||
extends Bip39HDWallet<T>
|
||||
with ElectrumXInterface<T>, CoinControlInterface<T> {
|
||||
with
|
||||
ElectrumXInterface<T>,
|
||||
ExtendedKeysInterface<T>,
|
||||
CoinControlInterface<T> {
|
||||
@override
|
||||
int get isarTransactionVersion => 2;
|
||||
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
import '../../crypto_currency/interfaces/electrumx_currency_interface.dart';
|
||||
import 'electrumx_interface.dart';
|
||||
|
||||
typedef XPub = ({String path, String xpub});
|
||||
typedef XPriv = ({String path, String xpriv});
|
||||
|
||||
mixin ExtendedKeysInterface<T extends ElectrumXCurrencyInterface>
|
||||
on ElectrumXInterface<T> {
|
||||
Future<({List<XPub> xpubs, String fingerprint})> getXPubs() async {
|
||||
final paths = cryptoCurrency.supportedDerivationPathTypes.map(
|
||||
(e) => (
|
||||
path: e,
|
||||
addressType: e.getAddressType(),
|
||||
),
|
||||
);
|
||||
|
||||
final master = await getRootHDNode();
|
||||
final fingerprint = master.fingerprint.toRadixString(16);
|
||||
|
||||
final futures = paths.map((e) async {
|
||||
String path = cryptoCurrency.constructDerivePath(
|
||||
derivePathType: e.path,
|
||||
chain: 0,
|
||||
index: 0,
|
||||
);
|
||||
// trim chain and address index
|
||||
path = path.substring(0, path.lastIndexOf("'") + 1);
|
||||
final node = master.derivePath(path);
|
||||
|
||||
return (
|
||||
path: path,
|
||||
xpub: node.hdPublicKey.encode(
|
||||
cryptoCurrency.networkParams.pubHDPrefix,
|
||||
// 0x04b24746,
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
fingerprint: fingerprint,
|
||||
xpubs: await Future.wait(futures),
|
||||
);
|
||||
}
|
||||
|
||||
Future<({List<XPriv> xprivs, String fingerprint})> getXPrivs() async {
|
||||
final paths = cryptoCurrency.supportedDerivationPathTypes.map(
|
||||
(e) => (
|
||||
path: e,
|
||||
addressType: e.getAddressType(),
|
||||
),
|
||||
);
|
||||
|
||||
final master = await getRootHDNode();
|
||||
final fingerprint = master.fingerprint.toRadixString(16);
|
||||
|
||||
final futures = paths.map((e) async {
|
||||
String path = cryptoCurrency.constructDerivePath(
|
||||
derivePathType: e.path,
|
||||
chain: 0,
|
||||
index: 0,
|
||||
);
|
||||
// trim chain and address index
|
||||
path = path.substring(0, path.lastIndexOf("'") + 1);
|
||||
final node = master.derivePath(path);
|
||||
|
||||
return (
|
||||
path: path,
|
||||
xpriv: node.encode(
|
||||
cryptoCurrency.networkParams.privHDPrefix,
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
fingerprint: fingerprint,
|
||||
xprivs: await Future.wait(futures),
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue