diff --git a/android/gradle.properties b/android/gradle.properties index 7803bf46c..24863d218 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,3 +1,3 @@ -org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G +org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError android.useAndroidX=true android.enableJetifier=true \ No newline at end of file diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 3c85cfe05..afa1e8eb0 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip diff --git a/android/settings.gradle b/android/settings.gradle index a38bba1fb..02fb0cfb0 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -18,7 +18,7 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version '8.6.0' apply false + id "com.android.application" version '8.7.0' apply false id "org.jetbrains.kotlin.android" version "1.8.22" apply false } diff --git a/crypto_plugins/flutter_libepiccash b/crypto_plugins/flutter_libepiccash index 8830be2ba..238455f2b 160000 --- a/crypto_plugins/flutter_libepiccash +++ b/crypto_plugins/flutter_libepiccash @@ -1 +1 @@ -Subproject commit 8830be2ba661828d743be12df6f33d560448ed6a +Subproject commit 238455f2b3fe39564cc617ed0ea45f22971aa644 diff --git a/crypto_plugins/flutter_liblelantus b/crypto_plugins/flutter_liblelantus index 89f05ee42..30bc004bd 160000 --- a/crypto_plugins/flutter_liblelantus +++ b/crypto_plugins/flutter_liblelantus @@ -1 +1 @@ -Subproject commit 89f05ee42754f80da036ddcf31c7b1e1dc3b4a83 +Subproject commit 30bc004bd7cadd635e943d29033a8d261cbc1eda diff --git a/docs/building.md b/docs/building.md index d336eac16..c3dacb90b 100644 --- a/docs/building.md +++ b/docs/building.md @@ -72,8 +72,8 @@ Install [Rust](https://www.rust-lang.org/tools/install) via [rustup.rs](https:// ``` curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh source ~/.bashrc -rustup install 1.67.1 1.71.0 1.72.0 1.73.0 -rustup default 1.67.1 +rustup install 1.85.1 +rustup default 1.85.1 cargo install cargo-ndk --version 2.12.7 --locked ``` @@ -209,12 +209,12 @@ brew install brotli cairo coreutils gdbm gettext glib gmp libevent libidn2 libng ``` -Download and install [Rust](https://www.rust-lang.org/tools/install). [Rustup](https://rustup.rs/) is recommended for Rust setup. Use `rustc` to confirm successful installation. Install toolchains 1.67.1 and 1.72.0 and `cbindgen` and `cargo-lipo` too. You will also have to add the platform target(s) `aarch64-apple-ios` and/or `aarch64-apple-darwin`. You can use the command(s): +Download and install [Rust](https://www.rust-lang.org/tools/install). [Rustup](https://rustup.rs/) is recommended for Rust setup. Use `rustc` to confirm successful installation. Install toolchain 1.85.1 and `cbindgen` and `cargo-lipo` too. You will also have to add the platform target(s) `aarch64-apple-ios` and/or `aarch64-apple-darwin`. You can use the command(s): ``` curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh source ~/.bashrc -rustup install 1.67.1 1.71.0 1.72.0 1.73.0 -rustup default 1.67.1 +rustup install 1.85.1 +rustup default 1.85.1 cargo install cargo-ndk --version 2.12.7 --locked cargo install cbindgen cargo-lipo rustup target add aarch64-apple-ios aarch64-apple-darwin @@ -306,8 +306,8 @@ Run `flutter doctor` in PowerShell to confirm its installation. ### Rust Install [Rust](https://www.rust-lang.org/tools/install) on the Windows host (not in WSL2). Download the installer from [rustup.rs](https://rustup.rs), make sure it works on the commandline (you may need to open a new terminal), and install the following versions: ``` -rustup install 1.67.1 1.71.0 1.72.0 1.73.0 -rustup default 1.67.1 +rustup install 1.85.1 +rustup default 1.85.1 cargo install cargo-ndk --version 2.12.7 --locked ``` diff --git a/lib/wallets/wallet/impl/namecoin_wallet.dart b/lib/wallets/wallet/impl/namecoin_wallet.dart index 64dc23801..bf6f43e41 100644 --- a/lib/wallets/wallet/impl/namecoin_wallet.dart +++ b/lib/wallets/wallet/impl/namecoin_wallet.dart @@ -41,11 +41,7 @@ String nameSaltKeyBuilder(String txid, String walletId, int txPos) { } String encodeNameSaltData(String name, String salt, String value) => - jsonEncode({ - "name": name, - "salt": salt, - "value": value, - }); + jsonEncode({"name": name, "salt": salt, "value": value}); ({String salt, String name, String value}) decodeNameSaltData(String value) { try { @@ -76,25 +72,26 @@ class NamecoinWallet @override Future> fetchAddressesForElectrumXScan() async { - final allAddresses = await mainDB - .getAddresses(walletId) - .filter() - .not() - .group( - (q) => q - .typeEqualTo(AddressType.nonWallet) - .or() - .subTypeEqualTo(AddressSubType.nonWallet), - ) - .findAll(); + final allAddresses = + await mainDB + .getAddresses(walletId) + .filter() + .not() + .group( + (q) => q + .typeEqualTo(AddressType.nonWallet) + .or() + .subTypeEqualTo(AddressSubType.nonWallet), + ) + .findAll(); return allAddresses; } -// =========================================================================== + // =========================================================================== @override Future<({String? blockedReason, bool blocked, String? utxoLabel})> - checkBlockUTXO( + checkBlockUTXO( Map jsonUTXO, String? scriptPubKeyHex, Map jsonTX, @@ -108,9 +105,7 @@ class NamecoinWallet } @override - Future parseUTXO({ - required Map jsonUTXO, - }) async { + Future parseUTXO({required Map jsonUTXO}) async { final txn = await electrumXCachedClient.getTransaction( txHash: jsonUTXO["tx_hash"] as String, verbose: true, @@ -136,7 +131,7 @@ class NamecoinWallet if (output["n"] == vout) { utxoOwnerAddress = output["scriptPubKey"]?["addresses"]?[0] as String? ?? - output["scriptPubKey"]?["address"] as String?; + output["scriptPubKey"]?["address"] as String?; // check for nameOp if (output["scriptPubKey"]?["nameOp"] != null) { @@ -145,19 +140,15 @@ class NamecoinWallet blockReason = "Contains name"; try { - final rawNameOP = (output["scriptPubKey"]["nameOp"] as Map) - .cast(); + final rawNameOP = + (output["scriptPubKey"]["nameOp"] as Map) + .cast(); otherDataString = jsonEncode({ UTXOOtherDataKeys.nameOpData: jsonEncode(rawNameOP), }); - final nameOp = OpNameData( - rawNameOP, - jsonUTXO["height"] as int, - ); - Logging.instance.i( - "nameOp:\n$nameOp", - ); + final nameOp = OpNameData(rawNameOP, jsonUTXO["height"] as int); + Logging.instance.i("nameOp:\n$nameOp"); switch (nameOp.op) { case OpName.nameNew: @@ -193,7 +184,8 @@ class NamecoinWallet name: label ?? "", isBlocked: shouldBlock, blockedReason: blockReason, - isCoinbase: txn["is_coinbase"] as bool? ?? + isCoinbase: + txn["is_coinbase"] as bool? ?? txn["is-coinbase"] as bool? ?? txn["iscoinbase"] as bool? ?? isCoinbase, @@ -231,30 +223,34 @@ class NamecoinWallet await fetchAddressesForElectrumXScan(); // Separate receiving and change addresses. - final Set receivingAddresses = allAddressesOld - .where((e) => e.subType == AddressSubType.receiving) - .map((e) => e.value) - .toSet(); - final Set changeAddresses = allAddressesOld - .where((e) => e.subType == AddressSubType.change) - .map((e) => e.value) - .toSet(); + final Set receivingAddresses = + allAddressesOld + .where((e) => e.subType == AddressSubType.receiving) + .map((e) => e.value) + .toSet(); + final Set changeAddresses = + allAddressesOld + .where((e) => e.subType == AddressSubType.change) + .map((e) => e.value) + .toSet(); // Remove duplicates. final allAddressesSet = {...receivingAddresses, ...changeAddresses}; // Fetch history from ElectrumX. - final List> allTxHashes = - await fetchHistory(allAddressesSet); + final List> allTxHashes = await fetchHistory( + allAddressesSet, + ); // Only parse new txs (not in db yet). final List> allTransactions = []; for (final txHash in allTxHashes) { // Check for duplicates by searching for tx by tx_hash in db. - final storedTx = await mainDB.isar.transactionV2s - .where() - .txidWalletIdEqualTo(txHash["tx_hash"] as String, walletId) - .findFirst(); + final storedTx = + await mainDB.isar.transactionV2s + .where() + .txidWalletIdEqualTo(txHash["tx_hash"] as String, walletId) + .findFirst(); if (storedTx == null || storedTx.height == null || @@ -267,8 +263,9 @@ class NamecoinWallet ); // Only tx to list once. - if (allTransactions - .indexWhere((e) => e["txid"] == tx["txid"] as String) == + if (allTransactions.indexWhere( + (e) => e["txid"] == tx["txid"] as String, + ) == -1) { tx["height"] = txHash["height"]; allTransactions.add(tx); @@ -418,7 +415,8 @@ class NamecoinWallet txid: txData["txid"] as String, height: txData["height"] as int?, version: txData["version"] as int, - timestamp: txData["blocktime"] as int? ?? + timestamp: + txData["blocktime"] as int? ?? DateTime.timestamp().millisecondsSinceEpoch ~/ 1000, inputs: List.unmodifiable(inputs), outputs: List.unmodifiable(outputs), @@ -456,10 +454,7 @@ class NamecoinWallet final data = decodeNameSaltData(encoded); if (data.name == name) { - return ( - data: null, - nameState: NameState.unavailable, - ); + return (data: null, nameState: NameState.unavailable); } } } @@ -485,9 +480,7 @@ class NamecoinWallet opNameData = OpNameData.fromTx(txMap, txHeight); final isExpired = opNameData.expired(await chainHeight); - Logging.instance.i( - "Name $opNameData \nis expired = $isExpired", - ); + Logging.instance.i("Name $opNameData \nis expired = $isExpired"); available = isExpired; } catch (_) { available = false; // probably @@ -508,23 +501,22 @@ class NamecoinWallet /// Must be called in refresh() AFTER the wallet's UTXOs have been updated! Future checkAutoRegisterNameNewOutputs() async { - Logging.instance.t( - "$walletId checkAutoRegisterNameNewOutputs()", - ); + Logging.instance.t("$walletId checkAutoRegisterNameNewOutputs()"); try { final currentHeight = await chainHeight; // not ideal filtering - final utxos = await mainDB - .getUTXOs(walletId) - .filter() - .otherDataIsNotNull() - .and() - .blockHeightIsNotNull() - .and() - .blockHeightGreaterThan(0) - .and() - .blockHeightLessThan(currentHeight - kNameWaitBlocks) - .findAll(); + final utxos = + await mainDB + .getUTXOs(walletId) + .filter() + .otherDataIsNotNull() + .and() + .blockHeightIsNotNull() + .and() + .blockHeightGreaterThan(0) + .and() + .blockHeightLessThan(currentHeight - kNameWaitBlocks) + .findAll(); Logging.instance.t( "_unknownNameNewOutputs(count=${_unknownNameNewOutputs.length})" @@ -539,9 +531,7 @@ class NamecoinWallet for (final utxo in utxos) { final nameOp = getOpNameDataFrom(utxo); if (nameOp != null) { - Logging.instance.t( - "Found OpName: $nameOp\n\nIN UTXO: $utxo", - ); + Logging.instance.t("Found OpName: $nameOp\n\nIN UTXO: $utxo"); if (nameOp.op == OpName.nameNew) { // at this point we should have an unspent UTXO that is at least @@ -646,14 +636,10 @@ class NamecoinWallet switch (txData.opNameState!.type) { case OpName.nameNew: - assert( - nameAmount.raw == BigInt.from(kNameNewAmountSats), - ); + assert(nameAmount.raw == BigInt.from(kNameNewAmountSats)); break; case OpName.nameFirstUpdate || OpName.nameUpdate: - assert( - nameAmount.raw == BigInt.from(kNameAmountSats), - ); + assert(nameAmount.raw == BigInt.from(kNameAmountSats)); break; } } @@ -671,9 +657,10 @@ class NamecoinWallet ); // TODO: [prio=high]: check this opt in rbf - final sequence = this is RbfInterface && (this as RbfInterface).flagOptInRBF - ? 0xffffffff - 10 - : 0xffffffff - 1; + final sequence = + this is RbfInterface && (this as RbfInterface).flagOptInRBF + ? 0xffffffff - 10 + : 0xffffffff - 1; // Add transaction inputs for (int i = 0; i < utxoSigningData.length; i++) { @@ -683,10 +670,7 @@ class NamecoinWallet txid.toUint8ListFromHex.reversed.toList(), ); - final prevOutpoint = coinlib.OutPoint( - hash, - utxoSigningData[i].utxo.vout, - ); + final prevOutpoint = coinlib.OutPoint(hash, utxoSigningData[i].utxo.vout); final prevOutput = coinlib.Output.fromAddress( BigInt.from(utxoSigningData[i].utxo.value), @@ -746,9 +730,10 @@ class NamecoinWallet txid: utxoSigningData[i].utxo.txid, vout: utxoSigningData[i].utxo.vout, ), - addresses: utxoSigningData[i].utxo.address == null - ? [] - : [utxoSigningData[i].utxo.address!], + addresses: + utxoSigningData[i].utxo.address == null + ? [] + : [utxoSigningData[i].utxo.address!], valueStringSats: utxoSigningData[i].utxo.value.toString(), witness: null, innerRedeemScriptAsm: null, @@ -803,10 +788,9 @@ class NamecoinWallet OutputV2.isarCantDoRequiredInDefaultConstructor( scriptPubKeyHex: "000000", valueStringSats: txData.recipients![i].amount.raw.toString(), - addresses: [ - txData.recipients![i].address.toString(), - ], - walletOwns: (await mainDB.isar.addresses + addresses: [txData.recipients![i].address.toString()], + walletOwns: + (await mainDB.isar.addresses .where() .walletIdEqualTo(walletId) .filter() @@ -822,22 +806,33 @@ class NamecoinWallet // Sign the transaction accordingly for (int i = 0; i < utxoSigningData.length; i++) { final value = BigInt.from(utxoSigningData[i].utxo.value); - coinlib.ECPrivateKey key = utxoSigningData[i].keyPair!.privateKey; + final key = utxoSigningData[i].keyPair!.privateKey; if (clTx.inputs[i] is coinlib.TaprootKeyInput) { final taproot = coinlib.Taproot( internalKey: utxoSigningData[i].keyPair!.publicKey, ); - key = taproot.tweakPrivateKey(key); + clTx = clTx.signTaproot( + inputN: i, + key: taproot.tweakPrivateKey(key), + prevOuts: prevOuts, + ); + } else if (clTx.inputs[i] is coinlib.LegacyWitnessInput) { + clTx = clTx.signLegacyWitness(inputN: i, key: key, value: value); + } else if (clTx.inputs[i] is coinlib.LegacyInput) { + clTx = clTx.signLegacy(inputN: i, key: key); + } else if (clTx.inputs[i] is coinlib.TaprootSingleScriptSigInput) { + clTx = clTx.signTaprootSingleScriptSig( + inputN: i, + key: key, + prevOuts: prevOuts, + ); + } else { + throw Exception( + "Unable to sign input of type ${clTx.inputs[i].runtimeType}", + ); } - - clTx = clTx.sign( - inputN: i, - value: value, - key: key, - prevOuts: prevOuts, - ); } } catch (e, s) { Logging.instance.e( @@ -879,17 +874,13 @@ class NamecoinWallet ); } - Future prepareNameSend({ - required TxData txData, - }) async { + Future prepareNameSend({required TxData txData}) async { try { if (txData.amount == null) { throw Exception("No recipients in attempted transaction!"); } - Logging.instance.t( - "prepareNameSend called with TxData:\n\n$txData", - ); + Logging.instance.t("prepareNameSend called with TxData:\n\n$txData"); final feeRateType = txData.feeRateType; final customSatsPerVByte = txData.satsPerVByte; @@ -944,20 +935,17 @@ class NamecoinWallet } final result = await coinSelectionName( - txData: txData.copyWith( - feeRateAmount: rate, - ), + txData: txData.copyWith(feeRateAmount: rate), utxos: utxos?.toList(), coinControl: coinControl, ); - Logging.instance.d( - "prepare send: $result", - ); + Logging.instance.d("prepare send: $result"); if (result.fee!.raw.toInt() < result.vSize!) { throw Exception( - "Error in fee calculation: Transaction fee (${result.fee!.raw.toInt()}) cannot " - "be less than vSize (${result.vSize})"); + "Error in fee calculation: Transaction fee (${result.fee!.raw.toInt()}) cannot " + "be less than vSize (${result.vSize})", + ); } return result; @@ -1028,19 +1016,20 @@ class NamecoinWallet final canCPFP = this is CpfpInterface && coinControl; - final spendableOutputs = availableOutputs - .where( - (e) => - !e.isBlocked && - (e.used != true) && - (canCPFP || - e.isConfirmed( - currentChainHeight, - cryptoCurrency.minConfirms, - cryptoCurrency.minCoinbaseConfirms, - )), - ) - .toList(); + final spendableOutputs = + availableOutputs + .where( + (e) => + !e.isBlocked && + (e.used != true) && + (canCPFP || + e.isConfirmed( + currentChainHeight, + cryptoCurrency.minConfirms, + cryptoCurrency.minCoinbaseConfirms, + )), + ) + .toList(); if (coinControl) { if (spendableOutputs.length < availableOutputs.length) { @@ -1050,8 +1039,9 @@ class NamecoinWallet } else { // sort spendable by age (oldest first) spendableOutputs.sort( - (a, b) => (b.blockTime ?? currentChainHeight) - .compareTo((a.blockTime ?? currentChainHeight)), + (a, b) => (b.blockTime ?? currentChainHeight).compareTo( + (a.blockTime ?? currentChainHeight), + ), ); } @@ -1061,8 +1051,10 @@ class NamecoinWallet spendableOutputs.insert(0, txData.opNameState!.output!); } - final spendableSatoshiValue = - spendableOutputs.fold(BigInt.zero, (p, e) => p + BigInt.from(e.value)); + final spendableSatoshiValue = spendableOutputs.fold( + BigInt.zero, + (p, e) => p + BigInt.from(e.value), + ); if (spendableSatoshiValue < satoshiAmountToSend) { throw Exception("Insufficient balance"); @@ -1082,21 +1074,24 @@ class NamecoinWallet final List utxoObjectsToUse = []; if (!coinControl) { - for (int i = 0; - satoshisBeingUsed < satoshiAmountToSend && - i < spendableOutputs.length; - i++) { + for ( + int i = 0; + satoshisBeingUsed < satoshiAmountToSend && i < spendableOutputs.length; + i++ + ) { utxoObjectsToUse.add(spendableOutputs[i]); satoshisBeingUsed += BigInt.from(spendableOutputs[i].value); inputsBeingConsumed += 1; } - for (int i = 0; - i < additionalOutputs && - inputsBeingConsumed < spendableOutputs.length; - i++) { + for ( + int i = 0; + i < additionalOutputs && inputsBeingConsumed < spendableOutputs.length; + i++ + ) { utxoObjectsToUse.add(spendableOutputs[inputsBeingConsumed]); - satoshisBeingUsed += - BigInt.from(spendableOutputs[inputsBeingConsumed].value); + satoshisBeingUsed += BigInt.from( + spendableOutputs[inputsBeingConsumed].value, + ); inputsBeingConsumed += 1; } } else { @@ -1120,17 +1115,17 @@ class NamecoinWallet final int vSizeForOneOutput; try { - vSizeForOneOutput = (await _createNameTx( - utxoSigningData: utxoSigningData, - isForFeeCalcPurposesOnly: true, - txData: txData.copyWith( - recipients: await helperRecipientsConvert( - [recipientAddress], - [satoshisBeingUsed], - ), - ), - )) - .vSize!; + vSizeForOneOutput = + (await _createNameTx( + utxoSigningData: utxoSigningData, + isForFeeCalcPurposesOnly: true, + txData: txData.copyWith( + recipients: await helperRecipientsConvert( + [recipientAddress], + [satoshisBeingUsed], + ), + ), + )).vSize!; } catch (e, s) { Logging.instance.e("vSizeForOneOutput: $e", error: e, stackTrace: s); rethrow; @@ -1141,23 +1136,20 @@ class NamecoinWallet BigInt maxBI(BigInt a, BigInt b) => a > b ? a : b; try { - vSizeForTwoOutPuts = (await _createNameTx( - utxoSigningData: utxoSigningData, - isForFeeCalcPurposesOnly: true, - txData: txData.copyWith( - recipients: await helperRecipientsConvert( - [recipientAddress, (await getCurrentChangeAddress())!.value], - [ - satoshiAmountToSend, - maxBI( - BigInt.zero, - satoshisBeingUsed - satoshiAmountToSend, + vSizeForTwoOutPuts = + (await _createNameTx( + utxoSigningData: utxoSigningData, + isForFeeCalcPurposesOnly: true, + txData: txData.copyWith( + recipients: await helperRecipientsConvert( + [recipientAddress, (await getCurrentChangeAddress())!.value], + [ + satoshiAmountToSend, + maxBI(BigInt.zero, satoshisBeingUsed - satoshiAmountToSend), + ], ), - ], - ), - ), - )) - .vSize!; + ), + )).vSize!; } catch (e, s) { Logging.instance.e("vSizeForTwoOutPuts: $e", error: e, stackTrace: s); rethrow; @@ -1168,18 +1160,18 @@ class NamecoinWallet satsPerVByte != null ? (satsPerVByte * vSizeForOneOutput) : estimateTxFee( - vSize: vSizeForOneOutput, - feeRatePerKB: selectedTxFeeRate, - ), + vSize: vSizeForOneOutput, + feeRatePerKB: selectedTxFeeRate, + ), ); // Assume 2 outputs, one for recipient and one for change final feeForTwoOutputs = BigInt.from( satsPerVByte != null ? (satsPerVByte * vSizeForTwoOutPuts) : estimateTxFee( - vSize: vSizeForTwoOutPuts, - feeRatePerKB: selectedTxFeeRate, - ), + vSize: vSizeForTwoOutPuts, + feeRatePerKB: selectedTxFeeRate, + ), ); Logging.instance.d( @@ -1250,12 +1242,14 @@ class NamecoinWallet recipientsArray.add(newChangeAddress); recipientsAmtArray.add(changeOutputSize); - Logging.instance.d('2 outputs in tx' - '\nInput size: $satoshisBeingUsed' - '\nRecipient output size: $satoshiAmountToSend' - '\nChange Output Size: $changeOutputSize' - '\nDifference (fee being paid): $feeBeingPaid sats' - '\nEstimated fee: $feeForTwoOutputs'); + Logging.instance.d( + '2 outputs in tx' + '\nInput size: $satoshisBeingUsed' + '\nRecipient output size: $satoshiAmountToSend' + '\nChange Output Size: $changeOutputSize' + '\nDifference (fee being paid): $feeBeingPaid sats' + '\nEstimated fee: $feeForTwoOutputs', + ); TxData txnData = await _createNameTx( utxoSigningData: utxoSigningData, @@ -1305,9 +1299,7 @@ class NamecoinWallet } else { // Something went wrong here. It either overshot or undershot the estimated fee amount or the changeOutputSize // is smaller than or equal to cryptoCurrency.dustLimit. Revert to single output transaction. - Logging.instance.d( - 'Reverting to 1 output in tx', - ); + Logging.instance.d('Reverting to 1 output in tx'); return await _singleOutputTxn(); } @@ -1365,7 +1357,4 @@ class NamecoinWallet } } -enum NameState { - available, - unavailable; -} +enum NameState { available, unavailable } diff --git a/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart b/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart index 2660d60ff..e393ceb9d 100644 --- a/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart +++ b/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart @@ -36,7 +36,8 @@ import 'rbf_interface.dart'; import 'view_only_option_interface.dart'; mixin ElectrumXInterface - on Bip39HDWallet implements ViewOnlyOptionInterface { + on Bip39HDWallet + implements ViewOnlyOptionInterface { late ElectrumXClient electrumXClient; late CachedElectrumXClient electrumXCachedClient; @@ -54,9 +55,10 @@ mixin ElectrumXInterface try { _serverVersion ??= _parseServerVersion( - (await electrumXClient - .getServerFeatures() - .timeout(const Duration(seconds: 2)))["server_version"] as String, + (await electrumXClient.getServerFeatures().timeout( + const Duration(seconds: 2), + ))["server_version"] + as String, ); } catch (_) { // ignore failure as it doesn't matter @@ -74,32 +76,28 @@ mixin ElectrumXInterface } Future> - helperRecipientsConvert( - List addrs, - List satValues, - ) async { + helperRecipientsConvert(List addrs, List satValues) async { final List<({String address, Amount amount, bool isChange})> results = []; for (int i = 0; i < addrs.length; i++) { - results.add( - ( - address: addrs[i], - amount: Amount( - rawValue: satValues[i], - fractionDigits: cryptoCurrency.fractionDigits, - ), - isChange: (await mainDB.isar.addresses - .where() - .walletIdEqualTo(walletId) - .filter() - .subTypeEqualTo(AddressSubType.change) - .and() - .valueEqualTo(addrs[i]) - .valueProperty() - .findFirst()) != - null + results.add(( + address: addrs[i], + amount: Amount( + rawValue: satValues[i], + fractionDigits: cryptoCurrency.fractionDigits, ), - ); + isChange: + (await mainDB.isar.addresses + .where() + .walletIdEqualTo(walletId) + .filter() + .subTypeEqualTo(AddressSubType.change) + .and() + .valueEqualTo(addrs[i]) + .valueProperty() + .findFirst()) != + null, + )); } return results; @@ -133,21 +131,24 @@ mixin ElectrumXInterface final canCPFP = this is CpfpInterface && coinControl; - final spendableOutputs = availableOutputs - .where( - (e) => - !e.isBlocked && - (e.used != true) && - (canCPFP || - e.isConfirmed( - currentChainHeight, - cryptoCurrency.minConfirms, - cryptoCurrency.minCoinbaseConfirms, - )), - ) - .toList(); - final spendableSatoshiValue = - spendableOutputs.fold(BigInt.zero, (p, e) => p + BigInt.from(e.value)); + final spendableOutputs = + availableOutputs + .where( + (e) => + !e.isBlocked && + (e.used != true) && + (canCPFP || + e.isConfirmed( + currentChainHeight, + cryptoCurrency.minConfirms, + cryptoCurrency.minCoinbaseConfirms, + )), + ) + .toList(); + final spendableSatoshiValue = spendableOutputs.fold( + BigInt.zero, + (p, e) => p + BigInt.from(e.value), + ); if (spendableSatoshiValue < satoshiAmountToSend) { throw Exception("Insufficient balance"); @@ -165,45 +166,41 @@ mixin ElectrumXInterface } else { // sort spendable by age (oldest first) spendableOutputs.sort( - (a, b) => (b.blockTime ?? currentChainHeight) - .compareTo((a.blockTime ?? currentChainHeight)), + (a, b) => (b.blockTime ?? currentChainHeight).compareTo( + (a.blockTime ?? currentChainHeight), + ), ); } - Logging.instance.d( - "spendableOutputs.length: ${spendableOutputs.length}", - ); - Logging.instance.d( - "availableOutputs.length: ${availableOutputs.length}", - ); + Logging.instance.d("spendableOutputs.length: ${spendableOutputs.length}"); + Logging.instance.d("availableOutputs.length: ${availableOutputs.length}"); Logging.instance.d("spendableOutputs: $spendableOutputs"); - Logging.instance.d( - "spendableSatoshiValue: $spendableSatoshiValue", - ); - Logging.instance.d( - "satoshiAmountToSend: $satoshiAmountToSend", - ); + Logging.instance.d("spendableSatoshiValue: $spendableSatoshiValue"); + Logging.instance.d("satoshiAmountToSend: $satoshiAmountToSend"); BigInt satoshisBeingUsed = BigInt.zero; int inputsBeingConsumed = 0; final List utxoObjectsToUse = []; if (!coinControl) { - for (var i = 0; - satoshisBeingUsed < satoshiAmountToSend && - i < spendableOutputs.length; - i++) { + for ( + var i = 0; + satoshisBeingUsed < satoshiAmountToSend && i < spendableOutputs.length; + i++ + ) { utxoObjectsToUse.add(spendableOutputs[i]); satoshisBeingUsed += BigInt.from(spendableOutputs[i].value); inputsBeingConsumed += 1; } - for (int i = 0; - i < additionalOutputs && - inputsBeingConsumed < spendableOutputs.length; - i++) { + for ( + int i = 0; + i < additionalOutputs && inputsBeingConsumed < spendableOutputs.length; + i++ + ) { utxoObjectsToUse.add(spendableOutputs[inputsBeingConsumed]); - satoshisBeingUsed += - BigInt.from(spendableOutputs[inputsBeingConsumed].value); + satoshisBeingUsed += BigInt.from( + spendableOutputs[inputsBeingConsumed].value, + ); inputsBeingConsumed += 1; } } else { @@ -213,9 +210,7 @@ mixin ElectrumXInterface } Logging.instance.d("satoshisBeingUsed: $satoshisBeingUsed"); - Logging.instance.d( - "inputsBeingConsumed: $inputsBeingConsumed", - ); + Logging.instance.d("inputsBeingConsumed: $inputsBeingConsumed"); Logging.instance.d('utxoObjectsToUse: $utxoObjectsToUse'); // numberOfOutputs' length must always be equal to that of recipientsArray and recipientsAmtArray @@ -245,16 +240,16 @@ mixin ElectrumXInterface final int vSizeForOneOutput; try { - vSizeForOneOutput = (await buildTransaction( - utxoSigningData: utxoSigningData, - txData: txData.copyWith( - recipients: await helperRecipientsConvert( - [recipientAddress], - [satoshisBeingUsed - BigInt.one], - ), - ), - )) - .vSize!; + vSizeForOneOutput = + (await buildTransaction( + utxoSigningData: utxoSigningData, + txData: txData.copyWith( + recipients: await helperRecipientsConvert( + [recipientAddress], + [satoshisBeingUsed - BigInt.one], + ), + ), + )).vSize!; } catch (e, s) { Logging.instance.e("vSizeForOneOutput: $e", error: e, stackTrace: s); rethrow; @@ -265,22 +260,22 @@ mixin ElectrumXInterface BigInt maxBI(BigInt a, BigInt b) => a > b ? a : b; try { - vSizeForTwoOutPuts = (await buildTransaction( - utxoSigningData: utxoSigningData, - txData: txData.copyWith( - recipients: await helperRecipientsConvert( - [recipientAddress, (await getCurrentChangeAddress())!.value], - [ - satoshiAmountToSend, - maxBI( - BigInt.zero, - satoshisBeingUsed - (satoshiAmountToSend + BigInt.one), + vSizeForTwoOutPuts = + (await buildTransaction( + utxoSigningData: utxoSigningData, + txData: txData.copyWith( + recipients: await helperRecipientsConvert( + [recipientAddress, (await getCurrentChangeAddress())!.value], + [ + satoshiAmountToSend, + maxBI( + BigInt.zero, + satoshisBeingUsed - (satoshiAmountToSend + BigInt.one), + ), + ], ), - ], - ), - ), - )) - .vSize!; + ), + )).vSize!; } catch (e, s) { Logging.instance.e("vSizeForTwoOutPuts: $e", error: e, stackTrace: s); rethrow; @@ -291,42 +286,30 @@ mixin ElectrumXInterface satsPerVByte != null ? (satsPerVByte * vSizeForOneOutput) : estimateTxFee( - vSize: vSizeForOneOutput, - feeRatePerKB: selectedTxFeeRate, - ), + vSize: vSizeForOneOutput, + feeRatePerKB: selectedTxFeeRate, + ), ); // Assume 2 outputs, one for recipient and one for change final feeForTwoOutputs = BigInt.from( satsPerVByte != null ? (satsPerVByte * vSizeForTwoOutPuts) : estimateTxFee( - vSize: vSizeForTwoOutPuts, - feeRatePerKB: selectedTxFeeRate, - ), + vSize: vSizeForTwoOutPuts, + feeRatePerKB: selectedTxFeeRate, + ), ); - Logging.instance.d( - "feeForTwoOutputs: $feeForTwoOutputs", - ); - Logging.instance.d( - "feeForOneOutput: $feeForOneOutput", - ); + Logging.instance.d("feeForTwoOutputs: $feeForTwoOutputs"); + Logging.instance.d("feeForOneOutput: $feeForOneOutput"); final difference = satoshisBeingUsed - satoshiAmountToSend; Future singleOutputTxn() async { - Logging.instance.d( - 'Input size: $satoshisBeingUsed', - ); - Logging.instance.d( - 'Recipient output size: $satoshiAmountToSend', - ); - Logging.instance.d( - 'Fee being paid: $difference sats', - ); - Logging.instance.d( - 'Estimated fee: $feeForOneOutput', - ); + Logging.instance.d('Input size: $satoshisBeingUsed'); + Logging.instance.d('Recipient output size: $satoshiAmountToSend'); + Logging.instance.d('Fee being paid: $difference sats'); + Logging.instance.d('Estimated fee: $feeForOneOutput'); final txnData = await buildTransaction( utxoSigningData: utxoSigningData, txData: txData.copyWith( @@ -406,9 +389,7 @@ mixin ElectrumXInterface recipientsAmtArray.removeLast(); recipientsAmtArray.add(changeOutputSize); - Logging.instance.d( - 'Adjusted Input size: $satoshisBeingUsed', - ); + Logging.instance.d('Adjusted Input size: $satoshisBeingUsed'); Logging.instance.d( 'Adjusted Recipient output size: $satoshiAmountToSend', ); @@ -418,9 +399,7 @@ mixin ElectrumXInterface Logging.instance.d( 'Adjusted Difference (fee being paid): $feeBeingPaid sats', ); - Logging.instance.d( - 'Adjusted Estimated fee: $feeForTwoOutputs', - ); + Logging.instance.d('Adjusted Estimated fee: $feeForTwoOutputs'); txnData = await buildTransaction( utxoSigningData: utxoSigningData, @@ -443,9 +422,7 @@ mixin ElectrumXInterface } else { // Something went wrong here. It either overshot or undershot the estimated fee amount or the changeOutputSize // is smaller than or equal to cryptoCurrency.dustLimit. Revert to single output transaction. - Logging.instance.d( - 'Reverting to 1 output in tx', - ); + Logging.instance.d('Reverting to 1 output in tx'); return await singleOutputTxn(); } @@ -466,36 +443,28 @@ mixin ElectrumXInterface }) async { Logging.instance.d("Attempting to send all $cryptoCurrency"); if (txData.recipients!.length != 1) { - throw Exception( - "Send all to more than one recipient not yet supported", - ); + throw Exception("Send all to more than one recipient not yet supported"); } - final int vSizeForOneOutput = (await buildTransaction( - utxoSigningData: utxoSigningData, - txData: txData.copyWith( - recipients: await helperRecipientsConvert( - [recipientAddress], - [satoshisBeingUsed - BigInt.one], - ), - ), - )) - .vSize!; + final int vSizeForOneOutput = + (await buildTransaction( + utxoSigningData: utxoSigningData, + txData: txData.copyWith( + recipients: await helperRecipientsConvert( + [recipientAddress], + [satoshisBeingUsed - BigInt.one], + ), + ), + )).vSize!; BigInt feeForOneOutput = BigInt.from( satsPerVByte != null ? (satsPerVByte * vSizeForOneOutput) - : estimateTxFee( - vSize: vSizeForOneOutput, - feeRatePerKB: feeRatePerKB, - ), + : estimateTxFee(vSize: vSizeForOneOutput, feeRatePerKB: feeRatePerKB), ); if (satsPerVByte == null) { - final roughEstimate = roughFeeEstimate( - utxoSigningData.length, - 1, - feeRatePerKB, - ).raw; + final roughEstimate = + roughFeeEstimate(utxoSigningData.length, 1, feeRatePerKB).raw; if (feeForOneOutput < roughEstimate) { feeForOneOutput = roughEstimate; } @@ -511,10 +480,7 @@ mixin ElectrumXInterface final data = await buildTransaction( txData: txData.copyWith( - recipients: await helperRecipientsConvert( - [recipientAddress], - [amount], - ), + recipients: await helperRecipientsConvert([recipientAddress], [amount]), ), utxoSigningData: utxoSigningData, ); @@ -528,23 +494,19 @@ mixin ElectrumXInterface ); } - Future> fetchBuildTxData( - List utxosToUse, - ) async { + Future> fetchBuildTxData(List utxosToUse) async { // return data final List signingData = []; try { // Populating the addresses to check for (var i = 0; i < utxosToUse.length; i++) { - final derivePathType = - cryptoCurrency.addressType(address: utxosToUse[i].address!); + final derivePathType = cryptoCurrency.addressType( + address: utxosToUse[i].address!, + ); signingData.add( - SigningData( - derivePathType: derivePathType, - utxo: utxosToUse[i], - ), + SigningData(derivePathType: derivePathType, utxo: utxosToUse[i]), ); } @@ -564,9 +526,9 @@ mixin ElectrumXInterface final privateKey = await (this as PaynymInterface) .getPrivateKeyForPaynymReceivingAddress( - paymentCodeString: code!, - index: address.derivationIndex, - ); + paymentCodeString: code!, + index: address.derivationIndex, + ); keys = coinlib.HDPrivateKey.fromKeyAndChainCode( coinlib.ECPrivateKey.fromHex(privateKey.toHex), @@ -594,11 +556,7 @@ mixin ElectrumXInterface return signingData; } catch (e, s) { - Logging.instance.e( - "fetchBuildTxData() threw", - error: e, - stackTrace: s, - ); + Logging.instance.e("fetchBuildTxData() threw", error: e, stackTrace: s); rethrow; } } @@ -623,9 +581,10 @@ mixin ElectrumXInterface ); // TODO: [prio=high]: check this opt in rbf - final sequence = this is RbfInterface && (this as RbfInterface).flagOptInRBF - ? 0xffffffff - 10 - : 0xffffffff - 1; + final sequence = + this is RbfInterface && (this as RbfInterface).flagOptInRBF + ? 0xffffffff - 10 + : 0xffffffff - 1; // Add transaction inputs for (var i = 0; i < utxoSigningData.length; i++) { @@ -635,10 +594,7 @@ mixin ElectrumXInterface txid.toUint8ListFromHex.reversed.toList(), ); - final prevOutpoint = coinlib.OutPoint( - hash, - utxoSigningData[i].utxo.vout, - ); + final prevOutpoint = coinlib.OutPoint(hash, utxoSigningData[i].utxo.vout); final prevOutput = coinlib.Output.fromAddress( BigInt.from(utxoSigningData[i].utxo.value), @@ -699,9 +655,10 @@ mixin ElectrumXInterface txid: utxoSigningData[i].utxo.txid, vout: utxoSigningData[i].utxo.vout, ), - addresses: utxoSigningData[i].utxo.address == null - ? [] - : [utxoSigningData[i].utxo.address!], + addresses: + utxoSigningData[i].utxo.address == null + ? [] + : [utxoSigningData[i].utxo.address!], valueStringSats: utxoSigningData[i].utxo.value.toString(), witness: null, innerRedeemScriptAsm: null, @@ -741,10 +698,9 @@ mixin ElectrumXInterface OutputV2.isarCantDoRequiredInDefaultConstructor( scriptPubKeyHex: "000000", valueStringSats: txData.recipients![i].amount.raw.toString(), - addresses: [ - txData.recipients![i].address.toString(), - ], - walletOwns: (await mainDB.isar.addresses + addresses: [txData.recipients![i].address.toString()], + walletOwns: + (await mainDB.isar.addresses .where() .walletIdEqualTo(walletId) .filter() @@ -760,22 +716,33 @@ mixin ElectrumXInterface // Sign the transaction accordingly for (var i = 0; i < utxoSigningData.length; i++) { final value = BigInt.from(utxoSigningData[i].utxo.value); - coinlib.ECPrivateKey key = utxoSigningData[i].keyPair!.privateKey; + final key = utxoSigningData[i].keyPair!.privateKey; if (clTx.inputs[i] is coinlib.TaprootKeyInput) { final taproot = coinlib.Taproot( internalKey: utxoSigningData[i].keyPair!.publicKey, ); - key = taproot.tweakPrivateKey(key); + clTx = clTx.signTaproot( + inputN: i, + key: taproot.tweakPrivateKey(key), + prevOuts: prevOuts, + ); + } else if (clTx.inputs[i] is coinlib.LegacyWitnessInput) { + clTx = clTx.signLegacyWitness(inputN: i, key: key, value: value); + } else if (clTx.inputs[i] is coinlib.LegacyInput) { + clTx = clTx.signLegacy(inputN: i, key: key); + } else if (clTx.inputs[i] is coinlib.TaprootSingleScriptSigInput) { + clTx = clTx.signTaprootSingleScriptSig( + inputN: i, + key: key, + prevOuts: prevOuts, + ); + } else { + throw Exception( + "Unable to sign input of type ${clTx.inputs[i].runtimeType}", + ); } - - clTx = clTx.sign( - inputN: i, - value: value, - key: key, - prevOuts: prevOuts, - ); } } catch (e, s) { Logging.instance.e( @@ -839,8 +806,9 @@ mixin ElectrumXInterface } Future fetchTxCount({required String addressScriptHash}) async { - final transactions = - await electrumXClient.getHistory(scripthash: addressScriptHash); + final transactions = await electrumXClient.getHistory( + scripthash: addressScriptHash, + ); return transactions.length; } @@ -885,20 +853,21 @@ mixin ElectrumXInterface } Future updateElectrumX() async { - final failovers = nodeService - .failoverNodesFor(currency: cryptoCurrency) - .map( - (e) => ElectrumXNode( - address: e.host, - port: e.port, - name: e.name, - id: e.id, - useSSL: e.useSSL, - torEnabled: e.torEnabled, - clearnetEnabled: e.clearnetEnabled, - ), - ) - .toList(); + final failovers = + nodeService + .failoverNodesFor(currency: cryptoCurrency) + .map( + (e) => ElectrumXNode( + address: e.host, + port: e.port, + name: e.name, + id: e.id, + useSSL: e.useSSL, + torEnabled: e.torEnabled, + clearnetEnabled: e.clearnetEnabled, + ), + ) + .toList(); final newNode = await _getCurrentElectrumXNode(); try { @@ -937,9 +906,11 @@ mixin ElectrumXInterface int gapCounter = 0; int highestIndexWithHistory = 0; - for (int index = 0; - gapCounter < cryptoCurrency.maxUnusedAddressGap; - index += txCountBatchSize) { + for ( + int index = 0; + gapCounter < cryptoCurrency.maxUnusedAddressGap; + index += txCountBatchSize + ) { Logging.instance.d( "index: $index, \t GapCounter $chain ${type.name}: $gapCounter", ); @@ -985,9 +956,7 @@ mixin ElectrumXInterface addressArray.add(address); - txCountCallArgs.add( - addressString, - ); + txCountCallArgs.add(addressString); } // get address tx counts @@ -1115,8 +1084,9 @@ mixin ElectrumXInterface } for (int i = 0; i < batches.length; i++) { - final response = - await electrumXClient.getBatchHistory(args: batches[i]!); + final response = await electrumXClient.getBatchHistory( + args: batches[i]!, + ); for (int j = 0; j < response.length; j++) { final entry = response[j]; for (int k = 0; k < entry.length; k++) { @@ -1149,15 +1119,16 @@ mixin ElectrumXInterface return allTxHashes; } catch (e, s) { - Logging.instance - .e("$runtimeType._fetchHistory: ", error: e, stackTrace: s); + Logging.instance.e( + "$runtimeType._fetchHistory: ", + error: e, + stackTrace: s, + ); rethrow; } } - Future parseUTXO({ - required Map jsonUTXO, - }) async { + Future parseUTXO({required Map jsonUTXO}) async { final txn = await electrumXCachedClient.getTransaction( txHash: jsonUTXO["tx_hash"] as String, verbose: true, @@ -1179,7 +1150,7 @@ mixin ElectrumXInterface scriptPubKey = output["scriptPubKey"]?["hex"] as String?; utxoOwnerAddress = output["scriptPubKey"]?["addresses"]?[0] as String? ?? - output["scriptPubKey"]?["address"] as String?; + output["scriptPubKey"]?["address"] as String?; } } @@ -1198,7 +1169,8 @@ mixin ElectrumXInterface name: checkBlockResult.utxoLabel ?? "", isBlocked: checkBlockResult.blocked, blockedReason: checkBlockResult.blockedReason, - isCoinbase: txn["is_coinbase"] as bool? ?? + isCoinbase: + txn["is_coinbase"] as bool? ?? txn["is-coinbase"] as bool? ?? txn["iscoinbase"] as bool? ?? isCoinbase, @@ -1216,10 +1188,7 @@ mixin ElectrumXInterface @override Future updateChainHeight() async { final height = await fetchChainHeight(); - await info.updateCachedChainHeight( - newHeight: height, - isar: mainDB.isar, - ); + await info.updateCachedChainHeight(newHeight: height, isar: mainDB.isar); } @override @@ -1252,23 +1221,24 @@ mixin ElectrumXInterface numberOfBlocksFast: f, numberOfBlocksAverage: m, numberOfBlocksSlow: s, - fast: Amount.fromDecimal( - fast, - fractionDigits: info.coin.fractionDigits, - ).raw.toInt(), - medium: Amount.fromDecimal( - medium, - fractionDigits: info.coin.fractionDigits, - ).raw.toInt(), - slow: Amount.fromDecimal( - slow, - fractionDigits: info.coin.fractionDigits, - ).raw.toInt(), + fast: + Amount.fromDecimal( + fast, + fractionDigits: info.coin.fractionDigits, + ).raw.toInt(), + medium: + Amount.fromDecimal( + medium, + fractionDigits: info.coin.fractionDigits, + ).raw.toInt(), + slow: + Amount.fromDecimal( + slow, + fractionDigits: info.coin.fractionDigits, + ).raw.toInt(), ); - Logging.instance.d( - "fetched fees: $feeObject", - ); + Logging.instance.d("fetched fees: $feeObject"); _cachedFees = feeObject; return _cachedFees!; } catch (e, s) { @@ -1383,9 +1353,10 @@ mixin ElectrumXInterface } } } catch (e, s) { - Logging.instance - .e("Exception rethrown from _checkReceivingAddressForTransactions" - "($cryptoCurrency): $e\n$s"); + Logging.instance.e( + "Exception rethrown from _checkReceivingAddressForTransactions" + "($cryptoCurrency): $e\n$s", + ); rethrow; } } @@ -1434,9 +1405,10 @@ mixin ElectrumXInterface await checkChangeAddressForTransactions(); } } catch (e, s) { - Logging.instance - .e("Exception rethrown from _checkChangeAddressForTransactions" - "($cryptoCurrency): $e\n$s"); + Logging.instance.e( + "Exception rethrown from _checkChangeAddressForTransactions" + "($cryptoCurrency): $e\n$s", + ); rethrow; } } @@ -1472,47 +1444,25 @@ mixin ElectrumXInterface } // receiving addresses - Logging.instance.i( - "checking receiving addresses...", - ); + Logging.instance.i("checking receiving addresses..."); final canBatch = await serverCanBatch; for (final type in cryptoCurrency.supportedDerivationPathTypes) { receiveFutures.add( canBatch - ? checkGapsBatched( - txCountBatchSize, - root, - type, - receiveChain, - ) - : checkGapsLinearly( - root, - type, - receiveChain, - ), + ? checkGapsBatched(txCountBatchSize, root, type, receiveChain) + : checkGapsLinearly(root, type, receiveChain), ); } // change addresses - Logging.instance.d( - "checking change addresses...", - ); + Logging.instance.d("checking change addresses..."); for (final type in cryptoCurrency.supportedDerivationPathTypes) { changeFutures.add( canBatch - ? checkGapsBatched( - txCountBatchSize, - root, - type, - changeChain, - ) - : checkGapsLinearly( - root, - type, - changeChain, - ), + ? checkGapsBatched(txCountBatchSize, root, type, changeChain) + : checkGapsLinearly(root, type, changeChain), ); } @@ -1574,13 +1524,15 @@ mixin ElectrumXInterface final notificationAddress = await (this as PaynymInterface).getMyNotificationAddress(); - await (this as BitcoinWallet) - .updateTransactions(overrideAddresses: [notificationAddress]); + await (this as BitcoinWallet).updateTransactions( + overrideAddresses: [notificationAddress], + ); // get own payment code // isSegwit does not matter here at all - final myCode = - await (this as PaynymInterface).getPaymentCode(isSegwit: false); + final myCode = await (this as PaynymInterface).getPaymentCode( + isSegwit: false, + ); try { final Set codesToCheck = {}; @@ -1648,8 +1600,9 @@ mixin ElectrumXInterface } for (int i = 0; i < batchArgs.length; i++) { - final response = - await electrumXClient.getBatchUTXOs(args: batchArgs[i]!); + final response = await electrumXClient.getBatchUTXOs( + args: batchArgs[i]!, + ); for (final entry in response) { if (entry.isNotEmpty) { fetchedUtxoList.add(entry); @@ -1673,9 +1626,7 @@ mixin ElectrumXInterface for (int i = 0; i < fetchedUtxoList.length; i++) { for (int j = 0; j < fetchedUtxoList[i].length; j++) { - final utxo = await parseUTXO( - jsonUTXO: fetchedUtxoList[i][j], - ); + final utxo = await parseUTXO(jsonUTXO: fetchedUtxoList[i][j]); outputArray.add(utxo); } @@ -1695,16 +1646,12 @@ mixin ElectrumXInterface @override Future confirmSend({required TxData txData}) async { try { - Logging.instance.d( - "confirmSend txData: $txData", - ); + Logging.instance.d("confirmSend txData: $txData"); final txHash = await electrumXClient.broadcastTransaction( rawTx: txData.raw!, ); - Logging.instance.d( - "Sent txHash: $txHash", - ); + Logging.instance.d("Sent txHash: $txHash"); txData = txData.copyWith( usedUTXOs: @@ -1742,7 +1689,8 @@ mixin ElectrumXInterface final bool coinControl = utxos != null; - final isSendAllCoinControlUtxos = coinControl && + final isSendAllCoinControlUtxos = + coinControl && txData.amount!.raw == utxos .map((e) => e.value) @@ -1811,22 +1759,19 @@ mixin ElectrumXInterface } final result = await coinSelection( - txData: txData.copyWith( - feeRateAmount: rate, - ), + txData: txData.copyWith(feeRateAmount: rate), isSendAll: isSendAll, utxos: utxos?.toList(), coinControl: coinControl, isSendAllCoinControlUtxos: isSendAllCoinControlUtxos, ); - Logging.instance.d( - "prepare send: $result", - ); + Logging.instance.d("prepare send: $result"); if (result.fee!.raw.toInt() < result.vSize!) { throw Exception( - "Error in fee calculation: Transaction fee (${result.fee!.raw.toInt()}) cannot " - "be less than vSize (${result.vSize})"); + "Error in fee calculation: Transaction fee (${result.fee!.raw.toInt()}) cannot " + "be less than vSize (${result.vSize})", + ); } return result; @@ -1862,16 +1807,15 @@ mixin ElectrumXInterface Future _initializeServerVersionAndCheckGenesisHash() async { try { - final features = await electrumXClient - .getServerFeatures() - .timeout(const Duration(seconds: 5)); - - Logging.instance.d( - "features: $features", + final features = await electrumXClient.getServerFeatures().timeout( + const Duration(seconds: 5), ); - _serverVersion = - _parseServerVersion(features["server_version"] as String); + Logging.instance.d("features: $features"); + + _serverVersion = _parseServerVersion( + features["server_version"] as String, + ); if (cryptoCurrency.genesisHash != features['genesis_hash']) { throw Exception("Genesis hash does not match!"); @@ -1896,7 +1840,7 @@ mixin ElectrumXInterface /// Certain coins need to check if the utxo should be marked /// as blocked as well as give a reason. Future<({String? blockedReason, bool blocked, String? utxoLabel})> - checkBlockUTXO( + checkBlockUTXO( Map jsonUTXO, String? scriptPubKeyHex, Map jsonTX, @@ -1948,9 +1892,7 @@ mixin ElectrumXInterface } } catch (_) {} - Logging.instance.d( - "${info.name} _parseServerVersion($version) => $result", - ); + Logging.instance.d("${info.name} _parseServerVersion($version) => $result"); return result; } @@ -2003,9 +1945,7 @@ mixin ElectrumXInterface if (root != null) { // receiving addresses - Logging.instance.i( - "checking receiving addresses...", - ); + Logging.instance.i("checking receiving addresses..."); final canBatch = await serverCanBatch; @@ -2021,24 +1961,18 @@ mixin ElectrumXInterface receiveFutures.add( canBatch ? checkGapsBatched( - txCountBatchSize, - root, - type, - receiveChain, - ) - : checkGapsLinearly( - root, - type, - receiveChain, - ), + txCountBatchSize, + root, + type, + receiveChain, + ) + : checkGapsLinearly(root, type, receiveChain), ); } } // change addresses - Logging.instance.d( - "checking change addresses...", - ); + Logging.instance.d("checking change addresses..."); for (final type in cryptoCurrency.supportedDerivationPathTypes) { final path = cryptoCurrency.constructDerivePath( derivePathType: type, @@ -2051,16 +1985,12 @@ mixin ElectrumXInterface changeFutures.add( canBatch ? checkGapsBatched( - txCountBatchSize, - root, - type, - changeChain, - ) - : checkGapsLinearly( - root, - type, - changeChain, - ), + txCountBatchSize, + root, + type, + changeChain, + ) + : checkGapsLinearly(root, type, changeChain), ); } } diff --git a/lib/wallets/wallet/wallet_mixin_interfaces/paynym_interface.dart b/lib/wallets/wallet/wallet_mixin_interfaces/paynym_interface.dart index 9d1935bec..5c0ace879 100644 --- a/lib/wallets/wallet/wallet_mixin_interfaces/paynym_interface.dart +++ b/lib/wallets/wallet/wallet_mixin_interfaces/paynym_interface.dart @@ -42,34 +42,28 @@ String _notificationDerivationPath({required bool testnet}) => String _receivingPaynymAddressDerivationPath( int index, { required bool testnet, -}) => - "${_basePaynymDerivePath(testnet: testnet)}/$index/0"; -String _sendPaynymAddressDerivationPath( - int index, { - required bool testnet, -}) => +}) => "${_basePaynymDerivePath(testnet: testnet)}/$index/0"; +String _sendPaynymAddressDerivationPath(int index, {required bool testnet}) => "${_basePaynymDerivePath(testnet: testnet)}/0/$index"; mixin PaynymInterface on Bip39HDWallet, ElectrumXInterface { btc_dart.NetworkType get networkType => btc_dart.NetworkType( - messagePrefix: cryptoCurrency.networkParams.messagePrefix, - bech32: cryptoCurrency.networkParams.bech32Hrp, - bip32: btc_dart.Bip32Type( - public: cryptoCurrency.networkParams.pubHDPrefix, - private: cryptoCurrency.networkParams.privHDPrefix, - ), - pubKeyHash: cryptoCurrency.networkParams.p2pkhPrefix, - scriptHash: cryptoCurrency.networkParams.p2shPrefix, - wif: cryptoCurrency.networkParams.wifPrefix, - ); + messagePrefix: cryptoCurrency.networkParams.messagePrefix, + bech32: cryptoCurrency.networkParams.bech32Hrp, + bip32: btc_dart.Bip32Type( + public: cryptoCurrency.networkParams.pubHDPrefix, + private: cryptoCurrency.networkParams.privHDPrefix, + ), + pubKeyHash: cryptoCurrency.networkParams.p2pkhPrefix, + scriptHash: cryptoCurrency.networkParams.p2shPrefix, + wif: cryptoCurrency.networkParams.wifPrefix, + ); Future getBip47BaseNode() async { final root = await _getRootNode(); final node = root.derivePath( - _basePaynymDerivePath( - testnet: info.coin.network.isTestNet, - ), + _basePaynymDerivePath(testnet: info.coin.network.isTestNet), ); return node; } @@ -101,25 +95,29 @@ mixin PaynymInterface }) async { final keys = await lookupKey(sender.toString()); - final address = await mainDB - .getAddresses(walletId) - .filter() - .subTypeEqualTo(AddressSubType.paynymReceive) - .and() - .group((q) { - if (isSegwit) { - return q - .typeEqualTo(AddressType.p2sh) - .or() - .typeEqualTo(AddressType.p2wpkh); - } else { - return q.typeEqualTo(AddressType.p2pkh); - } - }) - .and() - .anyOf(keys, (q, String e) => q.otherDataEqualTo(e)) - .sortByDerivationIndexDesc() - .findFirst(); + final address = + await mainDB + .getAddresses(walletId) + .filter() + .subTypeEqualTo(AddressSubType.paynymReceive) + .and() + .group((q) { + if (isSegwit) { + return q + .typeEqualTo(AddressType.p2sh) + .or() + .typeEqualTo(AddressType.p2wpkh); + } else { + return q.typeEqualTo(AddressType.p2pkh); + } + }) + .and() + .anyOf( + keys, + (q, String e) => q.otherDataEqualTo(e), + ) + .sortByDerivationIndexDesc() + .findFirst(); if (address == null) { final generatedAddress = await _generatePaynymReceivingAddress( @@ -128,11 +126,12 @@ mixin PaynymInterface generateSegwitAddress: isSegwit, ); - final existing = await mainDB - .getAddresses(walletId) - .filter() - .valueEqualTo(generatedAddress.value) - .findFirst(); + final existing = + await mainDB + .getAddresses(walletId) + .filter() + .valueEqualTo(generatedAddress.value) + .findFirst(); if (existing == null) { // Add that new address @@ -142,10 +141,7 @@ mixin PaynymInterface await mainDB.updateAddress(existing, generatedAddress); } - return currentReceivingPaynymAddress( - isSegwit: isSegwit, - sender: sender, - ); + return currentReceivingPaynymAddress(isSegwit: isSegwit, sender: sender); } else { return address; } @@ -158,9 +154,7 @@ mixin PaynymInterface }) async { final root = await _getRootNode(); final node = root.derivePath( - _basePaynymDerivePath( - testnet: info.coin.network.isTestNet, - ), + _basePaynymDerivePath(testnet: info.coin.network.isTestNet), ); final paymentAddress = PaymentAddress( @@ -170,20 +164,22 @@ mixin PaynymInterface index: 0, ); - final addressString = generateSegwitAddress - ? paymentAddress.getReceiveAddressP2WPKH() - : paymentAddress.getReceiveAddressP2PKH(); + final addressString = + generateSegwitAddress + ? paymentAddress.getReceiveAddressP2WPKH() + : paymentAddress.getReceiveAddressP2PKH(); final address = Address( walletId: walletId, value: addressString, publicKey: [], derivationIndex: index, - derivationPath: DerivationPath() - ..value = _receivingPaynymAddressDerivationPath( - index, - testnet: info.coin.network.isTestNet, - ), + derivationPath: + DerivationPath() + ..value = _receivingPaynymAddressDerivationPath( + index, + testnet: info.coin.network.isTestNet, + ), type: generateSegwitAddress ? AddressType.p2wpkh : AddressType.p2pkh, subType: AddressSubType.paynymReceive, otherData: await storeCode(sender.toString()), @@ -207,20 +203,22 @@ mixin PaynymInterface index: index, ); - final addressString = generateSegwitAddress - ? paymentAddress.getSendAddressP2WPKH() - : paymentAddress.getSendAddressP2PKH(); + final addressString = + generateSegwitAddress + ? paymentAddress.getSendAddressP2WPKH() + : paymentAddress.getSendAddressP2PKH(); final address = Address( walletId: walletId, value: addressString, publicKey: [], derivationIndex: index, - derivationPath: DerivationPath() - ..value = _sendPaynymAddressDerivationPath( - index, - testnet: info.coin.network.isTestNet, - ), + derivationPath: + DerivationPath() + ..value = _sendPaynymAddressDerivationPath( + index, + testnet: info.coin.network.isTestNet, + ), type: AddressType.nonWallet, subType: AddressSubType.paynymSend, otherData: await storeCode(other.toString()), @@ -251,11 +249,12 @@ mixin PaynymInterface generateSegwitAddress: isSegwit, ); - final existing = await mainDB - .getAddresses(walletId) - .filter() - .valueEqualTo(nextAddress.value) - .findFirst(); + final existing = + await mainDB + .getAddresses(walletId) + .filter() + .valueEqualTo(nextAddress.value) + .findFirst(); if (existing == null) { // Add that new address @@ -312,26 +311,18 @@ mixin PaynymInterface Future deriveNotificationBip32Node() async { final root = await _getRootNode(); final node = root - .derivePath( - _basePaynymDerivePath( - testnet: info.coin.network.isTestNet, - ), - ) + .derivePath(_basePaynymDerivePath(testnet: info.coin.network.isTestNet)) .derive(0); return node; } /// fetch or generate this wallet's bip47 payment code - Future getPaymentCode({ - required bool isSegwit, - }) async { + Future getPaymentCode({required bool isSegwit}) async { final node = await _getRootNode(); final paymentCode = PaymentCode.fromBip32Node( node.derivePath( - _basePaynymDerivePath( - testnet: info.coin.network.isTestNet, - ), + _basePaynymDerivePath(testnet: info.coin.network.isTestNet), ), networkType: networkType, shouldSetSegwitBit: isSegwit, @@ -351,8 +342,9 @@ mixin PaynymInterface } Future signStringWithNotificationKey(String data) async { - final bytes = - await signWithNotificationKey(Uint8List.fromList(utf8.encode(data))); + final bytes = await signWithNotificationKey( + Uint8List.fromList(utf8.encode(data)), + ); return Format.uint8listToString(bytes); } @@ -411,15 +403,19 @@ mixin PaynymInterface for (int i = startIndex; i < maxCount; i++) { final keys = await lookupKey(pCode.toString()); - final address = await mainDB - .getAddresses(walletId) - .filter() - .subTypeEqualTo(AddressSubType.paynymSend) - .and() - .anyOf(keys, (q, String e) => q.otherDataEqualTo(e)) - .and() - .derivationIndexEqualTo(i) - .findFirst(); + final address = + await mainDB + .getAddresses(walletId) + .filter() + .subTypeEqualTo(AddressSubType.paynymSend) + .and() + .anyOf( + keys, + (q, String e) => q.otherDataEqualTo(e), + ) + .and() + .derivationIndexEqualTo(i) + .findFirst(); if (address != null) { final count = await fetchTxCount( @@ -506,21 +502,26 @@ mixin PaynymInterface int outputsBeingUsed = 0; final List utxoObjectsToUse = []; - for (int i = 0; - satoshisBeingUsed < amountToSend.raw && i < spendableOutputs.length; - i++) { + for ( + int i = 0; + satoshisBeingUsed < amountToSend.raw && i < spendableOutputs.length; + i++ + ) { utxoObjectsToUse.add(spendableOutputs[i]); satoshisBeingUsed += BigInt.from(spendableOutputs[i].value); outputsBeingUsed += 1; } // add additional outputs if required - for (int i = 0; - i < additionalOutputs && outputsBeingUsed < spendableOutputs.length; - i++) { + for ( + int i = 0; + i < additionalOutputs && outputsBeingUsed < spendableOutputs.length; + i++ + ) { utxoObjectsToUse.add(spendableOutputs[outputsBeingUsed]); - satoshisBeingUsed += - BigInt.from(spendableOutputs[outputsBeingUsed].value); + satoshisBeingUsed += BigInt.from( + spendableOutputs[outputsBeingUsed].value, + ); outputsBeingUsed += 1; } @@ -534,8 +535,7 @@ mixin PaynymInterface change: BigInt.zero, // override amount to get around absurd fees error overrideAmountForTesting: satoshisBeingUsed, - )) - .item2, + )).item2, ); final vSizeForWithChange = BigInt.from( @@ -543,8 +543,7 @@ mixin PaynymInterface targetPaymentCodeString: targetPaymentCodeString, utxoSigningData: utxoSigningData, change: satoshisBeingUsed - amountToSend.raw, - )) - .item2, + )).item2, ); // Assume 2 outputs, for recipient and payment code script @@ -836,10 +835,7 @@ mixin PaynymInterface clTx = clTx.addOutput(output); clTx = clTx.addOutput( - coinlib.Output.fromScriptBytes( - BigInt.zero, - opReturnScript, - ), + coinlib.Output.fromScriptBytes(BigInt.zero, opReturnScript), ); // TODO: add possible change output and mark output as dangerous @@ -859,32 +855,64 @@ mixin PaynymInterface clTx = clTx.addOutput(output); } - clTx = clTx.sign( - inputN: 0, - value: BigInt.from(utxo.value), - key: myKeyPair.privateKey, - prevOuts: prevOuts, - ); + if (clTx.inputs[0] is coinlib.TaprootKeyInput) { + final taproot = coinlib.Taproot(internalKey: myKeyPair.publicKey); + + clTx = clTx.signTaproot( + inputN: 0, + key: taproot.tweakPrivateKey(myKeyPair.privateKey), + prevOuts: prevOuts, + ); + } else if (clTx.inputs[0] is coinlib.LegacyWitnessInput) { + clTx = clTx.signLegacyWitness( + inputN: 0, + key: myKeyPair.privateKey, + value: BigInt.from(utxo.value), + ); + } else if (clTx.inputs[0] is coinlib.LegacyInput) { + clTx = clTx.signLegacy(inputN: 0, key: myKeyPair.privateKey); + } else if (clTx.inputs[0] is coinlib.TaprootSingleScriptSigInput) { + clTx = clTx.signTaprootSingleScriptSig( + inputN: 0, + key: myKeyPair.privateKey, + prevOuts: prevOuts, + ); + } else { + throw Exception( + "Unable to sign input of type ${clTx.inputs[0].runtimeType}", + ); + } // sign rest of possible inputs for (int i = 1; i < utxoSigningData.length; i++) { final value = BigInt.from(utxoSigningData[i].utxo.value); - coinlib.ECPrivateKey key = utxoSigningData[i].keyPair!.privateKey; + final key = utxoSigningData[i].keyPair!.privateKey; if (clTx.inputs[i] is coinlib.TaprootKeyInput) { final taproot = coinlib.Taproot( internalKey: utxoSigningData[i].keyPair!.publicKey, ); - key = taproot.tweakPrivateKey(key); + clTx = clTx.signTaproot( + inputN: i, + key: taproot.tweakPrivateKey(key), + prevOuts: prevOuts, + ); + } else if (clTx.inputs[i] is coinlib.LegacyWitnessInput) { + clTx = clTx.signLegacyWitness(inputN: i, key: key, value: value); + } else if (clTx.inputs[i] is coinlib.LegacyInput) { + clTx = clTx.signLegacy(inputN: i, key: key); + } else if (clTx.inputs[i] is coinlib.TaprootSingleScriptSigInput) { + clTx = clTx.signTaprootSingleScriptSig( + inputN: i, + key: key, + prevOuts: prevOuts, + ); + } else { + throw Exception( + "Unable to sign input of type ${clTx.inputs[i].runtimeType}", + ); } - - clTx = clTx.sign( - inputN: i, - value: value, - key: key, - prevOuts: prevOuts, - ); } return Tuple2(clTx.toHex(), clTx.vSize()); @@ -894,13 +922,12 @@ mixin PaynymInterface } } - Future broadcastNotificationTx({ - required TxData txData, - }) async { + Future broadcastNotificationTx({required TxData txData}) async { try { Logging.instance.d("confirmNotificationTx txData: $txData"); - final txHash = - await electrumXClient.broadcastTransaction(rawTx: txData.raw!); + final txHash = await electrumXClient.broadcastTransaction( + rawTx: txData.raw!, + ); Logging.instance.d("Sent txHash: $txHash"); try { @@ -913,10 +940,7 @@ mixin PaynymInterface ); } - return txData.copyWith( - txid: txHash, - txHash: txHash, - ); + return txData.copyWith(txid: txHash, txHash: txHash); } catch (e, s) { Logging.instance.e( "Exception rethrown from confirmSend(): ", @@ -964,12 +988,13 @@ mixin PaynymInterface final myNotificationAddress = await getMyNotificationAddress(); - final txns = await mainDB.isar.transactionV2s - .where() - .walletIdEqualTo(walletId) - .filter() - .subTypeEqualTo(TransactionSubType.bip47Notification) - .findAll(); + final txns = + await mainDB.isar.transactionV2s + .where() + .walletIdEqualTo(walletId) + .filter() + .subTypeEqualTo(TransactionSubType.bip47Notification) + .findAll(); for (final tx in txns) { switch (tx.type) { @@ -978,9 +1003,7 @@ mixin PaynymInterface for (final outputAddress in output.addresses) { if (outputAddress == myNotificationAddress.value) { final unBlindedPaymentCode = - await unBlindedPaymentCodeFromTransaction( - transaction: tx, - ); + await unBlindedPaymentCodeFromTransaction(transaction: tx); if (unBlindedPaymentCode != null && paymentCodeString == unBlindedPaymentCode.toString()) { @@ -990,8 +1013,8 @@ mixin PaynymInterface final unBlindedPaymentCodeBad = await unBlindedPaymentCodeFromTransactionBad( - transaction: tx, - ); + transaction: tx, + ); if (unBlindedPaymentCodeBad != null && paymentCodeString == unBlindedPaymentCodeBad.toString()) { @@ -1005,14 +1028,15 @@ mixin PaynymInterface case TransactionType.outgoing: for (final output in tx.outputs) { for (final outputAddress in output.addresses) { - final address = await mainDB.isar.addresses - .where() - .walletIdEqualTo(walletId) - .filter() - .subTypeEqualTo(AddressSubType.paynymNotification) - .and() - .valueEqualTo(outputAddress) - .findFirst(); + final address = + await mainDB.isar.addresses + .where() + .walletIdEqualTo(walletId) + .filter() + .subTypeEqualTo(AddressSubType.paynymNotification) + .and() + .valueEqualTo(outputAddress) + .findFirst(); if (address?.otherData != null) { final code = await paymentCodeStringByKey(address!.otherData!); @@ -1055,8 +1079,9 @@ mixin PaynymInterface required TransactionV2 transaction, }) async { try { - final blindedCodeBytes = - Bip47Utils.getBlindedPaymentCodeBytesFrom(transaction); + final blindedCodeBytes = Bip47Utils.getBlindedPaymentCodeBytesFrom( + transaction, + ); // transaction does not contain a payment code if (blindedCodeBytes == null) { @@ -1113,8 +1138,9 @@ mixin PaynymInterface required TransactionV2 transaction, }) async { try { - final blindedCodeBytes = - Bip47Utils.getBlindedPaymentCodeBytesFrom(transaction); + final blindedCodeBytes = Bip47Utils.getBlindedPaymentCodeBytesFrom( + transaction, + ); // transaction does not contain a payment code if (blindedCodeBytes == null) { @@ -1168,13 +1194,14 @@ mixin PaynymInterface } Future> - getAllPaymentCodesFromNotificationTransactions() async { - final txns = await mainDB.isar.transactionV2s - .where() - .walletIdEqualTo(walletId) - .filter() - .subTypeEqualTo(TransactionSubType.bip47Notification) - .findAll(); + getAllPaymentCodesFromNotificationTransactions() async { + final txns = + await mainDB.isar.transactionV2s + .where() + .walletIdEqualTo(walletId) + .filter() + .subTypeEqualTo(TransactionSubType.bip47Notification) + .findAll(); final List codes = []; @@ -1182,20 +1209,23 @@ mixin PaynymInterface // tx is sent so we can check the address's otherData for the code String if (tx.type == TransactionType.outgoing) { for (final output in tx.outputs) { - for (final outputAddress - in output.addresses.where((e) => e.isNotEmpty)) { - final address = await mainDB.isar.addresses - .where() - .walletIdEqualTo(walletId) - .filter() - .subTypeEqualTo(AddressSubType.paynymNotification) - .and() - .valueEqualTo(outputAddress) - .findFirst(); + for (final outputAddress in output.addresses.where( + (e) => e.isNotEmpty, + )) { + final address = + await mainDB.isar.addresses + .where() + .walletIdEqualTo(walletId) + .filter() + .subTypeEqualTo(AddressSubType.paynymNotification) + .and() + .valueEqualTo(outputAddress) + .findFirst(); if (address?.otherData != null) { - final codeString = - await paymentCodeStringByKey(address!.otherData!); + final codeString = await paymentCodeStringByKey( + address!.otherData!, + ); if (codeString != null && codes.where((e) => e.toString() == codeString).isEmpty) { codes.add( @@ -1236,14 +1266,15 @@ mixin PaynymInterface Future checkForNotificationTransactionsTo( Set otherCodeStrings, ) async { - final sentNotificationTransactions = await mainDB.isar.transactionV2s - .where() - .walletIdEqualTo(walletId) - .filter() - .subTypeEqualTo(TransactionSubType.bip47Notification) - .and() - .typeEqualTo(TransactionType.outgoing) - .findAll(); + final sentNotificationTransactions = + await mainDB.isar.transactionV2s + .where() + .walletIdEqualTo(walletId) + .filter() + .subTypeEqualTo(TransactionSubType.bip47Notification) + .and() + .typeEqualTo(TransactionType.outgoing) + .findAll(); final List codes = []; for (final codeString in otherCodeStrings) { @@ -1260,8 +1291,10 @@ mixin PaynymInterface final notificationAddress = code.notificationAddressP2PKH(); if (outputAddress == notificationAddress) { - Address? storedAddress = - await mainDB.getAddress(walletId, outputAddress); + Address? storedAddress = await mainDB.getAddress( + walletId, + outputAddress, + ); if (storedAddress == null) { // most likely not mine storedAddress = Address( @@ -1343,10 +1376,12 @@ mixin PaynymInterface int outgoingGapCounter = 0; // non segwit receiving - for (int i = 0; - i < maxNumberOfIndexesToCheck && - receivingGapCounter < maxUnusedAddressGap; - i++) { + for ( + int i = 0; + i < maxNumberOfIndexesToCheck && + receivingGapCounter < maxUnusedAddressGap; + i++ + ) { if (receivingGapCounter < maxUnusedAddressGap) { final address = await _generatePaynymReceivingAddress( sender: other, @@ -1371,10 +1406,11 @@ mixin PaynymInterface } // non segwit sends - for (int i = 0; - i < maxNumberOfIndexesToCheck && - outgoingGapCounter < maxUnusedAddressGap; - i++) { + for ( + int i = 0; + i < maxNumberOfIndexesToCheck && outgoingGapCounter < maxUnusedAddressGap; + i++ + ) { if (outgoingGapCounter < maxUnusedAddressGap) { final address = await _generatePaynymSendAddress( other: other, @@ -1403,10 +1439,12 @@ mixin PaynymInterface int receivingGapCounterSegwit = 0; int outgoingGapCounterSegwit = 0; // segwit receiving - for (int i = 0; - i < maxNumberOfIndexesToCheck && - receivingGapCounterSegwit < maxUnusedAddressGap; - i++) { + for ( + int i = 0; + i < maxNumberOfIndexesToCheck && + receivingGapCounterSegwit < maxUnusedAddressGap; + i++ + ) { if (receivingGapCounterSegwit < maxUnusedAddressGap) { final address = await _generatePaynymReceivingAddress( sender: other, @@ -1431,10 +1469,12 @@ mixin PaynymInterface } // segwit sends - for (int i = 0; - i < maxNumberOfIndexesToCheck && - outgoingGapCounterSegwit < maxUnusedAddressGap; - i++) { + for ( + int i = 0; + i < maxNumberOfIndexesToCheck && + outgoingGapCounterSegwit < maxUnusedAddressGap; + i++ + ) { if (outgoingGapCounterSegwit < maxUnusedAddressGap) { final address = await _generatePaynymSendAddress( other: other, @@ -1463,25 +1503,24 @@ mixin PaynymInterface } Future
getMyNotificationAddress() async { - final storedAddress = await mainDB - .getAddresses(walletId) - .filter() - .subTypeEqualTo(AddressSubType.paynymNotification) - .and() - .typeEqualTo(AddressType.p2pkh) - .and() - .not() - .typeEqualTo(AddressType.nonWallet) - .findFirst(); + final storedAddress = + await mainDB + .getAddresses(walletId) + .filter() + .subTypeEqualTo(AddressSubType.paynymNotification) + .and() + .typeEqualTo(AddressType.p2pkh) + .and() + .not() + .typeEqualTo(AddressType.nonWallet) + .findFirst(); if (storedAddress != null) { return storedAddress; } else { final root = await _getRootNode(); final node = root.derivePath( - _basePaynymDerivePath( - testnet: info.coin.network.isTestNet, - ), + _basePaynymDerivePath(testnet: info.coin.network.isTestNet), ); final paymentCode = PaymentCode.fromBip32Node( node, @@ -1493,23 +1532,19 @@ mixin PaynymInterface pubkey: paymentCode.notificationPublicKey(), ); - final addressString = btc_dart - .P2PKH( - data: data, - network: networkType, - ) - .data - .address!; + final addressString = + btc_dart.P2PKH(data: data, network: networkType).data.address!; Address address = Address( walletId: walletId, value: addressString, publicKey: paymentCode.getPubKey(), derivationIndex: 0, - derivationPath: DerivationPath() - ..value = _notificationDerivationPath( - testnet: info.coin.network.isTestNet, - ), + derivationPath: + DerivationPath() + ..value = _notificationDerivationPath( + testnet: info.coin.network.isTestNet, + ), type: AddressType.p2pkh, subType: AddressSubType.paynymNotification, otherData: await storeCode(paymentCode.toString()), @@ -1520,16 +1555,17 @@ mixin PaynymInterface // beginning to see if there already was notification address. This would // lead to a Unique Index violation error await mainDB.isar.writeTxn(() async { - final storedAddress = await mainDB - .getAddresses(walletId) - .filter() - .subTypeEqualTo(AddressSubType.paynymNotification) - .and() - .typeEqualTo(AddressType.p2pkh) - .and() - .not() - .typeEqualTo(AddressType.nonWallet) - .findFirst(); + final storedAddress = + await mainDB + .getAddresses(walletId) + .filter() + .subTypeEqualTo(AddressSubType.paynymNotification) + .and() + .typeEqualTo(AddressType.p2pkh) + .and() + .not() + .typeEqualTo(AddressType.nonWallet) + .findFirst(); if (storedAddress == null) { await mainDB.isar.addresses.put(address); @@ -1607,45 +1643,43 @@ mixin PaynymInterface overrideAddresses ?? await fetchAddressesForElectrumXScan(); // Separate receiving and change addresses. - final Set receivingAddresses = allAddressesOld - .where( - (e) => - e.subType == AddressSubType.receiving || - e.subType == AddressSubType.paynymNotification || - e.subType == AddressSubType.paynymReceive, - ) - .map((e) => e.value) - .toSet(); - final Set changeAddresses = allAddressesOld - .where((e) => e.subType == AddressSubType.change) - .map((e) => e.value) - .toSet(); + final Set receivingAddresses = + allAddressesOld + .where( + (e) => + e.subType == AddressSubType.receiving || + e.subType == AddressSubType.paynymNotification || + e.subType == AddressSubType.paynymReceive, + ) + .map((e) => e.value) + .toSet(); + final Set changeAddresses = + allAddressesOld + .where((e) => e.subType == AddressSubType.change) + .map((e) => e.value) + .toSet(); // Remove duplicates. final allAddressesSet = {...receivingAddresses, ...changeAddresses}; // Fetch history from ElectrumX. - final List> allTxHashes = - await fetchHistory(allAddressesSet); - - final unconfirmedTxs = await mainDB.isar.transactionV2s - .where() - .walletIdEqualTo(walletId) - .filter() - .heightIsNull() - .or() - .heightEqualTo(0) - .txidProperty() - .findAll(); - - allTxHashes.addAll( - unconfirmedTxs.map( - (e) => { - "tx_hash": e, - }, - ), + final List> allTxHashes = await fetchHistory( + allAddressesSet, ); + final unconfirmedTxs = + await mainDB.isar.transactionV2s + .where() + .walletIdEqualTo(walletId) + .filter() + .heightIsNull() + .or() + .heightEqualTo(0) + .txidProperty() + .findAll(); + + allTxHashes.addAll(unconfirmedTxs.map((e) => {"tx_hash": e})); + // Only parse new txs (not in db yet). final List> allTransactions = []; for (final txHash in allTxHashes) { @@ -1670,16 +1704,17 @@ mixin PaynymInterface } catch (e) { // tx no longer exists then delete from local db if (e.toString().contains( - "JSON-RPC error 2: daemon error: DaemonError({'code': -5, " - "'message': 'No such mempool or blockchain transaction", - )) { + "JSON-RPC error 2: daemon error: DaemonError({'code': -5, " + "'message': 'No such mempool or blockchain transaction", + )) { await mainDB.isar.writeTxn( - () async => await mainDB.isar.transactionV2s - .where() - .walletIdEqualTo(walletId) - .filter() - .txidEqualTo(txid) - .deleteFirst(), + () async => + await mainDB.isar.transactionV2s + .where() + .walletIdEqualTo(walletId) + .filter() + .txidEqualTo(txid) + .deleteFirst(), ); continue; } else { @@ -1802,8 +1837,9 @@ mixin PaynymInterface TransactionSubType subType = TransactionSubType.none; if (outputs.length > 1 && inputs.isNotEmpty) { for (int i = 0; i < outputs.length; i++) { - final List? scriptChunks = - outputs[i].scriptPubKeyAsm?.split(" "); + final List? scriptChunks = outputs[i].scriptPubKeyAsm?.split( + " ", + ); if (scriptChunks?.length == 2 && scriptChunks?[0] == "OP_RETURN") { final blindedPaymentCode = scriptChunks![1]; final bytes = blindedPaymentCode.toUint8ListFromHex; @@ -1856,7 +1892,8 @@ mixin PaynymInterface txid: txData["txid"] as String, height: txData["height"] as int?, version: txData["version"] as int, - timestamp: txData["blocktime"] as int? ?? + timestamp: + txData["blocktime"] as int? ?? DateTime.timestamp().millisecondsSinceEpoch ~/ 1000, inputs: List.unmodifiable(inputs), outputs: List.unmodifiable(outputs), @@ -1872,12 +1909,8 @@ mixin PaynymInterface } @override - Future< - ({ - String? blockedReason, - bool blocked, - String? utxoLabel, - })> checkBlockUTXO( + Future<({String? blockedReason, bool blocked, String? utxoLabel})> + checkBlockUTXO( Map jsonUTXO, String? scriptPubKeyHex, Map? jsonTX, @@ -1905,7 +1938,8 @@ mixin PaynymInterface blocked = true; blockedReason = "Incoming paynym notification transaction."; } else { - blockedReason = "Paynym notification change output. Incautious " + blockedReason = + "Paynym notification change output. Incautious " "handling of change outputs from notification transactions " "may cause unintended loss of privacy."; utxoLabel = blockedReason; @@ -1920,23 +1954,21 @@ mixin PaynymInterface return ( blockedReason: blockedReason, blocked: blocked, - utxoLabel: utxoLabel + utxoLabel: utxoLabel, ); } @override FilterOperation? get transactionFilterOperation => FilterGroup.not( - const FilterGroup.and( - [ - FilterCondition.equalTo( - property: r"subType", - value: TransactionSubType.bip47Notification, - ), - FilterCondition.equalTo( - property: r"type", - value: TransactionType.incoming, - ), - ], - ), - ); + const FilterGroup.and([ + FilterCondition.equalTo( + property: r"subType", + value: TransactionSubType.bip47Notification, + ), + FilterCondition.equalTo( + property: r"type", + value: TransactionType.incoming, + ), + ]), + ); } diff --git a/pubspec.lock b/pubspec.lock index 8bdf56e80..c74b3910d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -352,21 +352,19 @@ packages: coinlib: dependency: "direct overridden" description: - path: coinlib - ref: "0acacfd17eacf72135c693a7b862bd9b7cc56739" - resolved-ref: "0acacfd17eacf72135c693a7b862bd9b7cc56739" - url: "https://github.com/julian-CStack/coinlib.git" - source: git - version: "2.2.0" + name: coinlib + sha256: f99c090ca300b6c9b5414dc100f7f36f49a5a2af31d477b3ce04a605c5f1103c + url: "https://pub.dev" + source: hosted + version: "3.1.0" coinlib_flutter: dependency: "direct main" description: - path: coinlib_flutter - ref: "0acacfd17eacf72135c693a7b862bd9b7cc56739" - resolved-ref: "0acacfd17eacf72135c693a7b862bd9b7cc56739" - url: "https://github.com/julian-CStack/coinlib.git" - source: git - version: "2.2.0" + name: coinlib_flutter + sha256: "185c622986d12d2ccda98f151ce047360464dd7a6cbb6877781a9816d14bb8c4" + url: "https://pub.dev" + source: hosted + version: "3.0.0" collection: dependency: transitive description: @@ -832,8 +830,8 @@ packages: dependency: "direct main" description: path: "." - ref: ca0c72cecc40fc0bfbafc0d26af675d973ab516b - resolved-ref: ca0c72cecc40fc0bfbafc0d26af675d973ab516b + ref: "33e1034911b842c57bdf6ddaa825cbf635a0c9db" + resolved-ref: "33e1034911b842c57bdf6ddaa825cbf635a0c9db" url: "https://github.com/cypherstack/flutter_libsparkmobile.git" source: git version: "0.0.2" @@ -1247,7 +1245,7 @@ packages: path: "crypto_plugins/flutter_liblelantus" relative: true source: path - version: "0.0.2" + version: "0.0.3" lints: dependency: transitive description: diff --git a/scripts/android/build_all.sh b/scripts/android/build_all.sh index 60aa13c6a..3b19c1c5b 100755 --- a/scripts/android/build_all.sh +++ b/scripts/android/build_all.sh @@ -2,19 +2,13 @@ set -x -e -# libepiccash requires old rust -source ../rust_version.sh -set_rust_to_1671 - mkdir -p build . ./config.sh -./install_ndk.sh PLUGINS_DIR=../../crypto_plugins (cd "${PLUGINS_DIR}"/flutter_liblelantus/scripts/android && ./build_all.sh ) (cd "${PLUGINS_DIR}"/flutter_libepiccash/scripts/android && ./build_all.sh ) -set_rust_to_1720 (cd "${PLUGINS_DIR}"/frostdart/scripts/android && ./build_all.sh ) wait diff --git a/scripts/android/build_all_campfire.sh b/scripts/android/build_all_campfire.sh index 60aa13c6a..3b19c1c5b 100755 --- a/scripts/android/build_all_campfire.sh +++ b/scripts/android/build_all_campfire.sh @@ -2,19 +2,13 @@ set -x -e -# libepiccash requires old rust -source ../rust_version.sh -set_rust_to_1671 - mkdir -p build . ./config.sh -./install_ndk.sh PLUGINS_DIR=../../crypto_plugins (cd "${PLUGINS_DIR}"/flutter_liblelantus/scripts/android && ./build_all.sh ) (cd "${PLUGINS_DIR}"/flutter_libepiccash/scripts/android && ./build_all.sh ) -set_rust_to_1720 (cd "${PLUGINS_DIR}"/frostdart/scripts/android && ./build_all.sh ) wait diff --git a/scripts/android/build_all_duo.sh b/scripts/android/build_all_duo.sh index d67e700a8..25b3ce9ea 100755 --- a/scripts/android/build_all_duo.sh +++ b/scripts/android/build_all_duo.sh @@ -4,19 +4,13 @@ set -x -e # todo: revisit following at some point -# libepiccash requires old rust -source ../rust_version.sh -set_rust_to_1671 - mkdir -p build . ./config.sh -./install_ndk.sh PLUGINS_DIR=../../crypto_plugins (cd "${PLUGINS_DIR}"/flutter_liblelantus/scripts/android && ./build_all.sh ) (cd "${PLUGINS_DIR}"/flutter_libepiccash/scripts/android && ./build_all.sh ) -set_rust_to_1720 (cd "${PLUGINS_DIR}"/frostdart/scripts/android && ./build_all.sh ) wait diff --git a/scripts/android/config.sh b/scripts/android/config.sh index 864c78c18..8d560ec36 100644 --- a/scripts/android/config.sh +++ b/scripts/android/config.sh @@ -1,7 +1,5 @@ #!/bin/sh export WORKDIR="$(pwd)/"build -export ANDROID_NDK_ZIP=${WORKDIR}/android-ndk-r20b.zip -export TOOLCHAIN_DIR="${WORKDIR}/toolchain" # Change this Value to a lower number if you run out of memory while compiling export OVERRIDE_THREADS="$(nproc)" \ No newline at end of file diff --git a/scripts/android/install_ndk.sh b/scripts/android/install_ndk.sh deleted file mode 100755 index 0864a2bde..000000000 --- a/scripts/android/install_ndk.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -mkdir -p build -. ./config.sh -ANDROID_NDK_SHA256="8381c440fe61fcbb01e209211ac01b519cd6adf51ab1c2281d5daad6ca4c8c8c" - -if [ ! -e "$ANDROID_NDK_ZIP" ]; then - curl https://dl.google.com/android/repository/android-ndk-r20b-linux-x86_64.zip -o "${ANDROID_NDK_ZIP}" -fi -echo "${ANDROID_NDK_SHA256}" "${ANDROID_NDK_ZIP}" | sha256sum -c || exit 1 - - -PLUGINS_DIR=../../crypto_plugins - -mkdir -p "${PLUGINS_DIR}"/flutter_libmonero/scripts/android/build -mkdir -p "${PLUGINS_DIR}"/flutter_liblelantus/scripts/android/build -mkdir -p "${PLUGINS_DIR}"/flutter_libepiccash/scripts/android/build - -cp "${ANDROID_NDK_ZIP}" "${PLUGINS_DIR}"/flutter_libmonero/scripts/android/build/ -cp "${ANDROID_NDK_ZIP}" "${PLUGINS_DIR}"/flutter_liblelantus/scripts/android/build/ -cp "${ANDROID_NDK_ZIP}" "${PLUGINS_DIR}"/flutter_libepiccash/scripts/android/build/ diff --git a/scripts/app_config/templates/android/app/build.gradle b/scripts/app_config/templates/android/app/build.gradle index b9cebc7b4..dc1cb233a 100644 --- a/scripts/app_config/templates/android/app/build.gradle +++ b/scripts/app_config/templates/android/app/build.gradle @@ -15,7 +15,7 @@ android { namespace "com.place.holder" compileSdk flutter.compileSdkVersion // ndkVersion flutter.ndkVersion - ndkVersion = "26.1.10909125" + ndkVersion = "28.0.13004108" packagingOptions { pickFirst 'lib/x86/libc++_shared.so' @@ -90,6 +90,7 @@ android { task.doFirst { println "The compileSdkVersion is $flutter.compileSdkVersion" println "The targetSdkVersion is $flutter.targetSdkVersion" + println "The ndkVersion is $ndkVersion" } } } diff --git a/scripts/app_config/templates/android/app/src/debug/AndroidManifest.xml b/scripts/app_config/templates/android/app/src/debug/AndroidManifest.xml index 9aa98e2e8..399f6981d 100644 --- a/scripts/app_config/templates/android/app/src/debug/AndroidManifest.xml +++ b/scripts/app_config/templates/android/app/src/debug/AndroidManifest.xml @@ -1,6 +1,6 @@ - - diff --git a/scripts/app_config/templates/android/app/src/main/AndroidManifest.xml b/scripts/app_config/templates/android/app/src/main/AndroidManifest.xml index 204663635..07f7a3ef0 100644 --- a/scripts/app_config/templates/android/app/src/main/AndroidManifest.xml +++ b/scripts/app_config/templates/android/app/src/main/AndroidManifest.xml @@ -1,10 +1,4 @@ - - + - diff --git a/scripts/app_config/templates/pubspec.template b/scripts/app_config/templates/pubspec.template index 62b1947ca..7f9d25c86 100644 --- a/scripts/app_config/templates/pubspec.template +++ b/scripts/app_config/templates/pubspec.template @@ -38,7 +38,7 @@ dependencies: flutter_libsparkmobile: git: url: https://github.com/cypherstack/flutter_libsparkmobile.git - ref: ca0c72cecc40fc0bfbafc0d26af675d973ab516b + ref: 33e1034911b842c57bdf6ddaa825cbf635a0c9db # cs_monero compat (unpublished) compat: @@ -176,12 +176,7 @@ dependencies: convert: ^3.1.1 flutter_hooks: ^0.20.3 meta: ^1.9.1 -# coinlib_flutter: ^2.1.0-rc.1 - coinlib_flutter: - git: - url: https://github.com/julian-CStack/coinlib.git - ref: 0acacfd17eacf72135c693a7b862bd9b7cc56739 - path: coinlib_flutter + coinlib_flutter: ^3.0.0 electrum_adapter: git: url: https://github.com/cypherstack/electrum_adapter.git @@ -261,18 +256,9 @@ dependency_overrides: # needed for dart 3.5+ (at least for now) win32: ^5.5.4 - # coin lib git for testing while waiting for publishing - coinlib: - git: - url: https://github.com/julian-CStack/coinlib.git - ref: 0acacfd17eacf72135c693a7b862bd9b7cc56739 - path: coinlib - - coinlib_flutter: - git: - url: https://github.com/julian-CStack/coinlib.git - ref: 0acacfd17eacf72135c693a7b862bd9b7cc56739 - path: coinlib_flutter + # namecoin names lib needs to be updated + coinlib: ^3.0.0 + coinlib_flutter: ^3.0.0 bip47: git: diff --git a/scripts/ios/build_all.sh b/scripts/ios/build_all.sh index bcb03e991..6ac527632 100755 --- a/scripts/ios/build_all.sh +++ b/scripts/ios/build_all.sh @@ -2,10 +2,6 @@ set -x -e -# libepiccash requires old rust -source ../rust_version.sh -set_rust_to_1671 - # ensure ios rust triples are there rustup target add aarch64-apple-ios rustup target add x86_64-apple-ios @@ -16,7 +12,6 @@ rustup target add x86_64-apple-ios (cd ../../crypto_plugins/flutter_liblelantus/scripts/ios && ./build_all.sh ) (cd ../../crypto_plugins/flutter_libepiccash/scripts/ios && ./build_all.sh ) -set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/ios && ./build_all.sh ) wait diff --git a/scripts/ios/build_all_campfire.sh b/scripts/ios/build_all_campfire.sh index bcb03e991..6ac527632 100755 --- a/scripts/ios/build_all_campfire.sh +++ b/scripts/ios/build_all_campfire.sh @@ -2,10 +2,6 @@ set -x -e -# libepiccash requires old rust -source ../rust_version.sh -set_rust_to_1671 - # ensure ios rust triples are there rustup target add aarch64-apple-ios rustup target add x86_64-apple-ios @@ -16,7 +12,6 @@ rustup target add x86_64-apple-ios (cd ../../crypto_plugins/flutter_liblelantus/scripts/ios && ./build_all.sh ) (cd ../../crypto_plugins/flutter_libepiccash/scripts/ios && ./build_all.sh ) -set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/ios && ./build_all.sh ) wait diff --git a/scripts/ios/build_all_duo.sh b/scripts/ios/build_all_duo.sh index 89e6f4641..4f5191bd2 100755 --- a/scripts/ios/build_all_duo.sh +++ b/scripts/ios/build_all_duo.sh @@ -4,10 +4,6 @@ set -x -e # todo: revisit following at some point -# libepiccash requires old rust -source ../rust_version.sh -set_rust_to_1671 - # ensure ios rust triples are there rustup target add aarch64-apple-ios rustup target add x86_64-apple-ios @@ -18,7 +14,6 @@ rustup target add x86_64-apple-ios (cd ../../crypto_plugins/flutter_liblelantus/scripts/ios && ./build_all.sh ) (cd ../../crypto_plugins/flutter_libepiccash/scripts/ios && ./build_all.sh ) -set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/ios && ./build_all.sh ) wait diff --git a/scripts/linux/build_all.sh b/scripts/linux/build_all.sh index 423646185..0562c2191 100755 --- a/scripts/linux/build_all.sh +++ b/scripts/linux/build_all.sh @@ -2,10 +2,6 @@ set -x -e -# libepiccash requires old rust -source ../rust_version.sh -set_rust_to_1671 - # for arm # flutter-elinux clean # flutter-elinux pub get @@ -14,7 +10,6 @@ mkdir -p build ./build_secure_storage_deps.sh (cd ../../crypto_plugins/flutter_liblelantus/scripts/linux && ./build_all.sh ) (cd ../../crypto_plugins/flutter_libepiccash/scripts/linux && ./build_all.sh ) -set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/linux && ./build_all.sh ) ./build_secp256k1.sh diff --git a/scripts/linux/build_all_campfire.sh b/scripts/linux/build_all_campfire.sh index 423646185..0562c2191 100755 --- a/scripts/linux/build_all_campfire.sh +++ b/scripts/linux/build_all_campfire.sh @@ -2,10 +2,6 @@ set -x -e -# libepiccash requires old rust -source ../rust_version.sh -set_rust_to_1671 - # for arm # flutter-elinux clean # flutter-elinux pub get @@ -14,7 +10,6 @@ mkdir -p build ./build_secure_storage_deps.sh (cd ../../crypto_plugins/flutter_liblelantus/scripts/linux && ./build_all.sh ) (cd ../../crypto_plugins/flutter_libepiccash/scripts/linux && ./build_all.sh ) -set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/linux && ./build_all.sh ) ./build_secp256k1.sh diff --git a/scripts/linux/build_all_duo.sh b/scripts/linux/build_all_duo.sh index 78067b478..60557556d 100755 --- a/scripts/linux/build_all_duo.sh +++ b/scripts/linux/build_all_duo.sh @@ -4,9 +4,6 @@ set -x -e # todo: revisit following at some point -# libepiccash requires old rust -source ../rust_version.sh -set_rust_to_1671 # for arm # flutter-elinux clean @@ -16,7 +13,6 @@ mkdir -p build ./build_secure_storage_deps.sh & (cd ../../crypto_plugins/flutter_liblelantus/scripts/linux && ./build_all.sh ) (cd ../../crypto_plugins/flutter_libepiccash/scripts/linux && ./build_all.sh ) -set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/linux && ./build_all.sh ) ./build_secp256k1.sh diff --git a/scripts/macos/build_all.sh b/scripts/macos/build_all.sh index af608846f..5fa49e6ff 100755 --- a/scripts/macos/build_all.sh +++ b/scripts/macos/build_all.sh @@ -2,17 +2,10 @@ set -x -e -# libepiccash requires old rust -source ../rust_version.sh -set_rust_to_1671 - (cd ../../crypto_plugins/flutter_liblelantus/scripts/macos && ./build_all.sh ) (cd ../../crypto_plugins/flutter_libepiccash/scripts/macos && ./build_all.sh ) -set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/macos && ./build_all.sh ) wait echo "Done building" -# set rust (back) to a more recent stable release to allow stack wallet to build tor -set_rust_to_1720 diff --git a/scripts/macos/build_all_campfire.sh b/scripts/macos/build_all_campfire.sh index af608846f..8102b1d00 100755 --- a/scripts/macos/build_all_campfire.sh +++ b/scripts/macos/build_all_campfire.sh @@ -2,17 +2,9 @@ set -x -e -# libepiccash requires old rust -source ../rust_version.sh -set_rust_to_1671 - (cd ../../crypto_plugins/flutter_liblelantus/scripts/macos && ./build_all.sh ) (cd ../../crypto_plugins/flutter_libepiccash/scripts/macos && ./build_all.sh ) -set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/macos && ./build_all.sh ) wait echo "Done building" - -# set rust (back) to a more recent stable release to allow stack wallet to build tor -set_rust_to_1720 diff --git a/scripts/macos/build_all_duo.sh b/scripts/macos/build_all_duo.sh index 8a53e5801..23c4e0be3 100755 --- a/scripts/macos/build_all_duo.sh +++ b/scripts/macos/build_all_duo.sh @@ -4,17 +4,10 @@ set -x -e # todo: revisit following at some point -# libepiccash requires old rust -source ../rust_version.sh -set_rust_to_1671 - (cd ../../crypto_plugins/flutter_liblelantus/scripts/macos && ./build_all.sh ) (cd ../../crypto_plugins/flutter_libepiccash/scripts/macos && ./build_all.sh ) -set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/macos && ./build_all.sh ) wait echo "Done building" -# set rust (back) to a more recent stable release to allow stack wallet to build tor -set_rust_to_1720 diff --git a/scripts/rust_version.sh b/scripts/rust_version.sh deleted file mode 100755 index 8cda1229b..000000000 --- a/scripts/rust_version.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -set_rust_to_1671() { - if rustup toolchain list | grep -q "1.67.1"; then - rustup default 1.67.1 - else - echo "Rust version 1.67.1 is not installed. Please install it using 'rustup install 1.67.1'." >&2 - exit 1 - fi -} - -set_rust_to_1720() { - if rustup toolchain list | grep -q "1.72.0"; then - rustup default 1.72.0 - else - echo "Rust version 1.72.0 is not installed. Please install it using 'rustup install 1.72.0'." >&2 - exit 1 - fi -} \ No newline at end of file diff --git a/scripts/windows/build_all.sh b/scripts/windows/build_all.sh index 191a46cc0..0f4d61b19 100755 --- a/scripts/windows/build_all.sh +++ b/scripts/windows/build_all.sh @@ -2,14 +2,9 @@ set -x -e -# libepiccash requires old rust -source ../rust_version.sh -set_rust_to_1671 - mkdir -p build (cd ../../crypto_plugins/flutter_libepiccash/scripts/windows && ./build_all.sh ) (cd ../../crypto_plugins/flutter_liblelantus/scripts/windows && ./build_all.sh ) -set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/windows && ./build_all.sh ) ./build_secp256k1_wsl.sh diff --git a/scripts/windows/build_all_campfire.sh b/scripts/windows/build_all_campfire.sh index 191a46cc0..0f4d61b19 100755 --- a/scripts/windows/build_all_campfire.sh +++ b/scripts/windows/build_all_campfire.sh @@ -2,14 +2,9 @@ set -x -e -# libepiccash requires old rust -source ../rust_version.sh -set_rust_to_1671 - mkdir -p build (cd ../../crypto_plugins/flutter_libepiccash/scripts/windows && ./build_all.sh ) (cd ../../crypto_plugins/flutter_liblelantus/scripts/windows && ./build_all.sh ) -set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/windows && ./build_all.sh ) ./build_secp256k1_wsl.sh diff --git a/scripts/windows/build_all_duo.sh b/scripts/windows/build_all_duo.sh index 3e27eff02..5ee690c05 100755 --- a/scripts/windows/build_all_duo.sh +++ b/scripts/windows/build_all_duo.sh @@ -4,14 +4,9 @@ set -x -e # todo: revisit following at some point -# libepiccash requires old rust -source ../rust_version.sh -set_rust_to_1671 - mkdir -p build (cd ../../crypto_plugins/flutter_libepiccash/scripts/windows && ./build_all.sh ) (cd ../../crypto_plugins/flutter_liblelantus/scripts/windows && ./build_all.sh ) -set_rust_to_1720 (cd ../../crypto_plugins/frostdart/scripts/windows && ./build_all.sh ) ./build_secp256k1_wsl.sh