mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-08 19:59:29 +00:00
feat: add account index selection
This commit is contained in:
parent
94d7f566b7
commit
1e5236a8a4
4 changed files with 131 additions and 53 deletions
|
@ -28,8 +28,8 @@ class MultisigCoordinatorState extends StateNotifier<MultisigCoordinatorData> {
|
||||||
state = state.copyWith(threshold: threshold);
|
state = state.copyWith(threshold: threshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateTotalCosigners(int total) {
|
void updateParticipants(int total) {
|
||||||
state = state.copyWith(totalCosigners: total);
|
state = state.copyWith(participants: total);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateScriptType(MultisigScriptType type) {
|
void updateScriptType(MultisigScriptType type) {
|
||||||
|
@ -37,7 +37,7 @@ class MultisigCoordinatorState extends StateNotifier<MultisigCoordinatorData> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void addCosignerXpub(String xpub) {
|
void addCosignerXpub(String xpub) {
|
||||||
if (state.cosignerXpubs.length < state.totalCosigners) {
|
if (state.cosignerXpubs.length < state.participants) {
|
||||||
state = state.copyWith(
|
state = state.copyWith(
|
||||||
cosignerXpubs: [...state.cosignerXpubs, xpub],
|
cosignerXpubs: [...state.cosignerXpubs, xpub],
|
||||||
);
|
);
|
||||||
|
@ -50,14 +50,16 @@ class MultisigCoordinatorView extends ConsumerStatefulWidget {
|
||||||
super.key,
|
super.key,
|
||||||
required this.walletId,
|
required this.walletId,
|
||||||
required this.scriptType,
|
required this.scriptType,
|
||||||
required this.totalCosigners,
|
required this.participants,
|
||||||
required this.threshold,
|
required this.threshold,
|
||||||
|
required this.account,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String walletId;
|
final String walletId;
|
||||||
final MultisigScriptType scriptType;
|
final MultisigScriptType scriptType;
|
||||||
final int totalCosigners;
|
final int participants;
|
||||||
final int threshold;
|
final int threshold;
|
||||||
|
final int account;
|
||||||
|
|
||||||
static const String routeName = "/multisigCoordinator";
|
static const String routeName = "/multisigCoordinator";
|
||||||
|
|
||||||
|
@ -77,7 +79,7 @@ class _MultisigSetupViewState extends ConsumerState<MultisigCoordinatorView> {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
// Initialize controllers.
|
// Initialize controllers.
|
||||||
for (int i = 0; i < widget.totalCosigners - 1; i++) {
|
for (int i = 0; i < widget.participants - 1; i++) {
|
||||||
xpubControllers.add(TextEditingController());
|
xpubControllers.add(TextEditingController());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +88,7 @@ class _MultisigSetupViewState extends ConsumerState<MultisigCoordinatorView> {
|
||||||
final targetPath = _getTargetPathForScriptType(widget.scriptType);
|
final targetPath = _getTargetPathForScriptType(widget.scriptType);
|
||||||
final xpubData = await (ref.read(pWallets).getWallet(widget.walletId)
|
final xpubData = await (ref.read(pWallets).getWallet(widget.walletId)
|
||||||
as ExtendedKeysInterface)
|
as ExtendedKeysInterface)
|
||||||
.getXPubs(bip48: true);
|
.getXPubs(bip48: true, account: widget.account);
|
||||||
print(xpubData);
|
print(xpubData);
|
||||||
|
|
||||||
final matchingPub = xpubData.xpubs.firstWhere(
|
final matchingPub = xpubData.xpubs.firstWhere(
|
||||||
|
@ -300,7 +302,7 @@ class _MultisigSetupViewState extends ConsumerState<MultisigCoordinatorView> {
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
|
|
||||||
// Generate input fields for each cosigner.
|
// Generate input fields for each cosigner.
|
||||||
for (int i = 1; i < widget.totalCosigners; i++)
|
for (int i = 1; i < widget.participants; i++)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 16),
|
padding: const EdgeInsets.only(bottom: 16),
|
||||||
child: Column(
|
child: Column(
|
||||||
|
@ -394,7 +396,14 @@ class _MultisigSetupViewState extends ConsumerState<MultisigCoordinatorView> {
|
||||||
enabled: xpubControllers.every(
|
enabled: xpubControllers.every(
|
||||||
(controller) => controller.text.isNotEmpty),
|
(controller) => controller.text.isNotEmpty),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
// TODO.
|
// final privWallet = Bip48Wallet(
|
||||||
|
// masterKey: masterKey,
|
||||||
|
// coinType: 0,
|
||||||
|
// account: 0,
|
||||||
|
// scriptType: Bip48ScriptType.p2shMultisig,
|
||||||
|
// threshold: 2,
|
||||||
|
// totalKeys: 3,
|
||||||
|
// );
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -422,33 +431,33 @@ class _MultisigSetupViewState extends ConsumerState<MultisigCoordinatorView> {
|
||||||
class MultisigCoordinatorData {
|
class MultisigCoordinatorData {
|
||||||
const MultisigCoordinatorData({
|
const MultisigCoordinatorData({
|
||||||
this.threshold = 2,
|
this.threshold = 2,
|
||||||
this.totalCosigners = 3,
|
this.participants = 3,
|
||||||
this.coinType = 0, // Bitcoin mainnet.
|
this.coinType = 0, // Bitcoin mainnet.
|
||||||
this.accountIndex = 0,
|
this.account = 0,
|
||||||
this.scriptType = MultisigScriptType.nativeSegwit,
|
this.scriptType = MultisigScriptType.nativeSegwit,
|
||||||
this.cosignerXpubs = const [],
|
this.cosignerXpubs = const [],
|
||||||
});
|
});
|
||||||
|
|
||||||
final int threshold;
|
final int threshold;
|
||||||
final int totalCosigners;
|
final int participants;
|
||||||
final int coinType;
|
final int coinType;
|
||||||
final int accountIndex;
|
final int account;
|
||||||
final MultisigScriptType scriptType;
|
final MultisigScriptType scriptType;
|
||||||
final List<String> cosignerXpubs;
|
final List<String> cosignerXpubs;
|
||||||
|
|
||||||
MultisigCoordinatorData copyWith({
|
MultisigCoordinatorData copyWith({
|
||||||
int? threshold,
|
int? threshold,
|
||||||
int? totalCosigners,
|
int? participants,
|
||||||
int? coinType,
|
int? coinType,
|
||||||
int? accountIndex,
|
int? account,
|
||||||
MultisigScriptType? scriptType,
|
MultisigScriptType? scriptType,
|
||||||
List<String>? cosignerXpubs,
|
List<String>? cosignerXpubs,
|
||||||
}) {
|
}) {
|
||||||
return MultisigCoordinatorData(
|
return MultisigCoordinatorData(
|
||||||
threshold: threshold ?? this.threshold,
|
threshold: threshold ?? this.threshold,
|
||||||
totalCosigners: totalCosigners ?? this.totalCosigners,
|
participants: participants ?? this.participants,
|
||||||
coinType: coinType ?? this.coinType,
|
coinType: coinType ?? this.coinType,
|
||||||
accountIndex: accountIndex ?? this.accountIndex,
|
account: account ?? this.account,
|
||||||
scriptType: scriptType ?? this.scriptType,
|
scriptType: scriptType ?? this.scriptType,
|
||||||
cosignerXpubs: cosignerXpubs ?? this.cosignerXpubs,
|
cosignerXpubs: cosignerXpubs ?? this.cosignerXpubs,
|
||||||
);
|
);
|
||||||
|
@ -456,9 +465,9 @@ class MultisigCoordinatorData {
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
'threshold': threshold,
|
'threshold': threshold,
|
||||||
'totalCosigners': totalCosigners,
|
'participants': participants,
|
||||||
'coinType': coinType,
|
'coinType': coinType,
|
||||||
'accountIndex': accountIndex,
|
'accountIndex': account,
|
||||||
'scriptType': scriptType.index,
|
'scriptType': scriptType.index,
|
||||||
'cosignerXpubs': cosignerXpubs,
|
'cosignerXpubs': cosignerXpubs,
|
||||||
};
|
};
|
||||||
|
@ -466,9 +475,9 @@ class MultisigCoordinatorData {
|
||||||
factory MultisigCoordinatorData.fromJson(Map<String, dynamic> json) {
|
factory MultisigCoordinatorData.fromJson(Map<String, dynamic> json) {
|
||||||
return MultisigCoordinatorData(
|
return MultisigCoordinatorData(
|
||||||
threshold: json['threshold'] as int,
|
threshold: json['threshold'] as int,
|
||||||
totalCosigners: json['totalCosigners'] as int,
|
participants: json['participants'] as int,
|
||||||
coinType: json['coinType'] as int,
|
coinType: json['coinType'] as int,
|
||||||
accountIndex: json['accountIndex'] as int,
|
account: json['accountIndex'] as int,
|
||||||
scriptType: MultisigScriptType.values[json['scriptType'] as int],
|
scriptType: MultisigScriptType.values[json['scriptType'] as int],
|
||||||
cosignerXpubs: (json['cosignerXpubs'] as List).cast<String>(),
|
cosignerXpubs: (json['cosignerXpubs'] as List).cast<String>(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -25,33 +25,33 @@ final multisigSetupStateProvider =
|
||||||
class MultisigSetupData {
|
class MultisigSetupData {
|
||||||
const MultisigSetupData({
|
const MultisigSetupData({
|
||||||
this.threshold = 2,
|
this.threshold = 2,
|
||||||
this.totalCosigners = 3,
|
this.participants = 3,
|
||||||
this.coinType = 0, // Bitcoin mainnet.
|
this.coinType = 0, // Bitcoin mainnet.
|
||||||
this.accountIndex = 0,
|
this.account = 0,
|
||||||
this.scriptType = MultisigScriptType.nativeSegwit,
|
this.scriptType = MultisigScriptType.nativeSegwit,
|
||||||
this.cosignerXpubs = const [],
|
this.cosignerXpubs = const [],
|
||||||
});
|
});
|
||||||
|
|
||||||
final int threshold;
|
final int threshold;
|
||||||
final int totalCosigners;
|
final int participants;
|
||||||
final int coinType;
|
final int coinType;
|
||||||
final int accountIndex;
|
final int account;
|
||||||
final MultisigScriptType scriptType;
|
final MultisigScriptType scriptType;
|
||||||
final List<String> cosignerXpubs;
|
final List<String> cosignerXpubs;
|
||||||
|
|
||||||
MultisigSetupData copyWith({
|
MultisigSetupData copyWith({
|
||||||
int? threshold,
|
int? threshold,
|
||||||
int? totalCosigners,
|
int? participants,
|
||||||
int? coinType,
|
int? coinType,
|
||||||
int? accountIndex,
|
int? account,
|
||||||
MultisigScriptType? scriptType,
|
MultisigScriptType? scriptType,
|
||||||
List<String>? cosignerXpubs,
|
List<String>? cosignerXpubs,
|
||||||
}) {
|
}) {
|
||||||
return MultisigSetupData(
|
return MultisigSetupData(
|
||||||
threshold: threshold ?? this.threshold,
|
threshold: threshold ?? this.threshold,
|
||||||
totalCosigners: totalCosigners ?? this.totalCosigners,
|
participants: participants ?? this.participants,
|
||||||
coinType: coinType ?? this.coinType,
|
coinType: coinType ?? this.coinType,
|
||||||
accountIndex: accountIndex ?? this.accountIndex,
|
account: account ?? this.account,
|
||||||
scriptType: scriptType ?? this.scriptType,
|
scriptType: scriptType ?? this.scriptType,
|
||||||
cosignerXpubs: cosignerXpubs ?? this.cosignerXpubs,
|
cosignerXpubs: cosignerXpubs ?? this.cosignerXpubs,
|
||||||
);
|
);
|
||||||
|
@ -59,9 +59,9 @@ class MultisigSetupData {
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
'threshold': threshold,
|
'threshold': threshold,
|
||||||
'totalCosigners': totalCosigners,
|
'participants': participants,
|
||||||
'coinType': coinType,
|
'coinType': coinType,
|
||||||
'accountIndex': accountIndex,
|
'account': account,
|
||||||
'scriptType': scriptType.index,
|
'scriptType': scriptType.index,
|
||||||
'cosignerXpubs': cosignerXpubs,
|
'cosignerXpubs': cosignerXpubs,
|
||||||
};
|
};
|
||||||
|
@ -69,9 +69,9 @@ class MultisigSetupData {
|
||||||
factory MultisigSetupData.fromJson(Map<String, dynamic> json) {
|
factory MultisigSetupData.fromJson(Map<String, dynamic> json) {
|
||||||
return MultisigSetupData(
|
return MultisigSetupData(
|
||||||
threshold: json['threshold'] as int,
|
threshold: json['threshold'] as int,
|
||||||
totalCosigners: json['totalCosigners'] as int,
|
participants: json['participants'] as int,
|
||||||
coinType: json['coinType'] as int,
|
coinType: json['coinType'] as int,
|
||||||
accountIndex: json['accountIndex'] as int,
|
account: json['account'] as int,
|
||||||
scriptType: MultisigScriptType.values[json['scriptType'] as int],
|
scriptType: MultisigScriptType.values[json['scriptType'] as int],
|
||||||
cosignerXpubs: (json['cosignerXpubs'] as List).cast<String>(),
|
cosignerXpubs: (json['cosignerXpubs'] as List).cast<String>(),
|
||||||
);
|
);
|
||||||
|
@ -85,8 +85,8 @@ class MultisigSetupState extends StateNotifier<MultisigSetupData> {
|
||||||
state = state.copyWith(threshold: threshold);
|
state = state.copyWith(threshold: threshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateTotalCosigners(int total) {
|
void updateParticipants(int total) {
|
||||||
state = state.copyWith(totalCosigners: total);
|
state = state.copyWith(participants: total);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateScriptType(MultisigScriptType type) {
|
void updateScriptType(MultisigScriptType type) {
|
||||||
|
@ -94,7 +94,7 @@ class MultisigSetupState extends StateNotifier<MultisigSetupData> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void addCosignerXpub(String xpub) {
|
void addCosignerXpub(String xpub) {
|
||||||
if (state.cosignerXpubs.length < state.totalCosigners) {
|
if (state.cosignerXpubs.length < state.participants) {
|
||||||
state = state.copyWith(
|
state = state.copyWith(
|
||||||
cosignerXpubs: [...state.cosignerXpubs, xpub],
|
cosignerXpubs: [...state.cosignerXpubs, xpub],
|
||||||
);
|
);
|
||||||
|
@ -107,14 +107,16 @@ class MultisigSetupView extends ConsumerStatefulWidget {
|
||||||
super.key,
|
super.key,
|
||||||
required this.walletId,
|
required this.walletId,
|
||||||
this.scriptType,
|
this.scriptType,
|
||||||
this.totalCosigners,
|
this.participants,
|
||||||
this.threshold,
|
this.threshold,
|
||||||
|
this.account,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String walletId;
|
final String walletId;
|
||||||
final MultisigScriptType? scriptType;
|
final MultisigScriptType? scriptType;
|
||||||
final int? totalCosigners;
|
final int? participants;
|
||||||
final int? threshold;
|
final int? threshold;
|
||||||
|
final int? account;
|
||||||
|
|
||||||
static const String routeName = "/multisigSetup";
|
static const String routeName = "/multisigSetup";
|
||||||
|
|
||||||
|
@ -128,11 +130,11 @@ class _MultisigSetupViewState extends ConsumerState<MultisigSetupView> {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
// Initialize participants count if provided.
|
// Initialize participants count if provided.
|
||||||
if (widget.totalCosigners != null) {
|
if (widget.participants != null) {
|
||||||
_participantsCount = widget.totalCosigners!;
|
_participantsCount = widget.participants!;
|
||||||
_participantsController.text = widget.totalCosigners!.toString();
|
_participantsController.text = widget.participants!.toString();
|
||||||
// Initialize the controllers list.
|
// Initialize the controllers list.
|
||||||
for (int i = 0; i < widget.totalCosigners!; i++) {
|
for (int i = 0; i < widget.participants!; i++) {
|
||||||
controllers.add(TextEditingController());
|
controllers.add(TextEditingController());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,6 +228,7 @@ class _MultisigSetupViewState extends ConsumerState<MultisigSetupView> {
|
||||||
|
|
||||||
final _thresholdController = TextEditingController();
|
final _thresholdController = TextEditingController();
|
||||||
final _participantsController = TextEditingController();
|
final _participantsController = TextEditingController();
|
||||||
|
final _accountController = TextEditingController();
|
||||||
|
|
||||||
final List<TextEditingController> controllers = [];
|
final List<TextEditingController> controllers = [];
|
||||||
|
|
||||||
|
@ -254,6 +257,10 @@ class _MultisigSetupViewState extends ConsumerState<MultisigSetupView> {
|
||||||
return "Participants count error";
|
return "Participants count error";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_accountController.text.isEmpty) {
|
||||||
|
return "Choose an account (0 is OK)";
|
||||||
|
}
|
||||||
|
|
||||||
return "valid";
|
return "valid";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,10 +330,41 @@ class _MultisigSetupViewState extends ConsumerState<MultisigSetupView> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _showWhatIsAccountDialog() {
|
||||||
|
showDialog<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (_) => SimpleMobileDialog(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"What is an account?",
|
||||||
|
style: STextStyles.w600_20(context),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 12,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"The account number you choose will determine which extended "
|
||||||
|
"public key (xPub) you share with all participants. If you use "
|
||||||
|
"the same xPub across multiple multisignature accounts, a shared "
|
||||||
|
"cosigner in any of them will be able to recognize your "
|
||||||
|
"participation in them and so your privacy could be degraded. "
|
||||||
|
"For maximum privacy, use a distinct account number for each "
|
||||||
|
"multisignature account.",
|
||||||
|
style: STextStyles.w400_16(context),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_thresholdController.dispose();
|
_thresholdController.dispose();
|
||||||
_participantsController.dispose();
|
_participantsController.dispose();
|
||||||
|
_accountController.dispose();
|
||||||
for (final controller in controllers) {
|
for (final controller in controllers) {
|
||||||
controller.dispose();
|
controller.dispose();
|
||||||
}
|
}
|
||||||
|
@ -449,7 +487,7 @@ class _MultisigSetupViewState extends ConsumerState<MultisigSetupView> {
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
|
|
||||||
// Threshold and Participants.
|
// Threshold, Participants, and Account.
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
@ -500,6 +538,34 @@ class _MultisigSetupViewState extends ConsumerState<MultisigSetupView> {
|
||||||
hintStyle: STextStyles.fieldLabel(context),
|
hintStyle: STextStyles.fieldLabel(context),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Account",
|
||||||
|
style: STextStyles.w500_14(context).copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textDark3,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
CustomTextButton(
|
||||||
|
text: "What is an account?",
|
||||||
|
onTap: _showWhatIsAccountDialog,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
TextField(
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
||||||
|
controller: _accountController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: "Enter account number",
|
||||||
|
hintStyle: STextStyles.fieldLabel(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
|
@ -529,9 +595,9 @@ class _MultisigSetupViewState extends ConsumerState<MultisigSetupView> {
|
||||||
builder: (context) => MultisigCoordinatorView(
|
builder: (context) => MultisigCoordinatorView(
|
||||||
walletId: widget.walletId,
|
walletId: widget.walletId,
|
||||||
scriptType: setupData.scriptType, // TODO,
|
scriptType: setupData.scriptType, // TODO,
|
||||||
totalCosigners:
|
participants: int.parse(_participantsController.text),
|
||||||
int.parse(_participantsController.text),
|
|
||||||
threshold: int.parse(_thresholdController.text),
|
threshold: int.parse(_thresholdController.text),
|
||||||
|
account: int.parse(_accountController.text),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -2158,13 +2158,15 @@ class RouteGenerator {
|
||||||
return _routeError("${settings.name} invalid args: ${args.toString()}");
|
return _routeError("${settings.name} invalid args: ${args.toString()}");
|
||||||
|
|
||||||
case MultisigSetupView.routeName:
|
case MultisigSetupView.routeName:
|
||||||
if (args is Tuple3<String, int?, int?>) {
|
if (args is Tuple5<String, MultisigScriptType?, int?, int?, int?>) {
|
||||||
return getRoute(
|
return getRoute(
|
||||||
shouldUseMaterialRoute: useMaterialPageRoute,
|
shouldUseMaterialRoute: useMaterialPageRoute,
|
||||||
builder: (_) => MultisigSetupView(
|
builder: (_) => MultisigSetupView(
|
||||||
walletId: args.item1,
|
walletId: args.item1,
|
||||||
totalCosigners: args.item2,
|
scriptType: args.item2,
|
||||||
threshold: args.item3,
|
participants: args.item3,
|
||||||
|
threshold: args.item4,
|
||||||
|
account: args.item5,
|
||||||
),
|
),
|
||||||
settings: RouteSettings(
|
settings: RouteSettings(
|
||||||
name: settings.name,
|
name: settings.name,
|
||||||
|
@ -2184,14 +2186,15 @@ class RouteGenerator {
|
||||||
return _routeError("${settings.name} invalid args: ${args.toString()}");
|
return _routeError("${settings.name} invalid args: ${args.toString()}");
|
||||||
|
|
||||||
case MultisigCoordinatorView.routeName:
|
case MultisigCoordinatorView.routeName:
|
||||||
if (args is Tuple4<String, MultisigScriptType, int, int>) {
|
if (args is Tuple5<String, MultisigScriptType, int, int, int>) {
|
||||||
return getRoute(
|
return getRoute(
|
||||||
shouldUseMaterialRoute: useMaterialPageRoute,
|
shouldUseMaterialRoute: useMaterialPageRoute,
|
||||||
builder: (_) => MultisigCoordinatorView(
|
builder: (_) => MultisigCoordinatorView(
|
||||||
walletId: args.item1,
|
walletId: args.item1,
|
||||||
scriptType: args.item2,
|
scriptType: args.item2,
|
||||||
totalCosigners: args.item3,
|
participants: args.item3,
|
||||||
threshold: args.item4,
|
threshold: args.item4,
|
||||||
|
account: args.item5,
|
||||||
),
|
),
|
||||||
settings: RouteSettings(
|
settings: RouteSettings(
|
||||||
name: settings.name,
|
name: settings.name,
|
||||||
|
|
|
@ -29,15 +29,15 @@ class XPriv extends XKey {
|
||||||
mixin ExtendedKeysInterface<T extends ElectrumXCurrencyInterface>
|
mixin ExtendedKeysInterface<T extends ElectrumXCurrencyInterface>
|
||||||
on ElectrumXInterface<T> {
|
on ElectrumXInterface<T> {
|
||||||
Future<({List<XPub> xpubs, String fingerprint})> getXPubs(
|
Future<({List<XPub> xpubs, String fingerprint})> getXPubs(
|
||||||
{bool bip48 = false}) async {
|
{bool bip48 = false, int account = 0}) async {
|
||||||
final paths = cryptoCurrency.supportedHardenedDerivationPaths;
|
final paths = cryptoCurrency.supportedHardenedDerivationPaths;
|
||||||
|
|
||||||
if (bip48) {
|
if (bip48) {
|
||||||
// This hack was used because I was not able to correctly cast an existing
|
// This hack was used because I was not able to correctly cast an existing
|
||||||
// Bitcoin wallet as a BIP48Bitcoin wallet in order to use its
|
// Bitcoin wallet as a BIP48Bitcoin wallet in order to use its
|
||||||
// supportedDerivationPathTypes override.
|
// supportedDerivationPathTypes override.
|
||||||
paths.add("m/48'/0'/0'/1'");
|
paths.add("m/48'/0'/$account'/1'");
|
||||||
paths.add("m/48'/0'/0'/2'");
|
paths.add("m/48'/0'/$account'/2'");
|
||||||
}
|
}
|
||||||
|
|
||||||
final master = await getRootHDNode();
|
final master = await getRootHDNode();
|
||||||
|
|
Loading…
Reference in a new issue