fix issue where changing the primary/default address type for a coin would break older wallets with a mismatching type

This commit is contained in:
julian 2024-06-20 10:16:12 -06:00
parent a81fb14f13
commit 57ebacd519
29 changed files with 89 additions and 54 deletions

View file

@ -171,7 +171,7 @@ Future<void> migrateWalletsToIsar({
walletId: old.walletId,
name: old.name,
mainAddressType: AppConfig.getCryptoCurrencyFor(old.coinIdentifier)!
.primaryAddressType,
.defaultAddressType,
favouriteOrderIndex: favourites.indexOf(old.walletId),
cachedChainHeight: walletBox.get(
DBKeys.storedChainHeight,

View file

@ -188,7 +188,7 @@ class _ReceiveViewState extends ConsumerState<ReceiveView> {
wallet is Bip39HDWallet &&
wallet.supportedAddressTypes.length > 1);
_walletAddressTypes.add(coin.primaryAddressType);
_walletAddressTypes.add(wallet.info.mainAddressType);
if (_showMultiType) {
if (_supportsSpark) {
@ -197,7 +197,7 @@ class _ReceiveViewState extends ConsumerState<ReceiveView> {
_walletAddressTypes.addAll(
(wallet as Bip39HDWallet)
.supportedAddressTypes
.where((e) => e != coin.primaryAddressType),
.where((e) => e != wallet.info.mainAddressType),
);
}
}

View file

@ -814,7 +814,7 @@ abstract class SWB {
coinName: coin.identifier,
walletId: walletId,
name: walletName,
mainAddressType: coin.primaryAddressType,
mainAddressType: coin.defaultAddressType,
restoreHeight: walletbackup['restoreHeight'] as int? ?? 0,
otherDataJsonString: otherData == null ? null : jsonEncode(otherData),
cachedChainHeight: walletbackup['storedChainHeight'] as int? ?? 0,

View file

@ -53,7 +53,7 @@ class Banano extends NanoCurrency {
int get minConfirms => 1;
@override
AddressType get primaryAddressType => AddressType.banano;
AddressType get defaultAddressType => AddressType.banano;
@override
String get defaultRepresentative =>
@ -97,7 +97,7 @@ class Banano extends NanoCurrency {
}
@override
DerivePathType get primaryDerivePathType => throw UnsupportedError(
DerivePathType get defaultDerivePathType => throw UnsupportedError(
"$runtimeType does not use bitcoin style derivation paths",
);
}

View file

@ -288,7 +288,7 @@ class Bitcoin extends Bip39HDCurrency
List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 24];
@override
AddressType get primaryAddressType => AddressType.p2tr;
AddressType get defaultAddressType => defaultDerivePathType.getAddressType();
@override
BigInt get satsPerCoin => BigInt.from(100000000);
@ -297,7 +297,7 @@ class Bitcoin extends Bip39HDCurrency
int get targetBlockTimeSeconds => 600;
@override
DerivePathType get primaryDerivePathType => DerivePathType.bip86;
DerivePathType get defaultDerivePathType => DerivePathType.bip86;
@override
Uri defaultBlockExplorer(String txid) {

View file

@ -195,7 +195,7 @@ class BitcoinFrost extends FrostCurrency {
List<int> get possibleMnemonicLengths => [];
@override
AddressType get primaryAddressType => AddressType.frostMS;
AddressType get defaultAddressType => AddressType.frostMS;
@override
BigInt get satsPerCoin => BigInt.from(100000000);
@ -204,7 +204,7 @@ class BitcoinFrost extends FrostCurrency {
int get targetBlockTimeSeconds => 600;
@override
DerivePathType get primaryDerivePathType => throw UnsupportedError(
DerivePathType get defaultDerivePathType => throw UnsupportedError(
"$runtimeType does not use bitcoin style derivation paths",
);

View file

@ -336,7 +336,7 @@ class Bitcoincash extends Bip39HDCurrency with ElectrumXCurrencyInterface {
List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 24];
@override
AddressType get primaryAddressType => AddressType.p2pkh;
AddressType get defaultAddressType => defaultDerivePathType.getAddressType();
@override
BigInt get satsPerCoin => BigInt.from(100000000);
@ -345,7 +345,7 @@ class Bitcoincash extends Bip39HDCurrency with ElectrumXCurrencyInterface {
int get targetBlockTimeSeconds => 600;
@override
DerivePathType get primaryDerivePathType => DerivePathType.bip44;
DerivePathType get defaultDerivePathType => DerivePathType.bip44;
@override
Uri defaultBlockExplorer(String txid) {

View file

@ -225,7 +225,7 @@ class Dogecoin extends Bip39HDCurrency with ElectrumXCurrencyInterface {
List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 24];
@override
AddressType get primaryAddressType => AddressType.p2pkh;
AddressType get defaultAddressType => defaultDerivePathType.getAddressType();
@override
BigInt get satsPerCoin => BigInt.from(100000000);
@ -234,7 +234,7 @@ class Dogecoin extends Bip39HDCurrency with ElectrumXCurrencyInterface {
int get targetBlockTimeSeconds => 60;
@override
DerivePathType get primaryDerivePathType => DerivePathType.bip44;
DerivePathType get defaultDerivePathType => DerivePathType.bip44;
@override
Uri defaultBlockExplorer(String txid) {

View file

@ -314,7 +314,7 @@ class Ecash extends Bip39HDCurrency with ElectrumXCurrencyInterface {
List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 24];
@override
AddressType get primaryAddressType => AddressType.p2pkh;
AddressType get defaultAddressType => defaultDerivePathType.getAddressType();
@override
BigInt get satsPerCoin => BigInt.from(100);
@ -323,7 +323,7 @@ class Ecash extends Bip39HDCurrency with ElectrumXCurrencyInterface {
int get targetBlockTimeSeconds => 600;
@override
DerivePathType get primaryDerivePathType => DerivePathType.eCash44;
DerivePathType get defaultDerivePathType => DerivePathType.eCash44;
@override
Uri defaultBlockExplorer(String txid) {

View file

@ -1,4 +1,5 @@
import 'package:flutter_libepiccash/lib.dart' as epic;
import '../../../models/isar/models/blockchain_data/address.dart';
import '../../../models/node_model.dart';
import '../../../utilities/default_nodes.dart';
@ -102,7 +103,7 @@ class Epiccash extends Bip39Currency {
List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 12];
@override
AddressType get primaryAddressType => AddressType.mimbleWimble;
AddressType get defaultAddressType => AddressType.mimbleWimble;
@override
BigInt get satsPerCoin => BigInt.from(100000000);
@ -111,7 +112,7 @@ class Epiccash extends Bip39Currency {
int get targetBlockTimeSeconds => 60;
@override
DerivePathType get primaryDerivePathType => throw UnsupportedError(
DerivePathType get defaultDerivePathType => throw UnsupportedError(
"$runtimeType does not use bitcoin style derivation paths",
);

View file

@ -1,4 +1,5 @@
import 'package:ethereum_addresses/ethereum_addresses.dart';
import '../../../models/isar/models/blockchain_data/address.dart';
import '../../../models/node_model.dart';
import '../../../utilities/default_nodes.dart';
@ -86,7 +87,7 @@ class Ethereum extends Bip39Currency {
List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 24];
@override
AddressType get primaryAddressType => AddressType.ethereum;
AddressType get defaultAddressType => defaultDerivePathType.getAddressType();
@override
BigInt get satsPerCoin => BigInt.from(1000000000000000000);
@ -95,7 +96,7 @@ class Ethereum extends Bip39Currency {
int get targetBlockTimeSeconds => 15;
@override
DerivePathType get primaryDerivePathType => DerivePathType.eth;
DerivePathType get defaultDerivePathType => DerivePathType.eth;
@override
Uri defaultBlockExplorer(String txid) {

View file

@ -243,7 +243,7 @@ class Firo extends Bip39HDCurrency with ElectrumXCurrencyInterface {
List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 24];
@override
AddressType get primaryAddressType => AddressType.p2pkh;
AddressType get defaultAddressType => defaultDerivePathType.getAddressType();
@override
BigInt get satsPerCoin => BigInt.from(100000000);
@ -252,7 +252,7 @@ class Firo extends Bip39HDCurrency with ElectrumXCurrencyInterface {
int get targetBlockTimeSeconds => 150;
@override
DerivePathType get primaryDerivePathType => DerivePathType.bip44;
DerivePathType get defaultDerivePathType => DerivePathType.bip44;
@override
Uri defaultBlockExplorer(String txid) {

View file

@ -256,7 +256,7 @@ class Litecoin extends Bip39HDCurrency with ElectrumXCurrencyInterface {
List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 24];
@override
AddressType get primaryAddressType => AddressType.p2wpkh;
AddressType get defaultAddressType => defaultDerivePathType.getAddressType();
@override
BigInt get satsPerCoin => BigInt.from(100000000);
@ -265,7 +265,7 @@ class Litecoin extends Bip39HDCurrency with ElectrumXCurrencyInterface {
int get targetBlockTimeSeconds => 150;
@override
DerivePathType get primaryDerivePathType => DerivePathType.bip84;
DerivePathType get defaultDerivePathType => DerivePathType.bip84;
@override
Uri defaultBlockExplorer(String txid) {

View file

@ -100,7 +100,7 @@ class Monero extends CryptonoteCurrency {
int get targetBlockTimeSeconds => 120;
@override
DerivePathType get primaryDerivePathType => throw UnsupportedError(
DerivePathType get defaultDerivePathType => throw UnsupportedError(
"$runtimeType does not use bitcoin style derivation paths",
);

View file

@ -230,7 +230,7 @@ class Namecoin extends Bip39HDCurrency with ElectrumXCurrencyInterface {
List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 12];
@override
AddressType get primaryAddressType => AddressType.p2wpkh;
AddressType get defaultAddressType => defaultDerivePathType.getAddressType();
@override
BigInt get satsPerCoin => BigInt.from(100000000);
@ -239,7 +239,7 @@ class Namecoin extends Bip39HDCurrency with ElectrumXCurrencyInterface {
int get targetBlockTimeSeconds => 600;
@override
DerivePathType get primaryDerivePathType => DerivePathType.bip84;
DerivePathType get defaultDerivePathType => DerivePathType.bip84;
@override
Uri defaultBlockExplorer(String txid) {

View file

@ -53,7 +53,7 @@ class Nano extends NanoCurrency {
int get minConfirms => 1;
@override
AddressType get primaryAddressType => AddressType.nano;
AddressType get defaultAddressType => AddressType.nano;
@override
String get defaultRepresentative =>
@ -85,7 +85,7 @@ class Nano extends NanoCurrency {
}
@override
DerivePathType get primaryDerivePathType => throw UnsupportedError(
DerivePathType get defaultDerivePathType => throw UnsupportedError(
"$runtimeType does not use bitcoin style derivation paths",
);

View file

@ -208,7 +208,7 @@ class Particl extends Bip39HDCurrency with ElectrumXCurrencyInterface {
List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 24];
@override
AddressType get primaryAddressType => AddressType.p2wpkh;
AddressType get defaultAddressType => defaultDerivePathType.getAddressType();
@override
BigInt get satsPerCoin => BigInt.from(100000000);
@ -217,7 +217,7 @@ class Particl extends Bip39HDCurrency with ElectrumXCurrencyInterface {
int get targetBlockTimeSeconds => 600;
@override
DerivePathType get primaryDerivePathType => DerivePathType.bip84;
DerivePathType get defaultDerivePathType => DerivePathType.bip84;
@override
Uri defaultBlockExplorer(String txid) {

View file

@ -228,7 +228,7 @@ class Peercoin extends Bip39HDCurrency with ElectrumXCurrencyInterface {
List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 24];
@override
AddressType get primaryAddressType => AddressType.p2wpkh;
AddressType get defaultAddressType => defaultDerivePathType.getAddressType();
@override
BigInt get satsPerCoin => BigInt.from(1000000); // 1*10^6.
@ -237,7 +237,7 @@ class Peercoin extends Bip39HDCurrency with ElectrumXCurrencyInterface {
int get targetBlockTimeSeconds => 600;
@override
DerivePathType get primaryDerivePathType => DerivePathType.bip84;
DerivePathType get defaultDerivePathType => DerivePathType.bip84;
@override
Uri defaultBlockExplorer(String txid) {

View file

@ -94,7 +94,7 @@ class Solana extends Bip39Currency {
List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 24];
@override
AddressType get primaryAddressType => AddressType.solana;
AddressType get defaultAddressType => defaultDerivePathType.getAddressType();
@override
BigInt get satsPerCoin => BigInt.from(1000000000);
@ -103,7 +103,7 @@ class Solana extends Bip39Currency {
int get targetBlockTimeSeconds => 1;
@override
DerivePathType get primaryDerivePathType => DerivePathType.solana;
DerivePathType get defaultDerivePathType => DerivePathType.solana;
@override
Uri defaultBlockExplorer(String txid) {

View file

@ -108,7 +108,7 @@ class Stellar extends Bip39Currency {
List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 12];
@override
AddressType get primaryAddressType => AddressType.stellar;
AddressType get defaultAddressType => AddressType.stellar;
@override
BigInt get satsPerCoin => BigInt.from(
@ -119,7 +119,7 @@ class Stellar extends Bip39Currency {
int get targetBlockTimeSeconds => 5;
@override
DerivePathType get primaryDerivePathType => throw UnsupportedError(
DerivePathType get defaultDerivePathType => throw UnsupportedError(
"$runtimeType does not use bitcoin style derivation paths",
);

View file

@ -195,7 +195,7 @@ class Tezos extends Bip39Currency {
List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 12];
@override
AddressType get primaryAddressType => AddressType.tezos;
AddressType get defaultAddressType => AddressType.tezos;
@override
BigInt get satsPerCoin => BigInt.from(1000000);
@ -204,7 +204,7 @@ class Tezos extends Bip39Currency {
int get targetBlockTimeSeconds => 60;
@override
DerivePathType get primaryDerivePathType =>
DerivePathType get defaultDerivePathType =>
throw UnsupportedError("Is this even used?");
@override

View file

@ -95,7 +95,7 @@ class Wownero extends CryptonoteCurrency {
int get targetBlockTimeSeconds => 120;
@override
DerivePathType get primaryDerivePathType => throw UnsupportedError(
DerivePathType get defaultDerivePathType => throw UnsupportedError(
"$runtimeType does not use bitcoin style derivation paths",
);

View file

@ -71,10 +71,10 @@ abstract class CryptoCurrency {
bool get hasBuySupport;
bool get hasMnemonicPassphraseSupport;
List<int> get possibleMnemonicLengths;
AddressType get primaryAddressType;
AddressType get defaultAddressType;
BigInt get satsPerCoin;
int get targetBlockTimeSeconds;
DerivePathType get primaryDerivePathType;
DerivePathType get defaultDerivePathType;
Uri defaultBlockExplorer(String txid);

View file

@ -10,5 +10,5 @@ abstract class CryptonoteCurrency extends CryptoCurrency {
}
@override
AddressType get primaryAddressType => AddressType.cryptonote;
AddressType get defaultAddressType => AddressType.cryptonote;
}

View file

@ -458,7 +458,7 @@ class WalletInfo implements IsarId {
coinName: coin.identifier,
walletId: walletIdOverride ?? const Uuid().v1(),
name: name,
mainAddressType: coin.primaryAddressType,
mainAddressType: coin.defaultAddressType,
restoreHeight: restoreHeight,
otherDataJsonString: otherDataJsonString,
);

View file

@ -46,7 +46,7 @@ class SolanaWallet extends Bip39Wallet<Solana> {
publicKey: List<int>.empty(),
derivationIndex: 0,
derivationPath: DerivationPath()..value = _addressDerivationPath,
type: cryptoCurrency.primaryAddressType,
type: info.mainAddressType,
subType: AddressSubType.receiving,
);
return addressStruct;

View file

@ -1,6 +1,9 @@
import 'dart:io';
import 'package:isar/isar.dart';
import 'package:tezart/tezart.dart' as tezart;
import 'package:tuple/tuple.dart';
import '../../../models/balance.dart';
import '../../../models/isar/models/blockchain_data/address.dart';
import '../../../models/isar/models/blockchain_data/transaction.dart';
@ -18,8 +21,6 @@ import '../../crypto_currency/crypto_currency.dart';
import '../../isar/models/wallet_info.dart';
import '../../models/tx_data.dart';
import '../intermediate/bip39_wallet.dart';
import 'package:tezart/tezart.dart' as tezart;
import 'package:tuple/tuple.dart';
// const kDefaultTransactionStorageLimit = 496;
// const kDefaultTransactionGasLimit = 10600;
@ -83,7 +84,7 @@ class TezosWallet extends Bip39Wallet<Tezos> {
publicKey: keyStore.publicKey.toUint8ListFromBase58CheckEncoded,
derivationIndex: 0,
derivationPath: DerivationPath()..value = derivationPath,
type: info.coin.primaryAddressType,
type: info.mainAddressType,
subType: AddressSubType.receiving,
);
}

View file

@ -1,13 +1,14 @@
import 'package:bip39/bip39.dart' as bip39;
import 'package:coinlib_flutter/coinlib_flutter.dart' as coinlib;
import 'package:isar/isar.dart';
import '../../../models/balance.dart';
import '../../../models/isar/models/blockchain_data/address.dart';
import '../../../utilities/amount/amount.dart';
import '../../../utilities/enums/derive_path_type_enum.dart';
import '../../crypto_currency/intermediate/bip39_hd_currency.dart';
import 'bip39_wallet.dart';
import '../wallet_mixin_interfaces/multi_address_interface.dart';
import 'bip39_wallet.dart';
abstract class Bip39HDWallet<T extends Bip39HDCurrency> extends Bip39Wallet<T>
with MultiAddressInterface<T> {
@ -66,7 +67,7 @@ abstract class Bip39HDWallet<T extends Bip39HDCurrency> extends Bip39Wallet<T>
final address = await _generateAddress(
chain: chain,
index: index,
derivePathType: info.coin.primaryDerivePathType,
derivePathType: _fromAddressType(info.mainAddressType),
);
await mainDB.updateOrPutAddresses([address]);
@ -88,7 +89,7 @@ abstract class Bip39HDWallet<T extends Bip39HDCurrency> extends Bip39Wallet<T>
final address = await _generateAddress(
chain: chain,
index: index,
derivePathType: info.coin.primaryDerivePathType,
derivePathType: _fromAddressType(info.mainAddressType),
);
await mainDB.updateOrPutAddresses([address]);
@ -101,7 +102,7 @@ abstract class Bip39HDWallet<T extends Bip39HDCurrency> extends Bip39Wallet<T>
final address = await _generateAddress(
chain: 0, // receiving
index: 0, // initial index
derivePathType: info.coin.primaryDerivePathType,
derivePathType: _fromAddressType(info.mainAddressType),
);
await mainDB.updateOrPutAddresses([address]);
@ -118,6 +119,37 @@ abstract class Bip39HDWallet<T extends Bip39HDCurrency> extends Bip39Wallet<T>
// ========== Private ========================================================
DerivePathType _fromAddressType(AddressType addressType) {
switch (addressType) {
case AddressType.p2pkh:
// DerivePathType.bip44:
// DerivePathType.bch44:
// DerivePathType.eCash44:
// Should be one of the above due to silly case due to bch and ecash
return info.coin.defaultDerivePathType;
case AddressType.p2sh:
return DerivePathType.bip49;
case AddressType.p2wpkh:
return DerivePathType.bip84;
case AddressType.p2tr:
return DerivePathType.bip86;
case AddressType.solana:
return DerivePathType.solana;
case AddressType.ethereum:
return DerivePathType.eth;
default:
throw ArgumentError(
"Incompatible AddressType \"$addressType\" passed to DerivePathType.fromAddressType()",
);
}
}
Future<Address> _generateAddress({
required int chain,
required int index,

View file

@ -93,7 +93,7 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
publicKey: publicKey.toUint8ListFromHex,
derivationIndex: 0,
derivationPath: null,
type: cryptoCurrency.primaryAddressType,
type: info.mainAddressType,
subType: AddressSubType.receiving,
);
}
@ -599,7 +599,7 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
value: tx["account"].toString(),
derivationIndex: 0,
derivationPath: null,
type: info.coin.primaryAddressType,
type: info.mainAddressType,
subType: AddressSubType.nonWallet,
);
final Tuple2<Transaction, Address> tuple = Tuple2(transaction, address);