Fix address error, remove bip84

This commit is contained in:
likho 2022-10-26 14:42:07 +02:00
parent 9baa30c1a4
commit b0cee75b76

View file

@ -50,7 +50,7 @@ const String GENESIS_HASH_MAINNET =
const String GENESIS_HASH_TESTNET = const String GENESIS_HASH_TESTNET =
"0000594ada5310b367443ee0afd4fa3d0bbd5850ea4e33cdc7d6a904a7ec7c90"; "0000594ada5310b367443ee0afd4fa3d0bbd5850ea4e33cdc7d6a904a7ec7c90";
enum DerivePathType { bip44, bip49, bip84 } enum DerivePathType { bip44, bip49 }
bip32.BIP32 getBip32Node( bip32.BIP32 getBip32Node(
int chain, int chain,
@ -97,8 +97,6 @@ bip32.BIP32 getBip32NodeFromRoot(
return root.derivePath("m/44'/$coinType'/0'/$chain/$index"); return root.derivePath("m/44'/$coinType'/0'/$chain/$index");
case DerivePathType.bip49: case DerivePathType.bip49:
return root.derivePath("m/49'/$coinType'/0'/$chain/$index"); return root.derivePath("m/49'/$coinType'/0'/$chain/$index");
case DerivePathType.bip84:
return root.derivePath("m/84'/$coinType'/0'/$chain/$index");
default: default:
throw Exception("DerivePathType must not be null."); throw Exception("DerivePathType must not be null.");
} }
@ -226,11 +224,7 @@ class ParticlWallet extends CoinServiceAPI {
} }
@override @override
Future<String> get currentReceivingAddress => _currentReceivingAddress ??= Future<String> get currentReceivingAddress =>
_getCurrentAddressForChain(0, DerivePathType.bip84);
Future<String>? _currentReceivingAddress;
Future<String> get currentLegacyReceivingAddress =>
_currentReceivingAddressP2PKH ??= _currentReceivingAddressP2PKH ??=
_getCurrentAddressForChain(0, DerivePathType.bip44); _getCurrentAddressForChain(0, DerivePathType.bip44);
Future<String>? _currentReceivingAddressP2PKH; Future<String>? _currentReceivingAddressP2PKH;
@ -319,8 +313,7 @@ class ParticlWallet extends CoinServiceAPI {
if (decodeBech32.version != 0) { if (decodeBech32.version != 0) {
throw ArgumentError('Invalid address version'); throw ArgumentError('Invalid address version');
} }
// P2WPKH throw ArgumentError('$address has no matching Script');
return DerivePathType.bip84;
} }
} }
@ -443,13 +436,6 @@ class ParticlWallet extends CoinServiceAPI {
.data .data
.address!; .address!;
break; break;
case DerivePathType.bip84:
address = P2WPKH(
network: _network,
data: PaymentData(pubkey: node.publicKey))
.data
.address!;
break;
default: default:
throw Exception("No Path type $type exists"); throw Exception("No Path type $type exists");
} }
@ -531,28 +517,24 @@ class ParticlWallet extends CoinServiceAPI {
Map<String, Map<String, String>> p2pkhReceiveDerivations = {}; Map<String, Map<String, String>> p2pkhReceiveDerivations = {};
Map<String, Map<String, String>> p2shReceiveDerivations = {}; Map<String, Map<String, String>> p2shReceiveDerivations = {};
Map<String, Map<String, String>> p2wpkhReceiveDerivations = {};
Map<String, Map<String, String>> p2pkhChangeDerivations = {}; Map<String, Map<String, String>> p2pkhChangeDerivations = {};
Map<String, Map<String, String>> p2shChangeDerivations = {}; Map<String, Map<String, String>> p2shChangeDerivations = {};
Map<String, Map<String, String>> p2wpkhChangeDerivations = {};
final root = await compute(getBip32RootWrapper, Tuple2(mnemonic, _network)); final root = await compute(getBip32RootWrapper, Tuple2(mnemonic, _network));
List<String> p2pkhReceiveAddressArray = []; List<String> p2pkhReceiveAddressArray = [];
List<String> p2shReceiveAddressArray = []; List<String> p2shReceiveAddressArray = [];
List<String> p2wpkhReceiveAddressArray = [];
int p2pkhReceiveIndex = -1; int p2pkhReceiveIndex = -1;
int p2shReceiveIndex = -1; int p2shReceiveIndex = -1;
int p2wpkhReceiveIndex = -1;
List<String> p2pkhChangeAddressArray = []; List<String> p2pkhChangeAddressArray = [];
List<String> p2shChangeAddressArray = []; List<String> p2shChangeAddressArray = [];
List<String> p2wpkhChangeAddressArray = [];
int p2pkhChangeIndex = -1; int p2pkhChangeIndex = -1;
int p2shChangeIndex = -1; int p2shChangeIndex = -1;
int p2wpkhChangeIndex = -1;
// actual size is 36 due to p2pkh, p2sh, and p2wpkh so 12x3 // actual size is 24 due to p2pkh, p2sh so 12x2
const txCountBatchSize = 12; const txCountBatchSize = 12;
try { try {
@ -565,9 +547,6 @@ class ParticlWallet extends CoinServiceAPI {
final resultReceive49 = _checkGaps(maxNumberOfIndexesToCheck, final resultReceive49 = _checkGaps(maxNumberOfIndexesToCheck,
maxUnusedAddressGap, txCountBatchSize, root, DerivePathType.bip49, 0); maxUnusedAddressGap, txCountBatchSize, root, DerivePathType.bip49, 0);
final resultReceive84 = _checkGaps(maxNumberOfIndexesToCheck,
maxUnusedAddressGap, txCountBatchSize, root, DerivePathType.bip84, 0);
Logging.instance Logging.instance
.log("checking change addresses...", level: LogLevel.Info); .log("checking change addresses...", level: LogLevel.Info);
// change addresses // change addresses
@ -577,16 +556,11 @@ class ParticlWallet extends CoinServiceAPI {
final resultChange49 = _checkGaps(maxNumberOfIndexesToCheck, final resultChange49 = _checkGaps(maxNumberOfIndexesToCheck,
maxUnusedAddressGap, txCountBatchSize, root, DerivePathType.bip49, 1); maxUnusedAddressGap, txCountBatchSize, root, DerivePathType.bip49, 1);
final resultChange84 = _checkGaps(maxNumberOfIndexesToCheck,
maxUnusedAddressGap, txCountBatchSize, root, DerivePathType.bip84, 1);
await Future.wait([ await Future.wait([
resultReceive44, resultReceive44,
resultReceive49, resultReceive49,
resultReceive84,
resultChange44, resultChange44,
resultChange49, resultChange49,
resultChange84
]); ]);
p2pkhReceiveAddressArray = p2pkhReceiveAddressArray =
@ -601,12 +575,6 @@ class ParticlWallet extends CoinServiceAPI {
p2shReceiveDerivations = (await resultReceive49)['derivations'] p2shReceiveDerivations = (await resultReceive49)['derivations']
as Map<String, Map<String, String>>; as Map<String, Map<String, String>>;
p2wpkhReceiveAddressArray =
(await resultReceive84)['addressArray'] as List<String>;
p2wpkhReceiveIndex = (await resultReceive84)['index'] as int;
p2wpkhReceiveDerivations = (await resultReceive84)['derivations']
as Map<String, Map<String, String>>;
p2pkhChangeAddressArray = p2pkhChangeAddressArray =
(await resultChange44)['addressArray'] as List<String>; (await resultChange44)['addressArray'] as List<String>;
p2pkhChangeIndex = (await resultChange44)['index'] as int; p2pkhChangeIndex = (await resultChange44)['index'] as int;
@ -619,12 +587,6 @@ class ParticlWallet extends CoinServiceAPI {
p2shChangeDerivations = (await resultChange49)['derivations'] p2shChangeDerivations = (await resultChange49)['derivations']
as Map<String, Map<String, String>>; as Map<String, Map<String, String>>;
p2wpkhChangeAddressArray =
(await resultChange84)['addressArray'] as List<String>;
p2wpkhChangeIndex = (await resultChange84)['index'] as int;
p2wpkhChangeDerivations = (await resultChange84)['derivations']
as Map<String, Map<String, String>>;
// save the derivations (if any) // save the derivations (if any)
if (p2pkhReceiveDerivations.isNotEmpty) { if (p2pkhReceiveDerivations.isNotEmpty) {
await addDerivations( await addDerivations(
@ -638,12 +600,7 @@ class ParticlWallet extends CoinServiceAPI {
derivePathType: DerivePathType.bip49, derivePathType: DerivePathType.bip49,
derivationsToAdd: p2shReceiveDerivations); derivationsToAdd: p2shReceiveDerivations);
} }
if (p2wpkhReceiveDerivations.isNotEmpty) {
await addDerivations(
chain: 0,
derivePathType: DerivePathType.bip84,
derivationsToAdd: p2wpkhReceiveDerivations);
}
if (p2pkhChangeDerivations.isNotEmpty) { if (p2pkhChangeDerivations.isNotEmpty) {
await addDerivations( await addDerivations(
chain: 1, chain: 1,
@ -656,12 +613,6 @@ class ParticlWallet extends CoinServiceAPI {
derivePathType: DerivePathType.bip49, derivePathType: DerivePathType.bip49,
derivationsToAdd: p2shChangeDerivations); derivationsToAdd: p2shChangeDerivations);
} }
if (p2wpkhChangeDerivations.isNotEmpty) {
await addDerivations(
chain: 1,
derivePathType: DerivePathType.bip84,
derivationsToAdd: p2wpkhChangeDerivations);
}
// If restoring a wallet that never received any funds, then set receivingArray manually // If restoring a wallet that never received any funds, then set receivingArray manually
// If we didn't do this, it'd store an empty array // If we didn't do this, it'd store an empty array
@ -677,12 +628,6 @@ class ParticlWallet extends CoinServiceAPI {
p2shReceiveAddressArray.add(address); p2shReceiveAddressArray.add(address);
p2shReceiveIndex = 0; p2shReceiveIndex = 0;
} }
if (p2wpkhReceiveIndex == -1) {
final address =
await _generateAddressForChain(0, 0, DerivePathType.bip84);
p2wpkhReceiveAddressArray.add(address);
p2wpkhReceiveIndex = 0;
}
// If restoring a wallet that never sent any funds with change, then set changeArray // If restoring a wallet that never sent any funds with change, then set changeArray
// manually. If we didn't do this, it'd store an empty array. // manually. If we didn't do this, it'd store an empty array.
@ -698,21 +643,7 @@ class ParticlWallet extends CoinServiceAPI {
p2shChangeAddressArray.add(address); p2shChangeAddressArray.add(address);
p2shChangeIndex = 0; p2shChangeIndex = 0;
} }
if (p2wpkhChangeIndex == -1) {
final address =
await _generateAddressForChain(1, 0, DerivePathType.bip84);
p2wpkhChangeAddressArray.add(address);
p2wpkhChangeIndex = 0;
}
await DB.instance.put<dynamic>(
boxName: walletId,
key: 'receivingAddressesP2WPKH',
value: p2wpkhReceiveAddressArray);
await DB.instance.put<dynamic>(
boxName: walletId,
key: 'changeAddressesP2WPKH',
value: p2wpkhChangeAddressArray);
await DB.instance.put<dynamic>( await DB.instance.put<dynamic>(
boxName: walletId, boxName: walletId,
key: 'receivingAddressesP2PKH', key: 'receivingAddressesP2PKH',
@ -729,14 +660,6 @@ class ParticlWallet extends CoinServiceAPI {
boxName: walletId, boxName: walletId,
key: 'changeAddressesP2SH', key: 'changeAddressesP2SH',
value: p2shChangeAddressArray); value: p2shChangeAddressArray);
await DB.instance.put<dynamic>(
boxName: walletId,
key: 'receivingIndexP2WPKH',
value: p2wpkhReceiveIndex);
await DB.instance.put<dynamic>(
boxName: walletId,
key: 'changeIndexP2WPKH',
value: p2wpkhChangeIndex);
await DB.instance.put<dynamic>( await DB.instance.put<dynamic>(
boxName: walletId, key: 'changeIndexP2PKH', value: p2pkhChangeIndex); boxName: walletId, key: 'changeIndexP2PKH', value: p2pkhChangeIndex);
await DB.instance.put<dynamic>( await DB.instance.put<dynamic>(
@ -966,7 +889,7 @@ class ParticlWallet extends CoinServiceAPI {
GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.2, walletId)); GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.2, walletId));
final changeAddressForTransactions = final changeAddressForTransactions =
_checkChangeAddressForTransactions(DerivePathType.bip84); _checkChangeAddressForTransactions(DerivePathType.bip44);
GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.3, walletId)); GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.3, walletId));
final currentReceivingAddressesForTransactions = final currentReceivingAddressesForTransactions =
@ -1378,10 +1301,6 @@ class ParticlWallet extends CoinServiceAPI {
Future<List<String>> _fetchAllOwnAddresses() async { Future<List<String>> _fetchAllOwnAddresses() async {
final List<String> allAddresses = []; final List<String> allAddresses = [];
final receivingAddresses = DB.instance.get<dynamic>(
boxName: walletId, key: 'receivingAddressesP2WPKH') as List<dynamic>;
final changeAddresses = DB.instance.get<dynamic>(
boxName: walletId, key: 'changeAddressesP2WPKH') as List<dynamic>;
final receivingAddressesP2PKH = DB.instance.get<dynamic>( final receivingAddressesP2PKH = DB.instance.get<dynamic>(
boxName: walletId, key: 'receivingAddressesP2PKH') as List<dynamic>; boxName: walletId, key: 'receivingAddressesP2PKH') as List<dynamic>;
final changeAddressesP2PKH = final changeAddressesP2PKH =
@ -1393,16 +1312,6 @@ class ParticlWallet extends CoinServiceAPI {
DB.instance.get<dynamic>(boxName: walletId, key: 'changeAddressesP2SH') DB.instance.get<dynamic>(boxName: walletId, key: 'changeAddressesP2SH')
as List<dynamic>; as List<dynamic>;
for (var i = 0; i < receivingAddresses.length; i++) {
if (!allAddresses.contains(receivingAddresses[i])) {
allAddresses.add(receivingAddresses[i] as String);
}
}
for (var i = 0; i < changeAddresses.length; i++) {
if (!allAddresses.contains(changeAddresses[i])) {
allAddresses.add(changeAddresses[i] as String);
}
}
for (var i = 0; i < receivingAddressesP2PKH.length; i++) { for (var i = 0; i < receivingAddressesP2PKH.length; i++) {
if (!allAddresses.contains(receivingAddressesP2PKH[i])) { if (!allAddresses.contains(receivingAddressesP2PKH[i])) {
allAddresses.add(receivingAddressesP2PKH[i] as String); allAddresses.add(receivingAddressesP2PKH[i] as String);
@ -1481,10 +1390,6 @@ class ParticlWallet extends CoinServiceAPI {
value: bip39.generateMnemonic(strength: 256)); value: bip39.generateMnemonic(strength: 256));
// Set relevant indexes // Set relevant indexes
await DB.instance
.put<dynamic>(boxName: walletId, key: "receivingIndexP2WPKH", value: 0);
await DB.instance
.put<dynamic>(boxName: walletId, key: "changeIndexP2WPKH", value: 0);
await DB.instance await DB.instance
.put<dynamic>(boxName: walletId, key: "receivingIndexP2PKH", value: 0); .put<dynamic>(boxName: walletId, key: "receivingIndexP2PKH", value: 0);
await DB.instance await DB.instance
@ -1506,23 +1411,6 @@ class ParticlWallet extends CoinServiceAPI {
// Generate and add addresses to relevant arrays // Generate and add addresses to relevant arrays
await Future.wait([ await Future.wait([
// P2WPKH
_generateAddressForChain(0, 0, DerivePathType.bip84).then(
(initialReceivingAddressP2WPKH) {
_addToAddressesArrayForChain(
initialReceivingAddressP2WPKH, 0, DerivePathType.bip84);
_currentReceivingAddress =
Future(() => initialReceivingAddressP2WPKH);
},
),
_generateAddressForChain(1, 0, DerivePathType.bip84).then(
(initialChangeAddressP2WPKH) => _addToAddressesArrayForChain(
initialChangeAddressP2WPKH,
1,
DerivePathType.bip84,
),
),
// P2PKH // P2PKH
_generateAddressForChain(0, 0, DerivePathType.bip44).then( _generateAddressForChain(0, 0, DerivePathType.bip44).then(
(initialReceivingAddressP2PKH) { (initialReceivingAddressP2PKH) {
@ -1558,42 +1446,10 @@ class ParticlWallet extends CoinServiceAPI {
), ),
]); ]);
// // P2PKH
// _generateAddressForChain(0, 0, DerivePathType.bip44).then(
// (initialReceivingAddressP2PKH) {
// _addToAddressesArrayForChain(
// initialReceivingAddressP2PKH, 0, DerivePathType.bip44);
// this._currentReceivingAddressP2PKH =
// Future(() => initialReceivingAddressP2PKH);
// },
// );
// _generateAddressForChain(1, 0, DerivePathType.bip44)
// .then((initialChangeAddressP2PKH) => _addToAddressesArrayForChain(
// initialChangeAddressP2PKH,
// 1,
// DerivePathType.bip44,
// ));
//
// // P2SH
// _generateAddressForChain(0, 0, DerivePathType.bip49).then(
// (initialReceivingAddressP2SH) {
// _addToAddressesArrayForChain(
// initialReceivingAddressP2SH, 0, DerivePathType.bip49);
// this._currentReceivingAddressP2SH =
// Future(() => initialReceivingAddressP2SH);
// },
// );
// _generateAddressForChain(1, 0, DerivePathType.bip49)
// .then((initialChangeAddressP2SH) => _addToAddressesArrayForChain(
// initialChangeAddressP2SH,
// 1,
// DerivePathType.bip49,
// ));
Logging.instance.log("_generateNewWalletFinished", level: LogLevel.Info); Logging.instance.log("_generateNewWalletFinished", level: LogLevel.Info);
} }
/// Generates a new internal or external chain address for the wallet using a BIP84, BIP44, or BIP49 derivation path. /// Generates a new internal or external chain address for the wallet using a BIP44, or BIP49 derivation path.
/// [chain] - Use 0 for receiving (external), 1 for change (internal). Should not be any other value! /// [chain] - Use 0 for receiving (external), 1 for change (internal). Should not be any other value!
/// [index] - This can be any integer >= 0 /// [index] - This can be any integer >= 0
Future<String> _generateAddressForChain( Future<String> _generateAddressForChain(
@ -1627,9 +1483,6 @@ class ParticlWallet extends CoinServiceAPI {
.data .data
.address!; .address!;
break; break;
case DerivePathType.bip84:
address = P2WPKH(network: _network, data: data).data.address!;
break;
} }
// add generated address & info to derivations // add generated address & info to derivations
@ -1657,9 +1510,6 @@ class ParticlWallet extends CoinServiceAPI {
case DerivePathType.bip49: case DerivePathType.bip49:
indexKey += "P2SH"; indexKey += "P2SH";
break; break;
case DerivePathType.bip84:
indexKey += "P2WPKH";
break;
} }
final newIndex = final newIndex =
@ -1686,9 +1536,6 @@ class ParticlWallet extends CoinServiceAPI {
case DerivePathType.bip49: case DerivePathType.bip49:
chainArray += "P2SH"; chainArray += "P2SH";
break; break;
case DerivePathType.bip84:
chainArray += "P2WPKH";
break;
} }
final addressArray = final addressArray =
@ -1726,9 +1573,6 @@ class ParticlWallet extends CoinServiceAPI {
case DerivePathType.bip49: case DerivePathType.bip49:
arrayKey += "P2SH"; arrayKey += "P2SH";
break; break;
case DerivePathType.bip84:
arrayKey += "P2WPKH";
break;
} }
final internalChainArray = final internalChainArray =
DB.instance.get<dynamic>(boxName: walletId, key: arrayKey); DB.instance.get<dynamic>(boxName: walletId, key: arrayKey);
@ -1748,9 +1592,6 @@ class ParticlWallet extends CoinServiceAPI {
case DerivePathType.bip49: case DerivePathType.bip49:
key = "${walletId}_${chainId}DerivationsP2SH"; key = "${walletId}_${chainId}DerivationsP2SH";
break; break;
case DerivePathType.bip84:
key = "${walletId}_${chainId}DerivationsP2WPKH";
break;
} }
return key; return key;
} }
@ -2065,9 +1906,6 @@ class ParticlWallet extends CoinServiceAPI {
case DerivePathType.bip49: case DerivePathType.bip49:
indexKey += "P2SH"; indexKey += "P2SH";
break; break;
case DerivePathType.bip84:
indexKey += "P2WPKH";
break;
} }
final newReceivingIndex = final newReceivingIndex =
DB.instance.get<dynamic>(boxName: walletId, key: indexKey) as int; DB.instance.get<dynamic>(boxName: walletId, key: indexKey) as int;
@ -2089,9 +1927,6 @@ class ParticlWallet extends CoinServiceAPI {
case DerivePathType.bip49: case DerivePathType.bip49:
_currentReceivingAddressP2SH = Future(() => newReceivingAddress); _currentReceivingAddressP2SH = Future(() => newReceivingAddress);
break; break;
case DerivePathType.bip84:
_currentReceivingAddress = Future(() => newReceivingAddress);
break;
} }
} }
} catch (e, s) { } catch (e, s) {
@ -2125,9 +1960,6 @@ class ParticlWallet extends CoinServiceAPI {
case DerivePathType.bip49: case DerivePathType.bip49:
indexKey += "P2SH"; indexKey += "P2SH";
break; break;
case DerivePathType.bip84:
indexKey += "P2WPKH";
break;
} }
final newChangeIndex = final newChangeIndex =
DB.instance.get<dynamic>(boxName: walletId, key: indexKey) as int; DB.instance.get<dynamic>(boxName: walletId, key: indexKey) as int;
@ -2314,22 +2146,18 @@ class ParticlWallet extends CoinServiceAPI {
} }
Future<TransactionData> _fetchTransactionData() async { Future<TransactionData> _fetchTransactionData() async {
final List<String> allAddresses = await _fetchAllOwnAddresses(); List<String> allAddressesOld = await _fetchAllOwnAddresses();
List<String> allAddresses = [];
for (String address in allAddressesOld) {
allAddresses.add(address);
}
final changeAddresses = DB.instance.get<dynamic>( var changeAddressesP2PKHOld =
boxName: walletId, key: 'changeAddressesP2WPKH') as List<dynamic>;
final changeAddressesP2PKH =
DB.instance.get<dynamic>(boxName: walletId, key: 'changeAddressesP2PKH') DB.instance.get<dynamic>(boxName: walletId, key: 'changeAddressesP2PKH')
as List<dynamic>; as List<dynamic>;
final changeAddressesP2SH = List<dynamic> changeAddressesP2PKH = [];
DB.instance.get<dynamic>(boxName: walletId, key: 'changeAddressesP2SH') for (var address in changeAddressesP2PKHOld) {
as List<dynamic>; changeAddressesP2PKH.add(address);
for (var i = 0; i < changeAddressesP2PKH.length; i++) {
changeAddresses.add(changeAddressesP2PKH[i] as String);
}
for (var i = 0; i < changeAddressesP2SH.length; i++) {
changeAddresses.add(changeAddressesP2SH[i] as String);
} }
final List<Map<String, dynamic>> allTxHashes = final List<Map<String, dynamic>> allTxHashes =
@ -2348,23 +2176,27 @@ class ParticlWallet extends CoinServiceAPI {
unconfirmedCachedTransactions unconfirmedCachedTransactions
.removeWhere((key, value) => value.confirmedStatus); .removeWhere((key, value) => value.confirmedStatus);
print("CACHED_TRANSACTIONS_IS $cachedTransactions");
if (cachedTransactions != null) { if (cachedTransactions != null) {
for (final tx in allTxHashes.toList(growable: false)) { for (final tx in allTxHashes.toList(growable: false)) {
final txHeight = tx["height"] as int; final txHeight = tx["height"] as int;
if (txHeight > 0 && if (txHeight > 0 &&
txHeight < latestTxnBlockHeight - MINIMUM_CONFIRMATIONS) { txHeight < latestTxnBlockHeight - MINIMUM_CONFIRMATIONS) {
if (unconfirmedCachedTransactions[tx["tx_hash"] as String] == null) { if (unconfirmedCachedTransactions[tx["tx_hash"] as String] == null) {
allTxHashes.remove(tx); print(cachedTransactions.findTransaction(tx["tx_hash"] as String));
print(unconfirmedCachedTransactions[tx["tx_hash"] as String]);
final cachedTx =
cachedTransactions.findTransaction(tx["tx_hash"] as String);
if (!(cachedTx != null &&
addressType(address: cachedTx.address) ==
DerivePathType.bip44)) {
allTxHashes.remove(tx);
}
} }
} }
} }
} }
Set<String> hashes = {};
for (var element in allTxHashes) {
hashes.add(element['tx_hash'] as String);
}
await fastFetch(hashes.toList());
List<Map<String, dynamic>> allTransactions = []; List<Map<String, dynamic>> allTransactions = [];
for (final txHash in allTxHashes) { for (final txHash in allTxHashes) {
@ -2394,16 +2226,6 @@ class ParticlWallet extends CoinServiceAPI {
Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero; Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero;
final List<Map<String, dynamic>> midSortedArray = []; final List<Map<String, dynamic>> midSortedArray = [];
Set<String> vHashes = {};
for (final txObject in allTransactions) {
for (int i = 0; i < (txObject["vin"] as List).length; i++) {
final input = txObject["vin"]![i] as Map;
final prevTxid = input["txid"] as String;
vHashes.add(prevTxid);
}
}
await fastFetch(vHashes.toList());
for (final txObject in allTransactions) { for (final txObject in allTransactions) {
List<String> sendersArray = []; List<String> sendersArray = [];
List<String> recipientsArray = []; List<String> recipientsArray = [];
@ -2417,18 +2239,16 @@ class ParticlWallet extends CoinServiceAPI {
Map<String, dynamic> midSortedTx = {}; Map<String, dynamic> midSortedTx = {};
for (int i = 0; i < (txObject["vin"] as List).length; i++) { for (int i = 0; i < (txObject["vin"] as List).length; i++) {
final input = txObject["vin"]![i] as Map; final input = txObject["vin"][i] as Map;
final prevTxid = input["txid"] as String; final prevTxid = input["txid"] as String;
final prevOut = input["vout"] as int; final prevOut = input["vout"] as int;
final tx = await _cachedElectrumXClient.getTransaction( final tx = await _cachedElectrumXClient.getTransaction(
txHash: prevTxid, txHash: prevTxid, coin: coin);
coin: coin,
);
for (final out in tx["vout"] as List) { for (final out in tx["vout"] as List) {
if (prevOut == out["n"]) { if (prevOut == out["n"]) {
final address = out["scriptPubKey"]["address"] as String?; final address = out["scriptPubKey"]["addresses"][0] as String?;
if (address != null) { if (address != null) {
sendersArray.add(address); sendersArray.add(address);
} }
@ -2439,7 +2259,7 @@ class ParticlWallet extends CoinServiceAPI {
Logging.instance.log("sendersArray: $sendersArray", level: LogLevel.Info); Logging.instance.log("sendersArray: $sendersArray", level: LogLevel.Info);
for (final output in txObject["vout"] as List) { for (final output in txObject["vout"] as List) {
final address = output["scriptPubKey"]["address"] as String?; final address = output["scriptPubKey"]["addresses"][0] as String?;
if (address != null) { if (address != null) {
recipientsArray.add(address); recipientsArray.add(address);
} }
@ -2449,7 +2269,8 @@ class ParticlWallet extends CoinServiceAPI {
.log("recipientsArray: $recipientsArray", level: LogLevel.Info); .log("recipientsArray: $recipientsArray", level: LogLevel.Info);
final foundInSenders = final foundInSenders =
allAddresses.any((element) => sendersArray.contains(element)); allAddresses.any((element) => sendersArray.contains(element)) ||
allAddressesOld.any((element) => sendersArray.contains(element));
Logging.instance Logging.instance
.log("foundInSenders: $foundInSenders", level: LogLevel.Info); .log("foundInSenders: $foundInSenders", level: LogLevel.Info);
@ -2457,7 +2278,7 @@ class ParticlWallet extends CoinServiceAPI {
if (foundInSenders) { if (foundInSenders) {
int totalInput = 0; int totalInput = 0;
for (int i = 0; i < (txObject["vin"] as List).length; i++) { for (int i = 0; i < (txObject["vin"] as List).length; i++) {
final input = txObject["vin"]![i] as Map; final input = txObject["vin"][i] as Map;
final prevTxid = input["txid"] as String; final prevTxid = input["txid"] as String;
final prevOut = input["vout"] as int; final prevOut = input["vout"] as int;
final tx = await _cachedElectrumXClient.getTransaction( final tx = await _cachedElectrumXClient.getTransaction(
@ -2468,7 +2289,7 @@ class ParticlWallet extends CoinServiceAPI {
for (final out in tx["vout"] as List) { for (final out in tx["vout"] as List) {
if (prevOut == out["n"]) { if (prevOut == out["n"]) {
inputAmtSentFromWallet += inputAmtSentFromWallet +=
(Decimal.parse(out["value"]!.toString()) * (Decimal.parse(out["value"].toString()) *
Decimal.fromInt(Constants.satsPerCoin)) Decimal.fromInt(Constants.satsPerCoin))
.toBigInt() .toBigInt()
.toInt(); .toInt();
@ -2479,14 +2300,14 @@ class ParticlWallet extends CoinServiceAPI {
int totalOutput = 0; int totalOutput = 0;
for (final output in txObject["vout"] as List) { for (final output in txObject["vout"] as List) {
final String address = output["scriptPubKey"]!["address"] as String; final address = output["scriptPubKey"]["addresses"][0];
final value = output["value"]!; final value = output["value"];
final _value = (Decimal.parse(value.toString()) * final _value = (Decimal.parse(value.toString()) *
Decimal.fromInt(Constants.satsPerCoin)) Decimal.fromInt(Constants.satsPerCoin))
.toBigInt() .toBigInt()
.toInt(); .toInt();
totalOutput += _value; totalOutput += _value;
if (changeAddresses.contains(address)) { if (changeAddressesP2PKH.contains(address)) {
inputAmtSentFromWallet -= _value; inputAmtSentFromWallet -= _value;
} else { } else {
// change address from 'sent from' to the 'sent to' address // change address from 'sent from' to the 'sent to' address
@ -2504,14 +2325,15 @@ class ParticlWallet extends CoinServiceAPI {
// add up received tx value // add up received tx value
for (final output in txObject["vout"] as List) { for (final output in txObject["vout"] as List) {
final address = output["scriptPubKey"]["address"]; final address = output["scriptPubKey"]["addresses"][0];
if (address != null) { if (address != null) {
final value = (Decimal.parse(output["value"].toString()) * final value = (Decimal.parse(output["value"].toString()) *
Decimal.fromInt(Constants.satsPerCoin)) Decimal.fromInt(Constants.satsPerCoin))
.toBigInt() .toBigInt()
.toInt(); .toInt();
totalOut += value; totalOut += value;
if (allAddresses.contains(address)) { if (allAddresses.contains(address) ||
allAddressesOld.contains(address)) {
outputAmtAddressedToWallet += value; outputAmtAddressedToWallet += value;
} }
} }
@ -2789,7 +2611,7 @@ class ParticlWallet extends CoinServiceAPI {
utxoSigningData: utxoSigningData, utxoSigningData: utxoSigningData,
recipients: [ recipients: [
_recipientAddress, _recipientAddress,
await _getCurrentAddressForChain(1, DerivePathType.bip84), await _getCurrentAddressForChain(1, DerivePathType.bip44),
], ],
satoshiAmounts: [ satoshiAmounts: [
satoshiAmountToSend, satoshiAmountToSend,
@ -2827,9 +2649,9 @@ class ParticlWallet extends CoinServiceAPI {
satoshisBeingUsed - satoshiAmountToSend - changeOutputSize == satoshisBeingUsed - satoshiAmountToSend - changeOutputSize ==
feeForTwoOutputs) { feeForTwoOutputs) {
// generate new change address if current change address has been used // generate new change address if current change address has been used
await _checkChangeAddressForTransactions(DerivePathType.bip84); await _checkChangeAddressForTransactions(DerivePathType.bip44);
final String newChangeAddress = final String newChangeAddress =
await _getCurrentAddressForChain(1, DerivePathType.bip84); await _getCurrentAddressForChain(1, DerivePathType.bip44);
int feeBeingPaid = int feeBeingPaid =
satoshisBeingUsed - satoshiAmountToSend - changeOutputSize; satoshisBeingUsed - satoshiAmountToSend - changeOutputSize;
@ -3006,7 +2828,6 @@ class ParticlWallet extends CoinServiceAPI {
// addresses to check // addresses to check
List<String> addressesP2PKH = []; List<String> addressesP2PKH = [];
List<String> addressesP2SH = []; List<String> addressesP2SH = [];
List<String> addressesP2WPKH = [];
try { try {
// Populating the addresses to check // Populating the addresses to check
@ -3032,9 +2853,6 @@ class ParticlWallet extends CoinServiceAPI {
case DerivePathType.bip49: case DerivePathType.bip49:
addressesP2SH.add(address); addressesP2SH.add(address);
break; break;
case DerivePathType.bip84:
addressesP2WPKH.add(address);
break;
} }
} }
} }
@ -3169,65 +2987,6 @@ class ParticlWallet extends CoinServiceAPI {
} }
} }
// p2wpkh / bip84
final p2wpkhLength = addressesP2WPKH.length;
if (p2wpkhLength > 0) {
final receiveDerivations = await _fetchDerivations(
chain: 0,
derivePathType: DerivePathType.bip84,
);
final changeDerivations = await _fetchDerivations(
chain: 1,
derivePathType: DerivePathType.bip84,
);
for (int i = 0; i < p2wpkhLength; i++) {
// receives
final receiveDerivation = receiveDerivations[addressesP2WPKH[i]];
// if a match exists it will not be null
if (receiveDerivation != null) {
final data = P2WPKH(
data: PaymentData(
pubkey: Format.stringToUint8List(
receiveDerivation["pubKey"] as String)),
network: _network,
).data;
for (String tx in addressTxid[addressesP2WPKH[i]]!) {
results[tx] = {
"output": data.output,
"keyPair": ECPair.fromWIF(
receiveDerivation["wif"] as String,
network: _network,
),
};
}
} else {
// if its not a receive, check change
final changeDerivation = changeDerivations[addressesP2WPKH[i]];
// if a match exists it will not be null
if (changeDerivation != null) {
final data = P2WPKH(
data: PaymentData(
pubkey: Format.stringToUint8List(
changeDerivation["pubKey"] as String)),
network: _network,
).data;
for (String tx in addressTxid[addressesP2WPKH[i]]!) {
results[tx] = {
"output": data.output,
"keyPair": ECPair.fromWIF(
changeDerivation["wif"] as String,
network: _network,
),
};
}
}
}
}
}
return results; return results;
} catch (e, s) { } catch (e, s) {
Logging.instance Logging.instance
@ -3411,40 +3170,6 @@ class ParticlWallet extends CoinServiceAPI {
await DB.instance await DB.instance
.delete<dynamic>(key: 'changeIndexP2SH_BACKUP', boxName: walletId); .delete<dynamic>(key: 'changeIndexP2SH_BACKUP', boxName: walletId);
// p2wpkh
final tempReceivingAddressesP2WPKH = DB.instance.get<dynamic>(
boxName: walletId, key: 'receivingAddressesP2WPKH_BACKUP');
final tempChangeAddressesP2WPKH = DB.instance
.get<dynamic>(boxName: walletId, key: 'changeAddressesP2WPKH_BACKUP');
final tempReceivingIndexP2WPKH = DB.instance
.get<dynamic>(boxName: walletId, key: 'receivingIndexP2WPKH_BACKUP');
final tempChangeIndexP2WPKH = DB.instance
.get<dynamic>(boxName: walletId, key: 'changeIndexP2WPKH_BACKUP');
await DB.instance.put<dynamic>(
boxName: walletId,
key: 'receivingAddressesP2WPKH',
value: tempReceivingAddressesP2WPKH);
await DB.instance.put<dynamic>(
boxName: walletId,
key: 'changeAddressesP2WPKH',
value: tempChangeAddressesP2WPKH);
await DB.instance.put<dynamic>(
boxName: walletId,
key: 'receivingIndexP2WPKH',
value: tempReceivingIndexP2WPKH);
await DB.instance.put<dynamic>(
boxName: walletId,
key: 'changeIndexP2WPKH',
value: tempChangeIndexP2WPKH);
await DB.instance.delete<dynamic>(
key: 'receivingAddressesP2WPKH_BACKUP', boxName: walletId);
await DB.instance.delete<dynamic>(
key: 'changeAddressesP2WPKH_BACKUP', boxName: walletId);
await DB.instance
.delete<dynamic>(key: 'receivingIndexP2WPKH_BACKUP', boxName: walletId);
await DB.instance
.delete<dynamic>(key: 'changeIndexP2WPKH_BACKUP', boxName: walletId);
// P2PKH derivations // P2PKH derivations
final p2pkhReceiveDerivationsString = await _secureStore.read( final p2pkhReceiveDerivationsString = await _secureStore.read(
key: "${walletId}_receiveDerivationsP2PKH_BACKUP"); key: "${walletId}_receiveDerivationsP2PKH_BACKUP");
@ -3478,24 +3203,6 @@ class ParticlWallet extends CoinServiceAPI {
await _secureStore.delete(key: "${walletId}_receiveDerivationsP2SH_BACKUP"); await _secureStore.delete(key: "${walletId}_receiveDerivationsP2SH_BACKUP");
await _secureStore.delete(key: "${walletId}_changeDerivationsP2SH_BACKUP"); await _secureStore.delete(key: "${walletId}_changeDerivationsP2SH_BACKUP");
// P2WPKH derivations
final p2wpkhReceiveDerivationsString = await _secureStore.read(
key: "${walletId}_receiveDerivationsP2WPKH_BACKUP");
final p2wpkhChangeDerivationsString = await _secureStore.read(
key: "${walletId}_changeDerivationsP2WPKH_BACKUP");
await _secureStore.write(
key: "${walletId}_receiveDerivationsP2WPKH",
value: p2wpkhReceiveDerivationsString);
await _secureStore.write(
key: "${walletId}_changeDerivationsP2WPKH",
value: p2wpkhChangeDerivationsString);
await _secureStore.delete(
key: "${walletId}_receiveDerivationsP2WPKH_BACKUP");
await _secureStore.delete(
key: "${walletId}_changeDerivationsP2WPKH_BACKUP");
// UTXOs // UTXOs
final utxoData = DB.instance final utxoData = DB.instance
.get<dynamic>(boxName: walletId, key: 'latest_utxo_model_BACKUP'); .get<dynamic>(boxName: walletId, key: 'latest_utxo_model_BACKUP');
@ -3585,43 +3292,6 @@ class ParticlWallet extends CoinServiceAPI {
await DB.instance await DB.instance
.delete<dynamic>(key: 'changeIndexP2SH', boxName: walletId); .delete<dynamic>(key: 'changeIndexP2SH', boxName: walletId);
// p2wpkh
final tempReceivingAddressesP2WPKH = DB.instance
.get<dynamic>(boxName: walletId, key: 'receivingAddressesP2WPKH');
await DB.instance.put<dynamic>(
boxName: walletId,
key: 'receivingAddressesP2WPKH_BACKUP',
value: tempReceivingAddressesP2WPKH);
await DB.instance
.delete<dynamic>(key: 'receivingAddressesP2WPKH', boxName: walletId);
final tempChangeAddressesP2WPKH = DB.instance
.get<dynamic>(boxName: walletId, key: 'changeAddressesP2WPKH');
await DB.instance.put<dynamic>(
boxName: walletId,
key: 'changeAddressesP2WPKH_BACKUP',
value: tempChangeAddressesP2WPKH);
await DB.instance
.delete<dynamic>(key: 'changeAddressesP2WPKH', boxName: walletId);
final tempReceivingIndexP2WPKH = DB.instance
.get<dynamic>(boxName: walletId, key: 'receivingIndexP2WPKH');
await DB.instance.put<dynamic>(
boxName: walletId,
key: 'receivingIndexP2WPKH_BACKUP',
value: tempReceivingIndexP2WPKH);
await DB.instance
.delete<dynamic>(key: 'receivingIndexP2WPKH', boxName: walletId);
final tempChangeIndexP2WPKH =
DB.instance.get<dynamic>(boxName: walletId, key: 'changeIndexP2WPKH');
await DB.instance.put<dynamic>(
boxName: walletId,
key: 'changeIndexP2WPKH_BACKUP',
value: tempChangeIndexP2WPKH);
await DB.instance
.delete<dynamic>(key: 'changeIndexP2WPKH', boxName: walletId);
// P2PKH derivations // P2PKH derivations
final p2pkhReceiveDerivationsString = final p2pkhReceiveDerivationsString =
await _secureStore.read(key: "${walletId}_receiveDerivationsP2PKH"); await _secureStore.read(key: "${walletId}_receiveDerivationsP2PKH");
@ -3654,22 +3324,6 @@ class ParticlWallet extends CoinServiceAPI {
await _secureStore.delete(key: "${walletId}_receiveDerivationsP2SH"); await _secureStore.delete(key: "${walletId}_receiveDerivationsP2SH");
await _secureStore.delete(key: "${walletId}_changeDerivationsP2SH"); await _secureStore.delete(key: "${walletId}_changeDerivationsP2SH");
// P2WPKH derivations
final p2wpkhReceiveDerivationsString =
await _secureStore.read(key: "${walletId}_receiveDerivationsP2WPKH");
final p2wpkhChangeDerivationsString =
await _secureStore.read(key: "${walletId}_changeDerivationsP2WPKH");
await _secureStore.write(
key: "${walletId}_receiveDerivationsP2WPKH_BACKUP",
value: p2wpkhReceiveDerivationsString);
await _secureStore.write(
key: "${walletId}_changeDerivationsP2WPKH_BACKUP",
value: p2wpkhChangeDerivationsString);
await _secureStore.delete(key: "${walletId}_receiveDerivationsP2WPKH");
await _secureStore.delete(key: "${walletId}_changeDerivationsP2WPKH");
// UTXOs // UTXOs
final utxoData = final utxoData =
DB.instance.get<dynamic>(boxName: walletId, key: 'latest_utxo_model'); DB.instance.get<dynamic>(boxName: walletId, key: 'latest_utxo_model');
@ -3754,21 +3408,21 @@ class ParticlWallet extends CoinServiceAPI {
Future<bool> generateNewAddress() async { Future<bool> generateNewAddress() async {
try { try {
await _incrementAddressIndexForChain( await _incrementAddressIndexForChain(
0, DerivePathType.bip84); // First increment the receiving index 0, DerivePathType.bip44); // First increment the receiving index
final newReceivingIndex = DB.instance.get<dynamic>( final newReceivingIndex = DB.instance.get<dynamic>(
boxName: walletId, boxName: walletId,
key: 'receivingIndexP2WPKH') as int; // Check the new receiving index key: 'receivingIndexP2PKH') as int; // Check the new receiving index
final newReceivingAddress = await _generateAddressForChain( final newReceivingAddress = await _generateAddressForChain(
0, 0,
newReceivingIndex, newReceivingIndex,
DerivePathType DerivePathType
.bip84); // Use new index to derive a new receiving address .bip44); // Use new index to derive a new receiving address
await _addToAddressesArrayForChain( await _addToAddressesArrayForChain(
newReceivingAddress, newReceivingAddress,
0, 0,
DerivePathType DerivePathType
.bip84); // Add that new receiving address to the array of receiving addresses .bip44); // Add that new receiving address to the array of receiving addresses
_currentReceivingAddress = Future(() => _currentReceivingAddressP2PKH = Future(() =>
newReceivingAddress); // Set the new receiving address that the service newReceivingAddress); // Set the new receiving address that the service
return true; return true;