mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-26 06:08:40 +01:00
v6.3.0 Release Candidate (#3414)
* v6.3.0 Release Candidate - the new transaction history - Radar in Apps screen - Zcash update - Flutter update - Parts of the Refactor should improve how amounts are handled in the app and fix any issue with amounts improve handling sending to aliases - Improvements for Cake Pay mobile - Bug fixes * don't use memo for note/message values * save message in QR locally in the notes field * Make stealth addresses generated from silent payment, not reliant on output index (#3420) * - fix swaps showing only on primary account - switch tron default node - privacy fixes * - enlarge destination tag and make it copiable - migrate users on hashvault - minor fix
This commit is contained in:
+10
-18
@@ -687,28 +687,20 @@ class CWBitcoin extends Bitcoin {
|
||||
}
|
||||
|
||||
List<Output> updateOutputs(PendingTransaction pendingTransaction, List<Output> outputs) {
|
||||
if (pendingTransaction is PendingLightningTransaction) return outputs;
|
||||
|
||||
final pendingTx = pendingTransaction as PendingBitcoinTransaction;
|
||||
|
||||
if (!pendingTx.hasSilentPayment) {
|
||||
if (pendingTransaction is! PendingBitcoinTransaction || !pendingTransaction.hasSilentPayment) {
|
||||
return outputs;
|
||||
}
|
||||
|
||||
final updatedOutputs = outputs.map((output) {
|
||||
try {
|
||||
final pendingOut = pendingTx.outputs[outputs.indexOf(output)];
|
||||
final updatedOutput = output;
|
||||
final stealthAddresses = pendingTransaction.stealthAddresses;
|
||||
if (stealthAddresses.length != outputs.length) {
|
||||
printV("well, that shouldn't happen");
|
||||
return outputs;
|
||||
}
|
||||
|
||||
updatedOutput.stealthAddress = P2trAddress.fromScriptPubkey(script: pendingOut.scriptPubKey)
|
||||
.toAddress(BitcoinNetwork.mainnet);
|
||||
return updatedOutput;
|
||||
} catch (_) {}
|
||||
|
||||
return output;
|
||||
}).toList();
|
||||
|
||||
return updatedOutputs;
|
||||
for (var i = 0; i < outputs.length; i++) {
|
||||
outputs[i].stealthAddress = stealthAddresses[i];
|
||||
}
|
||||
return outputs;
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -10,7 +10,6 @@ import 'package:cake_wallet/entities/fiat_api_mode.dart';
|
||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
import 'package:cake_wallet/entities/fs_migration.dart';
|
||||
import 'package:cake_wallet/entities/haven_seed_store.dart';
|
||||
import 'package:cake_wallet/entities/node_list.dart';
|
||||
import 'package:cake_wallet/entities/preferences_key.dart';
|
||||
import 'package:cake_wallet/entities/secret_store_key.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
@@ -46,7 +45,7 @@ const cakeWalletBitcoinCashDefaultNodeUri = 'bitcoincash.stackwallet.com:50002';
|
||||
const nanoDefaultNodeUri = 'rpc.nano.to';
|
||||
const nanoDefaultPowNodeUri = 'rpc.nano.to';
|
||||
const solanaDefaultNodeUri = 'solana-mainnet.core.chainstack.com';
|
||||
const tronDefaultNodeUri = 'api.trongrid.io';
|
||||
const tronDefaultNodeUri = 'trx.nownodes.io';
|
||||
const newCakeWalletBitcoinUri = 'btc-electrum.cakewallet.com:50002';
|
||||
const wowneroDefaultNodeUri = 'node3.monerodevs.org:34568';
|
||||
const zanoDefaultNodeUri = '37.27.100.59:10500';
|
||||
@@ -607,6 +606,28 @@ Future<void> defaultSettingsMigration(
|
||||
enabled: true,
|
||||
);
|
||||
break;
|
||||
case 68:
|
||||
await _changeDefaultNode(
|
||||
sharedPreferences: sharedPreferences,
|
||||
type: WalletType.tron,
|
||||
newDefaultUri: tronDefaultNodeUri,
|
||||
currentNodePreferenceKey: PreferencesKey.currentTronNodeIdKey,
|
||||
useSSL: true,
|
||||
oldUri: [
|
||||
'tron-rpc.publicnode.com:443',
|
||||
'api.trongrid.io',
|
||||
],
|
||||
);
|
||||
await _changeDefaultNode(
|
||||
sharedPreferences: sharedPreferences,
|
||||
type: WalletType.monero,
|
||||
newDefaultUri: newCakeWalletMoneroUri,
|
||||
currentNodePreferenceKey: PreferencesKey.currentNodeIdKey,
|
||||
useSSL: true,
|
||||
trusted: true,
|
||||
oldUri: ['nodes.hashvault.pro:18081'],
|
||||
);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -663,7 +684,7 @@ Future<void> _changeDefaultNode({
|
||||
} else {
|
||||
final currentNode = nodes.firstWhereOrNull((node) => node.id == currentNodeId);
|
||||
shouldReplace =
|
||||
currentNode == null || (oldUri?.any((e) => currentNode!.uriRaw.contains(e)) ?? true);
|
||||
currentNode == null || (oldUri?.any((e) => currentNode.uriRaw.contains(e)) ?? true);
|
||||
}
|
||||
|
||||
if (shouldReplace) {
|
||||
|
||||
@@ -539,7 +539,7 @@ class TrocadorExchangeProvider extends ExchangeProvider {
|
||||
}
|
||||
|
||||
Future<Uri> _getUri(String path, Map<String, String> queryParams) async {
|
||||
final uri = Uri.http(onionApiAuthority, path, queryParams);
|
||||
final uri = Uri.https(onionApiAuthority, path, queryParams);
|
||||
|
||||
if (useTorOnly) return uri;
|
||||
|
||||
|
||||
+1
-1
@@ -315,7 +315,7 @@ Future<void> initializeAppConfigs({bool loadWallet = true}) async {
|
||||
payjoinSessionSource: payjoinSessionSource,
|
||||
anonpayInvoiceInfo: anonpayInvoiceInfo,
|
||||
havenSeedStore: havenSeedStore,
|
||||
initialMigrationVersion: 67,
|
||||
initialMigrationVersion: 68,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -241,7 +241,9 @@ class _NewSendPageState extends State<NewSendPage> {
|
||||
widget.initialPaymentRequest!.scheme.toLowerCase()) {
|
||||
_addressControllers[0].text = widget.initialPaymentRequest!.address;
|
||||
_amountControllers[0].text = widget.initialPaymentRequest!.amount;
|
||||
_memoControllers[0].text = widget.initialPaymentRequest!.note;
|
||||
// _memoControllers[0].text = widget.initialPaymentRequest!.note;
|
||||
_applyNote(widget.initialPaymentRequest!.note, 0);
|
||||
|
||||
final contractAddress = widget.initialPaymentRequest!.contractAddress;
|
||||
if (contractAddress != null && contractAddress.isNotEmpty) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
@@ -1308,7 +1310,9 @@ class _NewSendPageState extends State<NewSendPage> {
|
||||
);
|
||||
} catch (e) {}
|
||||
}
|
||||
_memoControllers[_selectedOutput].text = paymentRequest.note;
|
||||
// _memoControllers[_selectedOutput].text = paymentRequest.note;
|
||||
|
||||
_applyNote(paymentRequest.note, _selectedOutput);
|
||||
}
|
||||
|
||||
Future<void> _handleSwapFlow(
|
||||
@@ -1456,6 +1460,15 @@ class _NewSendPageState extends State<NewSendPage> {
|
||||
|
||||
String _wrapAmount(String amount, int maxChars) =>
|
||||
amount.length <= maxChars ? amount : "${amount.substring(0, maxChars - 3)}...";
|
||||
|
||||
// TODO: make a separate variable for memo in payment request model
|
||||
void _applyNote(String note, int selectedOutput) {
|
||||
if (widget.sendViewModel.hasMemos && note.length <= widget.sendViewModel.maxMemoLength) {
|
||||
widget.sendViewModel.outputs[selectedOutput].memo = note;
|
||||
} else {
|
||||
widget.sendViewModel.outputs[selectedOutput].note = note;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SendHelpPage extends StatelessWidget {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/new-ui/widgets/copy_wrapper.dart';
|
||||
import 'package:cake_wallet/new-ui/widgets/new_primary_button.dart';
|
||||
import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart';
|
||||
import 'package:cake_wallet/new-ui/widgets/swap_page/swap_modal_header.dart';
|
||||
@@ -9,6 +10,7 @@ import 'package:cake_wallet/view_model/exchange/exchange_trade_view_model.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/payment_uris.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class SwapSendExternalModal extends StatefulWidget {
|
||||
const SwapSendExternalModal(
|
||||
@@ -166,10 +168,59 @@ class _SwapSendExternalModalState extends State<SwapSendExternalModal> {
|
||||
),
|
||||
)),
|
||||
if (widget.exchangeTradeViewModel.trade.extraId != null)
|
||||
Text(
|
||||
"${S.of(context).destination_tag} ${widget.exchangeTradeViewModel.trade.extraId}",
|
||||
style: TextStyle(
|
||||
fontSize: 12, color: Theme.of(context).colorScheme.onSurfaceVariant),
|
||||
CopyWrapper(
|
||||
data: ClipboardData(
|
||||
text: widget.exchangeTradeViewModel.trade.extraId!),
|
||||
builder: (context, copied) => Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
spacing: 8,
|
||||
children: [
|
||||
Text(
|
||||
S.of(context).destination_tag,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
spacing: 8,
|
||||
children: [
|
||||
Flexible(
|
||||
child: Text(
|
||||
widget.exchangeTradeViewModel.trade.extraId!,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).colorScheme.primary),
|
||||
),
|
||||
),
|
||||
AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: Icon(
|
||||
copied ? Icons.check : Icons.copy,
|
||||
key: ValueKey(copied),
|
||||
size: 18,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
spacing: 8,
|
||||
|
||||
@@ -34,6 +34,8 @@ class MoneroHardwareWalletPassphraseInputModal extends StatelessWidget {
|
||||
BaseTextFormField(
|
||||
controller: controller,
|
||||
hintText: S.of(context).passphrase_raw,
|
||||
autocorrect: false,
|
||||
enableSuggestions: false,
|
||||
),
|
||||
const SizedBox(),
|
||||
NewPrimaryButton(
|
||||
|
||||
Reference in New Issue
Block a user