feat: generic fixes, testnet UI improvements, useSSL on bitcoin nodes

This commit is contained in:
Rafael Saes 2024-04-05 17:27:42 -03:00
parent d6de17c710
commit 226c47c6e3
52 changed files with 533 additions and 326 deletions

BIN
assets/images/tbtc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View file

@ -33,19 +33,21 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
List<BitcoinSilentPaymentAddressRecord>? initialSilentAddresses,
int initialSilentAddressIndex = 0,
}) : super(
mnemonic: mnemonic,
password: password,
walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfo,
networkType: networkParam == null
? bitcoin.bitcoin
: networkParam == BitcoinNetwork.mainnet
? bitcoin.bitcoin
: bitcoin.testnet,
initialAddresses: initialAddresses,
initialBalance: initialBalance,
seedBytes: seedBytes,
currency: CryptoCurrency.btc) {
mnemonic: mnemonic,
password: password,
walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfo,
networkType: networkParam == null
? bitcoin.bitcoin
: networkParam == BitcoinNetwork.mainnet
? bitcoin.bitcoin
: bitcoin.testnet,
initialAddresses: initialAddresses,
initialBalance: initialBalance,
seedBytes: seedBytes,
currency:
networkParam == BitcoinNetwork.testnet ? CryptoCurrency.tbtc : CryptoCurrency.btc,
) {
walletAddresses = BitcoinWalletAddresses(
walletInfo,
initialAddresses: initialAddresses,

View file

@ -50,18 +50,24 @@ class ElectrumClient {
String unterminatedString;
Uri? uri;
bool? useSSL;
Future<void> connectToUri(Uri uri) async {
Future<void> connectToUri(Uri uri, {bool? useSSL}) async {
this.uri = uri;
await connect(host: uri.host, port: uri.port);
this.useSSL = useSSL;
await connect(host: uri.host, port: uri.port, useSSL: useSSL);
}
Future<void> connect({required String host, required int port}) async {
Future<void> connect({required String host, required int port, bool? useSSL}) async {
try {
await socket?.close();
} catch (_) {}
socket = await SecureSocket.connect(host, port, timeout: connectionTimeout);
if (useSSL == true) {
socket = await SecureSocket.connect(host, port, timeout: connectionTimeout);
} else {
socket = await Socket.connect(host, port, timeout: connectionTimeout);
}
_setIsConnected(true);
socket!.listen((Uint8List event) {

View file

@ -44,8 +44,6 @@ import 'package:http/http.dart' as http;
part 'electrum_wallet.g.dart';
const SCANNING_BLOCK_COUNT = 50;
class ElectrumWallet = ElectrumWalletBase with _$ElectrumWallet;
abstract class ElectrumWalletBase
@ -89,6 +87,10 @@ abstract class ElectrumWalletBase
this.electrumClient = electrumClient ?? ElectrumClient();
this.walletInfo = walletInfo;
transactionHistory = ElectrumTransactionHistory(walletInfo: walletInfo, password: password);
reaction((_) => syncStatus, (SyncStatus syncStatus) {
silentPaymentsScanningActive = syncStatus is SyncingSyncStatus;
});
}
static bitcoin.HDWallet bitcoinCashHDWallet(Uint8List seedBytes) =>
@ -146,10 +148,10 @@ abstract class ElectrumWalletBase
bool silentPaymentsScanningActive = false;
@action
void setSilentPaymentsScanning(bool value) {
hasSilentPaymentsScanning = value;
void setSilentPaymentsScanning(bool active) {
silentPaymentsScanningActive = active;
if (value) {
if (active) {
_setInitialHeight().then((_) {
if ((currentChainTip ?? 0) > walletInfo.restoreHeight) {
_setListeners(walletInfo.restoreHeight, chainTip: currentChainTip);
@ -218,16 +220,11 @@ abstract class ElectrumWalletBase
chainTip: currentChainTip,
electrumClient: ElectrumClient(),
transactionHistoryIds: transactionHistory.transactions.keys.toList(),
node: electrumClient.uri.toString(),
node: node!,
labels: walletAddresses.labels,
));
await for (var message in receivePort) {
if (message is bool && message == false) {
nodeSupportsSilentPayments = message;
syncStatus = TimedOutSyncStatus();
}
if (message is Map<String, ElectrumTransactionInfo>) {
for (final map in message.entries) {
final txid = map.key;
@ -274,6 +271,10 @@ abstract class ElectrumWalletBase
// check if is a SyncStatus type since "is SyncStatus" doesn't work here
if (message is SyncResponse) {
if (message.syncStatus is UnsupportedSyncStatus) {
nodeSupportsSilentPayments = false;
}
syncStatus = message.syncStatus;
walletInfo.restoreHeight = message.height;
await walletInfo.save();
@ -316,11 +317,15 @@ abstract class ElectrumWalletBase
}
}
Node? node;
@action
Future<void> _electrumConnect(Node node, {bool? attemptedReconnect}) async {
this.node = node;
try {
syncStatus = ConnectingSyncStatus();
await electrumClient.connectToUri(node.uri);
await electrumClient.connectToUri(node.uri, useSSL: node.useSSL);
electrumClient.onConnectionStatusChange = (bool isConnected) async {
if (!isConnected) {
syncStatus = LostConnectionSyncStatus();
@ -346,6 +351,52 @@ abstract class ElectrumWalletBase
bool _isBelowDust(int amount) => amount <= _getDustAmount() && network != BitcoinNetwork.testnet;
void _createSilentPayments(
List<BitcoinOutput> outputs,
List<ECPublic> inputPubKeys,
List<Outpoint> vinOutpoints,
List<ECPrivateInfo> inputPrivKeyInfos,
) {
List<SilentPaymentDestination> silentPaymentDestinations = [];
for (final out in outputs) {
final address = out.address;
final amount = out.value;
if (address is SilentPaymentAddress) {
silentPaymentDestinations.add(
SilentPaymentDestination.fromAddress(address.toAddress(network), amount.toInt()),
);
}
}
if (silentPaymentDestinations.isNotEmpty) {
final spb = SilentPaymentBuilder(pubkeys: inputPubKeys, outpoints: vinOutpoints);
final sendingOutputs = spb.createOutputs(inputPrivKeyInfos, silentPaymentDestinations);
final outputsAdded = [];
for (var i = 0; i < outputs.length; i++) {
final out = outputs[i];
final silentOutputs = sendingOutputs[out.address.toAddress(network)];
if (silentOutputs != null) {
final silentOutput =
silentOutputs.firstWhereOrNull((element) => !outputsAdded.contains(element));
if (silentOutput != null) {
outputs[i] = BitcoinOutput(
address: silentOutput.address,
value: BigInt.from(silentOutput.amount),
);
outputsAdded.add(silentOutput);
}
}
}
}
}
Future<EstimatedTxResult> estimateSendAllTx(
List<BitcoinOutput> outputs,
int feeRate, {
@ -416,6 +467,10 @@ abstract class ElectrumWalletBase
throw BitcoinTransactionNoInputsException();
}
if (hasSilentPayment == true) {
_createSilentPayments(outputs, inputPubKeys, vinOutpoints, inputPrivKeyInfos);
}
int estimatedSize;
if (network is BitcoinCashNetwork) {
estimatedSize = ForkedTransactionBuilder.estimateTransactionSize(
@ -433,45 +488,6 @@ abstract class ElectrumWalletBase
);
}
if (hasSilentPayment == true) {
List<SilentPaymentDestination> silentPaymentDestinations = [];
for (final out in outputs) {
final address = out.address;
final amount = out.value;
if (address is SilentPaymentAddress) {
final silentPaymentDestination =
SilentPaymentDestination.fromAddress(address.toAddress(network), amount.toInt());
silentPaymentDestinations.add(silentPaymentDestination);
}
}
final spb = SilentPaymentBuilder(pubkeys: inputPubKeys, outpoints: vinOutpoints);
final sendingOutputs = spb.createOutputs(inputPrivKeyInfos, silentPaymentDestinations);
var outputsAdded = [];
for (var i = 0; i < outputs.length; i++) {
final out = outputs[i];
final silentOutputs = sendingOutputs[out.address.toAddress(network)];
if (silentOutputs != null) {
final silentOutput =
silentOutputs.firstWhereOrNull((element) => !outputsAdded.contains(element));
if (silentOutput != null) {
outputs[i] = BitcoinOutput(
address: silentOutput.address,
value: BigInt.from(silentOutput.amount),
);
outputsAdded.add(silentOutput);
}
}
}
}
int fee = feeAmountWithFeeRate(feeRate, 0, 0, size: estimatedSize);
if (fee == 0) {
@ -518,7 +534,9 @@ abstract class ElectrumWalletBase
bool hasSilentPayment = false,
}) async {
final utxos = <UtxoWithAddress>[];
List<Outpoint> vinOutpoints = [];
List<ECPrivateInfo> inputPrivKeyInfos = [];
List<ECPublic> inputPubKeys = [];
int allInputsAmount = 0;
bool spendsSilentPayment = false;
@ -553,6 +571,10 @@ abstract class ElectrumWalletBase
);
}
inputPrivKeyInfos.add(ECPrivateInfo(privkey, address.type == SegwitAddresType.p2tr));
inputPubKeys.add(privkey.getPublic());
vinOutpoints.add(Outpoint(txid: utx.hash, index: utx.vout));
utxos.add(
UtxoWithAddress(
utxo: BitcoinUtxo(
@ -579,6 +601,10 @@ abstract class ElectrumWalletBase
throw BitcoinTransactionNoInputsException();
}
if (hasSilentPayment == true) {
_createSilentPayments(outputs, inputPubKeys, vinOutpoints, inputPrivKeyInfos);
}
final spendingAllCoins = sendingCoins.length == utxos.length;
// How much is being spent - how much is being sent
@ -952,8 +978,10 @@ abstract class ElectrumWalletBase
await transactionHistory.changePassword(password);
}
@action
@override
Future<void> rescan({required int height, int? chainTip, ScanData? scanData}) async {
silentPaymentsScanningActive = true;
_setListeners(height);
}
@ -1388,7 +1416,7 @@ class ScanData {
final SendPort sendPort;
final SilentPaymentOwner silentAddress;
final int height;
final String node;
final Node node;
final BasedUtxoNetwork network;
final int chainTip;
final ElectrumClient electrumClient;
@ -1436,7 +1464,7 @@ Future<void> startRefresh(ScanData scanData) async {
final electrumClient = scanData.electrumClient;
if (!electrumClient.isConnected) {
final node = scanData.node;
await electrumClient.connectToUri(Uri.parse(node));
await electrumClient.connectToUri(node.uri, useSSL: node.useSSL);
}
return electrumClient;
}
@ -1489,21 +1517,31 @@ Future<void> startRefresh(ScanData scanData) async {
try {
final electrumClient = await getElectrumConnection();
final scanningBlockCount = scanData.network == BitcoinNetwork.testnet ? 50 : 10;
Map<String, dynamic>? tweaks;
try {
tweaks = await electrumClient.getTweaks(height: syncHeight, count: SCANNING_BLOCK_COUNT);
tweaks = await electrumClient.getTweaks(height: syncHeight, count: scanningBlockCount);
} catch (e) {
if (e is RequestFailedTimeoutException) {
return scanData.sendPort.send(false);
return scanData.sendPort.send(
SyncResponse(syncHeight, TimedOutSyncStatus()),
);
}
}
if (tweaks == null) {
scanData.sendPort.send(SyncResponse(syncHeight,
SyncingSyncStatus.fromHeightValues(currentChainTip, initialSyncHeight, syncHeight)));
return scanData.sendPort.send(
SyncResponse(syncHeight, UnsupportedSyncStatus()),
);
}
final blockHeights = tweaks!.keys;
if (tweaks.isEmpty) {
syncHeight += scanningBlockCount;
continue;
}
final blockHeights = tweaks.keys;
for (var i = 0; i < blockHeights.length; i++) {
try {
final blockHeight = blockHeights.elementAt(i).toString();
@ -1515,81 +1553,83 @@ Future<void> startRefresh(ScanData scanData) async {
final outputPubkeys = (details["output_pubkeys"] as Map<dynamic, dynamic>);
final tweak = details["tweak"].toString();
final spb = SilentPaymentBuilder(receiverTweak: tweak);
final addToWallet = spb.scanOutputs(
scanData.silentAddress.b_scan,
scanData.silentAddress.B_spend,
outputPubkeys.values
.map((o) => getScriptFromOutput(
o["pubkey"].toString(), int.parse(o["amount"].toString())))
.toList(),
precomputedLabels: scanData.labels,
);
if (addToWallet.isEmpty) {
// no results tx, continue to next tx
continue;
}
addToWallet.forEach((key, value) async {
final t_k = value.tweak;
final addressRecord = BitcoinSilentPaymentAddressRecord(
value.output.address.toAddress(scanData.network),
index: 0,
isHidden: false,
isUsed: true,
network: scanData.network,
silentPaymentTweak: t_k,
type: SegwitAddresType.p2tr,
try {
final spb = SilentPaymentBuilder(receiverTweak: tweak);
final addToWallet = spb.scanOutputs(
scanData.silentAddress.b_scan,
scanData.silentAddress.B_spend,
outputPubkeys.values
.map((o) => getScriptFromOutput(
o["pubkey"].toString(), int.parse(o["amount"].toString())))
.toList(),
precomputedLabels: scanData.labels,
);
int? amount;
int? pos;
outputPubkeys.entries.firstWhere((k) {
final matches = k.value["pubkey"] == key;
if (matches) {
amount = int.parse(k.value["amount"].toString());
pos = int.parse(k.key.toString());
return true;
}
return false;
if (addToWallet.isEmpty) {
// no results tx, continue to next tx
continue;
}
addToWallet.forEach((key, value) async {
final t_k = value.tweak;
final addressRecord = BitcoinSilentPaymentAddressRecord(
value.output.address.toAddress(scanData.network),
index: 0,
isHidden: false,
isUsed: true,
network: scanData.network,
silentPaymentTweak: t_k,
type: SegwitAddresType.p2tr,
);
int? amount;
int? pos;
outputPubkeys.entries.firstWhere((k) {
final matches = k.value["pubkey"] == key;
if (matches) {
amount = int.parse(k.value["amount"].toString());
pos = int.parse(k.key.toString());
return true;
}
return false;
});
final json = <String, dynamic>{
'address_record': addressRecord.toJSON(),
'tx_hash': txid,
'value': amount!,
'tx_pos': pos!,
'silent_payment_tweak': t_k,
};
final tx = BitcoinUnspent.fromJSON(addressRecord, json);
final txInfo = ElectrumTransactionInfo(
WalletType.bitcoin,
id: tx.hash,
height: syncHeight,
amount: 0, // will be added later via unspent
fee: 0,
direction: TransactionDirection.incoming,
isPending: false,
date: DateTime.now(),
confirmations: currentChainTip - syncHeight - 1,
to: value.label != null
? SilentPaymentAddress(
version: scanData.silentAddress.version,
B_scan: scanData.silentAddress.B_scan.tweakAdd(
BigintUtils.fromBytes(BytesUtils.fromHexString(value.tweak))),
B_spend: scanData.silentAddress.B_spend,
hrp: scanData.silentAddress.hrp,
).toString()
: scanData.silentAddress.toString(),
unspents: [tx],
);
scanData.sendPort.send({txInfo.id: txInfo});
});
final json = <String, dynamic>{
'address_record': addressRecord.toJSON(),
'tx_hash': txid,
'value': amount!,
'tx_pos': pos!,
'silent_payment_tweak': t_k,
};
final tx = BitcoinUnspent.fromJSON(addressRecord, json);
final txInfo = ElectrumTransactionInfo(
WalletType.bitcoin,
id: tx.hash,
height: syncHeight,
amount: 0, // will be added later via unspent
fee: 0,
direction: TransactionDirection.incoming,
isPending: false,
date: DateTime.now(),
confirmations: currentChainTip - syncHeight - 1,
to: value.label != null
? SilentPaymentAddress(
version: scanData.silentAddress.version,
B_scan: scanData.silentAddress.B_scan
.tweakAdd(BigintUtils.fromBytes(BytesUtils.fromHexString(value.tweak))),
B_spend: scanData.silentAddress.B_spend,
hrp: scanData.silentAddress.hrp,
).toString()
: scanData.silentAddress.toString(),
unspents: [tx],
);
scanData.sendPort.send({txInfo.id: txInfo});
});
} catch (_) {}
}
} catch (e, s) {
print([e, s]);

View file

@ -53,7 +53,7 @@ class ElectrumWalletSnapshot {
.map((addr) => BitcoinSilentPaymentAddressRecord.fromJSON(addr, network: network))
.toList();
final balance = ElectrumBalance.fromJSON(data['balance'] as String) ??
final balance = ElectrumBalance.fromJSON(data['balance'] as String?) ??
ElectrumBalance(confirmed: 0, unconfirmed: 0, frozen: 0);
var regularAddressIndexByType = {SegwitAddresType.p2wpkh.toString(): 0};
var changeAddressIndexByType = {SegwitAddresType.p2wpkh.toString(): 0};

View file

@ -29,6 +29,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
CryptoCurrency.bch,
CryptoCurrency.bnb,
CryptoCurrency.btc,
CryptoCurrency.tbtc,
CryptoCurrency.dai,
CryptoCurrency.dash,
CryptoCurrency.eos,
@ -127,6 +128,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
static const bch = CryptoCurrency(title: 'BCH', fullName: 'Bitcoin Cash', raw: 2, name: 'bch', iconPath: 'assets/images/bch_icon.png', decimals: 8);
static const bnb = CryptoCurrency(title: 'BNB', tag: 'BSC', fullName: 'Binance Coin', raw: 3, name: 'bnb', iconPath: 'assets/images/bnb_icon.png', decimals: 8);
static const btc = CryptoCurrency(title: 'BTC', fullName: 'Bitcoin', raw: 4, name: 'btc', iconPath: 'assets/images/btc.png', decimals: 8);
static const tbtc = CryptoCurrency(title: 'tBTC', fullName: 'Testnet Bitcoin', raw: 4, name: 'tbtc', iconPath: 'assets/images/tbtc.png', decimals: 8);
static const dai = CryptoCurrency(title: 'DAI', tag: 'ETH', fullName: 'Dai', raw: 5, name: 'dai', iconPath: 'assets/images/dai_icon.png', decimals: 18);
static const dash = CryptoCurrency(title: 'DASH', fullName: 'Dash', raw: 6, name: 'dash', iconPath: 'assets/images/dash_icon.png', decimals: 8);
static const eos = CryptoCurrency(title: 'EOS', fullName: 'EOS', raw: 7, name: 'eos', iconPath: 'assets/images/eos_icon.png', decimals: 4);

View file

@ -1,9 +1,12 @@
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/wallet_type.dart';
CryptoCurrency currencyForWalletType(WalletType type) {
CryptoCurrency currencyForWalletType(WalletType type, {bool? isTestnet}) {
switch (type) {
case WalletType.bitcoin:
if (isTestnet == true) {
return CryptoCurrency.tbtc;
}
return CryptoCurrency.btc;
case WalletType.monero:
return CryptoCurrency.xmr;
@ -24,6 +27,7 @@ CryptoCurrency currencyForWalletType(WalletType type) {
case WalletType.solana:
return CryptoCurrency.sol;
default:
throw Exception('Unexpected wallet type: ${type.toString()} for CryptoCurrency currencyForWalletType');
throw Exception(
'Unexpected wallet type: ${type.toString()} for CryptoCurrency currencyForWalletType');
}
}

View file

@ -24,7 +24,7 @@ abstract class WalletBase<BalanceType extends Balance, HistoryType extends Trans
WalletType get type => walletInfo.type;
CryptoCurrency get currency => currencyForWalletType(type);
CryptoCurrency get currency => currencyForWalletType(type, isTestnet: isTestnet);
String get id => walletInfo.id;

View file

@ -161,11 +161,14 @@ String walletTypeToDisplayName(WalletType type) {
}
}
CryptoCurrency walletTypeToCryptoCurrency(WalletType type) {
CryptoCurrency walletTypeToCryptoCurrency(WalletType type, {bool isTestnet = false}) {
switch (type) {
case WalletType.monero:
return CryptoCurrency.xmr;
case WalletType.bitcoin:
if (isTestnet) {
return CryptoCurrency.tbtc;
}
return CryptoCurrency.btc;
case WalletType.litecoin:
return CryptoCurrency.ltc;

View file

@ -264,6 +264,8 @@ class CWBitcoin extends Bitcoin {
return (option as BitcoinReceivePageOption).toType();
}
@override
@computed
bool getScanningActive(Object wallet) {
final bitcoinWallet = wallet as ElectrumWallet;
return bitcoinWallet.silentPaymentsScanningActive;
@ -273,4 +275,9 @@ class CWBitcoin extends Bitcoin {
final bitcoinWallet = wallet as ElectrumWallet;
bitcoinWallet.setSilentPaymentsScanning(active);
}
bool isTestnet(Object wallet) {
final bitcoinWallet = wallet as ElectrumWallet;
return bitcoinWallet.isTestnet ?? false;
}
}

View file

@ -211,10 +211,12 @@ class CryptoBalanceWidget extends StatelessWidget {
dashboardViewModel.balanceViewModel.hasAdditionalBalance,
hasSilentPayments: dashboardViewModel.balanceViewModel.hasSilentPayments,
silentPaymentsScanningActive:
dashboardViewModel.balanceViewModel.silentPaymentsScanningActive,
setSilentPaymentsScanning: () => dashboardViewModel.balanceViewModel
.setSilentPaymentsScanning(
!dashboardViewModel.balanceViewModel.silentPaymentsScanningActive),
dashboardViewModel.silentPaymentsScanningActive,
setSilentPaymentsScanning: () =>
dashboardViewModel.setSilentPaymentsScanning(
!dashboardViewModel.silentPaymentsScanningActive,
),
isTestnet: dashboardViewModel.isTestnet,
);
});
},
@ -243,6 +245,7 @@ class BalanceRowWidget extends StatelessWidget {
required this.hasSilentPayments,
required this.silentPaymentsScanningActive,
required this.setSilentPaymentsScanning,
required this.isTestnet,
super.key,
});
@ -258,6 +261,7 @@ class BalanceRowWidget extends StatelessWidget {
final bool hasAdditionalBalance;
final bool hasSilentPayments;
final bool silentPaymentsScanningActive;
final bool isTestnet;
final void Function() setSilentPaymentsScanning;
// void _showBalanceDescription(BuildContext context) {
@ -333,14 +337,24 @@ class BalanceRowWidget extends StatelessWidget {
maxLines: 1,
textAlign: TextAlign.start),
SizedBox(height: 6),
Text('${availableFiatBalance}',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
fontFamily: 'Lato',
fontWeight: FontWeight.w500,
color: Theme.of(context).extension<BalancePageTheme>()!.textColor,
height: 1)),
if (isTestnet)
Text(S.current.testnet_coins_no_value,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context).extension<BalancePageTheme>()!.textColor,
height: 1)),
if (!isTestnet)
Text('${availableFiatBalance}',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
fontFamily: 'Lato',
fontWeight: FontWeight.w500,
color: Theme.of(context).extension<BalancePageTheme>()!.textColor,
height: 1)),
],
),
),
@ -432,17 +446,18 @@ class BalanceRowWidget extends StatelessWidget {
textAlign: TextAlign.center,
),
SizedBox(height: 4),
Text(
frozenFiatBalance,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context).extension<BalancePageTheme>()!.textColor,
height: 1,
if (!isTestnet)
Text(
frozenFiatBalance,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context).extension<BalancePageTheme>()!.textColor,
height: 1,
),
),
),
],
),
),
@ -476,17 +491,18 @@ class BalanceRowWidget extends StatelessWidget {
textAlign: TextAlign.center,
),
SizedBox(height: 4),
Text(
'${additionalFiatBalance}',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context).extension<BalancePageTheme>()!.textColor,
height: 1,
if (!isTestnet)
Text(
'${additionalFiatBalance}',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context).extension<BalancePageTheme>()!.textColor,
height: 1,
),
),
),
],
),
if (hasSilentPayments) ...[

View file

@ -19,7 +19,7 @@ class NodeForm extends StatelessWidget {
_portController = TextEditingController(text: editingNode?.uri.port.toString()),
_loginController = TextEditingController(text: editingNode?.login),
_passwordController = TextEditingController(text: editingNode?.password),
_socksAddressController = TextEditingController(text: editingNode?.socksProxyAddress){
_socksAddressController = TextEditingController(text: editingNode?.socksProxyAddress) {
if (editingNode != null) {
nodeViewModel
..setAddress((editingNode!.uri.host.toString()))
@ -60,7 +60,8 @@ class NodeForm extends StatelessWidget {
_portController.addListener(() => nodeViewModel.port = _portController.text);
_loginController.addListener(() => nodeViewModel.login = _loginController.text);
_passwordController.addListener(() => nodeViewModel.password = _passwordController.text);
_socksAddressController.addListener(() => nodeViewModel.socksProxyAddress = _socksAddressController.text);
_socksAddressController
.addListener(() => nodeViewModel.socksProxyAddress = _socksAddressController.text);
}
final NodeCreateOrEditViewModel nodeViewModel;
@ -103,6 +104,25 @@ class NodeForm extends StatelessWidget {
],
),
SizedBox(height: 10.0),
Padding(
padding: EdgeInsets.symmetric(vertical: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Observer(
builder: (_) => StandardCheckbox(
value: nodeViewModel.useSSL,
gradientBackground: true,
borderColor: Theme.of(context).dividerColor,
iconColor: Colors.white,
onChanged: (value) => nodeViewModel.useSSL = value,
caption: S.of(context).use_ssl,
),
)
],
),
),
if (nodeViewModel.hasAuthCredentials) ...[
Row(
children: <Widget>[
@ -123,25 +143,6 @@ class NodeForm extends StatelessWidget {
))
],
),
Padding(
padding: EdgeInsets.only(top: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Observer(
builder: (_) => StandardCheckbox(
value: nodeViewModel.useSSL,
gradientBackground: true,
borderColor: Theme.of(context).dividerColor,
iconColor: Colors.white,
onChanged: (value) => nodeViewModel.useSSL = value,
caption: S.of(context).use_ssl,
),
)
],
),
),
Padding(
padding: EdgeInsets.only(top: 20),
child: Row(
@ -163,44 +164,44 @@ class NodeForm extends StatelessWidget {
),
Observer(
builder: (_) => Column(
children: [
Padding(
padding: EdgeInsets.only(top: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
StandardCheckbox(
value: nodeViewModel.useSocksProxy,
gradientBackground: true,
borderColor: Theme.of(context).dividerColor,
iconColor: Colors.white,
onChanged: (value) {
if (!value) {
_socksAddressController.text = '';
}
nodeViewModel.useSocksProxy = value;
},
caption: 'SOCKS Proxy',
),
],
),
),
if (nodeViewModel.useSocksProxy) ...[
SizedBox(height: 10.0),
Row(
children: <Widget>[
Expanded(
child: BaseTextFormField(
children: [
Padding(
padding: EdgeInsets.only(top: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
StandardCheckbox(
value: nodeViewModel.useSocksProxy,
gradientBackground: true,
borderColor: Theme.of(context).dividerColor,
iconColor: Colors.white,
onChanged: (value) {
if (!value) {
_socksAddressController.text = '';
}
nodeViewModel.useSocksProxy = value;
},
caption: 'SOCKS Proxy',
),
],
),
),
if (nodeViewModel.useSocksProxy) ...[
SizedBox(height: 10.0),
Row(
children: <Widget>[
Expanded(
child: BaseTextFormField(
controller: _socksAddressController,
hintText: '[<ip>:]<port>',
validator: SocksProxyNodeAddressValidator(),
))
],
),
]
],
)),
],
),
]
],
)),
]
],
),

View file

@ -102,7 +102,7 @@ class ReceivePage extends BasePage {
return (addressListViewModel.type == WalletType.monero ||
addressListViewModel.type == WalletType.haven ||
addressListViewModel.type == WalletType.nano ||
isElectrumWallet)
isElectrumWallet)
? KeyboardActions(
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
@ -164,21 +164,21 @@ class ReceivePage extends BasePage {
}
if (item is WalletAddressListHeader) {
cell = HeaderTile(
title: S.of(context).addresses,
walletAddressListViewModel: addressListViewModel,
showTrailingButton: !addressListViewModel.isAutoGenerateSubaddressEnabled,
showSearchButton: true,
trailingButtonTap: () =>
Navigator.of(context).pushNamed(Routes.newSubaddress),
trailingIcon: Icon(
Icons.add,
size: 20,
color: Theme.of(context)
.extension<ReceivePageTheme>()!
.iconsColor,
));
}
cell = HeaderTile(
title: S.of(context).addresses,
walletAddressListViewModel: addressListViewModel,
showTrailingButton:
!addressListViewModel.isAutoGenerateSubaddressEnabled,
showSearchButton: true,
trailingButtonTap: () =>
Navigator.of(context).pushNamed(Routes.newSubaddress),
trailingIcon: Icon(
Icons.add,
size: 20,
color:
Theme.of(context).extension<ReceivePageTheme>()!.iconsColor,
));
}
if (item is WalletAddressListItem) {
cell = Observer(builder: (_) {
@ -219,7 +219,7 @@ class ReceivePage extends BasePage {
child: cell,
);
})),
if (!addressListViewModel.hasSilentAddresses)
if (!addressListViewModel.isSilentPayments)
Padding(
padding: EdgeInsets.fromLTRB(24, 24, 24, 32),
child: Text(S.of(context).electrum_address_disclaimer,

View file

@ -11,7 +11,8 @@ class RescanPage extends BasePage {
: _blockchainHeightWidgetKey = GlobalKey<BlockchainHeightState>();
@override
String get title => S.current.rescan;
String get title =>
_rescanViewModel.isSilentPaymentsScan ? S.current.silent_payments_scanning : S.current.rescan;
final GlobalKey<BlockchainHeightState> _blockchainHeightWidgetKey;
final RescanViewModel _rescanViewModel;
@ -19,20 +20,19 @@ class RescanPage extends BasePage {
Widget body(BuildContext context) {
return Padding(
padding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
child:
Column(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
BlockchainHeightWidget(key: _blockchainHeightWidgetKey,
onHeightOrDateEntered: (value) =>
_rescanViewModel.isButtonEnabled = value),
child: Column(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
BlockchainHeightWidget(
key: _blockchainHeightWidgetKey,
onHeightOrDateEntered: (value) => _rescanViewModel.isButtonEnabled = value,
isSilentPaymentsScan: _rescanViewModel.isSilentPaymentsScan,
),
Observer(
builder: (_) => LoadingPrimaryButton(
isLoading:
_rescanViewModel.state == RescanWalletState.rescaning,
isLoading: _rescanViewModel.state == RescanWalletState.rescaning,
text: S.of(context).rescan,
onPressed: () async {
await _rescanViewModel.rescanCurrentWallet(
restoreHeight:
_blockchainHeightWidgetKey.currentState!.height);
restoreHeight: _blockchainHeightWidgetKey.currentState!.height);
Navigator.of(context).pop();
},
color: Theme.of(context).primaryColor,

View file

@ -2,7 +2,6 @@ import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/payment_request.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cw_core/crypto_currency.dart';
@ -167,7 +166,7 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
},
options: [
AddressTextFieldOption.paste,
if (DeviceInfo.instance.isMobile) AddressTextFieldOption.qrCode,
AddressTextFieldOption.qrCode,
AddressTextFieldOption.addressBook
],
buttonColor:

View file

@ -39,7 +39,9 @@ class ConnectionSyncPage extends BasePage {
),
if (dashboardViewModel.hasRescan) ...[
SettingsCellWithArrow(
title: S.current.rescan,
title: dashboardViewModel.hasRescan
? S.current.silent_payments_scanning
: S.current.rescan,
handler: (context) => Navigator.of(context).pushNamed(Routes.rescan),
),
if (DeviceInfo.instance.isMobile && FeatureFlag.isBackgroundSyncEnabled) ...[

View file

@ -96,6 +96,7 @@ class WalletListBody extends StatefulWidget {
class WalletListBodyState extends State<WalletListBody> {
final moneroIcon = Image.asset('assets/images/monero_logo.png', height: 24, width: 24);
final bitcoinIcon = Image.asset('assets/images/bitcoin.png', height: 24, width: 24);
final tBitcoinIcon = Image.asset('assets/images/tbtc.png', height: 24, width: 24);
final litecoinIcon = Image.asset('assets/images/litecoin_icon.png', height: 24, width: 24);
final nonWalletTypeIcon = Image.asset('assets/images/close.png', height: 24, width: 24);
final havenIcon = Image.asset('assets/images/haven_logo.png', height: 24, width: 24);
@ -161,7 +162,10 @@ class WalletListBodyState extends State<WalletListBody> {
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
wallet.isEnabled
? _imageFor(type: wallet.type)
? _imageFor(
type: wallet.type,
isTestnet: wallet.isTestnet,
)
: nonWalletTypeIcon,
SizedBox(width: 10),
Flexible(
@ -296,9 +300,12 @@ class WalletListBodyState extends State<WalletListBody> {
);
}
Image _imageFor({required WalletType type}) {
Image _imageFor({required WalletType type, bool? isTestnet}) {
switch (type) {
case WalletType.bitcoin:
if (isTestnet == true) {
return tBitcoinIcon;
}
return bitcoinIcon;
case WalletType.monero:
return moneroIcon;

View file

@ -1,6 +1,5 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
@ -134,7 +133,8 @@ class AddressTextField extends StatelessWidget {
),
)),
],
if (this.options.contains(AddressTextFieldOption.qrCode)) ...[
if (this.options.contains(AddressTextFieldOption.qrCode) &&
DeviceInfo.instance.isMobile) ...[
Container(
width: prefixIconWidth,
height: prefixIconHeight,
@ -194,7 +194,7 @@ class AddressTextField extends StatelessWidget {
Future<void> _presentQRScanner(BuildContext context) async {
bool isCameraPermissionGranted =
await PermissionHandler.checkPermission(Permission.camera, context);
await PermissionHandler.checkPermission(Permission.camera, context);
if (!isCameraPermissionGranted) return;
final code = await presentQRScanner();
if (code.isEmpty) {

View file

@ -12,13 +12,15 @@ class BlockchainHeightWidget extends StatefulWidget {
this.onHeightChange,
this.focusNode,
this.onHeightOrDateEntered,
this.hasDatePicker = true})
: super(key: key);
this.hasDatePicker = true,
this.isSilentPaymentsScan = false,
}) : super(key: key);
final Function(int)? onHeightChange;
final Function(bool)? onHeightOrDateEntered;
final FocusNode? focusNode;
final bool hasDatePicker;
final bool isSilentPaymentsScan;
@override
State<StatefulWidget> createState() => BlockchainHeightState();
@ -64,9 +66,10 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
child: BaseTextFormField(
focusNode: widget.focusNode,
controller: restoreHeightController,
keyboardType: TextInputType.numberWithOptions(
signed: false, decimal: false),
hintText: S.of(context).widgets_restore_from_blockheight,
keyboardType: TextInputType.numberWithOptions(signed: false, decimal: false),
hintText: widget.isSilentPaymentsScan
? S.of(context).silent_payments_scan_from_height
: S.of(context).widgets_restore_from_blockheight,
)))
],
),
@ -78,8 +81,7 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.w500,
color:
Theme.of(context).extension<CakeTextTheme>()!.titleColor),
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
),
),
Row(
@ -91,7 +93,9 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
child: IgnorePointer(
child: BaseTextFormField(
controller: dateController,
hintText: S.of(context).widgets_restore_from_date,
hintText: widget.isSilentPaymentsScan
? S.of(context).silent_payments_scan_from_date
: S.of(context).widgets_restore_from_date,
)),
),
))
@ -100,13 +104,12 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
Padding(
padding: EdgeInsets.only(left: 40, right: 40, top: 24),
child: Text(
S.of(context).restore_from_date_or_blockheight,
widget.isSilentPaymentsScan
? S.of(context).silent_payments_scan_from_date_or_blockheight
: S.of(context).restore_from_date_or_blockheight,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.normal,
color: Theme.of(context).hintColor
),
fontSize: 12, fontWeight: FontWeight.normal, color: Theme.of(context).hintColor),
),
)
]

View file

@ -46,8 +46,6 @@ abstract class BalanceViewModelBase with Store {
: isReversing = false,
isShowCard = appStore.wallet!.walletInfo.isShowIntroCakePayCard,
wallet = appStore.wallet! {
silentPaymentsScanningActive = hasSilentPayments && bitcoin!.getScanningActive(wallet);
reaction((_) => appStore.wallet, _onWalletChange);
}
@ -66,17 +64,6 @@ abstract class BalanceViewModelBase with Store {
@computed
bool get hasSilentPayments => wallet.type == WalletType.bitcoin;
@observable
bool silentPaymentsScanningActive = false;
@action
void setSilentPaymentsScanning(bool active) {
if (hasSilentPayments) {
bitcoin!.setScanningActive(wallet, active);
silentPaymentsScanningActive = active;
}
}
@computed
double get price {
final price = fiatConvertationStore.prices[appStore.wallet!.currency];

View file

@ -201,6 +201,14 @@ abstract class DashboardViewModelBase with Store {
return true;
});
if (hasSilentPayments) {
silentPaymentsScanningActive = bitcoin!.getScanningActive(wallet);
reaction((_) => wallet.syncStatus, (SyncStatus syncStatus) {
silentPaymentsScanningActive = bitcoin!.getScanningActive(wallet);
});
}
}
@observable
@ -287,14 +295,33 @@ abstract class DashboardViewModelBase with Store {
@observable
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> wallet;
@computed
bool get isTestnet => wallet.type == WalletType.bitcoin && bitcoin!.isTestnet(wallet);
@computed
bool get hasRescan =>
(wallet.type == WalletType.bitcoin && bitcoin!.hasSelectedSilentPayments(wallet)) ||
wallet.type == WalletType.bitcoin ||
wallet.type == WalletType.monero ||
wallet.type == WalletType.haven;
@computed
bool get hasSilentPayments => hasRescan && wallet.type == WalletType.bitcoin;
final KeyService keyService;
final SharedPreferences sharedPreferences;
@observable
bool silentPaymentsScanningActive = false;
@action
void setSilentPaymentsScanning(bool active) {
silentPaymentsScanningActive = active;
if (hasSilentPayments) {
bitcoin!.setScanningActive(wallet, active);
}
}
BalanceViewModel balanceViewModel;
AppStore appStore;

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:mobx/mobx.dart';
@ -21,6 +22,9 @@ abstract class RescanViewModelBase with Store {
@observable
bool isButtonEnabled;
@computed
bool get isSilentPaymentsScan => bitcoin!.hasSelectedSilentPayments(_wallet);
@action
Future<void> rescanCurrentWallet({required int restoreHeight}) async {
state = RescanWalletState.rescaning;

View file

@ -183,6 +183,8 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
}) : _baseItems = <ListItem>[],
selectedCurrency = walletTypeToCryptoCurrency(appStore.wallet!.type),
_cryptoNumberFormat = NumberFormat(_cryptoNumberPattern),
hasAccounts =
appStore.wallet!.type == WalletType.monero || appStore.wallet!.type == WalletType.haven,
amount = '',
_settingsStore = appStore.settingsStore,
super(appStore: appStore) {
@ -194,8 +196,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
_init();
selectedCurrency = walletTypeToCryptoCurrency(wallet.type);
_hasAccounts =
hasSilentAddresses || wallet.type == WalletType.monero || wallet.type == WalletType.haven;
hasAccounts = wallet.type == WalletType.monero || wallet.type == WalletType.haven;
}
static const String _cryptoNumberPattern = '0.00000000';
@ -364,10 +365,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
}
@observable
bool _hasAccounts = false;
@computed
bool get hasAccounts => _hasAccounts;
bool hasAccounts;
@computed
String get accountLabel {
@ -382,21 +380,8 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
return '';
}
@observable
// ignore: prefer_final_fields
bool? _hasSilentAddresses = null;
@computed
bool get hasSilentAddresses => _hasSilentAddresses ?? wallet.type == WalletType.bitcoin;
// @computed
// bool get hasSilentAddresses =>
// _hasSilentAddresses ??
// wallet.type == WalletType.bitcoin &&
// wallet.walletAddresses.addressPageType == btc.AddressType.p2sp;
@computed
bool get hasAddressList =>
hasSilentAddresses ||
wallet.type == WalletType.monero ||
wallet.type == WalletType.haven ||
wallet.type == WalletType.bitcoinCash ||
@ -409,9 +394,12 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
wallet.type == WalletType.litecoin ||
wallet.type == WalletType.bitcoinCash;
@computed
bool get isSilentPayments => bitcoin!.hasSelectedSilentPayments(wallet);
@computed
bool get isAutoGenerateSubaddressEnabled => wallet.type == WalletType.bitcoin
? !bitcoin!.hasSelectedSilentPayments(wallet)
? !isSilentPayments
: _settingsStore.autoGenerateSubaddressStatus != AutoGenerateSubaddressStatus.disabled;
List<ListItem> _baseItems;

View file

@ -7,6 +7,7 @@ class WalletListItem {
required this.key,
this.isCurrent = false,
this.isEnabled = true,
this.isTestnet = false,
});
final String name;
@ -14,4 +15,5 @@ class WalletListItem {
final bool isCurrent;
final dynamic key;
final bool isEnabled;
final bool isTestnet;
}

View file

@ -61,6 +61,7 @@ abstract class WalletListViewModelBase with Store {
key: info.key,
isCurrent: info.name == _appStore.wallet?.name && info.type == _appStore.wallet?.type,
isEnabled: availableWalletTypes.contains(info.type),
isTestnet: info.network?.toLowerCase().contains('testnet') ?? false,
),
),
);

View file

@ -610,6 +610,9 @@
"sign_up": "اشتراك",
"signTransaction": " ﺔﻠﻣﺎﻌﻤﻟﺍ ﻊﻴﻗﻮﺗ",
"signup_for_card_accept_terms": "قم بالتسجيل للحصول على البطاقة وقبول الشروط.",
"silent_payments_scan_from_date": "فحص من التاريخ",
"silent_payments_scan_from_date_or_blockheight": "يرجى إدخال ارتفاع الكتلة الذي تريد بدء المسح الضوئي للمدفوعات الصامتة الواردة ، أو استخدام التاريخ بدلاً من ذلك. يمكنك اختيار ما إذا كانت المحفظة تواصل مسح كل كتلة ، أو تتحقق فقط من الارتفاع المحدد.",
"silent_payments_scan_from_height": "فحص من ارتفاع الكتلة",
"silent_payments_scanning": "المدفوعات الصامتة المسح الضوئي",
"slidable": "قابل للانزلاق",
"sort_by": "ترتيب حسب",
@ -646,6 +649,7 @@
"syncing_wallet_alert_title": "محفظتك تتم مزامنتها",
"template": "قالب",
"template_name": "اسم القالب",
"testnet_coins_no_value": "عملات TestNet ليس لها قيمة",
"third_intro_content": "يعيش Yats خارج Cake Wallet أيضًا. يمكن استبدال أي عنوان محفظة على وجه الأرض بـ Yat!",
"third_intro_title": "يتماشي Yat بلطف مع الآخرين",
"thorchain_taproot_address_not_supported": "لا يدعم مزود Thorchain عناوين Taproot. يرجى تغيير العنوان أو تحديد مزود مختلف.",

View file

@ -610,6 +610,9 @@
"sign_up": "Регистрация",
"signTransaction": "Подпишете транзакция",
"signup_for_card_accept_terms": "Регистрайте се за картата и приемете условията.",
"silent_payments_scan_from_date": "Сканиране от дата",
"silent_payments_scan_from_date_or_blockheight": "Моля, въведете височината на блока, която искате да започнете да сканирате за входящи безшумни плащания, или вместо това използвайте датата. Можете да изберете дали портфейлът продължава да сканира всеки блок или проверява само определената височина.",
"silent_payments_scan_from_height": "Сканиране от височината на блока",
"silent_payments_scanning": "Безшумни плащания за сканиране",
"slidable": "Плъзгащ се",
"sort_by": "Сортирай по",
@ -646,6 +649,7 @@
"syncing_wallet_alert_title": "Вашият портфейл се синхронизира",
"template": "Шаблон",
"template_name": "Име на шаблон",
"testnet_coins_no_value": "Тестовите монети нямат стойност",
"third_intro_content": "Yats също живее извън Cake Wallet. Всеки адрес на портфейл може да бъде заменен с Yat!",
"third_intro_title": "Yat добре се сработва с други",
"thorchain_taproot_address_not_supported": "Доставчикът на Thorchain не поддържа адреси на TapRoot. Моля, променете адреса или изберете друг доставчик.",

View file

@ -610,6 +610,9 @@
"sign_up": "Registrovat se",
"signTransaction": "Podepsat transakci",
"signup_for_card_accept_terms": "Zaregistrujte se pro kartu a souhlaste s podmínkami.",
"silent_payments_scan_from_date": "Skenovat od data",
"silent_payments_scan_from_date_or_blockheight": "Zadejte výšku bloku, kterou chcete začít skenovat, zda jsou přicházející tiché platby, nebo místo toho použijte datum. Můžete si vybrat, zda peněženka pokračuje v skenování každého bloku nebo zkontroluje pouze zadanou výšku.",
"silent_payments_scan_from_height": "Skenování z výšky bloku",
"silent_payments_scanning": "Skenování tichých plateb",
"slidable": "Posuvné",
"sort_by": "Seřazeno podle",
@ -646,6 +649,7 @@
"syncing_wallet_alert_title": "Vaše peněženka se synchronizuje",
"template": "Šablona",
"template_name": "Název šablony",
"testnet_coins_no_value": "Mince TestNet nemají žádnou hodnotu",
"third_intro_content": "Yat existuje i mimo Cake Wallet. Jakákoliv adresa peněženky na světě může být nahrazena Yatem!",
"third_intro_title": "Yat dobře spolupracuje s ostatními",
"thorchain_taproot_address_not_supported": "Poskytovatel Thorchain nepodporuje adresy Taproot. Změňte adresu nebo vyberte jiného poskytovatele.",

View file

@ -611,6 +611,9 @@
"sign_up": "Anmelden",
"signTransaction": "Transaktion unterzeichnen",
"signup_for_card_accept_terms": "Melden Sie sich für die Karte an und akzeptieren Sie die Bedingungen.",
"silent_payments_scan_from_date": "Scan ab Datum",
"silent_payments_scan_from_date_or_blockheight": "Bitte geben Sie die Blockhöhe ein, die Sie für eingehende stille Zahlungen scannen möchten, oder verwenden Sie stattdessen das Datum. Sie können wählen, ob die Brieftasche jeden Block scannt oder nur die angegebene Höhe überprüft.",
"silent_payments_scan_from_height": "Scan aus der Blockhöhe scannen",
"silent_payments_scanning": "Stille Zahlungen scannen",
"slidable": "Verschiebbar",
"sort_by": "Sortiere nach",
@ -647,6 +650,7 @@
"syncing_wallet_alert_title": "Ihr Wallet wird synchronisiert",
"template": "Vorlage",
"template_name": "Vorlagenname",
"testnet_coins_no_value": "Testnet -Münzen haben keinen Wert",
"third_intro_content": "Yats leben auch außerhalb von Cake Wallet. Jede Wallet-Adresse auf der Welt kann durch ein Yat ersetzt werden!",
"third_intro_title": "Yat spielt gut mit anderen",
"thorchain_taproot_address_not_supported": "Der Thorchain -Anbieter unterstützt keine Taproot -Adressen. Bitte ändern Sie die Adresse oder wählen Sie einen anderen Anbieter aus.",

View file

@ -610,6 +610,9 @@
"sign_up": "Sign Up",
"signTransaction": "Sign Transaction",
"signup_for_card_accept_terms": "Sign up for the card and accept the terms.",
"silent_payments_scan_from_date": "Scan from date",
"silent_payments_scan_from_date_or_blockheight": "Please enter the block height you want to start scanning for incoming silent payments, or, use the date instead. You can choose if the wallet continues scanning every block, or checks only the specified height.",
"silent_payments_scan_from_height": "Scan from block height",
"silent_payments_scanning": "Silent Payments Scanning",
"slidable": "Slidable",
"sort_by": "Sort by",
@ -646,6 +649,7 @@
"syncing_wallet_alert_title": "Your wallet is syncing",
"template": "Template",
"template_name": "Template Name",
"testnet_coins_no_value": "Testnet coins have no value",
"third_intro_content": "Yats live outside of Cake Wallet, too. Any wallet address on earth can be replaced with a Yat!",
"third_intro_title": "Yat plays nicely with others",
"thorchain_taproot_address_not_supported": "The ThorChain provider does not support Taproot addresses. Please change the address or select a different provider.",

View file

@ -611,6 +611,9 @@
"sign_up": "Registrarse",
"signTransaction": "Firmar transacción",
"signup_for_card_accept_terms": "Regístrese para obtener la tarjeta y acepte los términos.",
"silent_payments_scan_from_date": "Escanear desde la fecha",
"silent_payments_scan_from_date_or_blockheight": "Ingrese la altura del bloque que desea comenzar a escanear para pagos silenciosos entrantes, o use la fecha en su lugar. Puede elegir si la billetera continúa escaneando cada bloque, o verifica solo la altura especificada.",
"silent_payments_scan_from_height": "Escanear desde la altura del bloque",
"silent_payments_scanning": "Escaneo de pagos silenciosos",
"slidable": "deslizable",
"sort_by": "Ordenar por",
@ -647,6 +650,7 @@
"syncing_wallet_alert_title": "Tu billetera se está sincronizando",
"template": "Plantilla",
"template_name": "Nombre de la plantilla",
"testnet_coins_no_value": "Las monedas de prueba no tienen valor",
"third_intro_content": "Los Yats también viven fuera de Cake Wallet. Cualquier dirección de billetera en la tierra se puede reemplazar con un Yat!",
"third_intro_title": "Yat juega muy bien con otras",
"thorchain_taproot_address_not_supported": "El proveedor de Thorchain no admite las direcciones de Taproot. Cambie la dirección o seleccione un proveedor diferente.",

View file

@ -610,6 +610,9 @@
"sign_up": "S'inscrire",
"signTransaction": "Signer une transaction",
"signup_for_card_accept_terms": "Inscrivez-vous pour la carte et acceptez les conditions.",
"silent_payments_scan_from_date": "Analyser à partir de la date",
"silent_payments_scan_from_date_or_blockheight": "Veuillez saisir la hauteur du bloc que vous souhaitez commencer à scanner pour les paiements silencieux entrants, ou utilisez la date à la place. Vous pouvez choisir si le portefeuille continue de numériser chaque bloc ou ne vérifie que la hauteur spécifiée.",
"silent_payments_scan_from_height": "Scan à partir de la hauteur du bloc",
"silent_payments_scanning": "Payments silencieux SCANNING",
"slidable": "Glissable",
"sort_by": "Trier par",
@ -646,6 +649,7 @@
"syncing_wallet_alert_title": "Votre portefeuille (wallet) est en cours de synchronisation",
"template": "Modèle",
"template_name": "Nom du modèle",
"testnet_coins_no_value": "Les pièces TestNet n'ont aucune valeur",
"third_intro_content": "Les Yats existent aussi en dehors de Cake Wallet. Toute adresse sur terre peut être remplacée par un Yat !",
"third_intro_title": "Yat est universel",
"thorchain_taproot_address_not_supported": "Le fournisseur de Thorchain ne prend pas en charge les adresses de tapoot. Veuillez modifier l'adresse ou sélectionner un autre fournisseur.",

View file

@ -612,6 +612,9 @@
"sign_up": "Shiga",
"signTransaction": "Sa hannu Ma'amala",
"signup_for_card_accept_terms": "Yi rajista don katin kuma karɓi sharuɗɗan.",
"silent_payments_scan_from_date": "Scan daga kwanan wata",
"silent_payments_scan_from_date_or_blockheight": "Da fatan za a shigar da toshe wurin da kake son fara bincika don biyan silins mai shigowa, ko, yi amfani da kwanan wata. Zaka iya zabar idan walat ɗin ya ci gaba da bincika kowane toshe, ko duba tsinkaye da aka ƙayyade.",
"silent_payments_scan_from_height": "Scan daga tsayin daka",
"silent_payments_scanning": "Silent biya scanning",
"slidable": "Mai iya zamewa",
"sort_by": "Kasa",
@ -648,6 +651,7 @@
"syncing_wallet_alert_title": "Walat ɗin ku yana aiki tare",
"template": "Samfura",
"template_name": "Sunan Samfura",
"testnet_coins_no_value": "TalkNet tsabar kudi ba su da darajar",
"third_intro_content": "Yats suna zaune a wajen Kek Wallet, kuma. Ana iya maye gurbin kowane adireshin walat a duniya da Yat!",
"third_intro_title": "Yat yana wasa da kyau tare da wasu",
"thorchain_taproot_address_not_supported": "Mai ba da tallafi na ThorChain baya goyan bayan adreshin taproot. Da fatan za a canza adireshin ko zaɓi mai bayarwa daban.",

View file

@ -612,6 +612,9 @@
"sign_up": "साइन अप करें",
"signTransaction": "लेन-देन पर हस्ताक्षर करें",
"signup_for_card_accept_terms": "कार्ड के लिए साइन अप करें और शर्तें स्वीकार करें।",
"silent_payments_scan_from_date": "तिथि से स्कैन करना",
"silent_payments_scan_from_date_or_blockheight": "कृपया उस ब्लॉक ऊंचाई दर्ज करें जिसे आप आने वाले मूक भुगतान के लिए स्कैन करना शुरू करना चाहते हैं, या, इसके बजाय तारीख का उपयोग करें। आप चुन सकते हैं कि क्या वॉलेट हर ब्लॉक को स्कैन करना जारी रखता है, या केवल निर्दिष्ट ऊंचाई की जांच करता है।",
"silent_payments_scan_from_height": "ब्लॉक ऊंचाई से स्कैन करें",
"silent_payments_scanning": "मूक भुगतान स्कैनिंग",
"slidable": "फिसलने लायक",
"sort_by": "इसके अनुसार क्रमबद्ध करें",
@ -648,6 +651,7 @@
"syncing_wallet_alert_title": "आपका वॉलेट सिंक हो रहा है",
"template": "खाका",
"template_name": "टेम्पलेट नाम",
"testnet_coins_no_value": "टेस्टनेट सिक्कों का कोई मूल्य नहीं है",
"third_intro_content": "Yats Cake Wallet के बाहर भी रहता है। धरती पर किसी भी वॉलेट पते को Yat से बदला जा सकता है!",
"third_intro_title": "Yat दूसरों के साथ अच्छा खेलता है",
"thorchain_taproot_address_not_supported": "थोरचेन प्रदाता टैपरोट पते का समर्थन नहीं करता है। कृपया पता बदलें या एक अलग प्रदाता का चयन करें।",

View file

@ -610,6 +610,9 @@
"sign_up": "Prijavite se",
"signTransaction": "Potpišite transakciju",
"signup_for_card_accept_terms": "Prijavite se za karticu i prihvatite uvjete.",
"silent_payments_scan_from_date": "Skeniranje iz datuma",
"silent_payments_scan_from_date_or_blockheight": "Unesite visinu bloka koju želite započeti skeniranje za dolazna tiha plaćanja ili umjesto toga upotrijebite datum. Možete odabrati da li novčanik nastavlja skenirati svaki blok ili provjerava samo navedenu visinu.",
"silent_payments_scan_from_height": "Skeniranje s visine bloka",
"silent_payments_scanning": "Skeniranje tihih plaćanja",
"slidable": "Klizna",
"sort_by": "Poredaj po",
@ -646,6 +649,7 @@
"syncing_wallet_alert_title": "Vaš novčanik se sinkronizira",
"template": "Predložak",
"template_name": "Naziv predloška",
"testnet_coins_no_value": "TestNet kovanice nemaju vrijednost",
"third_intro_content": "Yats žive i izvan Cake Wallet -a. Bilo koja adresa novčanika na svijetu može se zamijeniti Yat!",
"third_intro_title": "Yat se lijepo igra s drugima",
"thorchain_taproot_address_not_supported": "Thorchain pružatelj ne podržava Taproot adrese. Promijenite adresu ili odaberite drugog davatelja usluga.",

View file

@ -613,6 +613,9 @@
"sign_up": "Daftar",
"signTransaction": "Tandatangani Transaksi",
"signup_for_card_accept_terms": "Daftar untuk kartu dan terima syarat dan ketentuan.",
"silent_payments_scan_from_date": "Pindai dari tanggal",
"silent_payments_scan_from_date_or_blockheight": "Harap masukkan ketinggian blok yang ingin Anda mulai pemindaian untuk pembayaran diam yang masuk, atau, gunakan tanggal sebagai gantinya. Anda dapat memilih jika dompet terus memindai setiap blok, atau memeriksa hanya ketinggian yang ditentukan.",
"silent_payments_scan_from_height": "Pindai dari Tinggi Blok",
"silent_payments_scanning": "Pemindaian pembayaran diam",
"slidable": "Dapat digeser",
"sort_by": "Sortir dengan",
@ -649,6 +652,7 @@
"syncing_wallet_alert_title": "Dompet Anda sedang disinkronkan",
"template": "Template",
"template_name": "Nama Templat",
"testnet_coins_no_value": "Koin TestNet tidak memiliki nilai",
"third_intro_content": "Yats hidup di luar Cake Wallet juga. Setiap alamat dompet di dunia dapat diganti dengan Yat!",
"third_intro_title": "Yat bermain baik dengan yang lain",
"thorchain_taproot_address_not_supported": "Penyedia Thorchain tidak mendukung alamat Taproot. Harap ubah alamatnya atau pilih penyedia yang berbeda.",

View file

@ -612,6 +612,9 @@
"sign_up": "Registrati",
"signTransaction": "Firma la transazione",
"signup_for_card_accept_terms": "Registrati per la carta e accetta i termini.",
"silent_payments_scan_from_date": "Scansionare dalla data",
"silent_payments_scan_from_date_or_blockheight": "Inserisci l'altezza del blocco che si desidera iniziare la scansione per i pagamenti silenziosi in arrivo o, utilizza invece la data. Puoi scegliere se il portafoglio continua a scansionare ogni blocco o controlla solo l'altezza specificata.",
"silent_payments_scan_from_height": "Scansione dall'altezza del blocco",
"silent_payments_scanning": "Scansione di pagamenti silenziosi",
"slidable": "Scorrevole",
"sort_by": "Ordina per",
@ -648,6 +651,7 @@
"syncing_wallet_alert_title": "Il tuo portafoglio si sta sincronizzando",
"template": "Modello",
"template_name": "Nome modello",
"testnet_coins_no_value": "Le monete TestNet non hanno valore",
"third_intro_content": "Yat può funzionare anche fuori da Cake Wallet. Qualsiasi indirizzo di portafoglio sulla terra può essere sostituito con uno Yat!",
"third_intro_title": "Yat gioca bene con gli altri",
"thorchain_taproot_address_not_supported": "Il provider di Thorchain non supporta gli indirizzi di TapRoot. Si prega di modificare l'indirizzo o selezionare un fornitore diverso.",

View file

@ -611,6 +611,9 @@
"sign_up": "サインアップ",
"signTransaction": "トランザクションに署名する",
"signup_for_card_accept_terms": "カードにサインアップして、利用規約に同意してください。",
"silent_payments_scan_from_date": "日付からスキャンします",
"silent_payments_scan_from_date_or_blockheight": "着信のサイレント決済のためにスキャンを開始するブロックの高さを入力するか、代わりに日付を使用してください。ウォレットがすべてのブロックをスキャンし続けるか、指定された高さのみをチェックするかどうかを選択できます。",
"silent_payments_scan_from_height": "ブロックの高さからスキャンします",
"silent_payments_scanning": "サイレントペイメントスキャン",
"slidable": "スライド可能",
"sort_by": "並び替え",
@ -647,6 +650,7 @@
"syncing_wallet_alert_title": "ウォレットは同期中です",
"template": "テンプレート",
"template_name": "テンプレート名",
"testnet_coins_no_value": "テストネットコインには価値がありません",
"third_intro_content": "YatsはCakeWalletの外にも住んでいます。 地球上のどのウォレットアドレスもYatに置き換えることができます",
"third_intro_title": "Yatは他の人とうまく遊ぶ",
"thorchain_taproot_address_not_supported": "Thorchainプロバイダーは、TapRootアドレスをサポートしていません。アドレスを変更するか、別のプロバイダーを選択してください。",

View file

@ -611,6 +611,9 @@
"sign_up": "가입",
"signTransaction": "거래 서명",
"signup_for_card_accept_terms": "카드에 가입하고 약관에 동의합니다.",
"silent_payments_scan_from_date": "날짜부터 스캔하십시오",
"silent_payments_scan_from_date_or_blockheight": "들어오는 사일런트 결제를 위해 스캔을 시작하려는 블록 높이를 입력하거나 대신 날짜를 사용하십시오. 지갑이 모든 블록을 계속 스캔하는지 여부를 선택하거나 지정된 높이 만 확인할 수 있습니다.",
"silent_payments_scan_from_height": "블록 높이에서 스캔하십시오",
"silent_payments_scanning": "조용한 지불 스캔",
"slidable": "슬라이딩 가능",
"sort_by": "정렬 기준",
@ -647,6 +650,7 @@
"syncing_wallet_alert_title": "지갑 동기화 중",
"template": "주형",
"template_name": "템플릿 이름",
"testnet_coins_no_value": "Testnet 코인은 가치가 없습니다",
"third_intro_content": "Yats는 Cake Wallet 밖에서도 살고 있습니다. 지구상의 모든 지갑 주소는 Yat!",
"third_intro_title": "Yat는 다른 사람들과 잘 놉니다.",
"thorchain_taproot_address_not_supported": "Thorchain 제공 업체는 Taproot 주소를 지원하지 않습니다. 주소를 변경하거나 다른 공급자를 선택하십시오.",

View file

@ -610,6 +610,9 @@
"sign_up": "ဆိုင်းအပ်",
"signTransaction": "ငွေလွှဲဝင်ပါ။",
"signup_for_card_accept_terms": "ကတ်အတွက် စာရင်းသွင်းပြီး စည်းကမ်းချက်များကို လက်ခံပါ။",
"silent_payments_scan_from_date": "ရက်စွဲမှစကင်ဖတ်ပါ",
"silent_payments_scan_from_date_or_blockheight": "ကျေးဇူးပြု. သင်ဝင်လာသောအသံတိတ်ငွေပေးချေမှုအတွက်သင်စကင်ဖတ်စစ်ဆေးလိုသည့်အမြင့်ကိုဖြည့်ပါ။ သို့မဟုတ်နေ့စွဲကိုသုံးပါ။ Wallet သည်လုပ်ကွက်တိုင်းကိုဆက်လက်စကင်ဖတ်စစ်ဆေးပါကသို့မဟုတ်သတ်မှတ်ထားသောအမြင့်ကိုသာစစ်ဆေးပါကသင်ရွေးချယ်နိုင်သည်။",
"silent_payments_scan_from_height": "ပိတ်ပင်တားဆီးမှုအမြင့်ကနေ scan",
"silent_payments_scanning": "အသံတိတ်ငွေပေးချေမှု scanning",
"slidable": "လျှောချနိုင်သည်။",
"sort_by": "အလိုက်စဥ်သည်",
@ -646,6 +649,7 @@
"syncing_wallet_alert_title": "သင့်ပိုက်ဆံအိတ်ကို စင့်ခ်လုပ်နေပါသည်။",
"template": "ပုံစံခွက်",
"template_name": "နမူနာပုံစံ",
"testnet_coins_no_value": "Testnet ဒင်္ဂါးပြားတန်ဖိုးမရှိပါ",
"third_intro_content": "Yats သည် Cake Wallet အပြင်ဘက်တွင် နေထိုင်ပါသည်။ ကမ္ဘာပေါ်ရှိ မည်သည့်ပိုက်ဆံအိတ်လိပ်စာကို Yat ဖြင့် အစားထိုးနိုင်ပါသည်။",
"third_intro_title": "Yat သည် အခြားသူများနှင့် ကောင်းစွာကစားသည်။",
"thorchain_taproot_address_not_supported": "Thorchain Provider သည် Taproot လိပ်စာများကိုမထောက်ခံပါ။ ကျေးဇူးပြု. လိပ်စာကိုပြောင်းပါသို့မဟုတ်အခြားပံ့ပိုးပေးသူကိုရွေးချယ်ပါ။",

View file

@ -610,6 +610,9 @@
"sign_up": "Aanmelden",
"signTransaction": "Transactie ondertekenen",
"signup_for_card_accept_terms": "Meld je aan voor de kaart en accepteer de voorwaarden.",
"silent_payments_scan_from_date": "Scan vanaf datum",
"silent_payments_scan_from_date_or_blockheight": "Voer de blokhoogte in die u wilt beginnen met scannen op inkomende stille betalingen, of gebruik in plaats daarvan de datum. U kunt kiezen of de portemonnee elk blok blijft scannen of alleen de opgegeven hoogte controleert.",
"silent_payments_scan_from_height": "Scan van blokhoogte",
"silent_payments_scanning": "Stille betalingen scannen",
"slidable": "Verschuifbaar",
"sort_by": "Sorteer op",
@ -646,6 +649,7 @@
"syncing_wallet_alert_title": "Uw portemonnee wordt gesynchroniseerd",
"template": "Sjabloon",
"template_name": "Sjabloonnaam",
"testnet_coins_no_value": "Testnet -munten hebben geen waarde",
"third_intro_content": "Yats wonen ook buiten Cake Wallet. Elk portemonnee-adres op aarde kan worden vervangen door een Yat!",
"third_intro_title": "Yat speelt leuk met anderen",
"thorchain_taproot_address_not_supported": "De Thorchain -provider ondersteunt geen Taprooot -adressen. Wijzig het adres of selecteer een andere provider.",

View file

@ -610,6 +610,9 @@
"sign_up": "Zarejestruj się",
"signTransaction": "Podpisz transakcję",
"signup_for_card_accept_terms": "Zarejestruj się, aby otrzymać kartę i zaakceptuj warunki.",
"silent_payments_scan_from_date": "Skanuj z daty",
"silent_payments_scan_from_date_or_blockheight": "Wprowadź wysokość bloku, którą chcesz rozpocząć skanowanie w poszukiwaniu cichej płatności lub zamiast tego skorzystaj z daty. Możesz wybrać, czy portfel kontynuuje skanowanie każdego bloku, lub sprawdza tylko określoną wysokość.",
"silent_payments_scan_from_height": "Skanuj z wysokości bloku",
"silent_payments_scanning": "Skanowanie cichych płatności",
"slidable": "Przesuwne",
"sort_by": "Sortuj według",
@ -646,6 +649,7 @@
"syncing_wallet_alert_title": "Twój portfel się synchronizuje",
"template": "Szablon",
"template_name": "Nazwa szablonu",
"testnet_coins_no_value": "Monety testowe nie mają wartości",
"third_intro_content": "Yats mieszkają również poza Cake Wallet. Każdy adres portfela na ziemi można zastąpić Yat!",
"third_intro_title": "Yat ładnie bawi się z innymi",
"thorchain_taproot_address_not_supported": "Dostawca Thorchain nie obsługuje adresów TAPROOT. Zmień adres lub wybierz innego dostawcę.",

View file

@ -612,7 +612,10 @@
"sign_up": "Inscrever-se",
"signTransaction": "Assinar transação",
"signup_for_card_accept_terms": "Cadastre-se no cartão e aceite os termos.",
"silent_payments_scanning": "Scanear Pagamentos Silenciosos",
"silent_payments_scan_from_date": "Escanear a partir da data",
"silent_payments_scan_from_date_or_blockheight": "Por favor, insira a altura do bloco que deseja iniciar o escaneamento para obter pagamentos silenciosos ou use a data. Você pode escolher se a carteira continua digitalizando cada bloco ou verifica apenas a altura especificada.",
"silent_payments_scan_from_height": "Escanear a partir da altura do bloco",
"silent_payments_scanning": "Escanear Pagamentos Silenciosos",
"slidable": "Deslizável",
"sort_by": "Ordenar por",
"spend_key_private": "Chave de gastos (privada)",
@ -648,6 +651,7 @@
"syncing_wallet_alert_title": "Sua carteira está sincronizando",
"template": "Modelo",
"template_name": "Nome do modelo",
"testnet_coins_no_value": "As moedas de teste não têm valor",
"third_intro_content": "Yats também mora fora da Cake Wallet. Qualquer endereço de carteira na Terra pode ser substituído por um Yat!",
"third_intro_title": "Yat joga bem com os outros",
"thorchain_taproot_address_not_supported": "O provedor de Thorchain não suporta endereços de raiz de Tap. Altere o endereço ou selecione um provedor diferente.",
@ -807,4 +811,4 @@
"you_will_get": "Converter para",
"you_will_send": "Converter de",
"yy": "aa"
}
}

View file

@ -611,6 +611,9 @@
"sign_up": "Зарегистрироваться",
"signTransaction": "Подписать транзакцию",
"signup_for_card_accept_terms": "Подпишитесь на карту и примите условия.",
"silent_payments_scan_from_date": "Сканирование с даты",
"silent_payments_scan_from_date_or_blockheight": "Пожалуйста, введите высоту блока, которую вы хотите начать сканирование для входящих молчаливых платежей, или вместо этого используйте дату. Вы можете выбрать, продолжает ли кошелек сканировать каждый блок или проверять только указанную высоту.",
"silent_payments_scan_from_height": "Сканирование с высоты блока",
"silent_payments_scanning": "Сканирование безмолвных платежей",
"slidable": "Скользящий",
"sort_by": "Сортировать по",
@ -647,6 +650,7 @@
"syncing_wallet_alert_title": "Ваш кошелек синхронизируется",
"template": "Шаблон",
"template_name": "Имя Шаблона",
"testnet_coins_no_value": "Монеты теста не имеют значения",
"third_intro_content": "Yat находятся за пределами Cake Wallet. Любой адрес кошелька на земле можно заменить на Yat!",
"third_intro_title": "Yat хорошо взаимодействует с другими",
"thorchain_taproot_address_not_supported": "Поставщик Thorchain не поддерживает адреса taproot. Пожалуйста, измените адрес или выберите другого поставщика.",

View file

@ -610,6 +610,9 @@
"sign_up": "สมัครสมาชิก",
"signTransaction": "ลงนามในการทำธุรกรรม",
"signup_for_card_accept_terms": "ลงทะเบียนสำหรับบัตรและยอมรับเงื่อนไข",
"silent_payments_scan_from_date": "สแกนตั้งแต่วันที่",
"silent_payments_scan_from_date_or_blockheight": "โปรดป้อนความสูงของบล็อกที่คุณต้องการเริ่มการสแกนสำหรับการชำระเงินแบบเงียบ ๆ หรือใช้วันที่แทน คุณสามารถเลือกได้ว่ากระเป๋าเงินยังคงสแกนทุกบล็อกหรือตรวจสอบความสูงที่ระบุเท่านั้น",
"silent_payments_scan_from_height": "สแกนจากความสูงของบล็อก",
"silent_payments_scanning": "การสแกนการชำระเงินแบบเงียบ",
"slidable": "เลื่อนได้",
"sort_by": "เรียงตาม",
@ -646,6 +649,7 @@
"syncing_wallet_alert_title": "กระเป๋าสตางค์ของคุณกำลังซิงค์",
"template": "แบบฟอร์ม",
"template_name": "ชื่อแม่แบบ",
"testnet_coins_no_value": "Testnet Coins ไม่มีค่า",
"third_intro_content": "Yat อาศัยอยู่นอก Cake Wallet ด้วย ที่อยู่กระเป๋าใดๆ ทั่วโลกสามารถแทนด้วย Yat ได้อีกด้วย!",
"third_intro_title": "Yat ปฏิบัติตนอย่างดีกับผู้อื่น",
"thorchain_taproot_address_not_supported": "ผู้ให้บริการ Thorchain ไม่รองรับที่อยู่ taproot โปรดเปลี่ยนที่อยู่หรือเลือกผู้ให้บริการอื่น",

View file

@ -610,6 +610,9 @@
"sign_up": "Mag -sign up",
"signTransaction": "Mag-sign Transaksyon",
"signup_for_card_accept_terms": "Mag -sign up para sa card at tanggapin ang mga termino.",
"silent_payments_scan_from_date": "I -scan mula sa petsa",
"silent_payments_scan_from_date_or_blockheight": "Mangyaring ipasok ang taas ng block na nais mong simulan ang pag -scan para sa papasok na tahimik na pagbabayad, o, gamitin ang petsa sa halip. Maaari kang pumili kung ang pitaka ay patuloy na pag -scan sa bawat bloke, o suriin lamang ang tinukoy na taas.",
"silent_payments_scan_from_height": "I -scan mula sa taas ng block",
"silent_payments_scanning": "Tahimik na pag -scan ng mga pagbabayad",
"slidable": "Slidable",
"sort_by": "Pag -uri -uriin sa pamamagitan ng",
@ -646,6 +649,7 @@
"syncing_wallet_alert_title": "Ang iyong pitaka ay nag -sync",
"template": "Template",
"template_name": "Pangalan ng Template",
"testnet_coins_no_value": "Ang mga barya ng testnet ay walang halaga",
"third_intro_content": "Ang mga yats ay nakatira sa labas ng cake wallet, din. Ang anumang address ng pitaka sa mundo ay maaaring mapalitan ng isang yat!",
"third_intro_title": "Si Yat ay mahusay na gumaganap sa iba",
"thorchain_taproot_address_not_supported": "Ang Tagabigay ng Thorchain ay hindi sumusuporta sa mga address ng taproot. Mangyaring baguhin ang address o pumili ng ibang provider.",

View file

@ -610,6 +610,9 @@
"sign_up": "Kaydol",
"signTransaction": "İşlem İmzala",
"signup_for_card_accept_terms": "Kart için kaydol ve koşulları kabul et.",
"silent_payments_scan_from_date": "Tarihten tarama",
"silent_payments_scan_from_date_or_blockheight": "Lütfen gelen sessiz ödemeler için taramaya başlamak istediğiniz blok yüksekliğini girin veya bunun yerine tarihi kullanın. Cüzdanın her bloğu taramaya devam edip etmediğini veya yalnızca belirtilen yüksekliği kontrol edip etmediğini seçebilirsiniz.",
"silent_payments_scan_from_height": "Blok yüksekliğinden tarama",
"silent_payments_scanning": "Sessiz Ödemeler Taraması",
"slidable": "kaydırılabilir",
"sort_by": "Göre sırala",
@ -646,6 +649,7 @@
"syncing_wallet_alert_title": "Cüzdanınız senkronize ediliyor",
"template": "Şablon",
"template_name": "şablon adı",
"testnet_coins_no_value": "TestNet paralarının değeri yok",
"third_intro_content": "Yat'lar Cake Wallet'ın dışında da çalışabilir. Dünya üzerindeki herhangi bir cüzdan adresi Yat ile değiştirilebilir!",
"third_intro_title": "Yat diğerleriyle iyi çalışır",
"thorchain_taproot_address_not_supported": "Thorchain sağlayıcısı Taproot adreslerini desteklemiyor. Lütfen adresi değiştirin veya farklı bir sağlayıcı seçin.",

View file

@ -611,6 +611,9 @@
"sign_up": "Зареєструватися",
"signTransaction": "Підписати транзакцію",
"signup_for_card_accept_terms": "Зареєструйтеся на картку та прийміть умови.",
"silent_payments_scan_from_date": "Сканувати з дати",
"silent_payments_scan_from_date_or_blockheight": "Введіть висоту блоку, яку ви хочете почати сканувати для вхідних мовчазних платежів, або скористайтеся датою замість цього. Ви можете вибрати, якщо гаманець продовжує сканувати кожен блок, або перевіряє лише вказану висоту.",
"silent_payments_scan_from_height": "Сканування від висоти блоку",
"silent_payments_scanning": "Мовчазні платежі сканування",
"slidable": "Розсувний",
"sort_by": "Сортувати за",
@ -647,6 +650,7 @@
"syncing_wallet_alert_title": "Ваш гаманець синхронізується",
"template": "Шаблон",
"template_name": "Назва шаблону",
"testnet_coins_no_value": "Монети TestNet не мають значення",
"third_intro_content": "Yat знаходиться за межами Cake Wallet. Будь-яку адресу гаманця на землі можна замінити на Yat!",
"third_intro_title": "Yat добре взаємодіє з іншими",
"thorchain_taproot_address_not_supported": "Постачальник Thorchain не підтримує адреси Taproot. Будь ласка, змініть адресу або виберіть іншого постачальника.",

View file

@ -612,6 +612,9 @@
"sign_up": "سائن اپ",
"signTransaction": "۔ﮟﯾﺮﮐ ﻂﺨﺘﺳﺩ ﺮﭘ ﻦﯾﺩ ﻦﯿﻟ",
"signup_for_card_accept_terms": "کارڈ کے لیے سائن اپ کریں اور شرائط کو قبول کریں۔",
"silent_payments_scan_from_date": "تاریخ سے اسکین کریں",
"silent_payments_scan_from_date_or_blockheight": "براہ کرم بلاک اونچائی میں داخل ہوں جس سے آپ آنے والی خاموش ادائیگیوں کے لئے اسکیننگ شروع کرنا چاہتے ہیں ، یا اس کے بجائے تاریخ کا استعمال کریں۔ آپ یہ منتخب کرسکتے ہیں کہ اگر پرس ہر بلاک کو اسکیننگ جاری رکھے ہوئے ہے ، یا صرف مخصوص اونچائی کی جانچ پڑتال کرتا ہے۔",
"silent_payments_scan_from_height": "بلاک اونچائی سے اسکین کریں",
"silent_payments_scanning": "خاموش ادائیگی اسکیننگ",
"slidable": "سلائیڈ ایبل",
"sort_by": "ترتیب دیں",
@ -648,6 +651,7 @@
"syncing_wallet_alert_title": "آپ کا بٹوہ مطابقت پذیر ہو رہا ہے۔",
"template": "سانچے",
"template_name": "ٹیمپلیٹ کا نام",
"testnet_coins_no_value": "ٹیسٹ نیٹ سکے کی کوئی قیمت نہیں ہے",
"third_intro_content": "Yats بھی Cake والیٹ سے باہر رہتے ہیں۔ زمین پر کسی بھی بٹوے کے پتے کو Yat سے تبدیل کیا جا سکتا ہے!",
"third_intro_title": "Yat دوسروں کے ساتھ اچھی طرح کھیلتا ہے۔",
"thorchain_taproot_address_not_supported": "تھورچین فراہم کنندہ ٹیپروٹ پتے کی حمایت نہیں کرتا ہے۔ براہ کرم پتہ تبدیل کریں یا ایک مختلف فراہم کنندہ کو منتخب کریں۔",

View file

@ -611,6 +611,9 @@
"sign_up": "Forúkọ sílẹ̀",
"signTransaction": "Wole Idunadura",
"signup_for_card_accept_terms": "Ẹ f'orúkọ sílẹ̀ láti gba káàdì àti àjọrò.",
"silent_payments_scan_from_date": "Scan lati ọjọ",
"silent_payments_scan_from_date_or_blockheight": "Jọwọ tẹ giga idibo ti o fẹ bẹrẹ ọlọjẹ fun awọn sisanwo ipalọlọ, tabi, lo ọjọ dipo. O le yan ti apamọwọ naa tẹsiwaju nṣapẹẹrẹ gbogbo bulọọki, tabi ṣayẹwo nikan giga ti o sọ tẹlẹ.",
"silent_payments_scan_from_height": "Scan lati Iga Iga",
"silent_payments_scanning": "Awọn sisanwo ipalọlọ",
"slidable": "Slidable",
"sort_by": "Sa pelu",
@ -647,6 +650,7 @@
"syncing_wallet_alert_title": "Apamọwọ rẹ n muṣiṣẹpọ",
"template": "Àwòṣe",
"template_name": "Orukọ Awoṣe",
"testnet_coins_no_value": "Awọn aṣọ irekọja ko ni iye",
"third_intro_content": "A sì lè lo Yats níta Cake Wallet. A lè rọ́pò Àdírẹ́sì kankan àpamọ́wọ́ fún Yat!",
"third_intro_title": "Àlàáfíà ni Yat àti àwọn ìmíìn jọ wà",
"thorchain_taproot_address_not_supported": "Olupese Trockchain ko ṣe atilẹyin awọn adirẹsi Taproot. Jọwọ yi adirẹsi pada tabi yan olupese ti o yatọ.",

View file

@ -610,6 +610,9 @@
"sign_up": "注册",
"signTransaction": "签署交易",
"signup_for_card_accept_terms": "注册卡并接受条款。",
"silent_payments_scan_from_date": "从日期开始扫描",
"silent_payments_scan_from_date_or_blockheight": "请输入您要开始扫描输入静音付款的块高度,或者使用日期。您可以选择钱包是否继续扫描每个块,或仅检查指定的高度。",
"silent_payments_scan_from_height": "从块高度扫描",
"silent_payments_scanning": "无声付款扫描",
"slidable": "可滑动",
"sort_by": "排序方式",
@ -646,6 +649,7 @@
"syncing_wallet_alert_title": "您的钱包正在同步",
"template": "模板",
"template_name": "模板名称",
"testnet_coins_no_value": "TestNet硬币没有价值",
"third_intro_content": "Yats 也住在 Cake Wallet 之外。 地球上任何一個錢包地址都可以用一個Yat來代替",
"third_intro_title": "Yat 和別人玩得很好",
"thorchain_taproot_address_not_supported": "Thorchain提供商不支持Taproot地址。请更改地址或选择其他提供商。",

View file

@ -128,7 +128,7 @@ abstract class Bitcoin {
List<String> getAddresses(Object wallet);
String getAddress(Object wallet);
List<BitcoinSilentPaymentAddressRecord> getSilentAddresses(Object wallet);
List<BitcoinSilentPaymentAddressRecord> getSilentAddresses(Object wallet);
Future<int> estimateFakeSendAllTxAmount(Object wallet, TransactionPriority priority);
List<ElectrumSubAddress> getSubAddresses(Object wallet);
@ -149,14 +149,15 @@ abstract class Bitcoin {
Future<void> setAddressType(Object wallet, dynamic option);
BitcoinReceivePageOption getSelectedAddressType(Object wallet);
List<BitcoinReceivePageOption> getBitcoinReceivePageOptions();
BitcoinAddressType getBitcoinAddressType(ReceivePageOption option);
bool hasSelectedSilentPayments(Object wallet);
List<BitcoinReceivePageOption> getBitcoinReceivePageOptions();
bool isBitcoinReceivePageOption(ReceivePageOption option);
BitcoinAddressType getOptionToType(ReceivePageOption option);
bool hasTaprootInput(PendingTransaction pendingTransaction);
bool getScanningActive(Object wallet);
void setScanningActive(Object wallet, bool active);
bool isTestnet(Object wallet);
}
""";
@ -1052,7 +1053,8 @@ Future<void> generatePubspec(
final inputFile = File(pubspecOutputPath);
final inputText = await inputFile.readAsString();
final inputLines = inputText.split('\n');
final dependenciesIndex = inputLines.indexWhere((line) => line.toLowerCase().contains('dependencies:'));
final dependenciesIndex =
inputLines.indexWhere((line) => line.toLowerCase().contains('dependencies:'));
var output = cwCore;
if (hasMonero) {