Merge branch 'main' into CW-685-passphrase-support-for-monero-wownero-wallets

# Conflicts:
#	cw_monero/lib/api/wallet.dart
#	cw_wownero/lib/api/wallet.dart
This commit is contained in:
Konstantin Ullrich 2024-08-19 11:31:54 +02:00
commit 52d8ab47f6
No known key found for this signature in database
GPG key ID: E9562A013280F5DB
97 changed files with 1742 additions and 404 deletions

View file

@ -2,3 +2,6 @@
uri: rpc.ankr.com uri: rpc.ankr.com
is_default: true is_default: true
useSSL: true useSSL: true
-
uri: api.mainnet-beta.solana.com:443
useSSL: true

View file

@ -1,4 +1,3 @@
Monero synchronization improvements Scan and verify messages
Enhance error handling Synchronization enhancements
UI enhancements
Bug fixes Bug fixes

View file

@ -1,6 +1,3 @@
Wallets enhancements Scan and verify messages
Monero synchronization improvements Synchronization enhancements
Improve wallet backups
Enhance error handling
UI enhancements
Bug fixes Bug fixes

View file

@ -66,6 +66,7 @@ class ElectrumClient {
try { try {
await socket?.close(); await socket?.close();
socket = null;
} catch (_) {} } catch (_) {}
try { try {
@ -90,7 +91,8 @@ class ElectrumClient {
} }
_setConnectionStatus(ConnectionStatus.connected); _setConnectionStatus(ConnectionStatus.connected);
socket!.listen((Uint8List event) { socket!.listen(
(Uint8List event) {
try { try {
final msg = utf8.decode(event.toList()); final msg = utf8.decode(event.toList());
final messagesList = msg.split("\n"); final messagesList = msg.split("\n");
@ -103,7 +105,9 @@ class ElectrumClient {
} catch (e) { } catch (e) {
print(e.toString()); print(e.toString());
} }
}, onError: (Object error) { },
onError: (Object error) {
socket = null;
final errorMsg = error.toString(); final errorMsg = error.toString();
print(errorMsg); print(errorMsg);
unterminatedString = ''; unterminatedString = '';
@ -113,10 +117,14 @@ class ElectrumClient {
if (currentHost != null && isErrorForCurrentHost) if (currentHost != null && isErrorForCurrentHost)
_setConnectionStatus(ConnectionStatus.failed); _setConnectionStatus(ConnectionStatus.failed);
}, onDone: () { },
onDone: () {
socket = null;
unterminatedString = ''; unterminatedString = '';
if (host == socket?.address.host) _setConnectionStatus(ConnectionStatus.disconnected); if (host == socket?.address.host) _setConnectionStatus(ConnectionStatus.disconnected);
}); },
cancelOnError: true,
);
keepAlive(); keepAlive();
} }

View file

@ -42,6 +42,7 @@ import 'package:flutter/foundation.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:rxdart/subjects.dart'; import 'package:rxdart/subjects.dart';
import 'package:http/http.dart' as http;
import 'package:sp_scanner/sp_scanner.dart'; import 'package:sp_scanner/sp_scanner.dart';
part 'electrum_wallet.g.dart'; part 'electrum_wallet.g.dart';
@ -132,6 +133,7 @@ abstract class ElectrumWalletBase
final String? _mnemonic; final String? _mnemonic;
Bip32Slip10Secp256k1 get hd => accountHD.childKey(Bip32KeyIndex(0)); Bip32Slip10Secp256k1 get hd => accountHD.childKey(Bip32KeyIndex(0));
Bip32Slip10Secp256k1 get sideHd => accountHD.childKey(Bip32KeyIndex(1));
final EncryptionFileUtils encryptionFileUtils; final EncryptionFileUtils encryptionFileUtils;
final String? passphrase; final String? passphrase;
@ -216,10 +218,7 @@ abstract class ElectrumWalletBase
if (electrumClient.isConnected) { if (electrumClient.isConnected) {
syncStatus = SyncedSyncStatus(); syncStatus = SyncedSyncStatus();
} else { } else {
if (electrumClient.uri != null) { syncStatus = NotConnectedSyncStatus();
await electrumClient.connectToUri(electrumClient.uri!, useSSL: electrumClient.useSSL);
startSync();
}
} }
} }
} }
@ -263,8 +262,10 @@ abstract class ElectrumWalletBase
Future<Isolate>? _isolate; Future<Isolate>? _isolate;
void Function(FlutterErrorDetails)? _onError; void Function(FlutterErrorDetails)? _onError;
Timer? _reconnectTimer;
Timer? _autoSaveTimer; Timer? _autoSaveTimer;
static const int _autoSaveInterval = 30; Timer? _updateFeeRateTimer;
static const int _autoSaveInterval = 1;
Future<void> init() async { Future<void> init() async {
await walletAddresses.init(); await walletAddresses.init();
@ -272,7 +273,7 @@ abstract class ElectrumWalletBase
await save(); await save();
_autoSaveTimer = _autoSaveTimer =
Timer.periodic(Duration(seconds: _autoSaveInterval), (_) async => await save()); Timer.periodic(Duration(minutes: _autoSaveInterval), (_) async => await save());
} }
@action @action
@ -425,6 +426,10 @@ abstract class ElectrumWalletBase
await updateTransactions(); await updateTransactions();
await updateAllUnspents(); await updateAllUnspents();
await updateBalance(); await updateBalance();
updateFeeRates();
_updateFeeRateTimer ??=
Timer.periodic(const Duration(minutes: 1), (timer) async => await updateFeeRates());
if (alwaysScan == true) { if (alwaysScan == true) {
_setListeners(walletInfo.restoreHeight); _setListeners(walletInfo.restoreHeight);
@ -591,7 +596,7 @@ abstract class ElectrumWalletBase
} }
final derivationPath = final derivationPath =
"${_hardenedDerivationPath(walletInfo.derivationInfo?.derivationPath ?? "m/0'")}" "${_hardenedDerivationPath(walletInfo.derivationInfo?.derivationPath ?? electrum_path)}"
"/${utx.bitcoinAddressRecord.isHidden ? "1" : "0"}" "/${utx.bitcoinAddressRecord.isHidden ? "1" : "0"}"
"/${utx.bitcoinAddressRecord.index}"; "/${utx.bitcoinAddressRecord.index}";
publicKeys[address.pubKeyHash()] = PublicKeyWithDerivationPath(pubKeyHex, derivationPath); publicKeys[address.pubKeyHash()] = PublicKeyWithDerivationPath(pubKeyHex, derivationPath);
@ -1213,6 +1218,7 @@ abstract class ElectrumWalletBase
await electrumClient.close(); await electrumClient.close();
} catch (_) {} } catch (_) {}
_autoSaveTimer?.cancel(); _autoSaveTimer?.cancel();
_updateFeeRateTimer?.cancel();
} }
@action @action
@ -1371,7 +1377,7 @@ abstract class ElectrumWalletBase
if (confirmations > 0) return false; if (confirmations > 0) return false;
if (transactionHex == null) { if (transactionHex == null || transactionHex.isEmpty) {
return false; return false;
} }
@ -1869,11 +1875,70 @@ abstract class ElectrumWalletBase
? walletAddresses.allAddresses.firstWhere((element) => element.address == address).index ? walletAddresses.allAddresses.firstWhere((element) => element.address == address).index
: null; : null;
final HD = index == null ? hd : hd.childKey(Bip32KeyIndex(index)); final HD = index == null ? hd : hd.childKey(Bip32KeyIndex(index));
final priv = ECPrivate.fromWif( final priv = ECPrivate.fromHex(HD.privateKey.privKey.toHex());
WifEncoder.encode(HD.privateKey.raw, netVer: network.wifNetVer),
netVersion: network.wifNetVer, String messagePrefix = '\x18Bitcoin Signed Message:\n';
); final hexEncoded = priv.signMessage(utf8.encode(message), messagePrefix: messagePrefix);
return priv.signMessage(StringUtils.encode(message)); final decodedSig = hex.decode(hexEncoded);
return base64Encode(decodedSig);
}
@override
Future<bool> verifyMessage(String message, String signature, {String? address = null}) async {
if (address == null) {
return false;
}
List<int> sigDecodedBytes = [];
if (signature.endsWith('=')) {
sigDecodedBytes = base64.decode(signature);
} else {
sigDecodedBytes = hex.decode(signature);
}
if (sigDecodedBytes.length != 64 && sigDecodedBytes.length != 65) {
throw ArgumentException(
"signature must be 64 bytes without recover-id or 65 bytes with recover-id");
}
String messagePrefix = '\x18Bitcoin Signed Message:\n';
final messageHash = QuickCrypto.sha256Hash(
BitcoinSignerUtils.magicMessage(utf8.encode(message), messagePrefix));
List<int> correctSignature =
sigDecodedBytes.length == 65 ? sigDecodedBytes.sublist(1) : List.from(sigDecodedBytes);
List<int> rBytes = correctSignature.sublist(0, 32);
List<int> sBytes = correctSignature.sublist(32);
final sig = ECDSASignature(BigintUtils.fromBytes(rBytes), BigintUtils.fromBytes(sBytes));
List<int> possibleRecoverIds = [0, 1];
final baseAddress = addressTypeFromStr(address, network);
for (int recoveryId in possibleRecoverIds) {
final pubKey = sig.recoverPublicKey(messageHash, Curves.generatorSecp256k1, recoveryId);
final recoveredPub = ECPublic.fromBytes(pubKey!.toBytes());
String? recoveredAddress;
if (baseAddress is P2pkAddress) {
recoveredAddress = recoveredPub.toP2pkAddress().toAddress(network);
} else if (baseAddress is P2pkhAddress) {
recoveredAddress = recoveredPub.toP2pkhAddress().toAddress(network);
} else if (baseAddress is P2wshAddress) {
recoveredAddress = recoveredPub.toP2wshAddress().toAddress(network);
} else if (baseAddress is P2wpkhAddress) {
recoveredAddress = recoveredPub.toP2wpkhAddress().toAddress(network);
}
if (recoveredAddress == address) {
return true;
}
}
return false;
} }
Future<void> _setInitialHeight() async { Future<void> _setInitialHeight() async {
@ -1919,13 +1984,6 @@ abstract class ElectrumWalletBase
break; break;
case ConnectionStatus.failed: case ConnectionStatus.failed:
syncStatus = LostConnectionSyncStatus(); syncStatus = LostConnectionSyncStatus();
// wait for 5 seconds and then try to reconnect:
Future.delayed(Duration(seconds: 5), () {
electrumClient.connectToUri(
node!.uri,
useSSL: node!.useSSL ?? false,
);
});
break; break;
case ConnectionStatus.connecting: case ConnectionStatus.connecting:
syncStatus = ConnectingSyncStatus(); syncStatus = ConnectingSyncStatus();
@ -1935,7 +1993,11 @@ abstract class ElectrumWalletBase
} }
void _syncStatusReaction(SyncStatus syncStatus) async { void _syncStatusReaction(SyncStatus syncStatus) async {
if (syncStatus is NotConnectedSyncStatus) { if (syncStatus is SyncingSyncStatus) {
return;
}
if (syncStatus is NotConnectedSyncStatus || syncStatus is LostConnectionSyncStatus) {
// Needs to re-subscribe to all scripthashes when reconnected // Needs to re-subscribe to all scripthashes when reconnected
_scripthashesUpdateSubject = {}; _scripthashesUpdateSubject = {};
@ -1943,7 +2005,8 @@ abstract class ElectrumWalletBase
_isTryingToConnect = true; _isTryingToConnect = true;
Future.delayed(Duration(seconds: 10), () { _reconnectTimer?.cancel();
_reconnectTimer = Timer(Duration(seconds: 10), () {
if (this.syncStatus is! SyncedSyncStatus && this.syncStatus is! SyncedTipSyncStatus) { if (this.syncStatus is! SyncedSyncStatus && this.syncStatus is! SyncedTipSyncStatus) {
this.electrumClient.connectToUri( this.electrumClient.connectToUri(
node!.uri, node!.uri,

View file

@ -1,6 +1,9 @@
import 'package:bip39/bip39.dart' as bip39; import 'dart:convert';
import 'package:bitcoin_base/bitcoin_base.dart'; import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:blockchain_utils/blockchain_utils.dart'; import 'package:blockchain_utils/blockchain_utils.dart';
import 'package:blockchain_utils/signer/ecdsa_signing_key.dart';
import 'package:bip39/bip39.dart' as bip39;
import 'package:cw_bitcoin/bitcoin_address_record.dart'; import 'package:cw_bitcoin/bitcoin_address_record.dart';
import 'package:cw_bitcoin/bitcoin_mnemonic.dart'; import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
import 'package:cw_bitcoin/bitcoin_transaction_priority.dart'; import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
@ -17,6 +20,9 @@ import 'package:cw_core/wallet_keys_file.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:bitcoin_base/src/crypto/keypair/sign_utils.dart';
import 'package:pointycastle/ecc/api.dart';
import 'package:pointycastle/ecc/curves/secp256k1.dart';
part 'litecoin_wallet.g.dart'; part 'litecoin_wallet.g.dart';
@ -167,4 +173,127 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
return 0; return 0;
} }
@override
Future<String> signMessage(String message, {String? address = null}) async {
final index = address != null
? walletAddresses.allAddresses.firstWhere((element) => element.address == address).index
: null;
final HD = index == null ? hd : hd.childKey(Bip32KeyIndex(index));
final priv = ECPrivate.fromHex(HD.privateKey.privKey.toHex());
final privateKey = ECDSAPrivateKey.fromBytes(
priv.toBytes(),
Curves.generatorSecp256k1,
);
final signature =
signLitecoinMessage(utf8.encode(message), privateKey: privateKey, bipPrive: priv.prive);
return base64Encode(signature);
}
List<int> _magicPrefix(List<int> message, List<int> messagePrefix) {
final encodeLength = IntUtils.encodeVarint(message.length);
return [...messagePrefix, ...encodeLength, ...message];
}
List<int> signLitecoinMessage(List<int> message,
{required ECDSAPrivateKey privateKey, required Bip32PrivateKey bipPrive}) {
String messagePrefix = '\x19Litecoin Signed Message:\n';
final messageHash = QuickCrypto.sha256Hash(magicMessage(message, messagePrefix));
final signingKey = EcdsaSigningKey(privateKey);
ECDSASignature ecdsaSign =
signingKey.signDigestDeterminstic(digest: messageHash, hashFunc: () => SHA256());
final n = Curves.generatorSecp256k1.order! >> 1;
BigInt newS;
if (ecdsaSign.s.compareTo(n) > 0) {
newS = Curves.generatorSecp256k1.order! - ecdsaSign.s;
} else {
newS = ecdsaSign.s;
}
final rawSig = ECDSASignature(ecdsaSign.r, newS);
final rawSigBytes = rawSig.toBytes(BitcoinSignerUtils.baselen);
final pub = bipPrive.publicKey;
final ECDomainParameters curve = ECCurve_secp256k1();
final point = curve.curve.decodePoint(pub.point.toBytes());
final rawSigEc = ECSignature(rawSig.r, rawSig.s);
final recId = SignUtils.findRecoveryId(
SignUtils.getHexString(messageHash, offset: 0, length: messageHash.length),
rawSigEc,
Uint8List.fromList(pub.uncompressed),
);
final v = recId + 27 + (point!.isCompressed ? 4 : 0);
final combined = Uint8List.fromList([v, ...rawSigBytes]);
return combined;
}
List<int> magicMessage(List<int> message, String messagePrefix) {
final prefixBytes = StringUtils.encode(messagePrefix);
final magic = _magicPrefix(message, prefixBytes);
return QuickCrypto.sha256Hash(magic);
}
@override
Future<bool> verifyMessage(String message, String signature, {String? address = null}) async {
if (address == null) {
return false;
}
List<int> sigDecodedBytes = [];
if (signature.endsWith('=')) {
sigDecodedBytes = base64.decode(signature);
} else {
sigDecodedBytes = hex.decode(signature);
}
if (sigDecodedBytes.length != 64 && sigDecodedBytes.length != 65) {
throw ArgumentException(
"litecoin signature must be 64 bytes without recover-id or 65 bytes with recover-id");
}
String messagePrefix = '\x19Litecoin Signed Message:\n';
final messageHash = QuickCrypto.sha256Hash(magicMessage(utf8.encode(message), messagePrefix));
List<int> correctSignature =
sigDecodedBytes.length == 65 ? sigDecodedBytes.sublist(1) : List.from(sigDecodedBytes);
List<int> rBytes = correctSignature.sublist(0, 32);
List<int> sBytes = correctSignature.sublist(32);
final sig = ECDSASignature(BigintUtils.fromBytes(rBytes), BigintUtils.fromBytes(sBytes));
List<int> possibleRecoverIds = [0, 1];
final baseAddress = addressTypeFromStr(address, network);
for (int recoveryId in possibleRecoverIds) {
final pubKey = sig.recoverPublicKey(messageHash, Curves.generatorSecp256k1, recoveryId);
final recoveredPub = ECPublic.fromBytes(pubKey!.toBytes());
String? recoveredAddress;
if (baseAddress is P2pkAddress) {
recoveredAddress = recoveredPub.toP2pkAddress().toAddress(network);
} else if (baseAddress is P2pkhAddress) {
recoveredAddress = recoveredPub.toP2pkhAddress().toAddress(network);
} else if (baseAddress is P2wshAddress) {
recoveredAddress = recoveredPub.toP2wshAddress().toAddress(network);
} else if (baseAddress is P2wpkhAddress) {
recoveredAddress = recoveredPub.toP2wpkhAddress().toAddress(network);
}
if (recoveredAddress == address) {
return true;
}
}
return false;
}
} }

View file

@ -67,11 +67,11 @@ packages:
source: git source: git
version: "1.0.1" version: "1.0.1"
bitcoin_base: bitcoin_base:
dependency: "direct main" dependency: "direct overridden"
description: description:
path: "." path: "."
ref: cake-update-v4 ref: cake-update-v5
resolved-ref: "574486bfcdbbaf978dcd006b46fc8716f880da29" resolved-ref: ff2b10eb27b0254ce4518d054332d97d77d9b380
url: "https://github.com/cake-tech/bitcoin_base" url: "https://github.com/cake-tech/bitcoin_base"
source: git source: git
version: "4.7.0" version: "4.7.0"

View file

@ -25,10 +25,6 @@ dependencies:
ref: Add-Support-For-OP-Return-data ref: Add-Support-For-OP-Return-data
rxdart: ^0.27.5 rxdart: ^0.27.5
cryptography: ^2.0.5 cryptography: ^2.0.5
bitcoin_base:
git:
url: https://github.com/cake-tech/bitcoin_base
ref: cake-update-v4
blockchain_utils: blockchain_utils:
git: git:
url: https://github.com/cake-tech/blockchain_utils url: https://github.com/cake-tech/blockchain_utils
@ -57,6 +53,10 @@ dependency_overrides:
url: https://github.com/cake-tech/ledger-flutter.git url: https://github.com/cake-tech/ledger-flutter.git
ref: cake-v3 ref: cake-v3
watcher: ^1.1.0 watcher: ^1.1.0
bitcoin_base:
git:
url: https://github.com/cake-tech/bitcoin_base
ref: cake-update-v5
# For information on the generic Dart part of this file, see the # For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec # following page: https://dart.dev/tools/pub/pubspec

View file

@ -202,11 +202,12 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
@override @override
Future<String> signMessage(String message, {String? address = null}) async { Future<String> signMessage(String message, {String? address = null}) async {
final index = address != null int? index;
? walletAddresses.allAddresses try {
.firstWhere((element) => element.address == AddressUtils.toLegacyAddress(address)) index = address != null
.index ? walletAddresses.allAddresses.firstWhere((element) => element.address == address).index
: null; : null;
} catch (_) {}
final HD = index == null ? hd : hd.childKey(Bip32KeyIndex(index)); final HD = index == null ? hd : hd.childKey(Bip32KeyIndex(index));
final priv = ECPrivate.fromWif( final priv = ECPrivate.fromWif(
WifEncoder.encode(HD.privateKey.raw, netVer: network.wifNetVer), WifEncoder.encode(HD.privateKey.raw, netVer: network.wifNetVer),

View file

@ -25,10 +25,6 @@ dependencies:
git: git:
url: https://github.com/cake-tech/bitbox-flutter.git url: https://github.com/cake-tech/bitbox-flutter.git
ref: Add-Support-For-OP-Return-data ref: Add-Support-For-OP-Return-data
bitcoin_base:
git:
url: https://github.com/cake-tech/bitcoin_base
ref: cake-update-v4
blockchain_utils: blockchain_utils:
git: git:
url: https://github.com/cake-tech/blockchain_utils url: https://github.com/cake-tech/blockchain_utils
@ -43,6 +39,10 @@ dev_dependencies:
dependency_overrides: dependency_overrides:
watcher: ^1.1.0 watcher: ^1.1.0
bitcoin_base:
git:
url: https://github.com/cake-tech/bitcoin_base
ref: cake-update-v5
# For information on the generic Dart part of this file, see the # For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec # following page: https://dart.dev/tools/pub/pubspec

View file

@ -69,7 +69,6 @@ abstract class WalletBase<BalanceType extends Balance, HistoryType extends Trans
int calculateEstimatedFee(TransactionPriority priority, int? amount); int calculateEstimatedFee(TransactionPriority priority, int? amount);
// void fetchTransactionsAsync( // void fetchTransactionsAsync(
// void Function(TransactionType transaction) onTransactionLoaded, // void Function(TransactionType transaction) onTransactionLoaded,
// {void Function() onFinished}); // {void Function() onFinished});
@ -92,7 +91,9 @@ abstract class WalletBase<BalanceType extends Balance, HistoryType extends Trans
Future<void> renameWalletFiles(String newWalletName); Future<void> renameWalletFiles(String newWalletName);
Future<String> signMessage(String message, {String? address = null}) => throw UnimplementedError(); Future<String> signMessage(String message, {String? address = null});
Future<bool> verifyMessage(String message, String signature, {String? address = null});
bool? isTestnet; bool? isTestnet;
} }

View file

@ -35,6 +35,7 @@ import 'package:mobx/mobx.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:web3dart/crypto.dart'; import 'package:web3dart/crypto.dart';
import 'package:web3dart/web3dart.dart'; import 'package:web3dart/web3dart.dart';
import 'package:eth_sig_util/eth_sig_util.dart';
import 'evm_chain_transaction_info.dart'; import 'evm_chain_transaction_info.dart';
import 'evm_erc20_balance.dart'; import 'evm_erc20_balance.dart';
@ -112,6 +113,8 @@ abstract class EVMChainWalletBase
int? gasBaseFee = 0; int? gasBaseFee = 0;
int estimatedGasUnits = 0; int estimatedGasUnits = 0;
Timer? _updateFeesTimer;
bool _isTransactionUpdating; bool _isTransactionUpdating;
// TODO: remove after integrating our own node and having eth_newPendingTransactionFilter // TODO: remove after integrating our own node and having eth_newPendingTransactionFilter
@ -262,6 +265,7 @@ abstract class EVMChainWalletBase
void close() { void close() {
_client.stop(); _client.stop();
_transactionsUpdateTimer?.cancel(); _transactionsUpdateTimer?.cancel();
_updateFeesTimer?.cancel();
} }
@action @action
@ -296,7 +300,7 @@ abstract class EVMChainWalletBase
await _updateEstimatedGasFeeParams(); await _updateEstimatedGasFeeParams();
Timer.periodic(const Duration(seconds: 10), (timer) async { _updateFeesTimer ??= Timer.periodic(const Duration(seconds: 30), (timer) async {
await _updateEstimatedGasFeeParams(); await _updateEstimatedGasFeeParams();
}); });
@ -692,8 +696,21 @@ abstract class EVMChainWalletBase
} }
@override @override
Future<String> signMessage(String message, {String? address}) async => Future<String> signMessage(String message, {String? address}) async {
bytesToHex(await _evmChainPrivateKey.signPersonalMessage(ascii.encode(message))); return bytesToHex(await _evmChainPrivateKey.signPersonalMessage(ascii.encode(message)));
}
@override
Future<bool> verifyMessage(String message, String signature, {String? address}) async {
if (address == null) {
return false;
}
final recoveredAddress = EthSigUtil.recoverPersonalSignature(
message: ascii.encode(message),
signature: signature,
);
return recoveredAddress.toUpperCase() == address.toUpperCase();
}
Web3Client? getWeb3Client() => _client.getWeb3Client(); Web3Client? getWeb3Client() => _client.getWeb3Client();

View file

@ -13,6 +13,8 @@ dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
web3dart: ^2.7.1 web3dart: ^2.7.1
eth_sig_util: ^0.0.9
erc20: ^1.0.1
bip39: ^1.0.6 bip39: ^1.0.6
bip32: ^2.0.0 bip32: ^2.0.0
hex: ^0.2.0 hex: ^0.2.0

View file

@ -10,10 +10,8 @@ import 'package:cw_haven/haven_transaction_info.dart';
import 'package:cw_haven/haven_wallet_addresses.dart'; import 'package:cw_haven/haven_wallet_addresses.dart';
import 'package:cw_core/monero_wallet_utils.dart'; import 'package:cw_core/monero_wallet_utils.dart';
import 'package:cw_haven/api/structs/pending_transaction.dart'; import 'package:cw_haven/api/structs/pending_transaction.dart';
import 'package:flutter/foundation.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:cw_haven/api/transaction_history.dart' as haven_transaction_history; import 'package:cw_haven/api/transaction_history.dart' as haven_transaction_history;
//import 'package:cw_haven/wallet.dart';
import 'package:cw_haven/api/wallet.dart' as haven_wallet; import 'package:cw_haven/api/wallet.dart' as haven_wallet;
import 'package:cw_haven/api/transaction_history.dart' as transaction_history; import 'package:cw_haven/api/transaction_history.dart' as transaction_history;
import 'package:cw_haven/api/monero_output.dart'; import 'package:cw_haven/api/monero_output.dart';
@ -123,7 +121,8 @@ abstract class HavenWalletBase
login: node.login, login: node.login,
password: node.password, password: node.password,
useSSL: node.useSSL ?? false, useSSL: node.useSSL ?? false,
isLightWallet: false, // FIXME: hardcoded value isLightWallet: false,
// FIXME: hardcoded value
socksProxyAddress: node.socksProxyAddress); socksProxyAddress: node.socksProxyAddress);
haven_wallet.setTrustedDaemon(node.trusted); haven_wallet.setTrustedDaemon(node.trusted);
@ -419,4 +418,12 @@ abstract class HavenWalletBase
@override @override
String get password => _password; String get password => _password;
@override
Future<String> signMessage(String message, {String? address = null}) =>
throw UnimplementedError();
@override
Future<bool> verifyMessage(String message, String signature, {String? address = null}) =>
throw UnimplementedError();
} }

View file

@ -49,12 +49,23 @@ String getSeedLegacy(String? language) {
final cakepassphrase = final cakepassphrase =
monero.Wallet_getCacheAttribute(wptr!, key: "cakewallet.passphrase"); monero.Wallet_getCacheAttribute(wptr!, key: "cakewallet.passphrase");
var legacy = monero.Wallet_seed(wptr!, seedOffset: cakepassphrase); var legacy = monero.Wallet_seed(wptr!, seedOffset: cakepassphrase);
switch (language) {
case "Chinese (Traditional)": language = "Chinese (simplified)"; break;
case "Chinese (Simplified)": language = "Chinese (simplified)"; break;
case "Korean": language = "English"; break;
case "Czech": language = "English"; break;
case "Japanese": language = "English"; break;
}
if (monero.Wallet_status(wptr!) != 0) { if (monero.Wallet_status(wptr!) != 0) {
monero.Wallet_setSeedLanguage(wptr!, language: language ?? "English"); monero.Wallet_setSeedLanguage(wptr!, language: language ?? "English");
legacy = monero.Wallet_seed(wptr!, seedOffset: cakepassphrase); legacy = monero.Wallet_seed(wptr!, seedOffset: cakepassphrase);
} }
if (monero.Wallet_status(wptr!) != 0) { if (monero.Wallet_status(wptr!) != 0) {
return monero.Wallet_errorString(wptr!); final err = monero.Wallet_errorString(wptr!);
if (legacy.isNotEmpty) {
return "$err\n\n$legacy";
}
return err;
} }
return legacy; return legacy;
} }
@ -316,3 +327,7 @@ Future<bool> trustedDaemon() async => monero.Wallet_trustedDaemon(wptr!);
String signMessage(String message, {String address = ""}) { String signMessage(String message, {String address = ""}) {
return monero.Wallet_signMessage(wptr!, message: message, address: address); return monero.Wallet_signMessage(wptr!, message: message, address: address);
} }
bool verifyMessage(String message, String address, String signature) {
return monero.Wallet_verifySignedMessage(wptr!, message: message, address: address, signature: signature);
}

View file

@ -787,4 +787,12 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
final useAddress = address ?? ""; final useAddress = address ?? "";
return monero_wallet.signMessage(message, address: useAddress); return monero_wallet.signMessage(message, address: useAddress);
} }
@override
Future<bool> verifyMessage(String message, String signature, {String? address = null}) async {
if (address == null) return false;
return monero_wallet.verifyMessage(message, address, signature);
}
} }

View file

@ -127,7 +127,7 @@ class MoneroWalletService extends WalletService<
} }
@override @override
Future<MoneroWallet> openWallet(String name, String password) async { Future<MoneroWallet> openWallet(String name, String password, {bool? retryOnFailure}) async {
MoneroWallet? wallet; MoneroWallet? wallet;
try { try {
final path = await pathForWallet(name: name, type: getType()); final path = await pathForWallet(name: name, type: getType());
@ -189,12 +189,12 @@ class MoneroWalletService extends WalletService<
wallet.onError != null) { wallet.onError != null) {
wallet.onError!(FlutterErrorDetails(exception: e, stack: s)); wallet.onError!(FlutterErrorDetails(exception: e, stack: s));
} }
if (invalidPassword) { if (invalidPassword || retryOnFailure == false) {
rethrow; rethrow;
} }
await restoreOrResetWalletFiles(name); await restoreOrResetWalletFiles(name);
return openWallet(name, password); return openWallet(name, password, retryOnFailure: false);
} }
} }

View file

@ -295,10 +295,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: hashlib name: hashlib
sha256: "5037d3b8c36384c03a728543ae67d962a56970c5432a50862279fe68ee4c8411" sha256: d41795742c10947930630118c6836608deeb9047cd05aee32d2baeb697afd66a
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.19.1" version: "1.19.2"
hashlib_codecs: hashlib_codecs:
dependency: transitive dependency: transitive
description: description:
@ -576,10 +576,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: polyseed name: polyseed
sha256: edf28042e7b0b28f97a0469aa98e6e4015937cef6b9340cd6ad2822139c95217 sha256: "11d4dbee409db053c5e9cd77382b2f5115f43fc2529158a826a96f3ba505d770"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.0.5" version: "0.0.6"
pool: pool:
dependency: transitive dependency: transitive
description: description:

View file

@ -19,7 +19,7 @@ dependencies:
flutter_mobx: ^2.0.6+1 flutter_mobx: ^2.0.6+1
intl: ^0.18.0 intl: ^0.18.0
encrypt: ^5.0.1 encrypt: ^5.0.1
polyseed: ^0.0.5 polyseed: ^0.0.6
cw_core: cw_core:
path: ../cw_core path: ../cw_core
monero: monero:

View file

@ -0,0 +1,37 @@
class BlockContentsResponse {
String type;
String account;
String previous;
String representative;
String balance;
String link;
String linkAsAccount;
String signature;
String work;
BlockContentsResponse({
required this.type,
required this.account,
required this.previous,
required this.representative,
required this.balance,
required this.link,
required this.linkAsAccount,
required this.signature,
required this.work,
});
factory BlockContentsResponse.fromJson(Map<String, dynamic> json) {
return BlockContentsResponse(
type: json['type'] as String,
account: json['account'] as String,
previous: json['previous'] as String,
representative: json['representative'] as String,
balance: json['balance'] as String,
link: json['link'] as String,
linkAsAccount: json['link_as_account'] as String,
signature: json['signature'] as String,
work: json['work'] as String,
);
}
}

View file

@ -2,11 +2,11 @@ import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'package:cw_core/nano_account_info_response.dart'; import 'package:cw_core/nano_account_info_response.dart';
import 'package:cw_nano/nano_block_info_response.dart';
import 'package:cw_core/n2_node.dart'; import 'package:cw_core/n2_node.dart';
import 'package:cw_nano/nano_balance.dart'; import 'package:cw_nano/nano_balance.dart';
import 'package:cw_nano/nano_transaction_model.dart'; import 'package:cw_nano/nano_transaction_model.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:nanodart/nanodart.dart';
import 'package:cw_core/node.dart'; import 'package:cw_core/node.dart';
import 'package:nanoutil/nanoutil.dart'; import 'package:nanoutil/nanoutil.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@ -111,6 +111,27 @@ class NanoClient {
} }
} }
Future<BlockContentsResponse?> getBlockContents(String block) async {
try {
final response = await http.post(
_node!.uri,
headers: CAKE_HEADERS,
body: jsonEncode(
{
"action": "block_info",
"json_block": "true",
"hash": block,
},
),
);
final data = await jsonDecode(response.body);
return BlockContentsResponse.fromJson(data["contents"] as Map<String, dynamic>);
} catch (e) {
print("error while getting block info $e");
return null;
}
}
Future<String> changeRep({ Future<String> changeRep({
required String privateKey, required String privateKey,
required String repAddress, required String repAddress,
@ -135,8 +156,8 @@ class NanoClient {
}; };
// sign the change block: // sign the change block:
final String hash = NanoBlocks.computeStateHash( final String hash = NanoSignatures.computeStateHash(
NanoAccountType.NANO, NanoBasedCurrency.NANO,
changeBlock["account"]!, changeBlock["account"]!,
changeBlock["previous"]!, changeBlock["previous"]!,
changeBlock["representative"]!, changeBlock["representative"]!,
@ -248,7 +269,7 @@ class NanoClient {
} }
final String representative = infoResponse.representative; final String representative = infoResponse.representative;
// link = destination address: // link = destination address:
final String link = NanoAccounts.extractPublicKey(destinationAddress); final String link = NanoDerivations.addressToPublicKey(destinationAddress);
final String linkAsAccount = destinationAddress; final String linkAsAccount = destinationAddress;
// construct the send block: // construct the send block:
@ -262,8 +283,8 @@ class NanoClient {
}; };
// sign the send block: // sign the send block:
final String hash = NanoBlocks.computeStateHash( final String hash = NanoSignatures.computeStateHash(
NanoAccountType.NANO, NanoBasedCurrency.NANO,
sendBlock["account"]!, sendBlock["account"]!,
sendBlock["previous"]!, sendBlock["previous"]!,
sendBlock["representative"]!, sendBlock["representative"]!,
@ -285,7 +306,6 @@ class NanoClient {
Future<void> receiveBlock({ Future<void> receiveBlock({
required String blockHash, required String blockHash,
required String source,
required String amountRaw, required String amountRaw,
required String destinationAddress, required String destinationAddress,
required String privateKey, required String privateKey,
@ -310,15 +330,56 @@ class NanoClient {
representative = infoData.representative; representative = infoData.representative;
} }
if ((BigInt.tryParse(amountRaw) ?? BigInt.zero) <= BigInt.zero) {
throw Exception("amountRaw must be greater than zero");
}
BlockContentsResponse? frontierContents;
if (!openBlock) {
// get the block info of the frontier block:
frontierContents = await getBlockContents(frontier);
if (frontierContents == null) {
throw Exception("error while getting frontier block info");
}
final String frontierHash = NanoSignatures.computeStateHash(
NanoBasedCurrency.NANO,
frontierContents.account,
frontierContents.previous,
frontierContents.representative,
BigInt.parse(frontierContents.balance),
frontierContents.link,
);
bool valid = await NanoSignatures.verify(
frontierHash,
frontierContents.signature,
destinationAddress,
);
if (!valid) {
throw Exception(
"Frontier block signature is invalid! Potentially malicious block detected!");
}
}
// first get the account balance: // first get the account balance:
final BigInt currentBalance = (await getBalance(destinationAddress)).currentBalance; late BigInt currentBalance;
if (!openBlock) {
currentBalance = BigInt.parse(frontierContents!.balance);
} else {
currentBalance = BigInt.zero;
}
final BigInt txAmount = BigInt.parse(amountRaw); final BigInt txAmount = BigInt.parse(amountRaw);
final BigInt balanceAfterTx = currentBalance + txAmount; final BigInt balanceAfterTx = currentBalance + txAmount;
// link = send block hash: // link = send block hash:
final String link = blockHash; final String link = blockHash;
// this "linkAsAccount" is meaningless: // this "linkAsAccount" is meaningless:
final String linkAsAccount = NanoAccounts.createAccount(NanoAccountType.NANO, blockHash); final String linkAsAccount =
NanoDerivations.publicKeyToAddress(blockHash, currency: NanoBasedCurrency.NANO);
// construct the receive block: // construct the receive block:
Map<String, String> receiveBlock = { Map<String, String> receiveBlock = {
@ -332,8 +393,8 @@ class NanoClient {
}; };
// sign the receive block: // sign the receive block:
final String hash = NanoBlocks.computeStateHash( final String hash = NanoSignatures.computeStateHash(
NanoAccountType.NANO, NanoBasedCurrency.NANO,
receiveBlock["account"]!, receiveBlock["account"]!,
receiveBlock["previous"]!, receiveBlock["previous"]!,
receiveBlock["representative"]!, receiveBlock["representative"]!,
@ -345,7 +406,7 @@ class NanoClient {
// get PoW for the receive block: // get PoW for the receive block:
String? work; String? work;
if (openBlock) { if (openBlock) {
work = await requestWork(NanoAccounts.extractPublicKey(destinationAddress)); work = await requestWork(NanoDerivations.addressToPublicKey(destinationAddress));
} else { } else {
work = await requestWork(frontier); work = await requestWork(frontier);
} }
@ -409,10 +470,8 @@ class NanoClient {
for (final blockHash in blocks.keys) { for (final blockHash in blocks.keys) {
final block = blocks[blockHash]; final block = blocks[blockHash];
final String amountRaw = block["amount"] as String; final String amountRaw = block["amount"] as String;
final String source = block["source"] as String;
await receiveBlock( await receiveBlock(
blockHash: blockHash, blockHash: blockHash,
source: source,
amountRaw: amountRaw, amountRaw: amountRaw,
privateKey: privateKey, privateKey: privateKey,
destinationAddress: destinationAddress, destinationAddress: destinationAddress,

View file

@ -27,7 +27,6 @@ import 'package:cw_nano/nano_wallet_addresses.dart';
import 'package:cw_nano/nano_wallet_keys.dart'; import 'package:cw_nano/nano_wallet_keys.dart';
import 'package:cw_nano/pending_nano_transaction.dart'; import 'package:cw_nano/pending_nano_transaction.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:nanodart/nanodart.dart';
import 'package:nanoutil/nanoutil.dart'; import 'package:nanoutil/nanoutil.dart';
part 'nano_wallet.g.dart'; part 'nano_wallet.g.dart';
@ -107,7 +106,6 @@ abstract class NanoWalletBase
if (_derivationType == DerivationType.unknown) { if (_derivationType == DerivationType.unknown) {
_derivationType = DerivationType.nano; _derivationType = DerivationType.nano;
} }
final String type = (_derivationType == DerivationType.nano) ? "standard" : "hd";
// our "mnemonic" is actually a hex form seed: // our "mnemonic" is actually a hex form seed:
if (!_mnemonic.contains(' ')) { if (!_mnemonic.contains(' ')) {
@ -122,8 +120,10 @@ abstract class NanoWalletBase
_hexSeed = await NanoDerivations.hdMnemonicListToSeed(_mnemonic.split(' ')); _hexSeed = await NanoDerivations.hdMnemonicListToSeed(_mnemonic.split(' '));
} }
} }
NanoDerivationType derivationType =
type == "standard" ? NanoDerivationType.STANDARD : NanoDerivationType.HD; final String type = (_derivationType == DerivationType.nano) ? "standard" : "hd";
NanoDerivationType derivationType = NanoDerivations.stringToType(type);
_privateKey = await NanoDerivations.universalSeedToPrivate( _privateKey = await NanoDerivations.universalSeedToPrivate(
_hexSeed!, _hexSeed!,
index: 0, index: 0,
@ -216,8 +216,8 @@ abstract class NanoWalletBase
balanceAfterTx: runningBalance, balanceAfterTx: runningBalance,
previousHash: previousHash, previousHash: previousHash,
); );
previousHash = NanoBlocks.computeStateHash( previousHash = NanoSignatures.computeStateHash(
NanoAccountType.NANO, NanoBasedCurrency.NANO,
block["account"]!, block["account"]!,
block["previous"]!, block["previous"]!,
block["representative"]!, block["representative"]!,
@ -535,4 +535,17 @@ abstract class NanoWalletBase
// Delete old name's dir and files // Delete old name's dir and files
await Directory(currentDirPath).delete(recursive: true); await Directory(currentDirPath).delete(recursive: true);
} }
@override
Future<String> signMessage(String message, {String? address = null}) async {
return NanoSignatures.signMessage(message, privateKey!);
}
@override
Future<bool> verifyMessage(String message, String signature, {String? address = null}) async {
if (address == null) {
return false;
}
return await NanoSignatures.verifyMessage(message, signature, address);
}
} }

View file

@ -513,7 +513,7 @@ packages:
source: hosted source: hosted
version: "2.3.0" version: "2.3.0"
nanodart: nanodart:
dependency: "direct main" dependency: transitive
description: description:
name: nanodart name: nanodart
sha256: "4b2f42d60307b54e8cf384d6193a567d07f8efd773858c0d5948246153c13282" sha256: "4b2f42d60307b54e8cf384d6193a567d07f8efd773858c0d5948246153c13282"
@ -524,11 +524,11 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
path: "." path: "."
ref: c37e72817cf0a28162f43124f79661d6c8e0098f ref: c01a9c552917008d8fbc6b540db657031625b04f
resolved-ref: c37e72817cf0a28162f43124f79661d6c8e0098f resolved-ref: c01a9c552917008d8fbc6b540db657031625b04f
url: "https://github.com/perishllc/nanoutil.git" url: "https://github.com/perishllc/nanoutil.git"
source: git source: git
version: "1.0.0" version: "1.0.3"
package_config: package_config:
dependency: transitive dependency: transitive
description: description:

View file

@ -15,7 +15,6 @@ dependencies:
mobx: ^2.0.7+4 mobx: ^2.0.7+4
bip39: ^1.0.6 bip39: ^1.0.6
bip32: ^2.0.0 bip32: ^2.0.0
nanodart: ^2.0.0
decimal: ^2.3.3 decimal: ^2.3.3
libcrypto: ^0.2.2 libcrypto: ^0.2.2
ed25519_hd_key: ^2.2.0 ed25519_hd_key: ^2.2.0
@ -25,7 +24,7 @@ dependencies:
nanoutil: nanoutil:
git: git:
url: https://github.com/perishllc/nanoutil.git url: https://github.com/perishllc/nanoutil.git
ref: c37e72817cf0a28162f43124f79661d6c8e0098f ref: c01a9c552917008d8fbc6b540db657031625b04f
cw_core: cw_core:
path: ../cw_core path: ../cw_core

View file

@ -32,6 +32,8 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'package:solana/base58.dart'; import 'package:solana/base58.dart';
import 'package:solana/metaplex.dart' as metaplex; import 'package:solana/metaplex.dart' as metaplex;
import 'package:solana/solana.dart'; import 'package:solana/solana.dart';
import 'package:solana/src/crypto/ed25519_hd_keypair.dart';
import 'package:cryptography/cryptography.dart';
part 'solana_wallet.g.dart'; part 'solana_wallet.g.dart';
@ -571,17 +573,59 @@ abstract class SolanaWalletBase
}); });
} }
Future<String> signSolanaMessage(String message) async { @override
Future<String> signMessage(String message, {String? address}) async {
// Convert the message to bytes // Convert the message to bytes
final messageBytes = utf8.encode(message); final messageBytes = utf8.encode(message);
// Sign the message bytes with the wallet's private key // Sign the message bytes with the wallet's private key
final signature = await _walletKeyPair!.sign(messageBytes); final signature = (await _walletKeyPair!.sign(messageBytes)).toString();
// Convert the signature to a hexadecimal string return HEX.encode(utf8.encode(signature)).toUpperCase();
final hex = HEX.encode(signature.bytes); }
return hex; List<List<int>> bytesFromSigString(String signatureString) {
final regex = RegExp(r'Signature\(\[(.+)\], publicKey: (.+)\)');
final match = regex.firstMatch(signatureString);
if (match != null) {
final bytesString = match.group(1)!;
final base58EncodedPublicKeyString = match.group(2)!;
final sigBytes = bytesString.split(', ').map(int.parse).toList();
List<int> pubKeyBytes = base58decode(base58EncodedPublicKeyString);
return [sigBytes, pubKeyBytes];
} else {
throw const FormatException('Invalid Signature string format');
}
}
@override
Future<bool> verifyMessage(String message, String signature, {String? address}) async {
String signatureString = utf8.decode(HEX.decode(signature));
List<List<int>> bytes = bytesFromSigString(signatureString);
final messageBytes = utf8.encode(message);
final sigBytes = bytes[0];
final pubKeyBytes = bytes[1];
if (address == null) {
return false;
}
// make sure the address derived from the public key provided matches the one we expect
final pub = Ed25519HDPublicKey(pubKeyBytes);
if (address != pub.toBase58()) {
return false;
}
return await verifySignature(
message: messageBytes,
signature: sigBytes,
publicKey: Ed25519HDPublicKey(pubKeyBytes),
);
} }
SolanaClient? get solanaClient => _client.getSolanaClient; SolanaClient? get solanaClient => _client.getSolanaClient;

View file

@ -580,8 +580,18 @@ abstract class TronWalletBase
} }
@override @override
Future<String> signMessage(String message, {String? address}) async => Future<String> signMessage(String message, {String? address}) async {
_tronPrivateKey.signPersonalMessage(ascii.encode(message)); return _tronPrivateKey.signPersonalMessage(ascii.encode(message));
}
@override
Future<bool> verifyMessage(String message, String signature, {String? address}) async {
if (address == null) {
return false;
}
TronPublicKey pubKey = TronPublicKey.fromPersonalSignature(ascii.encode(message), signature)!;
return pubKey.toAddress().toString() == address;
}
String getTronBase58AddressFromHex(String hexAddress) => TronAddress(hexAddress).toAddress(); String getTronBase58AddressFromHex(String hexAddress) => TronAddress(hexAddress).toAddress();

View file

@ -51,12 +51,23 @@ String getSeedLegacy(String? language) {
final cakepassphrase = final cakepassphrase =
wownero.Wallet_getCacheAttribute(wptr!, key: "cakewallet.passphrase"); wownero.Wallet_getCacheAttribute(wptr!, key: "cakewallet.passphrase");
var legacy = wownero.Wallet_seed(wptr!, seedOffset: cakepassphrase); var legacy = wownero.Wallet_seed(wptr!, seedOffset: cakepassphrase);
switch (language) {
case "Chinese (Traditional)": language = "Chinese (simplified)"; break;
case "Chinese (Simplified)": language = "Chinese (simplified)"; break;
case "Korean": language = "English"; break;
case "Czech": language = "English"; break;
case "Japanese": language = "English"; break;
}
if (wownero.Wallet_status(wptr!) != 0) { if (wownero.Wallet_status(wptr!) != 0) {
wownero.Wallet_setSeedLanguage(wptr!, language: language ?? "English"); wownero.Wallet_setSeedLanguage(wptr!, language: language ?? "English");
legacy = wownero.Wallet_seed(wptr!, seedOffset: cakepassphrase); legacy = wownero.Wallet_seed(wptr!, seedOffset: cakepassphrase);
} }
if (wownero.Wallet_status(wptr!) != 0) { if (wownero.Wallet_status(wptr!) != 0) {
return wownero.Wallet_errorString(wptr!); final err = wownero.Wallet_errorString(wptr!);
if (legacy.isNotEmpty) {
return "$err\n\n$legacy";
}
return err;
} }
return legacy; return legacy;
} }
@ -320,3 +331,7 @@ Future<bool> trustedDaemon() async => wownero.Wallet_trustedDaemon(wptr!);
String signMessage(String message, {String address = ""}) { String signMessage(String message, {String address = ""}) {
return wownero.Wallet_signMessage(wptr!, message: message, address: address); return wownero.Wallet_signMessage(wptr!, message: message, address: address);
} }
bool verifyMessage(String message, String address, String signature) {
return wownero.Wallet_verifySignedMessage(wptr!, message: message, address: address, signature: signature);
}

View file

@ -743,4 +743,11 @@ abstract class WowneroWalletBase
final useAddress = address ?? ""; final useAddress = address ?? "";
return wownero_wallet.signMessage(message, address: useAddress); return wownero_wallet.signMessage(message, address: useAddress);
} }
@override
Future<bool> verifyMessage(String message, String signature, {String? address = null}) async {
if (address == null) return false;
return wownero_wallet.verifyMessage(message, address, signature);
}
} }

View file

@ -295,18 +295,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: hashlib name: hashlib
sha256: "71bf102329ddb8e50c8a995ee4645ae7f1728bb65e575c17196b4d8262121a96" sha256: d41795742c10947930630118c6836608deeb9047cd05aee32d2baeb697afd66a
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.12.0" version: "1.19.2"
hashlib_codecs: hashlib_codecs:
dependency: transitive dependency: transitive
description: description:
name: hashlib_codecs name: hashlib_codecs
sha256: "49e2a471f74b15f1854263e58c2ac11f2b631b5b12c836f9708a35397d36d626" sha256: "2b570061f5a4b378425be28a576c1e11783450355ad4345a19f606ff3d96db0f"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.0" version: "2.5.0"
hive: hive:
dependency: transitive dependency: transitive
description: description:
@ -568,10 +568,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: polyseed name: polyseed
sha256: edf28042e7b0b28f97a0469aa98e6e4015937cef6b9340cd6ad2822139c95217 sha256: "11d4dbee409db053c5e9cd77382b2f5115f43fc2529158a826a96f3ba505d770"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.0.5" version: "0.0.6"
pool: pool:
dependency: transitive dependency: transitive
description: description:

View file

@ -19,7 +19,7 @@ dependencies:
flutter_mobx: ^2.0.6+1 flutter_mobx: ^2.0.6+1
intl: ^0.18.0 intl: ^0.18.0
encrypt: ^5.0.1 encrypt: ^5.0.1
polyseed: ^0.0.5 polyseed: ^0.0.6
cw_core: cw_core:
path: ../cw_core path: ../cw_core
monero: monero:

View file

@ -275,7 +275,7 @@ class CWBitcoin extends Bitcoin {
return [DerivationType.bip39, DerivationType.electrum]; return [DerivationType.bip39, DerivationType.electrum];
} }
int _countOccurrences(String str, String charToCount) { int _countCharOccurrences(String str, String charToCount) {
int count = 0; int count = 0;
for (int i = 0; i < str.length; i++) { for (int i = 0; i < str.length; i++) {
if (str[i] == charToCount) { if (str[i] == charToCount) {
@ -330,7 +330,7 @@ class CWBitcoin extends Bitcoin {
); );
String balancePath = dInfoCopy.derivationPath!; String balancePath = dInfoCopy.derivationPath!;
int derivationDepth = _countOccurrences(balancePath, "/"); int derivationDepth = _countCharOccurrences(balancePath, '/');
// for BIP44 // for BIP44
if (derivationDepth == 3 || derivationDepth == 1) { if (derivationDepth == 3 || derivationDepth == 1) {

View file

@ -124,12 +124,12 @@ class DFXBuyProvider extends BuyProvider {
switch (wallet.type) { switch (wallet.type) {
case WalletType.ethereum: case WalletType.ethereum:
case WalletType.polygon: case WalletType.polygon:
return wallet.signMessage(message); return await wallet.signMessage(message);
case WalletType.monero: case WalletType.monero:
case WalletType.litecoin: case WalletType.litecoin:
case WalletType.bitcoin: case WalletType.bitcoin:
case WalletType.bitcoinCash: case WalletType.bitcoinCash:
return wallet.signMessage(message, address: walletAddress); return await wallet.signMessage(message, address: walletAddress);
default: default:
throw Exception("WalletType is not available for DFX ${wallet.type}"); throw Exception("WalletType is not available for DFX ${wallet.type}");
} }

View file

@ -37,15 +37,15 @@ class RobinhoodBuyProvider extends BuyProvider {
String get _apiSecret => secrets.exchangeHelperApiKey; String get _apiSecret => secrets.exchangeHelperApiKey;
Future<String> getSignature(String message) { Future<String> getSignature(String message) async {
switch (wallet.type) { switch (wallet.type) {
case WalletType.ethereum: case WalletType.ethereum:
case WalletType.polygon: case WalletType.polygon:
return wallet.signMessage(message); return await wallet.signMessage(message);
case WalletType.litecoin: case WalletType.litecoin:
case WalletType.bitcoin: case WalletType.bitcoin:
case WalletType.bitcoinCash: case WalletType.bitcoinCash:
return wallet.signMessage(message, address: wallet.walletAddresses.address); return await wallet.signMessage(message, address: wallet.walletAddresses.address);
default: default:
throw Exception("WalletType is not available for Robinhood ${wallet.type}"); throw Exception("WalletType is not available for Robinhood ${wallet.type}");
} }

View file

@ -60,7 +60,9 @@ class WalletLoadingService {
String corruptedWalletsSeeds = "Corrupted wallets seeds (if retrievable, empty otherwise):"; String corruptedWalletsSeeds = "Corrupted wallets seeds (if retrievable, empty otherwise):";
try { try {
corruptedWalletsSeeds += await _getCorruptedWalletSeeds(name, type); corruptedWalletsSeeds += await _getCorruptedWalletSeeds(name, type);
} catch (_) {} } catch (e) {
corruptedWalletsSeeds += "\nFailed to fetch $name seeds: $e";
}
// try opening another wallet that is not corrupted to give user access to the app // try opening another wallet that is not corrupted to give user access to the app
final walletInfoSource = await CakeHive.openBox<WalletInfo>(WalletInfo.boxName); final walletInfoSource = await CakeHive.openBox<WalletInfo>(WalletInfo.boxName);
@ -90,7 +92,9 @@ class WalletLoadingService {
if (!corruptedWalletsSeeds.contains(seeds)) { if (!corruptedWalletsSeeds.contains(seeds)) {
corruptedWalletsSeeds += seeds; corruptedWalletsSeeds += seeds;
} }
} catch (_) {} } catch (e) {
corruptedWalletsSeeds += "\nFailed to fetch $name seeds: $e";
}
} }
} }

View file

@ -30,6 +30,12 @@ import 'package:cake_wallet/entities/contact.dart';
import 'package:cake_wallet/entities/contact_record.dart'; import 'package:cake_wallet/entities/contact_record.dart';
import 'package:cake_wallet/entities/exchange_api_mode.dart'; import 'package:cake_wallet/entities/exchange_api_mode.dart';
import 'package:cake_wallet/entities/parse_address_from_domain.dart'; import 'package:cake_wallet/entities/parse_address_from_domain.dart';
import 'package:cake_wallet/src/screens/receive/address_list_page.dart';
import 'package:cake_wallet/view_model/link_view_model.dart';
import 'package:cake_wallet/tron/tron.dart';
import 'package:cake_wallet/src/screens/transaction_details/rbf_details_page.dart';
import 'package:cake_wallet/view_model/dashboard/sign_view_model.dart';
import 'package:cw_core/receive_page_option.dart';
import 'package:cake_wallet/entities/preferences_key.dart'; import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cake_wallet/entities/qr_view_data.dart'; import 'package:cake_wallet/entities/qr_view_data.dart';
import 'package:cake_wallet/entities/template.dart'; import 'package:cake_wallet/entities/template.dart';
@ -159,7 +165,6 @@ import 'package:cw_core/wallet_service.dart';
import 'package:cw_core/transaction_info.dart'; import 'package:cw_core/transaction_info.dart';
import 'package:cw_core/node.dart'; import 'package:cw_core/node.dart';
import 'package:cake_wallet/src/screens/trade_details/trade_details_page.dart'; import 'package:cake_wallet/src/screens/trade_details/trade_details_page.dart';
import 'package:cake_wallet/src/screens/transaction_details/rbf_details_page.dart';
import 'package:cake_wallet/src/screens/transaction_details/transaction_details_page.dart'; import 'package:cake_wallet/src/screens/transaction_details/transaction_details_page.dart';
import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_details_page.dart'; import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_details_page.dart';
import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_list_page.dart'; import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_list_page.dart';
@ -179,7 +184,6 @@ import 'package:cake_wallet/store/templates/exchange_template_store.dart';
import 'package:cake_wallet/store/templates/send_template_store.dart'; import 'package:cake_wallet/store/templates/send_template_store.dart';
import 'package:cake_wallet/store/wallet_list_store.dart'; import 'package:cake_wallet/store/wallet_list_store.dart';
import 'package:cake_wallet/store/yat/yat_store.dart'; import 'package:cake_wallet/store/yat/yat_store.dart';
import 'package:cake_wallet/tron/tron.dart';
import 'package:cake_wallet/view_model/auth_view_model.dart'; import 'package:cake_wallet/view_model/auth_view_model.dart';
import 'package:cake_wallet/view_model/backup_view_model.dart'; import 'package:cake_wallet/view_model/backup_view_model.dart';
import 'package:cake_wallet/view_model/buy/buy_amount_view_model.dart'; import 'package:cake_wallet/view_model/buy/buy_amount_view_model.dart';
@ -193,7 +197,6 @@ import 'package:cake_wallet/view_model/edit_backup_password_view_model.dart';
import 'package:cake_wallet/view_model/exchange/exchange_trade_view_model.dart'; import 'package:cake_wallet/view_model/exchange/exchange_trade_view_model.dart';
import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart'; import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart'; import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';
import 'package:cake_wallet/view_model/link_view_model.dart';
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart'; import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
import 'package:cake_wallet/view_model/monero_account_list/monero_account_edit_or_create_view_model.dart'; import 'package:cake_wallet/view_model/monero_account_list/monero_account_edit_or_create_view_model.dart';
import 'package:cake_wallet/view_model/monero_account_list/monero_account_list_view_model.dart'; import 'package:cake_wallet/view_model/monero_account_list/monero_account_list_view_model.dart';
@ -224,7 +227,6 @@ import 'package:cake_wallet/view_model/wallet_unlock_loadable_view_model.dart';
import 'package:cake_wallet/view_model/wallet_unlock_verifiable_view_model.dart'; import 'package:cake_wallet/view_model/wallet_unlock_verifiable_view_model.dart';
import 'package:cake_wallet/wownero/wownero.dart'; import 'package:cake_wallet/wownero/wownero.dart';
import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/receive_page_option.dart';
import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -853,6 +855,8 @@ Future<void> setup({
getIt.registerFactoryParam<ContactPage, ContactRecord?, void>( getIt.registerFactoryParam<ContactPage, ContactRecord?, void>(
(ContactRecord? contact, _) => ContactPage(getIt.get<ContactViewModel>(param1: contact))); (ContactRecord? contact, _) => ContactPage(getIt.get<ContactViewModel>(param1: contact)));
getIt.registerFactory(() => AddressListPage(getIt.get<WalletAddressListViewModel>()));
getIt.registerFactory(() { getIt.registerFactory(() {
final appStore = getIt.get<AppStore>(); final appStore = getIt.get<AppStore>();
return NodeListViewModel(_nodeSource, appStore); return NodeListViewModel(_nodeSource, appStore);
@ -1275,5 +1279,7 @@ Future<void> setup({
getIt.registerFactory(() => NFTViewModel(appStore, getIt.get<BottomSheetService>())); getIt.registerFactory(() => NFTViewModel(appStore, getIt.get<BottomSheetService>()));
getIt.registerFactory<TorPage>(() => TorPage(getIt.get<AppStore>())); getIt.registerFactory<TorPage>(() => TorPage(getIt.get<AppStore>()));
getIt.registerFactory(() => SignViewModel(getIt.get<AppStore>().wallet!));
_isSetupFinished = true; _isSetupFinished = true;
} }

View file

@ -21,16 +21,14 @@ Future<void> bootstrap(GlobalKey<NavigatorState> navigatorKey) async {
final settingsStore = getIt.get<SettingsStore>(); final settingsStore = getIt.get<SettingsStore>();
final fiatConversionStore = getIt.get<FiatConversionStore>(); final fiatConversionStore = getIt.get<FiatConversionStore>();
final currentWalletName = getIt final currentWalletName =
.get<SharedPreferences>() getIt.get<SharedPreferences>().getString(PreferencesKey.currentWalletName);
.getString(PreferencesKey.currentWalletName);
if (currentWalletName != null) { if (currentWalletName != null) {
authenticationStore.installed(); authenticationStore.installed();
} }
startAuthenticationStateChange(authenticationStore, navigatorKey); startAuthenticationStateChange(authenticationStore, navigatorKey);
startCurrentWalletChangeReaction( startCurrentWalletChangeReaction(appStore, settingsStore, fiatConversionStore);
appStore, settingsStore, fiatConversionStore);
startCurrentFiatChangeReaction(appStore, settingsStore, fiatConversionStore); startCurrentFiatChangeReaction(appStore, settingsStore, fiatConversionStore);
startCurrentFiatApiModeChangeReaction(appStore, settingsStore, fiatConversionStore); startCurrentFiatApiModeChangeReaction(appStore, settingsStore, fiatConversionStore);
startOnCurrentNodeChangeReaction(appStore); startOnCurrentNodeChangeReaction(appStore);

View file

@ -7,14 +7,17 @@ import 'package:flutter/widgets.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:cake_wallet/entities/load_current_wallet.dart'; import 'package:cake_wallet/entities/load_current_wallet.dart';
import 'package:cake_wallet/store/authentication_store.dart'; import 'package:cake_wallet/store/authentication_store.dart';
import 'package:rxdart/subjects.dart';
ReactionDisposer? _onAuthenticationStateChange; ReactionDisposer? _onAuthenticationStateChange;
dynamic loginError; dynamic loginError;
StreamController<dynamic> authenticatedErrorStreamController = StreamController<dynamic>(); StreamController<dynamic> authenticatedErrorStreamController = BehaviorSubject<dynamic>();
void startAuthenticationStateChange( void startAuthenticationStateChange(
AuthenticationStore authenticationStore, GlobalKey<NavigatorState> navigatorKey) { AuthenticationStore authenticationStore,
GlobalKey<NavigatorState> navigatorKey,
) {
authenticatedErrorStreamController.stream.listen((event) { authenticatedErrorStreamController.stream.listen((event) {
if (authenticationStore.state == AuthenticationState.allowed) { if (authenticationStore.state == AuthenticationState.allowed) {
ExceptionHandler.showError(event.toString(), delayInSeconds: 3); ExceptionHandler.showError(event.toString(), delayInSeconds: 3);

View file

@ -27,6 +27,7 @@ import 'package:cake_wallet/src/screens/dashboard/edit_token_page.dart';
import 'package:cake_wallet/src/screens/dashboard/home_settings_page.dart'; import 'package:cake_wallet/src/screens/dashboard/home_settings_page.dart';
import 'package:cake_wallet/src/screens/dashboard/pages/address_page.dart'; import 'package:cake_wallet/src/screens/dashboard/pages/address_page.dart';
import 'package:cake_wallet/src/screens/dashboard/pages/nft_details_page.dart'; import 'package:cake_wallet/src/screens/dashboard/pages/nft_details_page.dart';
import 'package:cake_wallet/src/screens/dashboard/sign_page.dart';
import 'package:cake_wallet/src/screens/dashboard/pages/transactions_page.dart'; import 'package:cake_wallet/src/screens/dashboard/pages/transactions_page.dart';
import 'package:cake_wallet/src/screens/disclaimer/disclaimer_page.dart'; import 'package:cake_wallet/src/screens/disclaimer/disclaimer_page.dart';
import 'package:cake_wallet/src/screens/exchange/exchange_page.dart'; import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
@ -42,6 +43,8 @@ import 'package:cake_wallet/src/screens/new_wallet/new_wallet_page.dart';
import 'package:cake_wallet/src/screens/new_wallet/new_wallet_type_page.dart'; import 'package:cake_wallet/src/screens/new_wallet/new_wallet_type_page.dart';
import 'package:cake_wallet/src/screens/nodes/node_create_or_edit_page.dart'; import 'package:cake_wallet/src/screens/nodes/node_create_or_edit_page.dart';
import 'package:cake_wallet/src/screens/nodes/pow_node_create_or_edit_page.dart'; import 'package:cake_wallet/src/screens/nodes/pow_node_create_or_edit_page.dart';
import 'package:cake_wallet/src/screens/receive/address_list_page.dart';
import 'package:cake_wallet/src/screens/restore/sweeping_wallet_page.dart';
import 'package:cake_wallet/src/screens/order_details/order_details_page.dart'; import 'package:cake_wallet/src/screens/order_details/order_details_page.dart';
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart'; import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
import 'package:cake_wallet/src/screens/receive/anonpay_invoice_page.dart'; import 'package:cake_wallet/src/screens/receive/anonpay_invoice_page.dart';
@ -99,6 +102,7 @@ import 'package:cake_wallet/utils/payment_request.dart';
import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart'; import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/sign_view_model.dart';
import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart'; import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart'; import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart'; import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
@ -465,6 +469,9 @@ Route<dynamic> createRoute(RouteSettings settings) {
return MaterialPageRoute<void>( return MaterialPageRoute<void>(
builder: (_) => getIt.get<ContactListPage>(param1: selectedCurrency)); builder: (_) => getIt.get<ContactListPage>(param1: selectedCurrency));
case Routes.pickerWalletAddress:
return MaterialPageRoute<void>(builder: (_) => getIt.get<AddressListPage>());
case Routes.addressBookAddContact: case Routes.addressBookAddContact:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
builder: (_) => getIt.get<ContactPage>(param1: settings.arguments as ContactRecord?)); builder: (_) => getIt.get<ContactPage>(param1: settings.arguments as ContactRecord?));
@ -696,6 +703,13 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.torPage: case Routes.torPage:
return MaterialPageRoute<void>(builder: (_) => getIt.get<TorPage>()); return MaterialPageRoute<void>(builder: (_) => getIt.get<TorPage>());
case Routes.signPage:
return MaterialPageRoute<void>(
builder: (_) => SignPage(
getIt.get<SignViewModel>(),
),
);
case Routes.connectDevices: case Routes.connectDevices:
final params = settings.arguments as ConnectDevicePageParams; final params = settings.arguments as ConnectDevicePageParams;
return MaterialPageRoute<void>( return MaterialPageRoute<void>(

View file

@ -31,6 +31,7 @@ class Routes {
static const nanoAccountCreation = '/nano_account_new'; static const nanoAccountCreation = '/nano_account_new';
static const addressBook = '/address_book'; static const addressBook = '/address_book';
static const pickerAddressBook = '/picker_address_book'; static const pickerAddressBook = '/picker_address_book';
static const pickerWalletAddress = '/picker_wallet_address';
static const addressBookAddContact = '/address_book_add_contact'; static const addressBookAddContact = '/address_book_add_contact';
static const showKeys = '/show_keys'; static const showKeys = '/show_keys';
static const exchangeConfirm = '/exchange_confirm'; static const exchangeConfirm = '/exchange_confirm';
@ -103,5 +104,6 @@ class Routes {
static const nftDetailsPage = '/nft_details_page'; static const nftDetailsPage = '/nft_details_page';
static const importNFTPage = '/import_nft_page'; static const importNFTPage = '/import_nft_page';
static const torPage = '/tor_page'; static const torPage = '/tor_page';
static const signPage = '/sign_page';
static const connectDevices = '/device/connect'; static const connectDevices = '/device/connect';
} }

View file

@ -322,31 +322,31 @@ class CakePayBuyCardDetailPage extends BasePage {
await showPopUp<void>( await showPopUp<void>(
context: context, context: context,
builder: (_) { builder: (popupContext) {
return Observer( return Observer(
builder: (_) => ConfirmSendingAlert( builder: (_) => ConfirmSendingAlert(
alertTitle: S.of(context).confirm_sending, alertTitle: S.of(popupContext).confirm_sending,
paymentId: S.of(context).payment_id, paymentId: S.of(popupContext).payment_id,
paymentIdValue: order?.orderId, paymentIdValue: order?.orderId,
expirationTime: cakePayPurchaseViewModel.formattedRemainingTime, expirationTime: cakePayPurchaseViewModel.formattedRemainingTime,
onDispose: () => _handleDispose(disposer), onDispose: () => _handleDispose(disposer),
amount: S.of(context).send_amount, amount: S.of(popupContext).send_amount,
amountValue: pendingTransaction.amountFormatted, amountValue: pendingTransaction.amountFormatted,
fiatAmountValue: fiatAmountValue:
cakePayPurchaseViewModel.sendViewModel.pendingTransactionFiatAmountFormatted, cakePayPurchaseViewModel.sendViewModel.pendingTransactionFiatAmountFormatted,
fee: S.of(context).send_fee, fee: S.of(popupContext).send_fee,
feeValue: pendingTransaction.feeFormatted, feeValue: pendingTransaction.feeFormatted,
feeFiatAmount: feeFiatAmount:
cakePayPurchaseViewModel.sendViewModel.pendingTransactionFeeFiatAmountFormatted, cakePayPurchaseViewModel.sendViewModel.pendingTransactionFeeFiatAmountFormatted,
feeRate: pendingTransaction.feeRate, feeRate: pendingTransaction.feeRate,
outputs: cakePayPurchaseViewModel.sendViewModel.outputs, outputs: cakePayPurchaseViewModel.sendViewModel.outputs,
rightButtonText: S.of(context).send, rightButtonText: S.of(popupContext).send,
leftButtonText: S.of(context).cancel, leftButtonText: S.of(popupContext).cancel,
actionRightButton: () async { actionRightButton: () async {
Navigator.of(context).pop(); Navigator.of(popupContext).pop();
await cakePayPurchaseViewModel.sendViewModel.commitTransaction(); await cakePayPurchaseViewModel.sendViewModel.commitTransaction();
}, },
actionLeftButton: () => Navigator.of(context).pop())); actionLeftButton: () => Navigator.of(popupContext).pop()));
}, },
); );
} }

View file

@ -200,14 +200,14 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
} }
try { try {
if (context.mounted) { if (mounted) {
changeProcessText(S.of(context).wallet_list_loading_wallet(wallet.name)); changeProcessText(S.of(context).wallet_list_loading_wallet(wallet.name));
} }
await widget.walletListViewModel.loadWallet(wallet); await widget.walletListViewModel.loadWallet(wallet);
hideProgressText(); hideProgressText();
setState(() {}); setState(() {});
} catch (e) { } catch (e) {
if (context.mounted) { if (mounted) {
changeProcessText(S.of(context).wallet_list_failed_to_load(wallet.name, e.toString())); changeProcessText(S.of(context).wallet_list_failed_to_load(wallet.name, e.toString()));
} }
} }

View file

@ -206,7 +206,7 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
), ),
contractAddress: _contractAddressController.text, contractAddress: _contractAddressController.text,
); );
if (context.mounted) { if (mounted) {
Navigator.pop(context); Navigator.pop(context);
} }
} }

View file

@ -287,8 +287,8 @@ class CryptoBalanceWidget extends StatelessWidget {
padding: const EdgeInsets.fromLTRB(16, 0, 16, 8), padding: const EdgeInsets.fromLTRB(16, 0, 16, 8),
child: DashBoardRoundedCardWidget( child: DashBoardRoundedCardWidget(
customBorder: 30, customBorder: 30,
title: "Monero wallet is broken", title: "This wallet has encountered an issue",
subTitle: "Here are the things that are broken:\n - " subTitle: "Here are the things that you should note:\n - "
+dashboardViewModel.isMoneroWalletBrokenReasons.join("\n - ") +dashboardViewModel.isMoneroWalletBrokenReasons.join("\n - ")
+"\n\nPlease restart your wallet and if it doesn't help contact our support.", +"\n\nPlease restart your wallet and if it doesn't help contact our support.",
onTap: () {}, onTap: () {},

View file

@ -8,6 +8,7 @@ import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
import 'package:cake_wallet/view_model/dashboard/cake_features_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/cake_features_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
@ -64,6 +65,19 @@ class CakeFeaturesPage extends StatelessWidget {
subTitle: S.of(context).nanogpt_subtitle, subTitle: S.of(context).nanogpt_subtitle,
onTap: () => _launchUrl("cake.nano-gpt.com"), onTap: () => _launchUrl("cake.nano-gpt.com"),
), ),
SizedBox(height: 20),
Observer(
builder: (context) {
if (!dashboardViewModel.hasSignMessages) {
return const SizedBox();
}
return DashBoardRoundedCardWidget(
onTap: () => Navigator.of(context).pushNamed(Routes.signPage),
title: S.current.sign_verify_message,
subTitle: S.current.sign_verify_message_sub,
);
},
),
], ],
), ),
), ),

View file

@ -0,0 +1,202 @@
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/sign_form.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/verify_form.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/dashboard/sign_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
import 'package:mobx/mobx.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
class SignPage extends BasePage {
SignPage(this.signViewModel)
: signFormKey = GlobalKey<SignFormState>(),
verifyFormKey = GlobalKey<VerifyFormState>(),
_pages = [],
_controller = PageController(initialPage: 0) {
_pages.add(SignForm(
key: signFormKey,
type: signViewModel.wallet.type,
includeAddress: signViewModel.signIncludesAddress,
));
_pages.add(VerifyForm(
key: verifyFormKey,
type: signViewModel.wallet.type,
));
}
@override
Widget middle(BuildContext context) => Observer(
builder: (_) => Text(
S.current.sign_verify_title,
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
fontFamily: 'Lato',
color: titleColor(context),
),
));
final SignViewModel signViewModel;
final PageController _controller;
final List<Widget> _pages;
final GlobalKey<SignFormState> signFormKey;
final GlobalKey<VerifyFormState> verifyFormKey;
bool _isEffectsInstalled = false;
@override
Widget body(BuildContext context) {
_setEffects(context);
return KeyboardActions(
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor: Theme.of(context).extension<KeyboardTheme>()!.keyboardBarColor,
nextFocus: false,
actions: [
KeyboardActionsItem(
focusNode: FocusNode(),
toolbarButtons: [(_) => KeyboardDoneButton()],
)
],
),
child: Container(
height: 0,
color: Theme.of(context).colorScheme.background,
child: Center(
child: ConstrainedBox(
constraints:
BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: PageView.builder(
onPageChanged: (page) {
signViewModel.isSigning = page == 0;
},
controller: _controller,
itemCount: _pages.length,
itemBuilder: (_, index) => SingleChildScrollView(child: _pages[index]),
),
),
if (_pages.length > 1)
Padding(
padding: EdgeInsets.only(top: 10),
child: SmoothPageIndicator(
controller: _controller,
count: _pages.length,
effect: ColorTransitionEffect(
spacing: 6.0,
radius: 6.0,
dotWidth: 6.0,
dotHeight: 6.0,
dotColor: Theme.of(context).hintColor.withOpacity(0.5),
activeDotColor: Theme.of(context).hintColor,
),
),
),
Padding(
padding: EdgeInsets.only(top: 20, bottom: 24, left: 24, right: 24),
child: Column(
children: [
Observer(
builder: (context) {
return LoadingPrimaryButton(
onPressed: () async {
await _confirmForm(context);
},
text: signViewModel.isSigning
? S.current.sign_message
: S.current.verify_message,
color: Theme.of(context)
.extension<WalletListTheme>()!
.createNewWalletButtonBackgroundColor,
textColor: Theme.of(context)
.extension<WalletListTheme>()!
.restoreWalletButtonTextColor,
isLoading: signViewModel.state is IsExecutingState,
isDisabled: signViewModel.state is IsExecutingState,
);
},
),
],
),
)
],
),
),
),
),
);
}
void _setEffects(BuildContext context) async {
if (_isEffectsInstalled) {
return;
}
_isEffectsInstalled = true;
reaction((_) => signViewModel.state, (ExecutionState state) {
if (state is FailureState) {
WidgetsBinding.instance.addPostFrameCallback((_) {
showPopUp<void>(
context: context,
builder: (_) {
return AlertWithOneAction(
alertTitle: S.current.error,
alertContent: state.error,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop(),
);
});
});
}
if (state is ExecutedSuccessfullyState) {
if (signViewModel.isSigning) {
signFormKey.currentState!.signatureController.text = state.payload as String;
} else {
WidgetsBinding.instance.addPostFrameCallback((_) {
showPopUp<void>(
context: context,
builder: (_) {
return AlertWithOneAction(
alertTitle: S.current.successful,
alertContent: S.current.message_verified,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop(),
);
});
});
}
}
});
}
Future<void> _confirmForm(BuildContext context) async {
FocusManager.instance.primaryFocus?.unfocus();
if (signViewModel.isSigning) {
String message = signFormKey.currentState!.messageController.text;
String? address;
if (signViewModel.signIncludesAddress) {
address = signFormKey.currentState!.addressController.text;
}
await signViewModel.sign(message, address: address);
} else {
String message = verifyFormKey.currentState!.messageController.text;
String signature = verifyFormKey.currentState!.signatureController.text;
String address = verifyFormKey.currentState!.addressController.text;
await signViewModel.verify(message, signature, address: address);
}
}
}

View file

@ -0,0 +1,98 @@
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/address_text_field.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/utils/show_bar.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class SignForm extends StatefulWidget {
SignForm({
Key? key,
required this.type,
required this.includeAddress,
}) : super(key: key);
final WalletType type;
final bool includeAddress;
@override
SignFormState createState() => SignFormState();
}
class SignFormState extends State<SignForm> {
SignFormState()
: formKey = GlobalKey<FormState>(),
messageController = TextEditingController(),
addressController = TextEditingController(),
signatureController = TextEditingController();
final TextEditingController messageController;
final TextEditingController addressController;
final TextEditingController signatureController;
final GlobalKey<FormState> formKey;
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(left: 24, right: 24),
child: Column(
children: [
Form(
key: formKey,
child: Column(
children: [
AddressTextField(
controller: messageController,
placeholder: S.current.message,
options: [AddressTextFieldOption.paste],
buttonColor: Theme.of(context).hintColor,
),
if (widget.includeAddress) ...[
const SizedBox(height: 20),
AddressTextField(
controller: addressController,
options: [
AddressTextFieldOption.paste,
AddressTextFieldOption.walletAddresses
],
buttonColor: Theme.of(context).hintColor,
onSelectedContact: (contact) {
addressController.text = contact.address;
},
selectedCurrency: walletTypeToCryptoCurrency(widget.type),
),
],
],
)),
const SizedBox(height: 20),
GestureDetector(
onTap: () async {
final text = signatureController.text;
if (text.isEmpty) {
return;
}
Clipboard.setData(ClipboardData(text: text));
showBar<void>(context, S.of(context).transaction_details_copied(text));
},
child: BaseTextFormField(
enabled: false,
controller: signatureController,
hintText: S.current.signature,
),
),
],
),
);
}
}

View file

@ -0,0 +1,92 @@
import 'package:cake_wallet/core/wallet_name_validator.dart';
import 'package:cake_wallet/entities/generate_name.dart';
import 'package:cake_wallet/entities/seed_type.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/address_text_field.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart';
import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:cake_wallet/src/widgets/seed_language_picker.dart';
import 'package:cake_wallet/src/widgets/seed_widget.dart';
import 'package:cake_wallet/themes/extensions/address_theme.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
import 'package:cake_wallet/utils/show_bar.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:mobx/mobx.dart';
import 'package:polyseed/polyseed.dart';
class VerifyForm extends StatefulWidget {
VerifyForm({
Key? key,
required this.type,
}) : super(key: key);
final WalletType type;
@override
VerifyFormState createState() => VerifyFormState();
}
class VerifyFormState extends State<VerifyForm> {
VerifyFormState()
: formKey = GlobalKey<FormState>(),
messageController = TextEditingController(),
addressController = TextEditingController(),
signatureController = TextEditingController();
final TextEditingController messageController;
final TextEditingController addressController;
final TextEditingController signatureController;
final GlobalKey<FormState> formKey;
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(left: 24, right: 24),
child: Form(
key: formKey,
child: Column(
children: [
AddressTextField(
controller: messageController,
placeholder: S.current.message,
options: [AddressTextFieldOption.paste],
buttonColor: Theme.of(context).hintColor,
),
const SizedBox(height: 20),
AddressTextField(
controller: addressController,
options: [AddressTextFieldOption.paste, AddressTextFieldOption.walletAddresses],
buttonColor: Theme.of(context).hintColor,
onSelectedContact: (contact) {
addressController.text = contact.address;
},
selectedCurrency: walletTypeToCryptoCurrency(widget.type),
),
const SizedBox(height: 20),
AddressTextField(
controller: signatureController,
placeholder: S.current.signature,
options: [AddressTextFieldOption.paste],
buttonColor: Theme.of(context).hintColor,
),
],
),
),
);
}
}

View file

@ -284,7 +284,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
if (state is TransactionCommitted) { if (state is TransactionCommitted) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
if (context.mounted) { if (mounted) {
showPopUp<void>( showPopUp<void>(
context: context, context: context,
builder: (BuildContext popupContext) { builder: (BuildContext popupContext) {

View file

@ -95,7 +95,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
if (state is FailureState) { if (state is FailureState) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
if (context.mounted) { if (mounted) {
showPopUp<void>( showPopUp<void>(
context: context, context: context,
builder: (_) { builder: (_) {

View file

@ -0,0 +1,31 @@
import 'package:cake_wallet/src/screens/receive/widgets/address_list.dart';
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
class AddressListPage extends BasePage {
AddressListPage(this.addressListViewModel);
final WalletAddressListViewModel addressListViewModel;
@override
String get title => S.current.accounts_subaddresses;
@override
Widget body(BuildContext context) {
return SingleChildScrollView(
child: Column(
children: <Widget>[
AddressList(
addressListViewModel: addressListViewModel,
onSelect: (String address) async {
Navigator.of(context).pop(address);
},
),
],
),
);
}
}

View file

@ -1,4 +1,5 @@
import 'package:cake_wallet/src/screens/nano_accounts/nano_account_list_page.dart'; import 'package:cake_wallet/src/screens/nano_accounts/nano_account_list_page.dart';
import 'package:cake_wallet/src/screens/receive/widgets/address_list.dart';
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart'; import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart'; import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart'; import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
@ -122,108 +123,7 @@ class ReceivePage extends BasePage {
amountController: _amountController, amountController: _amountController,
isLight: currentTheme.type == ThemeType.light), isLight: currentTheme.type == ThemeType.light),
), ),
Observer( AddressList(addressListViewModel: addressListViewModel),
builder: (_) => ListView.separated(
padding: EdgeInsets.all(0),
separatorBuilder: (context, _) => const HorizontalSectionDivider(),
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: addressListViewModel.items.length,
itemBuilder: (context, index) {
final item = addressListViewModel.items[index];
Widget cell = Container();
if (item is WalletAccountListHeader) {
cell = HeaderTile(
showTrailingButton: true,
walletAddressListViewModel: addressListViewModel,
trailingButtonTap: () async {
if (addressListViewModel.type == WalletType.monero ||
addressListViewModel.type == WalletType.wownero ||
addressListViewModel.type == WalletType.haven) {
await showPopUp<void>(
context: context,
builder: (_) => getIt.get<MoneroAccountListPage>());
} else {
await showPopUp<void>(
context: context,
builder: (_) => getIt.get<NanoAccountListPage>());
}
},
title: S.of(context).accounts,
trailingIcon: Icon(
Icons.arrow_forward_ios,
size: 14,
color: Theme.of(context).extension<ReceivePageTheme>()!.iconsColor,
));
}
if (item is WalletAddressListHeader) {
final hasTitle = item.title != null;
cell = HeaderTile(
title: hasTitle ? item.title! : S.of(context).addresses,
walletAddressListViewModel: addressListViewModel,
showTrailingButton:
!addressListViewModel.isAutoGenerateSubaddressEnabled && !hasTitle,
showSearchButton: true,
trailingButtonTap: () =>
Navigator.of(context).pushNamed(Routes.newSubaddress),
trailingIcon: hasTitle
? null
: Icon(
Icons.add,
size: 20,
color:
Theme.of(context).extension<ReceivePageTheme>()!.iconsColor,
),
);
}
if (item is WalletAddressListItem) {
cell = Observer(builder: (_) {
final isCurrent = item.address == addressListViewModel.address.address;
final backgroundColor = isCurrent
? Theme.of(context)
.extension<ReceivePageTheme>()!
.currentTileBackgroundColor
: Theme.of(context)
.extension<ReceivePageTheme>()!
.tilesBackgroundColor;
final textColor = isCurrent
? Theme.of(context)
.extension<ReceivePageTheme>()!
.currentTileTextColor
: Theme.of(context).extension<ReceivePageTheme>()!.tilesTextColor;
return AddressCell.fromItem(
item,
isCurrent: isCurrent,
hasBalance: addressListViewModel.isElectrumWallet,
backgroundColor: backgroundColor,
textColor: textColor,
onTap: item.isOneTimeReceiveAddress == true
? null
: (_) => addressListViewModel.setAddress(item),
onEdit: item.isOneTimeReceiveAddress == true || item.isPrimary
? null
: () => Navigator.of(context)
.pushNamed(Routes.newSubaddress, arguments: item),
onDelete: !addressListViewModel.isSilentPayments || item.isPrimary
? null
: () => addressListViewModel.deleteAddress(item),
);
});
}
return index != 0
? cell
: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30), topRight: Radius.circular(30)),
child: cell,
);
})),
Padding( Padding(
padding: EdgeInsets.fromLTRB(24, 24, 24, 32), padding: EdgeInsets.fromLTRB(24, 24, 24, 32),
child: Text( child: Text(

View file

@ -0,0 +1,120 @@
import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/monero_accounts/monero_account_list_page.dart';
import 'package:cake_wallet/src/screens/nano_accounts/nano_account_list_page.dart';
import 'package:cake_wallet/src/screens/receive/widgets/address_cell.dart';
import 'package:cake_wallet/src/screens/receive/widgets/header_tile.dart';
import 'package:cake_wallet/src/widgets/section_divider.dart';
import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/wallet_address_list/wallet_account_list_header.dart';
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_header.dart';
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_item.dart';
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
class AddressList extends StatelessWidget {
const AddressList({
super.key,
required this.addressListViewModel,
this.onSelect,
});
final WalletAddressListViewModel addressListViewModel;
final Function(String)? onSelect;
@override
Widget build(BuildContext context) {
bool editable = onSelect == null;
return Observer(
builder: (_) => ListView.separated(
padding: EdgeInsets.all(0),
separatorBuilder: (context, _) => const HorizontalSectionDivider(),
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: addressListViewModel.items.length,
itemBuilder: (context, index) {
final item = addressListViewModel.items[index];
Widget cell = Container();
if (item is WalletAccountListHeader) {
cell = HeaderTile(
showTrailingButton: true,
walletAddressListViewModel: addressListViewModel,
trailingButtonTap: () async {
if (addressListViewModel.type == WalletType.monero ||
addressListViewModel.type == WalletType.haven) {
await showPopUp<void>(
context: context, builder: (_) => getIt.get<MoneroAccountListPage>());
} else {
await showPopUp<void>(
context: context, builder: (_) => getIt.get<NanoAccountListPage>());
}
},
title: S.of(context).accounts,
trailingIcon: Icon(
Icons.arrow_forward_ios,
size: 14,
color: Theme.of(context).extension<ReceivePageTheme>()!.iconsColor,
));
}
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,
));
}
if (item is WalletAddressListItem) {
cell = Observer(builder: (_) {
final isCurrent = item.address == addressListViewModel.address.address && editable;
final backgroundColor = isCurrent
? Theme.of(context).extension<ReceivePageTheme>()!.currentTileBackgroundColor
: Theme.of(context).extension<ReceivePageTheme>()!.tilesBackgroundColor;
final textColor = isCurrent
? Theme.of(context).extension<ReceivePageTheme>()!.currentTileTextColor
: Theme.of(context).extension<ReceivePageTheme>()!.tilesTextColor;
return AddressCell.fromItem(
item,
isCurrent: isCurrent,
hasBalance: addressListViewModel.isElectrumWallet,
backgroundColor: backgroundColor,
textColor: textColor,
onTap: (_) {
if (onSelect != null) {
onSelect!(item.address);
return;
}
addressListViewModel.setAddress(item);
},
onEdit: editable
? () => Navigator.of(context).pushNamed(Routes.newSubaddress, arguments: item)
: null,
);
});
}
return index != 0
? cell
: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30), topRight: Radius.circular(30)),
child: cell,
);
},
),
);
}
}

View file

@ -219,7 +219,7 @@ class RootState extends State<Root> with WidgetsBindingObserver {
void waitForWalletInstance(BuildContext context) { void waitForWalletInstance(BuildContext context) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
if (context.mounted) { if (mounted) {
_walletReactionDisposer = reaction( _walletReactionDisposer = reaction(
(_) => widget.appStore.wallet, (_) => widget.appStore.wallet,
(WalletBase? wallet) { (WalletBase? wallet) {

View file

@ -82,7 +82,7 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
if (initialPaymentRequest != null && if (initialPaymentRequest != null &&
sendViewModel.walletCurrencyName != initialPaymentRequest!.scheme.toLowerCase()) { sendViewModel.walletCurrencyName != initialPaymentRequest!.scheme.toLowerCase()) {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) { WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
if (context.mounted) { if (mounted) {
showPopUp<void>( showPopUp<void>(
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {

View file

@ -12,7 +12,7 @@ import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
import 'package:cake_wallet/utils/permission_handler.dart'; import 'package:cake_wallet/utils/permission_handler.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
enum AddressTextFieldOption { paste, qrCode, addressBook } enum AddressTextFieldOption { paste, qrCode, addressBook, walletAddresses }
class AddressTextField extends StatelessWidget { class AddressTextField extends StatelessWidget {
AddressTextField( AddressTextField(
@ -34,6 +34,7 @@ class AddressTextField extends StatelessWidget {
this.validator, this.validator,
this.onPushPasteButton, this.onPushPasteButton,
this.onPushAddressBookButton, this.onPushAddressBookButton,
this.onPushAddressPickerButton,
this.onSelectedContact, this.onSelectedContact,
this.selectedCurrency}); this.selectedCurrency});
@ -56,6 +57,7 @@ class AddressTextField extends StatelessWidget {
final FocusNode? focusNode; final FocusNode? focusNode;
final Function(BuildContext context)? onPushPasteButton; final Function(BuildContext context)? onPushPasteButton;
final Function(BuildContext context)? onPushAddressBookButton; final Function(BuildContext context)? onPushAddressBookButton;
final Function(BuildContext context)? onPushAddressPickerButton;
final Function(ContactBase contact)? onSelectedContact; final Function(ContactBase contact)? onSelectedContact;
final CryptoCurrency? selectedCurrency; final CryptoCurrency? selectedCurrency;
@ -70,16 +72,13 @@ class AddressTextField extends StatelessWidget {
enabled: isActive, enabled: isActive,
controller: controller, controller: controller,
focusNode: focusNode, focusNode: focusNode,
style: textStyle ?? style: textStyle ??
TextStyle( TextStyle(
fontSize: 16, color: Theme.of(context).extension<CakeTextTheme>()!.titleColor), fontSize: 16, color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
decoration: InputDecoration( decoration: InputDecoration(
suffixIcon: SizedBox( suffixIcon: SizedBox(
width: prefixIconWidth * options.length + (spaceBetweenPrefixIcons * options.length), width: prefixIconWidth * options.length + (spaceBetweenPrefixIcons * options.length),
), ),
hintStyle: hintStyle ?? TextStyle(fontSize: 16, color: Theme.of(context).hintColor), hintStyle: hintStyle ?? TextStyle(fontSize: 16, color: Theme.of(context).hintColor),
hintText: placeholder ?? S.current.widgets_address, hintText: placeholder ?? S.current.widgets_address,
focusedBorder: isBorderExist focusedBorder: isBorderExist
@ -104,14 +103,15 @@ class AddressTextField extends StatelessWidget {
top: 2, top: 2,
right: 0, right: 0,
child: SizedBox( child: SizedBox(
width: prefixIconWidth * options.length + (spaceBetweenPrefixIcons * options.length), width:
(prefixIconWidth * options.length) + (spaceBetweenPrefixIcons * options.length),
child: Row( child: Row(
mainAxisAlignment: responsiveLayoutUtil.shouldRenderMobileUI mainAxisAlignment: responsiveLayoutUtil.shouldRenderMobileUI
? MainAxisAlignment.spaceBetween ? MainAxisAlignment.spaceBetween
: MainAxisAlignment.end, : MainAxisAlignment.end,
children: [ children: [
SizedBox(width: 5),
if (this.options.contains(AddressTextFieldOption.paste)) ...[ if (this.options.contains(AddressTextFieldOption.paste)) ...[
SizedBox(width: 5),
Container( Container(
width: prefixIconWidth, width: prefixIconWidth,
height: prefixIconHeight, height: prefixIconHeight,
@ -123,8 +123,8 @@ class AddressTextField extends StatelessWidget {
child: Container( child: Container(
padding: EdgeInsets.all(8), padding: EdgeInsets.all(8),
decoration: BoxDecoration( decoration: BoxDecoration(
color: buttonColor ?? color:
Theme.of(context).dialogTheme.backgroundColor, buttonColor ?? Theme.of(context).dialogTheme.backgroundColor,
borderRadius: BorderRadius.all(Radius.circular(6))), borderRadius: BorderRadius.all(Radius.circular(6))),
child: Image.asset( child: Image.asset(
'assets/images/paste_ios.png', 'assets/images/paste_ios.png',
@ -134,10 +134,12 @@ class AddressTextField extends StatelessWidget {
.textFieldButtonIconColor, .textFieldButtonIconColor,
)), )),
), ),
)), ),
),
], ],
if (this.options.contains(AddressTextFieldOption.qrCode) && if (this.options.contains(AddressTextFieldOption.qrCode) &&
DeviceInfo.instance.isMobile) ...[ DeviceInfo.instance.isMobile) ...[
SizedBox(width: 5),
Container( Container(
width: prefixIconWidth, width: prefixIconWidth,
height: prefixIconHeight, height: prefixIconHeight,
@ -149,8 +151,8 @@ class AddressTextField extends StatelessWidget {
child: Container( child: Container(
padding: EdgeInsets.all(8), padding: EdgeInsets.all(8),
decoration: BoxDecoration( decoration: BoxDecoration(
color: buttonColor ?? color:
Theme.of(context).dialogTheme.backgroundColor, buttonColor ?? Theme.of(context).dialogTheme.backgroundColor,
borderRadius: BorderRadius.all(Radius.circular(6))), borderRadius: BorderRadius.all(Radius.circular(6))),
child: Image.asset( child: Image.asset(
'assets/images/qr_code_icon.png', 'assets/images/qr_code_icon.png',
@ -160,10 +162,11 @@ class AddressTextField extends StatelessWidget {
.textFieldButtonIconColor, .textFieldButtonIconColor,
)), )),
), ),
)) ),
] else ),
SizedBox(width: 5), ],
if (this.options.contains(AddressTextFieldOption.addressBook)) ...[ if (this.options.contains(AddressTextFieldOption.addressBook)) ...[
SizedBox(width: 5),
Container( Container(
width: prefixIconWidth, width: prefixIconWidth,
height: prefixIconHeight, height: prefixIconHeight,
@ -175,8 +178,8 @@ class AddressTextField extends StatelessWidget {
child: Container( child: Container(
padding: EdgeInsets.all(8), padding: EdgeInsets.all(8),
decoration: BoxDecoration( decoration: BoxDecoration(
color: buttonColor ?? color:
Theme.of(context).dialogTheme.backgroundColor, buttonColor ?? Theme.of(context).dialogTheme.backgroundColor,
borderRadius: BorderRadius.all(Radius.circular(6))), borderRadius: BorderRadius.all(Radius.circular(6))),
child: Image.asset( child: Image.asset(
'assets/images/open_book.png', 'assets/images/open_book.png',
@ -186,8 +189,36 @@ class AddressTextField extends StatelessWidget {
.textFieldButtonIconColor, .textFieldButtonIconColor,
)), )),
), ),
)) ),
] ),
],
if (this.options.contains(AddressTextFieldOption.walletAddresses)) ...[
SizedBox(width: 5),
Container(
width: prefixIconWidth,
height: prefixIconHeight,
padding: EdgeInsets.only(top: 0),
child: Semantics(
label: S.of(context).address_book,
child: InkWell(
onTap: () async => _presetWalletAddressPicker(context),
child: Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color:
buttonColor ?? Theme.of(context).dialogTheme.backgroundColor,
borderRadius: BorderRadius.all(Radius.circular(6))),
child: Image.asset(
'assets/images/open_book.png',
color: iconColor ??
Theme.of(context)
.extension<SendPageTheme>()!
.textFieldButtonIconColor,
)),
),
),
)
],
], ],
), ),
)) ))
@ -224,6 +255,15 @@ class AddressTextField extends StatelessWidget {
} }
} }
Future<void> _presetWalletAddressPicker(BuildContext context) async {
final address = await Navigator.of(context).pushNamed(Routes.pickerWalletAddress);
if (address is String) {
controller?.text = address;
onPushAddressPickerButton?.call(context);
}
}
Future<void> _pasteAddress(BuildContext context) async { Future<void> _pasteAddress(BuildContext context) async {
final clipboard = await Clipboard.getData('text/plain'); final clipboard = await Clipboard.getData('text/plain');
final address = clipboard?.text ?? ''; final address = clipboard?.text ?? '';

View file

@ -17,7 +17,7 @@ class SeedLanguagePickerOption {
final List<SeedLanguagePickerOption> seedLanguages = [ final List<SeedLanguagePickerOption> seedLanguages = [
SeedLanguagePickerOption('English', S.current.seed_language_english, SeedLanguagePickerOption('English', S.current.seed_language_english,
Image.asset('assets/images/flags/usa.png'), [SeedType.legacy, SeedType.polyseed]), Image.asset('assets/images/flags/usa.png'), [SeedType.legacy, SeedType.polyseed]),
SeedLanguagePickerOption('Chinese (simplified)', S.current.seed_language_chinese, SeedLanguagePickerOption('Chinese (Simplified)', S.current.seed_language_chinese,
Image.asset('assets/images/flags/chn.png'), [SeedType.legacy, SeedType.polyseed]), Image.asset('assets/images/flags/chn.png'), [SeedType.legacy, SeedType.polyseed]),
SeedLanguagePickerOption('Chinese (Traditional)', S.current.seed_language_chinese_traditional, SeedLanguagePickerOption('Chinese (Traditional)', S.current.seed_language_chinese_traditional,
Image.asset('assets/images/flags/chn.png'), [SeedType.polyseed]), Image.asset('assets/images/flags/chn.png'), [SeedType.polyseed]),

View file

@ -32,7 +32,6 @@ import 'package:cake_wallet/view_model/dashboard/trade_list_item.dart';
import 'package:cake_wallet/view_model/dashboard/transaction_list_item.dart'; import 'package:cake_wallet/view_model/dashboard/transaction_list_item.dart';
import 'package:cake_wallet/view_model/settings/sync_mode.dart'; import 'package:cake_wallet/view_model/settings/sync_mode.dart';
import 'package:cake_wallet/wallet_type_utils.dart'; import 'package:cake_wallet/wallet_type_utils.dart';
import 'package:cake_wallet/wownero/wownero.dart' as wow;
import 'package:cryptography/cryptography.dart'; import 'package:cryptography/cryptography.dart';
import 'package:cw_core/balance.dart'; import 'package:cw_core/balance.dart';
import 'package:cw_core/cake_hive.dart'; import 'package:cw_core/cake_hive.dart';
@ -182,7 +181,8 @@ abstract class DashboardViewModelBase with Store {
final _accountTransactions = _wallet.transactionHistory.transactions.values final _accountTransactions = _wallet.transactionHistory.transactions.values
.where((tx) => .where((tx) =>
wow.wownero!.getTransactionInfoAccountId(tx) == wow.wownero!.getCurrentAccount(wallet).id) wow.wownero!.getTransactionInfoAccountId(tx) ==
wow.wownero!.getCurrentAccount(wallet).id)
.toList(); .toList();
final sortedTransactions = [..._accountTransactions]; final sortedTransactions = [..._accountTransactions];
@ -482,6 +482,30 @@ abstract class DashboardViewModelBase with Store {
@computed @computed
bool get hasPowNodes => wallet.type == WalletType.nano || wallet.type == WalletType.banano; bool get hasPowNodes => wallet.type == WalletType.nano || wallet.type == WalletType.banano;
@computed
bool get hasSignMessages {
if (wallet.isHardwareWallet) {
return false;
}
switch (wallet.type) {
case WalletType.monero:
case WalletType.litecoin:
case WalletType.bitcoin:
case WalletType.bitcoinCash:
case WalletType.ethereum:
case WalletType.polygon:
case WalletType.solana:
case WalletType.nano:
case WalletType.banano:
case WalletType.tron:
case WalletType.wownero:
return true;
case WalletType.haven:
case WalletType.none:
return false;
}
}
bool get showRepWarning { bool get showRepWarning {
if (wallet.type != WalletType.nano) { if (wallet.type != WalletType.nano) {
return false; return false;
@ -575,7 +599,8 @@ abstract class DashboardViewModelBase with Store {
} }
if (wallet.type == WalletType.wownero) { if (wallet.type == WalletType.wownero) {
return wow.wownero!.getTransactionInfoAccountId(tx) == wow.wownero!.getCurrentAccount(wallet).id; return wow.wownero!.getTransactionInfoAccountId(tx) ==
wow.wownero!.getCurrentAccount(wallet).id;
} }
return true; return true;
@ -600,8 +625,8 @@ abstract class DashboardViewModelBase with Store {
.getTransactionHistory(wallet) .getTransactionHistory(wallet)
.transactions .transactions
.values .values
.where( .where((tx) =>
(tx) => monero!.getTransactionInfoAccountId(tx) == monero!.getCurrentAccount(wallet).id) monero!.getTransactionInfoAccountId(tx) == monero!.getCurrentAccount(wallet).id)
.toList(); .toList();
transactions.addAll(_accountTransactions.map((transaction) => TransactionListItem( transactions.addAll(_accountTransactions.map((transaction) => TransactionListItem(
@ -613,8 +638,9 @@ abstract class DashboardViewModelBase with Store {
.getTransactionHistory(wallet) .getTransactionHistory(wallet)
.transactions .transactions
.values .values
.where( .where((tx) =>
(tx) => wow.wownero!.getTransactionInfoAccountId(tx) == wow.wownero!.getCurrentAccount(wallet).id) wow.wownero!.getTransactionInfoAccountId(tx) ==
wow.wownero!.getCurrentAccount(wallet).id)
.toList(); .toList();
transactions.addAll(_accountTransactions.map((transaction) => TransactionListItem( transactions.addAll(_accountTransactions.map((transaction) => TransactionListItem(

View file

@ -0,0 +1,55 @@
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:mobx/mobx.dart';
part 'sign_view_model.g.dart';
class SignViewModel = SignViewModelBase with _$SignViewModel;
abstract class SignViewModelBase with Store {
SignViewModelBase(this.wallet) : state = InitialExecutionState();
final WalletBase wallet;
@observable
ExecutionState state;
@observable
bool isSigning = true;
bool get signIncludesAddress => [
WalletType.monero,
WalletType.bitcoin,
WalletType.bitcoinCash,
WalletType.litecoin,
WalletType.haven,
].contains(wallet.type);
@action
Future<void> sign(String message, {String? address}) async {
state = IsExecutingState();
try {
final signature = await wallet.signMessage(message, address: address);
state = ExecutedSuccessfullyState(payload: signature);
} catch (e) {
state = FailureState(e.toString());
}
}
@action
Future<void> verify(String message, String signature, {String? address}) async {
state = IsExecutingState();
try {
final sig = await wallet.verifyMessage(message, signature, address: address);
if (sig) {
state = ExecutedSuccessfullyState();
} else {
state = FailureState(S.current.signature_invalid_error);
}
} catch (e) {
state = FailureState(e.toString());
}
}
}

View file

@ -142,7 +142,16 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
_bestRate = 0; _bestRate = 0;
_calculateBestRate(); _calculateBestRate();
}); });
if (isElectrumWallet) {
bitcoin!.updateFeeRates(wallet);
} }
}
bool get isElectrumWallet =>
wallet.type == WalletType.bitcoin ||
wallet.type == WalletType.litecoin ||
wallet.type == WalletType.bitcoinCash;
bool _useTorOnly; bool _useTorOnly;
final Box<Trade> trades; final Box<Trade> trades;

View file

@ -583,6 +583,30 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
String errorMessage = error.toString(); String errorMessage = error.toString();
if (walletType == WalletType.solana) { if (walletType == WalletType.solana) {
if (errorMessage.contains('insufficient lamports')) {
double solValueNeeded = 0.0;
// Regular expression to match the number after "need". This shows the exact lamports the user needs to perform the transaction.
RegExp regExp = RegExp(r'need (\d+)');
// Find the match
Match? match = regExp.firstMatch(errorMessage);
if (match != null) {
String neededAmount = match.group(1)!;
final lamportsNeeded = int.tryParse(neededAmount);
// 5000 lamport used here is the constant for sending a transaction on solana
int lamportsPerSol = 1000000000;
solValueNeeded =
lamportsNeeded != null ? ((lamportsNeeded + 5000) / lamportsPerSol) : 0.0;
return S.current.insufficient_lamports(solValueNeeded.toString());
} else {
print("No match found.");
return S.current.insufficient_lamport_for_tx;
}
}
if (errorMessage.contains('insufficient funds for rent')) { if (errorMessage.contains('insufficient funds for rent')) {
return S.current.insufficientFundsForRentError; return S.current.insufficientFundsForRentError;
} }

View file

@ -6,6 +6,7 @@ import 'package:cake_wallet/ethereum/ethereum.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/haven/haven.dart'; import 'package:cake_wallet/haven/haven.dart';
import 'package:cake_wallet/monero/monero.dart'; import 'package:cake_wallet/monero/monero.dart';
import 'package:cake_wallet/nano/nano.dart';
import 'package:cake_wallet/polygon/polygon.dart'; import 'package:cake_wallet/polygon/polygon.dart';
import 'package:cake_wallet/solana/solana.dart'; import 'package:cake_wallet/solana/solana.dart';
import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/store/app_store.dart';
@ -438,6 +439,14 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
addressList.add(WalletAddressListItem(isPrimary: true, name: null, address: primaryAddress)); addressList.add(WalletAddressListItem(isPrimary: true, name: null, address: primaryAddress));
} }
if (wallet.type == WalletType.nano) {
addressList.add(WalletAddressListItem(
isPrimary: true,
name: null,
address: wallet.walletAddresses.address,
));
}
if (wallet.type == WalletType.tron) { if (wallet.type == WalletType.tron) {
final primaryAddress = tron!.getAddress(wallet); final primaryAddress = tron!.getAddress(wallet);

View file

@ -117,9 +117,7 @@ abstract class WalletCreationVMBase with Store {
DerivationInfo? getDefaultDerivation() { DerivationInfo? getDefaultDerivation() {
switch (this.type) { switch (this.type) {
case WalletType.nano: case WalletType.nano:
return DerivationInfo( return DerivationInfo(derivationType: DerivationType.nano);
derivationType: DerivationType.nano,
);
case WalletType.bitcoin: case WalletType.bitcoin:
case WalletType.litecoin: case WalletType.litecoin:
return bitcoin!.getElectrumDerivations()[DerivationType.electrum]!.first; return bitcoin!.getElectrumDerivations()[DerivationType.electrum]!.first;
@ -131,9 +129,7 @@ abstract class WalletCreationVMBase with Store {
DerivationInfo? getCommonRestoreDerivation() { DerivationInfo? getCommonRestoreDerivation() {
switch (this.type) { switch (this.type) {
case WalletType.nano: case WalletType.nano:
return DerivationInfo( return DerivationInfo(derivationType: DerivationType.nano);
derivationType: DerivationType.nano,
);
case WalletType.bitcoin: case WalletType.bitcoin:
return DerivationInfo( return DerivationInfo(
derivationType: DerivationType.bip39, derivationType: DerivationType.bip39,

View file

@ -17,15 +17,13 @@ PODS:
- in_app_review (0.2.0): - in_app_review (0.2.0):
- FlutterMacOS - FlutterMacOS
- OrderedSet (5.0.0) - OrderedSet (5.0.0)
- package_info (0.0.1):
- FlutterMacOS
- package_info_plus (0.0.1): - package_info_plus (0.0.1):
- FlutterMacOS - FlutterMacOS
- path_provider_foundation (0.0.1): - path_provider_foundation (0.0.1):
- Flutter - Flutter
- FlutterMacOS - FlutterMacOS
- ReachabilitySwift (5.0.0) - ReachabilitySwift (5.0.0)
- share_plus_macos (0.0.1): - share_plus (0.0.1):
- FlutterMacOS - FlutterMacOS
- shared_preferences_foundation (0.0.1): - shared_preferences_foundation (0.0.1):
- Flutter - Flutter
@ -46,10 +44,9 @@ DEPENDENCIES:
- flutter_secure_storage_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos`) - flutter_secure_storage_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos`)
- FlutterMacOS (from `Flutter/ephemeral`) - FlutterMacOS (from `Flutter/ephemeral`)
- in_app_review (from `Flutter/ephemeral/.symlinks/plugins/in_app_review/macos`) - in_app_review (from `Flutter/ephemeral/.symlinks/plugins/in_app_review/macos`)
- package_info (from `Flutter/ephemeral/.symlinks/plugins/package_info/macos`)
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`) - package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
- share_plus_macos (from `Flutter/ephemeral/.symlinks/plugins/share_plus_macos/macos`) - share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`)
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`) - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
- sp_scanner (from `Flutter/ephemeral/.symlinks/plugins/sp_scanner/macos`) - sp_scanner (from `Flutter/ephemeral/.symlinks/plugins/sp_scanner/macos`)
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
@ -77,14 +74,12 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral :path: Flutter/ephemeral
in_app_review: in_app_review:
:path: Flutter/ephemeral/.symlinks/plugins/in_app_review/macos :path: Flutter/ephemeral/.symlinks/plugins/in_app_review/macos
package_info:
:path: Flutter/ephemeral/.symlinks/plugins/package_info/macos
package_info_plus: package_info_plus:
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
path_provider_foundation: path_provider_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
share_plus_macos: share_plus:
:path: Flutter/ephemeral/.symlinks/plugins/share_plus_macos/macos :path: Flutter/ephemeral/.symlinks/plugins/share_plus/macos
shared_preferences_foundation: shared_preferences_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
sp_scanner: sp_scanner:
@ -104,11 +99,10 @@ SPEC CHECKSUMS:
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
in_app_review: a850789fad746e89bce03d4aeee8078b45a53fd0 in_app_review: a850789fad746e89bce03d4aeee8078b45a53fd0
OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
package_info: 6eba2fd8d3371dda2d85c8db6fe97488f24b74b2 package_info_plus: fa739dd842b393193c5ca93c26798dff6e3d0e0c
package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
share_plus_macos: 853ee48e7dce06b633998ca0735d482dd671ade4 share_plus: 36537c04ce0c3e3f5bd297ce4318b6d5ee5fd6cf
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
sp_scanner: 269d96e0ec3173e69156be7239b95182be3b8303 sp_scanner: 269d96e0ec3173e69156be7239b95182be3b8303
url_launcher_macos: 5f437abeda8c85500ceb03f5c1938a8c5a705399 url_launcher_macos: 5f437abeda8c85500ceb03f5c1938a8c5a705399

View file

@ -94,15 +94,15 @@ dependencies:
# ref: main # ref: main
socks5_proxy: ^1.0.4 socks5_proxy: ^1.0.4
flutter_svg: ^2.0.9 flutter_svg: ^2.0.9
polyseed: ^0.0.5 polyseed: ^0.0.6
nostr_tools: ^1.0.9 nostr_tools: ^1.0.9
solana: ^0.30.1 solana: ^0.30.1
bitcoin_base: bitcoin_base:
git: git:
url: https://github.com/cake-tech/bitcoin_base url: https://github.com/cake-tech/bitcoin_base
ref: cake-update-v4 ref: cake-update-v5
ledger_flutter: ^1.0.1 ledger_flutter: ^1.0.1
hashlib: 1.12.0 hashlib: ^1.19.2
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
@ -135,6 +135,10 @@ dependency_overrides:
url: https://github.com/cake-tech/web3dart.git url: https://github.com/cake-tech/web3dart.git
ref: cake ref: cake
flutter_secure_storage_platform_interface: 1.0.2 flutter_secure_storage_platform_interface: 1.0.2
bitcoin_base:
git:
url: https://github.com/cake-tech/bitcoin_base
ref: cake-update-v5
flutter_icons: flutter_icons:
image_path: "assets/images/app_logo.png" image_path: "assets/images/app_logo.png"

View file

@ -338,6 +338,8 @@
"incoming": "الواردة", "incoming": "الواردة",
"incorrect_seed": "النص الذي تم إدخاله غير صالح.", "incorrect_seed": "النص الذي تم إدخاله غير صالح.",
"inputs": "المدخلات", "inputs": "المدخلات",
"insufficient_lamport_for_tx": "ليس لديك ما يكفي من SOL لتغطية المعاملة ورسوم المعاملات الخاصة بها. يرجى إضافة المزيد من SOL إلى محفظتك أو تقليل كمية SOL التي ترسلها.",
"insufficient_lamports": "ليس لديك ما يكفي من SOL لتغطية المعاملة ورسوم المعاملات الخاصة بها. تحتاج على الأقل ${solValueNeeded} sol. يرجى إضافة المزيد من sol إلى محفظتك أو تقليل مبلغ sol الذي ترسله",
"insufficientFundsForRentError": "ليس لديك ما يكفي من SOL لتغطية رسوم المعاملة والإيجار للحساب. يرجى إضافة المزيد من sol إلى محفظتك أو تقليل مبلغ sol الذي ترسله", "insufficientFundsForRentError": "ليس لديك ما يكفي من SOL لتغطية رسوم المعاملة والإيجار للحساب. يرجى إضافة المزيد من sol إلى محفظتك أو تقليل مبلغ sol الذي ترسله",
"introducing_cake_pay": "نقدم لكم Cake Pay!", "introducing_cake_pay": "نقدم لكم Cake Pay!",
"invalid_input": "مدخل غير صالح", "invalid_input": "مدخل غير صالح",
@ -368,6 +370,7 @@
"max_value": "الحد الأقصى: ${value} ${currency}", "max_value": "الحد الأقصى: ${value} ${currency}",
"memo": "مذكرة:", "memo": "مذكرة:",
"message": "ﺔﻟﺎﺳﺭ", "message": "ﺔﻟﺎﺳﺭ",
"message_verified": "تم التحقق من الرسالة بنجاح",
"methods": " ﻕﺮﻃُ", "methods": " ﻕﺮﻃُ",
"min_amount": "الحد الأدنى: ${value}", "min_amount": "الحد الأدنى: ${value}",
"min_value": "الحد الأدنى: ${value} ${currency}", "min_value": "الحد الأدنى: ${value} ${currency}",
@ -659,7 +662,13 @@
"show_keys": "اظهار السييد / المفاتيح", "show_keys": "اظهار السييد / المفاتيح",
"show_market_place": "إظهار السوق", "show_market_place": "إظهار السوق",
"show_seed": "عرض السييد", "show_seed": "عرض السييد",
"sign_message": "تسجيل رسالة",
"sign_up": "اشتراك", "sign_up": "اشتراك",
"sign_verify_message": "توقيع أو التحقق من الرسالة",
"sign_verify_message_sub": "قم بتوقيع أو التحقق من رسالة باستخدام المفتاح الخاص بك",
"sign_verify_title": "تسجيل / تحقق",
"signature": "إمضاء",
"signature_invalid_error": "التوقيع غير صالح للرسالة المقدمة",
"signTransaction": " ﺔﻠﻣﺎﻌﻤﻟﺍ ﻊﻴﻗﻮﺗ", "signTransaction": " ﺔﻠﻣﺎﻌﻤﻟﺍ ﻊﻴﻗﻮﺗ",
"signup_for_card_accept_terms": "قم بالتسجيل للحصول على البطاقة وقبول الشروط.", "signup_for_card_accept_terms": "قم بالتسجيل للحصول على البطاقة وقبول الشروط.",
"silent_payments": "مدفوعات صامتة", "silent_payments": "مدفوعات صامتة",
@ -820,6 +829,7 @@
"value_type": "نوع القيمة", "value_type": "نوع القيمة",
"variable_pair_not_supported": "هذا الزوج المتغير غير مدعوم في التبادلات المحددة", "variable_pair_not_supported": "هذا الزوج المتغير غير مدعوم في التبادلات المحددة",
"verification": "تَحَقّق", "verification": "تَحَقّق",
"verify_message": "تحقق من الرسالة",
"verify_with_2fa": "تحقق مع Cake 2FA", "verify_with_2fa": "تحقق مع Cake 2FA",
"version": "الإصدار ${currentVersion}", "version": "الإصدار ${currentVersion}",
"view_all": "مشاهدة الكل", "view_all": "مشاهدة الكل",

View file

@ -338,6 +338,8 @@
"incoming": "Входящи", "incoming": "Входящи",
"incorrect_seed": "Въведеният текст е невалиден.", "incorrect_seed": "Въведеният текст е невалиден.",
"inputs": "Входове", "inputs": "Входове",
"insufficient_lamport_for_tx": "Нямате достатъчно SOL, за да покриете транзакцията и таксата му за транзакция. Моля, добавете повече SOL към портфейла си или намалете сумата на SOL, която изпращате.",
"insufficient_lamports": "Нямате достатъчно SOL, за да покриете транзакцията и таксата му за транзакция. Имате нужда от поне ${solValueNeeded} sol. Моля, добавете повече SOL към портфейла си или намалете сумата на SOL, която изпращате",
"insufficientFundsForRentError": "Нямате достатъчно SOL, за да покриете таксата за транзакцията и наемането на сметката. Моля, добавете повече SOL към портфейла си или намалете сумата на SOL, която изпращате", "insufficientFundsForRentError": "Нямате достатъчно SOL, за да покриете таксата за транзакцията и наемането на сметката. Моля, добавете повече SOL към портфейла си или намалете сумата на SOL, която изпращате",
"introducing_cake_pay": "Запознайте се с Cake Pay!", "introducing_cake_pay": "Запознайте се с Cake Pay!",
"invalid_input": "Невалиден вход", "invalid_input": "Невалиден вход",
@ -368,6 +370,7 @@
"max_value": "Макс: ${value} ${currency}", "max_value": "Макс: ${value} ${currency}",
"memo": "Мемо:", "memo": "Мемо:",
"message": "Съобщение", "message": "Съобщение",
"message_verified": "Съобщението беше успешно проверено",
"methods": "Методи", "methods": "Методи",
"min_amount": "Мин: ${value}", "min_amount": "Мин: ${value}",
"min_value": "Мин: ${value} ${currency}", "min_value": "Мин: ${value} ${currency}",
@ -659,7 +662,13 @@
"show_keys": "Покажи seed/keys", "show_keys": "Покажи seed/keys",
"show_market_place": "Покажи пазар", "show_market_place": "Покажи пазар",
"show_seed": "Покажи seed", "show_seed": "Покажи seed",
"sign_message": "Съобщение за подписване",
"sign_up": "Регистрация", "sign_up": "Регистрация",
"sign_verify_message": "Подпишете или проверете съобщението",
"sign_verify_message_sub": "Подпишете или проверете съобщение с помощта на вашия личен ключ",
"sign_verify_title": "Подпишете / проверете",
"signature": "Подпис",
"signature_invalid_error": "Подписът не е валиден за даденото съобщение",
"signTransaction": "Подпишете транзакция", "signTransaction": "Подпишете транзакция",
"signup_for_card_accept_terms": "Регистрайте се за картата и приемете условията.", "signup_for_card_accept_terms": "Регистрайте се за картата и приемете условията.",
"silent_payments": "Мълчаливи плащания", "silent_payments": "Мълчаливи плащания",
@ -820,6 +829,7 @@
"value_type": "Тип стойност", "value_type": "Тип стойност",
"variable_pair_not_supported": "Този variable pair не се поддържа от избраната борса", "variable_pair_not_supported": "Този variable pair не се поддържа от избраната борса",
"verification": "Потвърждаване", "verification": "Потвърждаване",
"verify_message": "Проверете съобщението",
"verify_with_2fa": "Проверете с Cake 2FA", "verify_with_2fa": "Проверете с Cake 2FA",
"version": "Версия ${currentVersion}", "version": "Версия ${currentVersion}",
"view_all": "Виж всички", "view_all": "Виж всички",

View file

@ -338,6 +338,8 @@
"incoming": "Příchozí", "incoming": "Příchozí",
"incorrect_seed": "Zadaný text není správný.", "incorrect_seed": "Zadaný text není správný.",
"inputs": "Vstupy", "inputs": "Vstupy",
"insufficient_lamport_for_tx": "Nemáte dostatek SOL na pokrytí transakce a jejího transakčního poplatku. Laskavě přidejte do své peněženky více solu nebo snižte množství Sol, kterou odesíláte.",
"insufficient_lamports": "Nemáte dostatek SOL na pokrytí transakce a jejího transakčního poplatku. Potřebujete alespoň ${solValueNeeded} sol. Laskavě přidejte do své peněženky více SOL nebo snižte množství Sol, kterou odesíláte",
"insufficientFundsForRentError": "Nemáte dostatek SOL na pokrytí transakčního poplatku a nájemného za účet. Laskavě přidejte do své peněženky více SOL nebo snižte množství Sol, kterou odesíláte", "insufficientFundsForRentError": "Nemáte dostatek SOL na pokrytí transakčního poplatku a nájemného za účet. Laskavě přidejte do své peněženky více SOL nebo snižte množství Sol, kterou odesíláte",
"introducing_cake_pay": "Představujeme Cake Pay!", "introducing_cake_pay": "Představujeme Cake Pay!",
"invalid_input": "Neplatný vstup", "invalid_input": "Neplatný vstup",
@ -368,6 +370,7 @@
"max_value": "Max: ${value} ${currency}", "max_value": "Max: ${value} ${currency}",
"memo": "Memo:", "memo": "Memo:",
"message": "Zpráva", "message": "Zpráva",
"message_verified": "Zpráva byla úspěšně ověřena",
"methods": "Metody", "methods": "Metody",
"min_amount": "Min: ${value}", "min_amount": "Min: ${value}",
"min_value": "Min: ${value} ${currency}", "min_value": "Min: ${value} ${currency}",
@ -659,7 +662,13 @@
"show_keys": "Zobrazit seed/klíče", "show_keys": "Zobrazit seed/klíče",
"show_market_place": "Zobrazit trh", "show_market_place": "Zobrazit trh",
"show_seed": "Zobrazit seed", "show_seed": "Zobrazit seed",
"sign_message": "Podepsat zprávu",
"sign_up": "Registrovat se", "sign_up": "Registrovat se",
"sign_verify_message": "Podepište nebo ověřte zprávu",
"sign_verify_message_sub": "Podepište nebo ověřte zprávu pomocí soukromého klíče",
"sign_verify_title": "Podepsat / ověřit",
"signature": "Podpis",
"signature_invalid_error": "Podpis není platný pro danou zprávu",
"signTransaction": "Podepsat transakci", "signTransaction": "Podepsat transakci",
"signup_for_card_accept_terms": "Zaregistrujte se pro kartu a souhlaste s podmínkami.", "signup_for_card_accept_terms": "Zaregistrujte se pro kartu a souhlaste s podmínkami.",
"silent_payments": "Tiché platby", "silent_payments": "Tiché platby",
@ -820,6 +829,7 @@
"value_type": "Typ hodnoty", "value_type": "Typ hodnoty",
"variable_pair_not_supported": "Tento pár s tržním kurzem není ve zvolené směnárně podporován", "variable_pair_not_supported": "Tento pár s tržním kurzem není ve zvolené směnárně podporován",
"verification": "Ověření", "verification": "Ověření",
"verify_message": "Ověřit zprávu",
"verify_with_2fa": "Ověřte pomocí Cake 2FA", "verify_with_2fa": "Ověřte pomocí Cake 2FA",
"version": "Verze ${currentVersion}", "version": "Verze ${currentVersion}",
"view_all": "Zobrazit vše", "view_all": "Zobrazit vše",

View file

@ -338,6 +338,8 @@
"incoming": "Eingehend", "incoming": "Eingehend",
"incorrect_seed": "Der eingegebene Text ist ungültig.", "incorrect_seed": "Der eingegebene Text ist ungültig.",
"inputs": "Eingänge", "inputs": "Eingänge",
"insufficient_lamport_for_tx": "Sie haben nicht genug SOL, um die Transaktion und ihre Transaktionsgebühr abzudecken. Bitte fügen Sie Ihrer Brieftasche mehr Sol hinzu oder reduzieren Sie die SO -Menge, die Sie senden.",
"insufficient_lamports": "Sie haben nicht genug SOL, um die Transaktion und ihre Transaktionsgebühr abzudecken. Sie brauchen mindestens ${solValueNeeded} Sol. Bitte fügen Sie mehr Sol zu Ihrer Wallet hinzu oder reduzieren Sie den von Ihnen gesendeten Sol -Betrag",
"insufficientFundsForRentError": "Sie haben nicht genug SOL, um die Transaktionsgebühr und die Miete für das Konto zu decken. Bitte fügen Sie mehr Sol zu Ihrer Brieftasche hinzu oder reduzieren Sie den von Ihnen gesendeten Sol -Betrag", "insufficientFundsForRentError": "Sie haben nicht genug SOL, um die Transaktionsgebühr und die Miete für das Konto zu decken. Bitte fügen Sie mehr Sol zu Ihrer Brieftasche hinzu oder reduzieren Sie den von Ihnen gesendeten Sol -Betrag",
"introducing_cake_pay": "Einführung von Cake Pay!", "introducing_cake_pay": "Einführung von Cake Pay!",
"invalid_input": "Ungültige Eingabe", "invalid_input": "Ungültige Eingabe",
@ -368,6 +370,7 @@
"max_value": "Max: ${value} ${currency}", "max_value": "Max: ${value} ${currency}",
"memo": "Memo:", "memo": "Memo:",
"message": "Nachricht", "message": "Nachricht",
"message_verified": "Die Nachricht wurde erfolgreich überprüft",
"methods": "Methoden", "methods": "Methoden",
"min_amount": "Min: ${value}", "min_amount": "Min: ${value}",
"min_value": "Min: ${value} ${currency}", "min_value": "Min: ${value} ${currency}",
@ -660,7 +663,13 @@
"show_keys": "Seed/Schlüssel anzeigen", "show_keys": "Seed/Schlüssel anzeigen",
"show_market_place": "Marktplatz anzeigen", "show_market_place": "Marktplatz anzeigen",
"show_seed": "Seed zeigen", "show_seed": "Seed zeigen",
"sign_message": "Nachricht unterschreiben",
"sign_up": "Anmelden", "sign_up": "Anmelden",
"sign_verify_message": "Nachricht unterschreiben oder überprüfen",
"sign_verify_message_sub": "Unterschreiben oder überprüfen Sie eine Nachricht mit Ihrem privaten Schlüssel",
"sign_verify_title": "Zeichen / überprüfen",
"signature": "Signatur",
"signature_invalid_error": "Die Signatur gilt nicht für die angegebene Nachricht",
"signTransaction": "Transaktion unterzeichnen", "signTransaction": "Transaktion unterzeichnen",
"signup_for_card_accept_terms": "Melden Sie sich für die Karte an und akzeptieren Sie die Bedingungen.", "signup_for_card_accept_terms": "Melden Sie sich für die Karte an und akzeptieren Sie die Bedingungen.",
"silent_payments": "Stille Zahlungen", "silent_payments": "Stille Zahlungen",
@ -822,6 +831,7 @@
"value_type": "Werttyp", "value_type": "Werttyp",
"variable_pair_not_supported": "Dieses Variablenpaar wird von den ausgewählten Börsen nicht unterstützt", "variable_pair_not_supported": "Dieses Variablenpaar wird von den ausgewählten Börsen nicht unterstützt",
"verification": "Verifizierung", "verification": "Verifizierung",
"verify_message": "Nachricht überprüfen",
"verify_with_2fa": "Verifizieren Sie mit Cake 2FA", "verify_with_2fa": "Verifizieren Sie mit Cake 2FA",
"version": "Version ${currentVersion}", "version": "Version ${currentVersion}",
"view_all": "Alle anzeigen", "view_all": "Alle anzeigen",

View file

@ -338,6 +338,8 @@
"incoming": "Incoming", "incoming": "Incoming",
"incorrect_seed": "The text entered is not valid.", "incorrect_seed": "The text entered is not valid.",
"inputs": "Inputs", "inputs": "Inputs",
"insufficient_lamport_for_tx": "You do not have enough SOL to cover the transaction and its transaction fee. Kindly add more SOL to your wallet or reduce the SOL amount you\\'re sending.",
"insufficient_lamports": "You do not have enough SOL to cover the transaction and its transaction fee. You need at least ${solValueNeeded} SOL. Kindly add more SOL to your wallet or reduce the SOL amount you\\'re sending",
"insufficientFundsForRentError": "You do not have enough SOL to cover the transaction fee and rent for the account. Kindly add more SOL to your wallet or reduce the SOL amount you\\'re sending", "insufficientFundsForRentError": "You do not have enough SOL to cover the transaction fee and rent for the account. Kindly add more SOL to your wallet or reduce the SOL amount you\\'re sending",
"introducing_cake_pay": "Introducing Cake Pay!", "introducing_cake_pay": "Introducing Cake Pay!",
"invalid_input": "Invalid input", "invalid_input": "Invalid input",
@ -368,6 +370,7 @@
"max_value": "Max: ${value} ${currency}", "max_value": "Max: ${value} ${currency}",
"memo": "Memo:", "memo": "Memo:",
"message": "Message", "message": "Message",
"message_verified": "The message was successfully verified",
"methods": "Methods", "methods": "Methods",
"min_amount": "Min: ${value}", "min_amount": "Min: ${value}",
"min_value": "Min: ${value} ${currency}", "min_value": "Min: ${value} ${currency}",
@ -660,7 +663,13 @@
"show_keys": "Show seed/keys", "show_keys": "Show seed/keys",
"show_market_place": "Show Marketplace", "show_market_place": "Show Marketplace",
"show_seed": "Show seed", "show_seed": "Show seed",
"sign_message": "Sign Message",
"sign_up": "Sign Up", "sign_up": "Sign Up",
"sign_verify_message": "Sign or verify message",
"sign_verify_message_sub": "Sign or verify a message using your private key",
"sign_verify_title": "Sign / Verify",
"signature": "Signature",
"signature_invalid_error": "The signature is not valid for the message given",
"signTransaction": "Sign Transaction", "signTransaction": "Sign Transaction",
"signup_for_card_accept_terms": "Sign up for the card and accept the terms.", "signup_for_card_accept_terms": "Sign up for the card and accept the terms.",
"silent_payments": "Silent Payments", "silent_payments": "Silent Payments",
@ -821,6 +830,7 @@
"value_type": "Value Type", "value_type": "Value Type",
"variable_pair_not_supported": "This variable pair is not supported with the selected exchanges", "variable_pair_not_supported": "This variable pair is not supported with the selected exchanges",
"verification": "Verification", "verification": "Verification",
"verify_message": "Verify Message",
"verify_with_2fa": "Verify with Cake 2FA", "verify_with_2fa": "Verify with Cake 2FA",
"version": "Version ${currentVersion}", "version": "Version ${currentVersion}",
"view_all": "View all", "view_all": "View all",

View file

@ -338,6 +338,8 @@
"incoming": "Entrante", "incoming": "Entrante",
"incorrect_seed": "El texto ingresado no es válido.", "incorrect_seed": "El texto ingresado no es válido.",
"inputs": "Entradas", "inputs": "Entradas",
"insufficient_lamport_for_tx": "No tiene suficiente SOL para cubrir la transacción y su tarifa de transacción. Por favor, agregue más SOL a su billetera o reduzca la cantidad de sol que está enviando.",
"insufficient_lamports": "No tiene suficiente SOL para cubrir la transacción y su tarifa de transacción. Necesita al menos ${solValueNeeded} sol. Por favor, agregue más sol a su billetera o reduzca la cantidad de sol que está enviando",
"insufficientFundsForRentError": "No tiene suficiente SOL para cubrir la tarifa de transacción y alquilar para la cuenta. Por favor, agregue más sol a su billetera o reduzca la cantidad de sol que está enviando", "insufficientFundsForRentError": "No tiene suficiente SOL para cubrir la tarifa de transacción y alquilar para la cuenta. Por favor, agregue más sol a su billetera o reduzca la cantidad de sol que está enviando",
"introducing_cake_pay": "¡Presentamos Cake Pay!", "introducing_cake_pay": "¡Presentamos Cake Pay!",
"invalid_input": "Entrada inválida", "invalid_input": "Entrada inválida",
@ -368,6 +370,7 @@
"max_value": "Max: ${value} ${currency}", "max_value": "Max: ${value} ${currency}",
"memo": "Memorándum:", "memo": "Memorándum:",
"message": "Mensaje", "message": "Mensaje",
"message_verified": "El mensaje fue verificado con éxito",
"methods": "Métodos", "methods": "Métodos",
"min_amount": "Mínimo: ${value}", "min_amount": "Mínimo: ${value}",
"min_value": "Min: ${value} ${currency}", "min_value": "Min: ${value} ${currency}",
@ -660,7 +663,13 @@
"show_keys": "Mostrar semilla/claves", "show_keys": "Mostrar semilla/claves",
"show_market_place": "Mostrar mercado", "show_market_place": "Mostrar mercado",
"show_seed": "Mostrar semilla", "show_seed": "Mostrar semilla",
"sign_message": "Mensaje de firma",
"sign_up": "Registrarse", "sign_up": "Registrarse",
"sign_verify_message": "Firmar o verificar el mensaje",
"sign_verify_message_sub": "Firmar o verificar un mensaje usando su clave privada",
"sign_verify_title": "Firmar / verificar",
"signature": "Firma",
"signature_invalid_error": "La firma no es válida para el mensaje dado",
"signTransaction": "Firmar transacción", "signTransaction": "Firmar transacción",
"signup_for_card_accept_terms": "Regístrese para obtener la tarjeta y acepte los términos.", "signup_for_card_accept_terms": "Regístrese para obtener la tarjeta y acepte los términos.",
"silent_payments": "Pagos silenciosos", "silent_payments": "Pagos silenciosos",
@ -821,6 +830,7 @@
"value_type": "Tipo de valor", "value_type": "Tipo de valor",
"variable_pair_not_supported": "Este par de variables no es compatible con los intercambios seleccionados", "variable_pair_not_supported": "Este par de variables no es compatible con los intercambios seleccionados",
"verification": "Verificación", "verification": "Verificación",
"verify_message": "Mensaje de verificación",
"verify_with_2fa": "Verificar con Cake 2FA", "verify_with_2fa": "Verificar con Cake 2FA",
"version": "Versión ${currentVersion}", "version": "Versión ${currentVersion}",
"view_all": "Ver todo", "view_all": "Ver todo",

View file

@ -338,6 +338,8 @@
"incoming": "Entrantes", "incoming": "Entrantes",
"incorrect_seed": "Le texte entré est invalide.", "incorrect_seed": "Le texte entré est invalide.",
"inputs": "Contributions", "inputs": "Contributions",
"insufficient_lamport_for_tx": "Vous n'avez pas assez de sol pour couvrir la transaction et ses frais de transaction. Veuillez ajouter plus de Sol à votre portefeuille ou réduire la quantité de Sol que vous envoyez.",
"insufficient_lamports": "Vous n'avez pas assez de sol pour couvrir la transaction et ses frais de transaction. Vous avez besoin d'au moins ${solValueNeeded} sol. Veuillez ajouter plus de Sol à votre portefeuille ou réduire la quantité de sol que vous envoyez",
"insufficientFundsForRentError": "Vous n'avez pas assez de SOL pour couvrir les frais de transaction et le loyer pour le compte. Veuillez ajouter plus de Sol à votre portefeuille ou réduire la quantité de sol que vous envoyez", "insufficientFundsForRentError": "Vous n'avez pas assez de SOL pour couvrir les frais de transaction et le loyer pour le compte. Veuillez ajouter plus de Sol à votre portefeuille ou réduire la quantité de sol que vous envoyez",
"introducing_cake_pay": "Présentation de Cake Pay !", "introducing_cake_pay": "Présentation de Cake Pay !",
"invalid_input": "Entrée invalide", "invalid_input": "Entrée invalide",
@ -368,6 +370,7 @@
"max_value": "Max: ${value} ${currency}", "max_value": "Max: ${value} ${currency}",
"memo": "Mémo :", "memo": "Mémo :",
"message": "Message", "message": "Message",
"message_verified": "Le message a été vérifié avec succès",
"methods": "Méthodes", "methods": "Méthodes",
"min_amount": "Min : ${value}", "min_amount": "Min : ${value}",
"min_value": "Min: ${value} ${currency}", "min_value": "Min: ${value} ${currency}",
@ -659,7 +662,13 @@
"show_keys": "Visualiser la phrase secrète (seed) et les clefs", "show_keys": "Visualiser la phrase secrète (seed) et les clefs",
"show_market_place": "Afficher la place de marché", "show_market_place": "Afficher la place de marché",
"show_seed": "Visualiser la phrase secrète (seed)", "show_seed": "Visualiser la phrase secrète (seed)",
"sign_message": "Signer le message",
"sign_up": "S'inscrire", "sign_up": "S'inscrire",
"sign_verify_message": "Signer ou vérifier le message",
"sign_verify_message_sub": "Signez ou vérifiez un message en utilisant votre clé privée",
"sign_verify_title": "Signe / vérifier",
"signature": "Signature",
"signature_invalid_error": "La signature n'est pas valable pour le message donné",
"signTransaction": "Signer une transaction", "signTransaction": "Signer une transaction",
"signup_for_card_accept_terms": "Inscrivez-vous pour la carte et acceptez les conditions.", "signup_for_card_accept_terms": "Inscrivez-vous pour la carte et acceptez les conditions.",
"silent_payments": "Paiements silencieux", "silent_payments": "Paiements silencieux",
@ -820,6 +829,7 @@
"value_type": "Type de valeur", "value_type": "Type de valeur",
"variable_pair_not_supported": "Cette paire variable n'est pas prise en charge avec les échanges sélectionnés", "variable_pair_not_supported": "Cette paire variable n'est pas prise en charge avec les échanges sélectionnés",
"verification": "Vérification", "verification": "Vérification",
"verify_message": "Vérifier le message",
"verify_with_2fa": "Vérifier avec Cake 2FA", "verify_with_2fa": "Vérifier avec Cake 2FA",
"version": "Version ${currentVersion}", "version": "Version ${currentVersion}",
"view_all": "Voir tout", "view_all": "Voir tout",

View file

@ -338,6 +338,8 @@
"incoming": "Mai shigowa", "incoming": "Mai shigowa",
"incorrect_seed": "rubutun da aka shigar ba shi da inganci.", "incorrect_seed": "rubutun da aka shigar ba shi da inganci.",
"inputs": "Abubuwan da ke ciki", "inputs": "Abubuwan da ke ciki",
"insufficient_lamport_for_tx": "Ba ku da isasshen sool don rufe ma'amala da kuɗin ma'amala. Da unara ƙara ƙarin sool a cikin walat ɗinku ko rage adadin Sol ɗin da kuke aikawa.",
"insufficient_lamports": "Ba ku da isasshen sool don rufe ma'amala da kuɗin ma'amala. Kuna buƙatar aƙalla ${solValueNeeded} Sol. Da kyau ƙara ƙarin sool zuwa walat ɗinku ko rage adadin Sol ɗin da kuke aikawa",
"insufficientFundsForRentError": "Ba ku da isasshen Sol don rufe kuɗin ma'amala da haya don asusun. Da kyau ƙara ƙarin sool zuwa walat ɗinku ko rage adadin Sol ɗin da kuke aikawa", "insufficientFundsForRentError": "Ba ku da isasshen Sol don rufe kuɗin ma'amala da haya don asusun. Da kyau ƙara ƙarin sool zuwa walat ɗinku ko rage adadin Sol ɗin da kuke aikawa",
"introducing_cake_pay": "Gabatar da Cake Pay!", "introducing_cake_pay": "Gabatar da Cake Pay!",
"invalid_input": "Shigar da ba daidai ba", "invalid_input": "Shigar da ba daidai ba",
@ -368,6 +370,7 @@
"max_value": "Max: ${value} ${currency}", "max_value": "Max: ${value} ${currency}",
"memo": "Memo:", "memo": "Memo:",
"message": "Sako", "message": "Sako",
"message_verified": "An yi nasarar tabbatar da sakon",
"methods": "Hanyoyin", "methods": "Hanyoyin",
"min_amount": "Min: ${value}", "min_amount": "Min: ${value}",
"min_value": "Min: ${value} ${currency}", "min_value": "Min: ${value} ${currency}",
@ -661,7 +664,13 @@
"show_keys": "Nuna iri/maɓallai", "show_keys": "Nuna iri/maɓallai",
"show_market_place": "Nuna dan kasuwa", "show_market_place": "Nuna dan kasuwa",
"show_seed": "Nuna iri", "show_seed": "Nuna iri",
"sign_message": "Sa hannu",
"sign_up": "Shiga", "sign_up": "Shiga",
"sign_verify_message": "Shiga ko Tabbatar da Saƙo",
"sign_verify_message_sub": "Shiga ko tabbatar da saƙo ta amfani da Maɓallinku na sirri",
"sign_verify_title": "Sa hannu / Tabbatar",
"signature": "Sa hannu",
"signature_invalid_error": "Sa hannu ba shi da inganci ga sakon da aka bayar",
"signTransaction": "Sa hannu Ma'amala", "signTransaction": "Sa hannu Ma'amala",
"signup_for_card_accept_terms": "Yi rajista don katin kuma karɓi sharuɗɗan.", "signup_for_card_accept_terms": "Yi rajista don katin kuma karɓi sharuɗɗan.",
"silent_payments": "Biya silent", "silent_payments": "Biya silent",
@ -822,6 +831,7 @@
"value_type": "Nau'in darajar", "value_type": "Nau'in darajar",
"variable_pair_not_supported": "Ba a samun goyan bayan wannan m biyu tare da zaɓaɓɓun musayar", "variable_pair_not_supported": "Ba a samun goyan bayan wannan m biyu tare da zaɓaɓɓun musayar",
"verification": "tabbatar", "verification": "tabbatar",
"verify_message": "Tabbatar saƙon",
"verify_with_2fa": "Tabbatar da Cake 2FA", "verify_with_2fa": "Tabbatar da Cake 2FA",
"version": "Sigar ${currentVersion}", "version": "Sigar ${currentVersion}",
"view_all": "Duba duka", "view_all": "Duba duka",

View file

@ -338,6 +338,8 @@
"incoming": "आने वाली", "incoming": "आने वाली",
"incorrect_seed": "दर्ज किया गया पाठ मान्य नहीं है।", "incorrect_seed": "दर्ज किया गया पाठ मान्य नहीं है।",
"inputs": "इनपुट", "inputs": "इनपुट",
"insufficient_lamport_for_tx": "आपके पास लेनदेन और इसके लेनदेन शुल्क को कवर करने के लिए पर्याप्त सोल नहीं है। कृपया अपने बटुए में अधिक सोल जोड़ें या आपके द्वारा भेजे जा रहे सोल राशि को कम करें।",
"insufficient_lamports": "आपके पास लेनदेन और इसके लेनदेन शुल्क को कवर करने के लिए पर्याप्त सोल नहीं है। आपको कम से कम ${solValueNeeded} सोल की आवश्यकता है। कृपया अपने बटुए में अधिक सोल जोड़ें या सोल राशि को कम करें जिसे आप भेज रहे हैं",
"insufficientFundsForRentError": "आपके पास लेन -देन शुल्क और खाते के लिए किराए को कवर करने के लिए पर्याप्त सोल नहीं है। कृपया अपने बटुए में अधिक सोल जोड़ें या सोल राशि को कम करें जिसे आप भेज रहे हैं", "insufficientFundsForRentError": "आपके पास लेन -देन शुल्क और खाते के लिए किराए को कवर करने के लिए पर्याप्त सोल नहीं है। कृपया अपने बटुए में अधिक सोल जोड़ें या सोल राशि को कम करें जिसे आप भेज रहे हैं",
"introducing_cake_pay": "परिचय Cake Pay!", "introducing_cake_pay": "परिचय Cake Pay!",
"invalid_input": "अमान्य निवेश", "invalid_input": "अमान्य निवेश",
@ -368,6 +370,7 @@
"max_value": "मैक्स: ${value} ${currency}", "max_value": "मैक्स: ${value} ${currency}",
"memo": "ज्ञापन:", "memo": "ज्ञापन:",
"message": "संदेश", "message": "संदेश",
"message_verified": "संदेश को सफलतापूर्वक सत्यापित किया गया था",
"methods": "तरीकों", "methods": "तरीकों",
"min_amount": "न्यूनतम: ${value}", "min_amount": "न्यूनतम: ${value}",
"min_value": "मिन: ${value} ${currency}", "min_value": "मिन: ${value} ${currency}",
@ -661,7 +664,13 @@
"show_keys": "बीज / कुंजियाँ दिखाएँ", "show_keys": "बीज / कुंजियाँ दिखाएँ",
"show_market_place": "बाज़ार दिखाएँ", "show_market_place": "बाज़ार दिखाएँ",
"show_seed": "बीज दिखाओ", "show_seed": "बीज दिखाओ",
"sign_message": "हस्ताक्षर संदेश",
"sign_up": "साइन अप करें", "sign_up": "साइन अप करें",
"sign_verify_message": "संदेश पर हस्ताक्षर या सत्यापित करें",
"sign_verify_message_sub": "अपनी निजी कुंजी का उपयोग करके किसी संदेश पर हस्ताक्षर या सत्यापित करें",
"sign_verify_title": "हस्ताक्षर / सत्यापित करें",
"signature": "हस्ताक्षर",
"signature_invalid_error": "हस्ताक्षर दिए गए संदेश के लिए मान्य नहीं है",
"signTransaction": "लेन-देन पर हस्ताक्षर करें", "signTransaction": "लेन-देन पर हस्ताक्षर करें",
"signup_for_card_accept_terms": "कार्ड के लिए साइन अप करें और शर्तें स्वीकार करें।", "signup_for_card_accept_terms": "कार्ड के लिए साइन अप करें और शर्तें स्वीकार करें।",
"silent_payments": "मूक भुगतान", "silent_payments": "मूक भुगतान",
@ -822,6 +831,7 @@
"value_type": "मान प्रकार", "value_type": "मान प्रकार",
"variable_pair_not_supported": "यह परिवर्तनीय जोड़ी चयनित एक्सचेंजों के साथ समर्थित नहीं है", "variable_pair_not_supported": "यह परिवर्तनीय जोड़ी चयनित एक्सचेंजों के साथ समर्थित नहीं है",
"verification": "सत्यापन", "verification": "सत्यापन",
"verify_message": "संदेश सत्यापित करें",
"verify_with_2fa": "केक 2FA के साथ सत्यापित करें", "verify_with_2fa": "केक 2FA के साथ सत्यापित करें",
"version": "संस्करण ${currentVersion}", "version": "संस्करण ${currentVersion}",
"view_all": "सभी देखें", "view_all": "सभी देखें",

View file

@ -338,6 +338,8 @@
"incoming": "Dolazno", "incoming": "Dolazno",
"incorrect_seed": "Uneseni tekst nije valjan.", "incorrect_seed": "Uneseni tekst nije valjan.",
"inputs": "Unosi", "inputs": "Unosi",
"insufficient_lamport_for_tx": "Nemate dovoljno SOL -a da pokriva transakciju i njegovu transakcijsku naknadu. Ljubazno dodajte više sol u svoj novčanik ili smanjite količinu SOL -a koju šaljete.",
"insufficient_lamports": "Nemate dovoljno SOL -a da pokriva transakciju i njegovu transakcijsku naknadu. Trebate najmanje ${solValueNeeded} sol. Ljubazno dodajte više sol u svoj novčanik ili smanjite količinu SOL -a koju šaljete",
"insufficientFundsForRentError": "Nemate dovoljno SOL -a za pokrivanje naknade za transakciju i najamninu za račun. Ljubazno dodajte više sol u svoj novčanik ili smanjite količinu SOL -a koju šaljete", "insufficientFundsForRentError": "Nemate dovoljno SOL -a za pokrivanje naknade za transakciju i najamninu za račun. Ljubazno dodajte više sol u svoj novčanik ili smanjite količinu SOL -a koju šaljete",
"introducing_cake_pay": "Predstavljamo Cake Pay!", "introducing_cake_pay": "Predstavljamo Cake Pay!",
"invalid_input": "Pogrešan unos", "invalid_input": "Pogrešan unos",
@ -368,6 +370,7 @@
"max_value": "Maks.: ${value} ${currency}", "max_value": "Maks.: ${value} ${currency}",
"memo": "Memo:", "memo": "Memo:",
"message": "Poruka", "message": "Poruka",
"message_verified": "Poruka je uspješno provjerena",
"methods": "Metode", "methods": "Metode",
"min_amount": "Minimalno: ${value}", "min_amount": "Minimalno: ${value}",
"min_value": "Min.: ${value} ${currency}", "min_value": "Min.: ${value} ${currency}",
@ -659,7 +662,13 @@
"show_keys": "Prikaži pristupni izraz/ključ", "show_keys": "Prikaži pristupni izraz/ključ",
"show_market_place": "Prikaži tržište", "show_market_place": "Prikaži tržište",
"show_seed": "Prikaži pristupni izraz", "show_seed": "Prikaži pristupni izraz",
"sign_message": "Poruka",
"sign_up": "Prijavite se", "sign_up": "Prijavite se",
"sign_verify_message": "Potpisati ili provjeriti poruku",
"sign_verify_message_sub": "Potpišite ili provjerite poruku pomoću privatnog ključa",
"sign_verify_title": "Potpisati / provjeriti",
"signature": "Potpis",
"signature_invalid_error": "Potpis ne vrijedi za danu poruku",
"signTransaction": "Potpišite transakciju", "signTransaction": "Potpišite transakciju",
"signup_for_card_accept_terms": "Prijavite se za karticu i prihvatite uvjete.", "signup_for_card_accept_terms": "Prijavite se za karticu i prihvatite uvjete.",
"silent_payments": "Tiha plaćanja", "silent_payments": "Tiha plaćanja",
@ -820,6 +829,7 @@
"value_type": "Tipa vrijednosti", "value_type": "Tipa vrijednosti",
"variable_pair_not_supported": "Ovaj par varijabli nije podržan s odabranim burzama", "variable_pair_not_supported": "Ovaj par varijabli nije podržan s odabranim burzama",
"verification": "Potvrda", "verification": "Potvrda",
"verify_message": "Provjerite poruku",
"verify_with_2fa": "Provjerite s Cake 2FA", "verify_with_2fa": "Provjerite s Cake 2FA",
"version": "Verzija ${currentVersion}", "version": "Verzija ${currentVersion}",
"view_all": "Prikaži sve", "view_all": "Prikaži sve",

View file

@ -338,6 +338,8 @@
"incoming": "Masuk", "incoming": "Masuk",
"incorrect_seed": "Teks yang dimasukkan tidak valid.", "incorrect_seed": "Teks yang dimasukkan tidak valid.",
"inputs": "Input", "inputs": "Input",
"insufficient_lamport_for_tx": "Anda tidak memiliki cukup SOL untuk menutupi transaksi dan biaya transaksinya. Mohon tambahkan lebih banyak sol ke dompet Anda atau kurangi jumlah sol yang Anda kirim.",
"insufficient_lamports": "Anda tidak memiliki cukup SOL untuk menutupi transaksi dan biaya transaksinya. Anda membutuhkan setidaknya ${solValueNeeded} sol. Mohon tambahkan lebih banyak sol ke dompet Anda atau kurangi jumlah sol yang Anda kirim",
"insufficientFundsForRentError": "Anda tidak memiliki cukup SOL untuk menutupi biaya transaksi dan menyewa untuk akun tersebut. Mohon tambahkan lebih banyak sol ke dompet Anda atau kurangi jumlah sol yang Anda kirim", "insufficientFundsForRentError": "Anda tidak memiliki cukup SOL untuk menutupi biaya transaksi dan menyewa untuk akun tersebut. Mohon tambahkan lebih banyak sol ke dompet Anda atau kurangi jumlah sol yang Anda kirim",
"introducing_cake_pay": "Perkenalkan Cake Pay!", "introducing_cake_pay": "Perkenalkan Cake Pay!",
"invalid_input": "Masukan tidak valid", "invalid_input": "Masukan tidak valid",
@ -368,6 +370,7 @@
"max_value": "Max: ${value} ${currency}", "max_value": "Max: ${value} ${currency}",
"memo": "Memo:", "memo": "Memo:",
"message": "Pesan", "message": "Pesan",
"message_verified": "Pesan itu berhasil diverifikasi",
"methods": "Metode", "methods": "Metode",
"min_amount": "Min: ${value}", "min_amount": "Min: ${value}",
"min_value": "Min: ${value} ${currency}", "min_value": "Min: ${value} ${currency}",
@ -662,7 +665,13 @@
"show_keys": "Tampilkan seed/kunci", "show_keys": "Tampilkan seed/kunci",
"show_market_place": "Tampilkan Pasar", "show_market_place": "Tampilkan Pasar",
"show_seed": "Tampilkan seed", "show_seed": "Tampilkan seed",
"sign_message": "Pesan tanda",
"sign_up": "Daftar", "sign_up": "Daftar",
"sign_verify_message": "Tanda tangan atau verifikasi pesan",
"sign_verify_message_sub": "Menandatangani atau memverifikasi pesan menggunakan kunci pribadi Anda",
"sign_verify_title": "Tanda / verifikasi",
"signature": "Tanda tangan",
"signature_invalid_error": "Tanda tangan tidak valid untuk pesan yang diberikan",
"signTransaction": "Tandatangani Transaksi", "signTransaction": "Tandatangani Transaksi",
"signup_for_card_accept_terms": "Daftar untuk kartu dan terima syarat dan ketentuan.", "signup_for_card_accept_terms": "Daftar untuk kartu dan terima syarat dan ketentuan.",
"silent_payments": "Pembayaran diam", "silent_payments": "Pembayaran diam",
@ -823,6 +832,7 @@
"value_type": "Jenis Nilai", "value_type": "Jenis Nilai",
"variable_pair_not_supported": "Pasangan variabel ini tidak didukung dengan bursa yang dipilih", "variable_pair_not_supported": "Pasangan variabel ini tidak didukung dengan bursa yang dipilih",
"verification": "Verifikasi", "verification": "Verifikasi",
"verify_message": "Verifikasi pesan",
"verify_with_2fa": "Verifikasi dengan Cake 2FA", "verify_with_2fa": "Verifikasi dengan Cake 2FA",
"version": "Versi ${currentVersion}", "version": "Versi ${currentVersion}",
"view_all": "Lihat Semua", "view_all": "Lihat Semua",

View file

@ -339,6 +339,8 @@
"incoming": "In arrivo", "incoming": "In arrivo",
"incorrect_seed": "Il testo inserito non è valido.", "incorrect_seed": "Il testo inserito non è valido.",
"inputs": "Input", "inputs": "Input",
"insufficient_lamport_for_tx": "Non hai abbastanza SOL per coprire la transazione e la sua quota di transazione. Si prega di aggiungere più SOL al tuo portafoglio o ridurre l'importo SOL che stai inviando.",
"insufficient_lamports": "Non hai abbastanza SOL per coprire la transazione e la sua quota di transazione. Hai bisogno di almeno ${solValueNeeded} sol. Si prega di aggiungere più SOL al tuo portafoglio o ridurre l'importo SOL che stai inviando",
"insufficientFundsForRentError": "Non hai abbastanza SOL per coprire la tassa di transazione e l'affitto per il conto. Si prega di aggiungere più SOL al tuo portafoglio o ridurre l'importo SOL che stai inviando", "insufficientFundsForRentError": "Non hai abbastanza SOL per coprire la tassa di transazione e l'affitto per il conto. Si prega di aggiungere più SOL al tuo portafoglio o ridurre l'importo SOL che stai inviando",
"introducing_cake_pay": "Presentazione di Cake Pay!", "introducing_cake_pay": "Presentazione di Cake Pay!",
"invalid_input": "Inserimento non valido", "invalid_input": "Inserimento non valido",
@ -369,6 +371,7 @@
"max_value": "Max: ${value} ${currency}", "max_value": "Max: ${value} ${currency}",
"memo": "Memo:", "memo": "Memo:",
"message": "Messaggio", "message": "Messaggio",
"message_verified": "Il messaggio è stato verificato con successo",
"methods": "Metodi", "methods": "Metodi",
"min_amount": "Min: ${value}", "min_amount": "Min: ${value}",
"min_value": "Min: ${value} ${currency}", "min_value": "Min: ${value} ${currency}",
@ -661,7 +664,13 @@
"show_keys": "Mostra seme/chiavi", "show_keys": "Mostra seme/chiavi",
"show_market_place": "Mostra mercato", "show_market_place": "Mostra mercato",
"show_seed": "Mostra seme", "show_seed": "Mostra seme",
"sign_message": "Messaggio di firma",
"sign_up": "Registrati", "sign_up": "Registrati",
"sign_verify_message": "Firmare o verificare il messaggio",
"sign_verify_message_sub": "Firma o verifica un messaggio utilizzando la chiave privata",
"sign_verify_title": "Firmare / verificare",
"signature": "Firma",
"signature_invalid_error": "La firma non è valida per il messaggio dato",
"signTransaction": "Firma la transazione", "signTransaction": "Firma la transazione",
"signup_for_card_accept_terms": "Registrati per la carta e accetta i termini.", "signup_for_card_accept_terms": "Registrati per la carta e accetta i termini.",
"silent_payments": "Pagamenti silenziosi", "silent_payments": "Pagamenti silenziosi",
@ -822,6 +831,7 @@
"value_type": "Tipo di valore", "value_type": "Tipo di valore",
"variable_pair_not_supported": "Questa coppia di variabili non è supportata con gli scambi selezionati", "variable_pair_not_supported": "Questa coppia di variabili non è supportata con gli scambi selezionati",
"verification": "Verifica", "verification": "Verifica",
"verify_message": "Verificare il messaggio",
"verify_with_2fa": "Verifica con Cake 2FA", "verify_with_2fa": "Verifica con Cake 2FA",
"version": "Versione ${currentVersion}", "version": "Versione ${currentVersion}",
"view_all": "Visualizza tutto", "view_all": "Visualizza tutto",

View file

@ -339,6 +339,8 @@
"incoming": "着信", "incoming": "着信",
"incorrect_seed": "入力されたテキストは無効です。", "incorrect_seed": "入力されたテキストは無効です。",
"inputs": "入力", "inputs": "入力",
"insufficient_lamport_for_tx": "トランザクションとその取引手数料をカバーするのに十分なSOLがありません。財布にソルを追加するか、送信するソル量を減らしてください。",
"insufficient_lamports": "トランザクションとその取引手数料をカバーするのに十分なSOLがありません。少なくとも${solValueNeeded} solが必要です。財布にソルを追加するか、送信するソル量を減らしてください",
"insufficientFundsForRentError": "アカウントの取引料金とレンタルをカバーするのに十分なソルがありません。財布にソルを追加するか、送信するソル量を減らしてください", "insufficientFundsForRentError": "アカウントの取引料金とレンタルをカバーするのに十分なソルがありません。財布にソルを追加するか、送信するソル量を減らしてください",
"introducing_cake_pay": "序章Cake Pay", "introducing_cake_pay": "序章Cake Pay",
"invalid_input": "無効入力", "invalid_input": "無効入力",
@ -369,6 +371,7 @@
"max_value": "マックス: ${value} ${currency}", "max_value": "マックス: ${value} ${currency}",
"memo": "メモ:", "memo": "メモ:",
"message": "メッセージ", "message": "メッセージ",
"message_verified": "メッセージは正常に検証されました",
"methods": "メソッド", "methods": "メソッド",
"min_amount": "最小: ${value}", "min_amount": "最小: ${value}",
"min_value": "分: ${value} ${currency}", "min_value": "分: ${value} ${currency}",
@ -660,7 +663,13 @@
"show_keys": "シード/キーを表示する", "show_keys": "シード/キーを表示する",
"show_market_place": "マーケットプレイスを表示", "show_market_place": "マーケットプレイスを表示",
"show_seed": "シードを表示", "show_seed": "シードを表示",
"sign_message": "署名メッセージ",
"sign_up": "サインアップ", "sign_up": "サインアップ",
"sign_verify_message": "メッセージに署名または確認します",
"sign_verify_message_sub": "秘密鍵を使用してメッセージに署名または確認します",
"sign_verify_title": "署名 /検証",
"signature": "サイン",
"signature_invalid_error": "署名は、指定されたメッセージに対して無効です",
"signTransaction": "トランザクションに署名する", "signTransaction": "トランザクションに署名する",
"signup_for_card_accept_terms": "カードにサインアップして、利用規約に同意してください。", "signup_for_card_accept_terms": "カードにサインアップして、利用規約に同意してください。",
"silent_payments": "サイレント支払い", "silent_payments": "サイレント支払い",
@ -821,6 +830,7 @@
"value_type": "値タイプ", "value_type": "値タイプ",
"variable_pair_not_supported": "この変数ペアは、選択した取引所ではサポートされていません", "variable_pair_not_supported": "この変数ペアは、選択した取引所ではサポートされていません",
"verification": "検証", "verification": "検証",
"verify_message": "メッセージを確認します",
"verify_with_2fa": "Cake 2FA で検証する", "verify_with_2fa": "Cake 2FA で検証する",
"version": "バージョン ${currentVersion}", "version": "バージョン ${currentVersion}",
"view_all": "すべて表示", "view_all": "すべて表示",

View file

@ -338,6 +338,8 @@
"incoming": "들어오는", "incoming": "들어오는",
"incorrect_seed": "입력하신 텍스트가 유효하지 않습니다.", "incorrect_seed": "입력하신 텍스트가 유효하지 않습니다.",
"inputs": "입력", "inputs": "입력",
"insufficient_lamport_for_tx": "거래 및 거래 수수료를 충당하기에 충분한 SOL이 없습니다. 지갑에 더 많은 솔을 추가하거나 보내는 솔을 줄입니다.",
"insufficient_lamports": "거래 및 거래 수수료를 충당하기에 충분한 SOL이 없습니다. 최소 ${solValueNeeded} sol이 필요합니다. 지갑에 더 많은 솔을 추가하거나 보내는 솔을 줄이십시오.",
"insufficientFundsForRentError": "거래 수수료와 계좌 임대료를 충당하기에 충분한 SOL이 없습니다. 지갑에 더 많은 솔을 추가하거나 보내는 솔을 줄이십시오.", "insufficientFundsForRentError": "거래 수수료와 계좌 임대료를 충당하기에 충분한 SOL이 없습니다. 지갑에 더 많은 솔을 추가하거나 보내는 솔을 줄이십시오.",
"introducing_cake_pay": "소개 Cake Pay!", "introducing_cake_pay": "소개 Cake Pay!",
"invalid_input": "잘못된 입력", "invalid_input": "잘못된 입력",
@ -368,6 +370,7 @@
"max_value": "맥스: ${value} ${currency}", "max_value": "맥스: ${value} ${currency}",
"memo": "메모:", "memo": "메모:",
"message": "메시지", "message": "메시지",
"message_verified": "메시지가 성공적으로 확인되었습니다",
"methods": "행동 양식", "methods": "행동 양식",
"min_amount": "최소: ${value}", "min_amount": "최소: ${value}",
"min_value": "최소: ${value} ${currency}", "min_value": "최소: ${value} ${currency}",
@ -660,7 +663,13 @@
"show_keys": "시드 / 키 표시", "show_keys": "시드 / 키 표시",
"show_market_place": "마켓플레이스 표시", "show_market_place": "마켓플레이스 표시",
"show_seed": "종자 표시", "show_seed": "종자 표시",
"sign_message": "서명 메시지",
"sign_up": "가입", "sign_up": "가입",
"sign_verify_message": "메시지에 서명하거나 확인하십시오",
"sign_verify_message_sub": "개인 키를 사용하여 메시지에 서명하거나 확인하십시오",
"sign_verify_title": "서명 / 확인",
"signature": "서명",
"signature_invalid_error": "서명은 주어진 메시지에 유효하지 않습니다",
"signTransaction": "거래 서명", "signTransaction": "거래 서명",
"signup_for_card_accept_terms": "카드에 가입하고 약관에 동의합니다.", "signup_for_card_accept_terms": "카드에 가입하고 약관에 동의합니다.",
"silent_payments": "조용한 지불", "silent_payments": "조용한 지불",
@ -821,6 +830,7 @@
"value_type": "가치 유형", "value_type": "가치 유형",
"variable_pair_not_supported": "이 변수 쌍은 선택한 교환에서 지원되지 않습니다.", "variable_pair_not_supported": "이 변수 쌍은 선택한 교환에서 지원되지 않습니다.",
"verification": "검증", "verification": "검증",
"verify_message": "메시지를 확인하십시오",
"verify_with_2fa": "케이크 2FA로 확인", "verify_with_2fa": "케이크 2FA로 확인",
"version": "버전 ${currentVersion}", "version": "버전 ${currentVersion}",
"view_all": "모두 보기", "view_all": "모두 보기",

View file

@ -338,6 +338,8 @@
"incoming": "ဝင်လာ", "incoming": "ဝင်လာ",
"incorrect_seed": "ထည့်သွင်းထားသော စာသားသည် မမှန်ကန်ပါ။", "incorrect_seed": "ထည့်သွင်းထားသော စာသားသည် မမှန်ကန်ပါ။",
"inputs": "သွင်းငေှ", "inputs": "သွင်းငေှ",
"insufficient_lamport_for_tx": "သငျသညျငွေပေးငွေယူနှင့်၎င်း၏ငွေပေးငွေယူကြေးကိုဖုံးလွှမ်းရန် sol ရှိသည်မဟုတ်ကြဘူး။ ကြင်နာစွာသင်၏ပိုက်ဆံအိတ်သို့ပိုမို sol ကိုထပ်ထည့်ပါသို့မဟုတ်သင်ပို့လွှတ်ခြင်း sol ပမာဏကိုလျှော့ချပါ။",
"insufficient_lamports": "သငျသညျငွေပေးငွေယူနှင့်၎င်း၏ငွေပေးငွေယူကြေးကိုဖုံးလွှမ်းရန် sol ရှိသည်မဟုတ်ကြဘူး။ သင်အနည်းဆုံး ${solValueNeeded} s ကိုလိုအပ်ပါတယ်။ ကြင်နာစွာသင်၏ပိုက်ဆံအိတ်သို့ပိုမို sol ကိုထပ်ထည့်ပါသို့မဟုတ်သင်ပို့နေသော sol ပမာဏကိုလျှော့ချပါ",
"insufficientFundsForRentError": "သင်ငွေပေးချေမှုအခကြေးငွေကိုဖုံးအုပ်ရန်နှင့်အကောင့်ငှားရန်လုံလောက်သော sol ရှိသည်မဟုတ်ကြဘူး။ ကြင်နာစွာသင်၏ပိုက်ဆံအိတ်သို့ပိုမို sol ကိုပိုမိုထည့်ပါသို့မဟုတ်သင်ပို့ခြင်း sol ပမာဏကိုလျှော့ချပါ", "insufficientFundsForRentError": "သင်ငွေပေးချေမှုအခကြေးငွေကိုဖုံးအုပ်ရန်နှင့်အကောင့်ငှားရန်လုံလောက်သော sol ရှိသည်မဟုတ်ကြဘူး။ ကြင်နာစွာသင်၏ပိုက်ဆံအိတ်သို့ပိုမို sol ကိုပိုမိုထည့်ပါသို့မဟုတ်သင်ပို့ခြင်း sol ပမာဏကိုလျှော့ချပါ",
"introducing_cake_pay": "Cake Pay ကို မိတ်ဆက်ခြင်း။", "introducing_cake_pay": "Cake Pay ကို မိတ်ဆက်ခြင်း။",
"invalid_input": "ထည့်သွင်းမှု မမှန်ကန်ပါ။", "invalid_input": "ထည့်သွင်းမှု မမှန်ကန်ပါ။",
@ -368,6 +370,7 @@
"max_value": "အများဆုံး- ${value} ${currency}", "max_value": "အများဆုံး- ${value} ${currency}",
"memo": "မှတ်စုတို:", "memo": "မှတ်စုတို:",
"message": "မက်ဆေ့ချ်", "message": "မက်ဆေ့ချ်",
"message_verified": "မက်ဆေ့ခ်ျကိုအောင်မြင်စွာအတည်ပြုခဲ့သည်",
"methods": "နည်းလမ်းများ", "methods": "နည်းလမ်းများ",
"min_amount": "အနည်းဆုံး- ${value}", "min_amount": "အနည်းဆုံး- ${value}",
"min_value": "အနည်းဆုံး- ${value} ${currency}", "min_value": "အနည်းဆုံး- ${value} ${currency}",
@ -659,7 +662,13 @@
"show_keys": "မျိုးစေ့ /သော့များကို ပြပါ။", "show_keys": "မျိုးစေ့ /သော့များကို ပြပါ။",
"show_market_place": "စျေးကွက်ကိုပြသပါ။", "show_market_place": "စျေးကွက်ကိုပြသပါ။",
"show_seed": "မျိုးစေ့ကိုပြပါ။", "show_seed": "မျိုးစေ့ကိုပြပါ။",
"sign_message": "လက်မှတ်စာ",
"sign_up": "ဆိုင်းအပ်", "sign_up": "ဆိုင်းအပ်",
"sign_verify_message": "မက်ဆေ့ခ်ျကိုလက်မှတ်ထိုးသို့မဟုတ်အတည်ပြုရန်",
"sign_verify_message_sub": "သင်၏ကိုယ်ပိုင်သော့ကို သုံး. မက်ဆေ့ခ်ျကိုလက်မှတ်ထိုးပါ",
"sign_verify_title": "လက်မှတ်ထိုး / အတည်ပြုရန်",
"signature": "လက်မှတ်",
"signature_invalid_error": "အဆိုပါလက်မှတ်ပေးထားသောမက်ဆေ့ခ်ျကိုများအတွက်မမှန်ကန်ပါ",
"signTransaction": "ငွေလွှဲဝင်ပါ။", "signTransaction": "ငွေလွှဲဝင်ပါ။",
"signup_for_card_accept_terms": "ကတ်အတွက် စာရင်းသွင်းပြီး စည်းကမ်းချက်များကို လက်ခံပါ။", "signup_for_card_accept_terms": "ကတ်အတွက် စာရင်းသွင်းပြီး စည်းကမ်းချက်များကို လက်ခံပါ။",
"silent_payments": "အသံတိတ်ငွေပေးချေမှု", "silent_payments": "အသံတိတ်ငွေပေးချေမှု",
@ -820,6 +829,7 @@
"value_type": "Value အမျိုးအစား", "value_type": "Value အမျိုးအစား",
"variable_pair_not_supported": "ရွေးချယ်ထားသော ဖလှယ်မှုများဖြင့် ဤပြောင်းလဲနိုင်သောအတွဲကို ပံ့ပိုးမထားပါ။", "variable_pair_not_supported": "ရွေးချယ်ထားသော ဖလှယ်မှုများဖြင့် ဤပြောင်းလဲနိုင်သောအတွဲကို ပံ့ပိုးမထားပါ။",
"verification": "စိစစ်ခြင်း။", "verification": "စိစစ်ခြင်း။",
"verify_message": "မက်ဆေ့ခ်ျကိုအတည်ပြုရန်",
"verify_with_2fa": "Cake 2FA ဖြင့် စစ်ဆေးပါ။", "verify_with_2fa": "Cake 2FA ဖြင့် စစ်ဆေးပါ။",
"version": "ဗားရှင်း ${currentVersion}", "version": "ဗားရှင်း ${currentVersion}",
"view_all": "အားလုံးကိုကြည့်ရှုပါ။", "view_all": "အားလုံးကိုကြည့်ရှုပါ။",

View file

@ -338,6 +338,8 @@
"incoming": "inkomend", "incoming": "inkomend",
"incorrect_seed": "De ingevoerde tekst is niet geldig.", "incorrect_seed": "De ingevoerde tekst is niet geldig.",
"inputs": "Invoer", "inputs": "Invoer",
"insufficient_lamport_for_tx": "U hebt niet genoeg SOL om de transactie en de transactiekosten te dekken. Voeg vriendelijk meer SOL toe aan uw portemonnee of verminder de SOL -hoeveelheid die u verzendt.",
"insufficient_lamports": "U hebt niet genoeg SOL om de transactie en de transactiekosten te dekken. Je hebt minstens ${solValueNeeded} sol nodig. Voeg vriendelijk meer Sol toe aan uw portemonnee of verminder de SOL -hoeveelheid die u verzendt",
"insufficientFundsForRentError": "U hebt niet genoeg SOL om de transactiekosten en huur voor de rekening te dekken. Voeg vriendelijk meer SOL toe aan uw portemonnee of verminder de SOL -hoeveelheid die u verzendt", "insufficientFundsForRentError": "U hebt niet genoeg SOL om de transactiekosten en huur voor de rekening te dekken. Voeg vriendelijk meer SOL toe aan uw portemonnee of verminder de SOL -hoeveelheid die u verzendt",
"introducing_cake_pay": "Introductie van Cake Pay!", "introducing_cake_pay": "Introductie van Cake Pay!",
"invalid_input": "Ongeldige invoer", "invalid_input": "Ongeldige invoer",
@ -368,6 +370,7 @@
"max_value": "Max: ${value} ${currency}", "max_value": "Max: ${value} ${currency}",
"memo": "Memo:", "memo": "Memo:",
"message": "Bericht", "message": "Bericht",
"message_verified": "Het bericht is succesvol geverifieerd",
"methods": "Methoden", "methods": "Methoden",
"min_amount": "Min: ${value}", "min_amount": "Min: ${value}",
"min_value": "Min: ${value} ${currency}", "min_value": "Min: ${value} ${currency}",
@ -659,7 +662,13 @@
"show_keys": "Toon zaad/sleutels", "show_keys": "Toon zaad/sleutels",
"show_market_place": "Toon Marktplaats", "show_market_place": "Toon Marktplaats",
"show_seed": "Toon zaad", "show_seed": "Toon zaad",
"sign_message": "Aanmeldingsbericht",
"sign_up": "Aanmelden", "sign_up": "Aanmelden",
"sign_verify_message": "Teken of verifieer bericht",
"sign_verify_message_sub": "Teken of verifieer een bericht met uw privésleutel",
"sign_verify_title": "Ondertekenen / verifiëren",
"signature": "Handtekening",
"signature_invalid_error": "De handtekening is niet geldig voor het gegeven bericht",
"signTransaction": "Transactie ondertekenen", "signTransaction": "Transactie ondertekenen",
"signup_for_card_accept_terms": "Meld je aan voor de kaart en accepteer de voorwaarden.", "signup_for_card_accept_terms": "Meld je aan voor de kaart en accepteer de voorwaarden.",
"silent_payments": "Stille betalingen", "silent_payments": "Stille betalingen",
@ -820,6 +829,7 @@
"value_type": "Waarde type", "value_type": "Waarde type",
"variable_pair_not_supported": "Dit variabelenpaar wordt niet ondersteund met de geselecteerde uitwisselingen", "variable_pair_not_supported": "Dit variabelenpaar wordt niet ondersteund met de geselecteerde uitwisselingen",
"verification": "Verificatie", "verification": "Verificatie",
"verify_message": "Verifieer bericht",
"verify_with_2fa": "Controleer met Cake 2FA", "verify_with_2fa": "Controleer met Cake 2FA",
"version": "Versie ${currentVersion}", "version": "Versie ${currentVersion}",
"view_all": "Alles bekijken", "view_all": "Alles bekijken",

View file

@ -338,6 +338,8 @@
"incoming": "Przychodzące", "incoming": "Przychodzące",
"incorrect_seed": "Wprowadzony seed jest nieprawidłowy.", "incorrect_seed": "Wprowadzony seed jest nieprawidłowy.",
"inputs": "Wejścia", "inputs": "Wejścia",
"insufficient_lamport_for_tx": "Nie masz wystarczającej ilości SOL, aby pokryć transakcję i opłatę za transakcję. Uprzejmie dodaj więcej sol do portfela lub zmniejsz wysyłaną kwotę SOL.",
"insufficient_lamports": "Nie masz wystarczającej ilości SOL, aby pokryć transakcję i opłatę za transakcję. Potrzebujesz przynajmniej ${solValueNeeded} sol. Uprzejmie dodaj więcej sol do portfela lub zmniejsz wysyłaną kwotę SOL, którą wysyłasz",
"insufficientFundsForRentError": "Nie masz wystarczającej ilości SOL, aby pokryć opłatę za transakcję i czynsz za konto. Uprzejmie dodaj więcej sol do portfela lub zmniejsz solę, którą wysyłasz", "insufficientFundsForRentError": "Nie masz wystarczającej ilości SOL, aby pokryć opłatę za transakcję i czynsz za konto. Uprzejmie dodaj więcej sol do portfela lub zmniejsz solę, którą wysyłasz",
"introducing_cake_pay": "Przedstawiamy Cake Pay!", "introducing_cake_pay": "Przedstawiamy Cake Pay!",
"invalid_input": "Nieprawidłowe dane wejściowe", "invalid_input": "Nieprawidłowe dane wejściowe",
@ -368,6 +370,7 @@
"max_value": "Max: ${value} ${currency}", "max_value": "Max: ${value} ${currency}",
"memo": "Notatka:", "memo": "Notatka:",
"message": "Wiadomość", "message": "Wiadomość",
"message_verified": "Wiadomość została pomyślnie zweryfikowana",
"methods": "Metody", "methods": "Metody",
"min_amount": "Min: ${value}", "min_amount": "Min: ${value}",
"min_value": "Min: ${value} ${currency}", "min_value": "Min: ${value} ${currency}",
@ -659,7 +662,13 @@
"show_keys": "Pokaż seed/klucze", "show_keys": "Pokaż seed/klucze",
"show_market_place": "Pokaż rynek", "show_market_place": "Pokaż rynek",
"show_seed": "Pokaż frazy seed", "show_seed": "Pokaż frazy seed",
"sign_message": "Podpisuj wiadomość",
"sign_up": "Zarejestruj się", "sign_up": "Zarejestruj się",
"sign_verify_message": "Podpisz lub zweryfikuj wiadomość",
"sign_verify_message_sub": "Podpisz lub zweryfikuj wiadomość za pomocą klucza prywatnego",
"sign_verify_title": "Podpisać / weryfikować",
"signature": "Podpis",
"signature_invalid_error": "Podpis nie jest ważny dla podanej wiadomości",
"signTransaction": "Podpisz transakcję", "signTransaction": "Podpisz transakcję",
"signup_for_card_accept_terms": "Zarejestruj się, aby otrzymać kartę i zaakceptuj warunki.", "signup_for_card_accept_terms": "Zarejestruj się, aby otrzymać kartę i zaakceptuj warunki.",
"silent_payments": "Ciche płatności", "silent_payments": "Ciche płatności",
@ -820,6 +829,7 @@
"value_type": "Typ wartości", "value_type": "Typ wartości",
"variable_pair_not_supported": "Ta para zmiennych nie jest obsługiwana na wybranych giełdach", "variable_pair_not_supported": "Ta para zmiennych nie jest obsługiwana na wybranych giełdach",
"verification": "Weryfikacja", "verification": "Weryfikacja",
"verify_message": "Sprawdź wiadomość",
"verify_with_2fa": "Sprawdź za pomocą Cake 2FA", "verify_with_2fa": "Sprawdź za pomocą Cake 2FA",
"version": "Wersja ${currentVersion}", "version": "Wersja ${currentVersion}",
"view_all": "Wyświetl wszystko", "view_all": "Wyświetl wszystko",

View file

@ -338,6 +338,8 @@
"incoming": "Recebidas", "incoming": "Recebidas",
"incorrect_seed": "O texto digitado não é válido.", "incorrect_seed": "O texto digitado não é válido.",
"inputs": "Entradas", "inputs": "Entradas",
"insufficient_lamport_for_tx": "Você não tem Sol suficiente para cobrir a transação e sua taxa de transação. Por favor, adicione mais sol à sua carteira ou reduza a quantidade de sol que você envia.",
"insufficient_lamports": "Você não tem Sol suficiente para cobrir a transação e sua taxa de transação. Você precisa de pelo menos ${solValueNeeded} sol. Por favor, adicione mais sol à sua carteira ou reduza a quantidade de sol que você está enviando",
"insufficientFundsForRentError": "Você não tem Sol suficiente para cobrir a taxa de transação e o aluguel da conta. Por favor, adicione mais sol à sua carteira ou reduza a quantidade de sol que você envia", "insufficientFundsForRentError": "Você não tem Sol suficiente para cobrir a taxa de transação e o aluguel da conta. Por favor, adicione mais sol à sua carteira ou reduza a quantidade de sol que você envia",
"introducing_cake_pay": "Apresentando o Cake Pay!", "introducing_cake_pay": "Apresentando o Cake Pay!",
"invalid_input": "Entrada inválida", "invalid_input": "Entrada inválida",
@ -369,6 +371,7 @@
"max_value": "Máx: ${value} ${currency}", "max_value": "Máx: ${value} ${currency}",
"memo": "Memorando:", "memo": "Memorando:",
"message": "Mensagem", "message": "Mensagem",
"message_verified": "A mensagem foi verificada com sucesso",
"methods": "Métodos", "methods": "Métodos",
"min_amount": "Mínimo: ${valor}", "min_amount": "Mínimo: ${valor}",
"min_value": "Mín: ${value} ${currency}", "min_value": "Mín: ${value} ${currency}",
@ -661,7 +664,13 @@
"show_keys": "Mostrar semente/chaves", "show_keys": "Mostrar semente/chaves",
"show_market_place": "Mostrar mercado", "show_market_place": "Mostrar mercado",
"show_seed": "Mostrar semente", "show_seed": "Mostrar semente",
"sign_message": "Mensagem de assinar",
"sign_up": "Inscrever-se", "sign_up": "Inscrever-se",
"sign_verify_message": "Assinar ou verificar mensagem",
"sign_verify_message_sub": "Assine ou verifique uma mensagem usando sua chave privada",
"sign_verify_title": "Assinar / verificar",
"signature": "Assinatura",
"signature_invalid_error": "A assinatura não é válida para a mensagem dada",
"signTransaction": "Assinar transação", "signTransaction": "Assinar transação",
"signup_for_card_accept_terms": "Cadastre-se no cartão e aceite os termos.", "signup_for_card_accept_terms": "Cadastre-se no cartão e aceite os termos.",
"silent_payments": "Pagamentos silenciosos", "silent_payments": "Pagamentos silenciosos",
@ -822,6 +831,7 @@
"value_type": "Tipo de valor", "value_type": "Tipo de valor",
"variable_pair_not_supported": "Este par de variáveis não é compatível com as trocas selecionadas", "variable_pair_not_supported": "Este par de variáveis não é compatível com as trocas selecionadas",
"verification": "Verificação", "verification": "Verificação",
"verify_message": "Verifique a mensagem",
"verify_with_2fa": "Verificar com Cake 2FA", "verify_with_2fa": "Verificar com Cake 2FA",
"version": "Versão ${currentVersion}", "version": "Versão ${currentVersion}",
"view_all": "Ver todos", "view_all": "Ver todos",

View file

@ -338,6 +338,8 @@
"incoming": "Входящие", "incoming": "Входящие",
"incorrect_seed": "Введённый текст некорректный.", "incorrect_seed": "Введённый текст некорректный.",
"inputs": "Входы", "inputs": "Входы",
"insufficient_lamport_for_tx": "У вас недостаточно Sol, чтобы покрыть транзакцию и плату за транзакцию. Пожалуйста, добавьте больше Sol в свой кошелек или уменьшите сумму Sol, которую вы отправляете.",
"insufficient_lamports": "У вас недостаточно Sol, чтобы покрыть транзакцию и плату за транзакцию. Вам нужен как минимум ${solValueNeeded} sol. Пожалуйста, добавьте больше Sol в свой кошелек или уменьшите сумму Sol, которую вы отправляете",
"insufficientFundsForRentError": "У вас недостаточно Sol, чтобы покрыть плату за транзакцию и аренду для счета. Пожалуйста, добавьте больше Sol в свой кошелек или уменьшите сумму Sol, которую вы отправляете", "insufficientFundsForRentError": "У вас недостаточно Sol, чтобы покрыть плату за транзакцию и аренду для счета. Пожалуйста, добавьте больше Sol в свой кошелек или уменьшите сумму Sol, которую вы отправляете",
"introducing_cake_pay": "Представляем Cake Pay!", "introducing_cake_pay": "Представляем Cake Pay!",
"invalid_input": "Неверный Ввод", "invalid_input": "Неверный Ввод",
@ -368,6 +370,7 @@
"max_value": "Макс: ${value} ${currency}", "max_value": "Макс: ${value} ${currency}",
"memo": "Памятка:", "memo": "Памятка:",
"message": "Сообщение", "message": "Сообщение",
"message_verified": "Сообщение было успешно проверено",
"methods": "Методы", "methods": "Методы",
"min_amount": "Минимум: ${value}", "min_amount": "Минимум: ${value}",
"min_value": "Мин: ${value} ${currency}", "min_value": "Мин: ${value} ${currency}",
@ -660,7 +663,13 @@
"show_keys": "Показать мнемоническую фразу/ключи", "show_keys": "Показать мнемоническую фразу/ключи",
"show_market_place": "Показать торговую площадку", "show_market_place": "Показать торговую площадку",
"show_seed": "Показать мнемоническую фразу", "show_seed": "Показать мнемоническую фразу",
"sign_message": "Сообщение о знаке",
"sign_up": "Зарегистрироваться", "sign_up": "Зарегистрироваться",
"sign_verify_message": "Подписать или проверить сообщение",
"sign_verify_message_sub": "Подписать или проверить сообщение, используя свой закрытый ключ",
"sign_verify_title": "Знак / проверка",
"signature": "Подпись",
"signature_invalid_error": "Подпись недопустима для данного сообщения",
"signTransaction": "Подписать транзакцию", "signTransaction": "Подписать транзакцию",
"signup_for_card_accept_terms": "Подпишитесь на карту и примите условия.", "signup_for_card_accept_terms": "Подпишитесь на карту и примите условия.",
"silent_payments": "Молчаливые платежи", "silent_payments": "Молчаливые платежи",
@ -821,6 +830,7 @@
"value_type": "Тип значения", "value_type": "Тип значения",
"variable_pair_not_supported": "Эта пара переменных не поддерживается выбранными биржами.", "variable_pair_not_supported": "Эта пара переменных не поддерживается выбранными биржами.",
"verification": "Проверка", "verification": "Проверка",
"verify_message": "Проверьте сообщение",
"verify_with_2fa": "Подтвердить с помощью Cake 2FA", "verify_with_2fa": "Подтвердить с помощью Cake 2FA",
"version": "Версия ${currentVersion}", "version": "Версия ${currentVersion}",
"view_all": "Просмотреть все", "view_all": "Просмотреть все",

View file

@ -338,6 +338,8 @@
"incoming": "ขาเข้า", "incoming": "ขาเข้า",
"incorrect_seed": "ข้อความที่ป้อนไม่ถูกต้อง", "incorrect_seed": "ข้อความที่ป้อนไม่ถูกต้อง",
"inputs": "อินพุต", "inputs": "อินพุต",
"insufficient_lamport_for_tx": "คุณไม่มีโซลเพียงพอที่จะครอบคลุมการทำธุรกรรมและค่าธรรมเนียมการทำธุรกรรม กรุณาเพิ่มโซลให้มากขึ้นลงในกระเป๋าเงินของคุณหรือลดจำนวนโซลที่คุณส่งมา",
"insufficient_lamports": "คุณไม่มีโซลเพียงพอที่จะครอบคลุมการทำธุรกรรมและค่าธรรมเนียมการทำธุรกรรม คุณต้องการอย่างน้อย ${solValueNeeded} SOL กรุณาเพิ่มโซลให้มากขึ้นลงในกระเป๋าเงินของคุณหรือลดจำนวนโซลที่คุณกำลังส่ง",
"insufficientFundsForRentError": "คุณไม่มีโซลเพียงพอที่จะครอบคลุมค่าธรรมเนียมการทำธุรกรรมและค่าเช่าสำหรับบัญชี กรุณาเพิ่มโซลให้มากขึ้นลงในกระเป๋าเงินของคุณหรือลดจำนวนโซลที่คุณส่งมา", "insufficientFundsForRentError": "คุณไม่มีโซลเพียงพอที่จะครอบคลุมค่าธรรมเนียมการทำธุรกรรมและค่าเช่าสำหรับบัญชี กรุณาเพิ่มโซลให้มากขึ้นลงในกระเป๋าเงินของคุณหรือลดจำนวนโซลที่คุณส่งมา",
"introducing_cake_pay": "ยินดีต้อนรับสู่ Cake Pay!", "introducing_cake_pay": "ยินดีต้อนรับสู่ Cake Pay!",
"invalid_input": "อินพุตไม่ถูกต้อง", "invalid_input": "อินพุตไม่ถูกต้อง",
@ -368,6 +370,7 @@
"max_value": "ขั้นสูง: ${value} ${currency}", "max_value": "ขั้นสูง: ${value} ${currency}",
"memo": "หมายเหตุ:", "memo": "หมายเหตุ:",
"message": "ข้อความ", "message": "ข้อความ",
"message_verified": "ข้อความได้รับการตรวจสอบอย่างประสบความสำเร็จ",
"methods": "วิธีการ", "methods": "วิธีการ",
"min_amount": "จำนวนขั้นต่ำ: ${value}", "min_amount": "จำนวนขั้นต่ำ: ${value}",
"min_value": "ขั้นต่ำ: ${value} ${currency}", "min_value": "ขั้นต่ำ: ${value} ${currency}",
@ -659,7 +662,13 @@
"show_keys": "แสดงซีด/คีย์", "show_keys": "แสดงซีด/คีย์",
"show_market_place": "แสดงตลาดกลาง", "show_market_place": "แสดงตลาดกลาง",
"show_seed": "แสดงซีด", "show_seed": "แสดงซีด",
"sign_message": "ลงนามข้อความ",
"sign_up": "สมัครสมาชิก", "sign_up": "สมัครสมาชิก",
"sign_verify_message": "ลงชื่อเข้าใช้หรือตรวจสอบข้อความ",
"sign_verify_message_sub": "ลงชื่อเข้าใช้หรือตรวจสอบข้อความโดยใช้คีย์ส่วนตัวของคุณ",
"sign_verify_title": "ลงชื่อ / ตรวจสอบ",
"signature": "ลายเซ็น",
"signature_invalid_error": "ลายเซ็นไม่ถูกต้องสำหรับข้อความที่ให้ไว้",
"signTransaction": "ลงนามในการทำธุรกรรม", "signTransaction": "ลงนามในการทำธุรกรรม",
"signup_for_card_accept_terms": "ลงทะเบียนสำหรับบัตรและยอมรับเงื่อนไข", "signup_for_card_accept_terms": "ลงทะเบียนสำหรับบัตรและยอมรับเงื่อนไข",
"silent_payments": "การชำระเงินเงียบ", "silent_payments": "การชำระเงินเงียบ",
@ -820,6 +829,7 @@
"value_type": "ประเภทค่า", "value_type": "ประเภทค่า",
"variable_pair_not_supported": "คู่ความสัมพันธ์ที่เปลี่ยนแปลงได้นี้ไม่สนับสนุนกับหุ้นที่เลือก", "variable_pair_not_supported": "คู่ความสัมพันธ์ที่เปลี่ยนแปลงได้นี้ไม่สนับสนุนกับหุ้นที่เลือก",
"verification": "การตรวจสอบ", "verification": "การตรวจสอบ",
"verify_message": "ยืนยันข้อความ",
"verify_with_2fa": "ตรวจสอบกับ Cake 2FA", "verify_with_2fa": "ตรวจสอบกับ Cake 2FA",
"version": "เวอร์ชัน ${currentVersion}", "version": "เวอร์ชัน ${currentVersion}",
"view_all": "ดูทั้งหมด", "view_all": "ดูทั้งหมด",

View file

@ -338,6 +338,8 @@
"incoming": "Papasok", "incoming": "Papasok",
"incorrect_seed": "Ang text na ipinasok ay hindi wasto.", "incorrect_seed": "Ang text na ipinasok ay hindi wasto.",
"inputs": "Mga input", "inputs": "Mga input",
"insufficient_lamport_for_tx": "Wala kang sapat na SOL upang masakop ang transaksyon at ang bayad sa transaksyon nito. Mabuting magdagdag ng higit pa sa iyong pitaka o bawasan ang sol na halaga na iyong ipinapadala.",
"insufficient_lamports": "Wala kang sapat na SOL upang masakop ang transaksyon at ang bayad sa transaksyon nito. Kailangan mo ng hindi bababa sa ${solValueNeeded} sol. Mabait na magdagdag ng higit pang sol sa iyong pitaka o bawasan ang dami ng iyong ipinapadala",
"insufficientFundsForRentError": "Wala kang sapat na SOL upang masakop ang fee sa transaksyon at upa para sa account. Mabait na magdagdag ng higit pa sa iyong wallet o bawasan ang halaga ng SOL na iyong ipinapadala", "insufficientFundsForRentError": "Wala kang sapat na SOL upang masakop ang fee sa transaksyon at upa para sa account. Mabait na magdagdag ng higit pa sa iyong wallet o bawasan ang halaga ng SOL na iyong ipinapadala",
"introducing_cake_pay": "Pagpapakilala ng Cake Pay!", "introducing_cake_pay": "Pagpapakilala ng Cake Pay!",
"invalid_input": "Di-wastong input", "invalid_input": "Di-wastong input",
@ -368,6 +370,7 @@
"max_value": "Max: ${value} ${currency}", "max_value": "Max: ${value} ${currency}",
"memo": "Memo:", "memo": "Memo:",
"message": "Mensahe", "message": "Mensahe",
"message_verified": "Ang mensahe ay matagumpay na na -verify",
"methods": "Mga Paraan", "methods": "Mga Paraan",
"min_amount": "Min: ${value}", "min_amount": "Min: ${value}",
"min_value": "Min: ${value} ${currency}", "min_value": "Min: ${value} ${currency}",
@ -658,6 +661,12 @@
"show_details": "Ipakita ang mga detalye", "show_details": "Ipakita ang mga detalye",
"show_keys": "Ipakita ang mga seed/key", "show_keys": "Ipakita ang mga seed/key",
"show_market_place": "Ipakita ang Marketplace", "show_market_place": "Ipakita ang Marketplace",
"sign_message": "Mag -sign Message",
"sign_verify_message": "Mag -sign o i -verify ang mensahe",
"sign_verify_message_sub": "Mag -sign o i -verify ang isang mensahe gamit ang iyong pribadong key",
"sign_verify_title": "Mag -sign / Mag -verify",
"signature": "Lagda",
"signature_invalid_error": "Ang lagda ay hindi wasto para sa ibinigay na mensahe",
"show_seed": "Ipakita ang seed", "show_seed": "Ipakita ang seed",
"sign_up": "Mag-sign Up", "sign_up": "Mag-sign Up",
"signTransaction": "Mag-sign ang Transaksyon", "signTransaction": "Mag-sign ang Transaksyon",
@ -818,6 +827,7 @@
"use_testnet": "Gumamit ng testnet", "use_testnet": "Gumamit ng testnet",
"value": "Halaga", "value": "Halaga",
"value_type": "Uri ng halaga", "value_type": "Uri ng halaga",
"verify_message": "I -verify ang mensahe",
"variable_pair_not_supported": "Ang variable na pares na ito ay hindi suportado sa mga napiling exchange", "variable_pair_not_supported": "Ang variable na pares na ito ay hindi suportado sa mga napiling exchange",
"verification": "Pag-verify", "verification": "Pag-verify",
"verify_with_2fa": "Mag-verify sa Cake 2FA", "verify_with_2fa": "Mag-verify sa Cake 2FA",

View file

@ -338,6 +338,8 @@
"incoming": "Gelen", "incoming": "Gelen",
"incorrect_seed": "Girilen metin geçerli değil.", "incorrect_seed": "Girilen metin geçerli değil.",
"inputs": "Girişler", "inputs": "Girişler",
"insufficient_lamport_for_tx": "İşlemi ve işlem ücretini karşılamak için yeterli SOL'unuz yok. Lütfen cüzdanınıza daha fazla SOL ekleyin veya gönderdiğiniz sol miktarını azaltın.",
"insufficient_lamports": "İşlemi ve işlem ücretini karşılamak için yeterli SOL'unuz yok. En az ${solValueNeeded} Sol'a ihtiyacınız var. Lütfen cüzdanınıza daha fazla sol ekleyin veya gönderdiğiniz sol miktarını azaltın",
"insufficientFundsForRentError": "İşlem ücretini karşılamak ve hesap için kiralamak için yeterli SOL'nuz yok. Lütfen cüzdanınıza daha fazla sol ekleyin veya gönderdiğiniz sol miktarını azaltın", "insufficientFundsForRentError": "İşlem ücretini karşılamak ve hesap için kiralamak için yeterli SOL'nuz yok. Lütfen cüzdanınıza daha fazla sol ekleyin veya gönderdiğiniz sol miktarını azaltın",
"introducing_cake_pay": "Cake Pay ile tanışın!", "introducing_cake_pay": "Cake Pay ile tanışın!",
"invalid_input": "Geçersiz Giriş", "invalid_input": "Geçersiz Giriş",
@ -368,6 +370,7 @@
"max_value": "En fazla: ${value} ${currency}", "max_value": "En fazla: ${value} ${currency}",
"memo": "Memo:", "memo": "Memo:",
"message": "İleti", "message": "İleti",
"message_verified": "Mesaj başarıyla doğrulandı",
"methods": "Yöntemler", "methods": "Yöntemler",
"min_amount": "Min: ${value}", "min_amount": "Min: ${value}",
"min_value": "En az: ${value} ${currency}", "min_value": "En az: ${value} ${currency}",
@ -659,7 +662,13 @@
"show_keys": "Tohumları/anahtarları göster", "show_keys": "Tohumları/anahtarları göster",
"show_market_place": "Pazar Yerini Göster", "show_market_place": "Pazar Yerini Göster",
"show_seed": "Tohumları göster", "show_seed": "Tohumları göster",
"sign_message": "İşaret mesajı",
"sign_up": "Kaydol", "sign_up": "Kaydol",
"sign_verify_message": "Mesajı işaretleyin veya doğrulayın",
"sign_verify_message_sub": "Özel anahtarınızı kullanarak bir mesajı imzalayın veya doğrulayın",
"sign_verify_title": "İşaretle / Doğrula",
"signature": "İmza",
"signature_invalid_error": "İmza verilen mesaj için geçerli değil",
"signTransaction": "İşlem İmzala", "signTransaction": "İşlem İmzala",
"signup_for_card_accept_terms": "Kart için kaydol ve koşulları kabul et.", "signup_for_card_accept_terms": "Kart için kaydol ve koşulları kabul et.",
"silent_payments": "Sessiz ödemeler", "silent_payments": "Sessiz ödemeler",
@ -820,6 +829,7 @@
"value_type": "Değer türü", "value_type": "Değer türü",
"variable_pair_not_supported": "Bu değişken paritesi seçilen borsalarda desteklenmemekte", "variable_pair_not_supported": "Bu değişken paritesi seçilen borsalarda desteklenmemekte",
"verification": "Doğrulama", "verification": "Doğrulama",
"verify_message": "Mesajı Doğrula",
"verify_with_2fa": "Cake 2FA ile Doğrulayın", "verify_with_2fa": "Cake 2FA ile Doğrulayın",
"version": "Sürüm ${currentVersion}", "version": "Sürüm ${currentVersion}",
"view_all": "Hepsini göster", "view_all": "Hepsini göster",

View file

@ -338,6 +338,8 @@
"incoming": "Вхідні", "incoming": "Вхідні",
"incorrect_seed": "Введений текст невірний.", "incorrect_seed": "Введений текст невірний.",
"inputs": "Вхoди", "inputs": "Вхoди",
"insufficient_lamport_for_tx": "У вас недостатньо SOL, щоб покрити транзакцію та її плату за трансакцію. Будь ласка, додайте до свого гаманця більше SOL або зменшіть суму, яку ви надсилаєте.",
"insufficient_lamports": "У вас недостатньо SOL, щоб покрити транзакцію та її плату за трансакцію. Вам потрібно щонайменше ${solValueNeeded} sol. Будь ласка, додайте до свого гаманця більше SOL або зменшіть суму Sol, яку ви надсилаєте",
"insufficientFundsForRentError": "У вас недостатньо SOL, щоб покрити плату за транзакцію та оренду на рахунок. Будь ласка, додайте до свого гаманця більше SOL або зменшіть суму, яку ви надсилаєте", "insufficientFundsForRentError": "У вас недостатньо SOL, щоб покрити плату за транзакцію та оренду на рахунок. Будь ласка, додайте до свого гаманця більше SOL або зменшіть суму, яку ви надсилаєте",
"introducing_cake_pay": "Представляємо Cake Pay!", "introducing_cake_pay": "Представляємо Cake Pay!",
"invalid_input": "Неправильні дані", "invalid_input": "Неправильні дані",
@ -368,6 +370,7 @@
"max_value": "Макс: ${value} ${currency}", "max_value": "Макс: ${value} ${currency}",
"memo": "Пам’ятка:", "memo": "Пам’ятка:",
"message": "повідомлення", "message": "повідомлення",
"message_verified": "Повідомлення було успішно перевірено",
"methods": "методи", "methods": "методи",
"min_amount": "Мінімум: ${value}", "min_amount": "Мінімум: ${value}",
"min_value": "Мін: ${value} ${currency}", "min_value": "Мін: ${value} ${currency}",
@ -660,7 +663,13 @@
"show_keys": "Показати мнемонічну фразу/ключі", "show_keys": "Показати мнемонічну фразу/ключі",
"show_market_place": "Відображати маркетплейс", "show_market_place": "Відображати маркетплейс",
"show_seed": "Показати мнемонічну фразу", "show_seed": "Показати мнемонічну фразу",
"sign_message": "Підпишіть повідомлення",
"sign_up": "Зареєструватися", "sign_up": "Зареєструватися",
"sign_verify_message": "Підпишіть або перевірити повідомлення",
"sign_verify_message_sub": "Підпишіть або перевірте повідомлення за допомогою вашого приватного ключа",
"sign_verify_title": "Знак / Перевірка",
"signature": "Підпис",
"signature_invalid_error": "Підпис не є дійсним для наведеного повідомлення",
"signTransaction": "Підписати транзакцію", "signTransaction": "Підписати транзакцію",
"signup_for_card_accept_terms": "Зареєструйтеся на картку та прийміть умови.", "signup_for_card_accept_terms": "Зареєструйтеся на картку та прийміть умови.",
"silent_payments": "Мовчазні платежі", "silent_payments": "Мовчазні платежі",
@ -821,6 +830,7 @@
"value_type": "Тип значення", "value_type": "Тип значення",
"variable_pair_not_supported": "Ця пара змінних не підтримується вибраними біржами", "variable_pair_not_supported": "Ця пара змінних не підтримується вибраними біржами",
"verification": "Перевірка", "verification": "Перевірка",
"verify_message": "Перевірте повідомлення",
"verify_with_2fa": "Перевірте за допомогою Cake 2FA", "verify_with_2fa": "Перевірте за допомогою Cake 2FA",
"version": "Версія ${currentVersion}", "version": "Версія ${currentVersion}",
"view_all": "Переглянути все", "view_all": "Переглянути все",

View file

@ -338,6 +338,8 @@
"incoming": "آنے والا", "incoming": "آنے والا",
"incorrect_seed": "درج کردہ متن درست نہیں ہے۔", "incorrect_seed": "درج کردہ متن درست نہیں ہے۔",
"inputs": "آدانوں", "inputs": "آدانوں",
"insufficient_lamport_for_tx": "آپ کے پاس ٹرانزیکشن اور اس کے لین دین کی فیس کا احاطہ کرنے کے لئے کافی SOL نہیں ہے۔ برائے مہربانی اپنے بٹوے میں مزید سول شامل کریں یا آپ کو بھیجنے والی سول رقم کو کم کریں۔",
"insufficient_lamports": "آپ کے پاس ٹرانزیکشن اور اس کے لین دین کی فیس کا احاطہ کرنے کے لئے کافی SOL نہیں ہے۔ آپ کو کم از کم ${solValueNeeded} sol کی ضرورت ہے۔ برائے مہربانی اپنے بٹوے میں مزید SOL شامل کریں یا آپ جس SOL رقم کو بھیج رہے ہو اسے کم کریں",
"insufficientFundsForRentError": "آپ کے پاس ٹرانزیکشن فیس اور اکاؤنٹ کے لئے کرایہ لینے کے ل enough اتنا SOL نہیں ہے۔ برائے مہربانی اپنے بٹوے میں مزید سول شامل کریں یا آپ کو بھیجنے والی سول رقم کو کم کریں", "insufficientFundsForRentError": "آپ کے پاس ٹرانزیکشن فیس اور اکاؤنٹ کے لئے کرایہ لینے کے ل enough اتنا SOL نہیں ہے۔ برائے مہربانی اپنے بٹوے میں مزید سول شامل کریں یا آپ کو بھیجنے والی سول رقم کو کم کریں",
"introducing_cake_pay": "Cake پے کا تعارف!", "introducing_cake_pay": "Cake پے کا تعارف!",
"invalid_input": "غلط ان پٹ", "invalid_input": "غلط ان پٹ",
@ -368,6 +370,7 @@
"max_value": "زیادہ سے زیادہ: ${value} ${currency}", "max_value": "زیادہ سے زیادہ: ${value} ${currency}",
"memo": "میمو:", "memo": "میمو:",
"message": "ﻡﺎﻐﯿﭘ", "message": "ﻡﺎﻐﯿﭘ",
"message_verified": "پیغام کی کامیابی کے ساتھ تصدیق کی گئی",
"methods": "ﮯﻘﯾﺮﻃ", "methods": "ﮯﻘﯾﺮﻃ",
"min_amount": "کم سے کم: ${value}", "min_amount": "کم سے کم: ${value}",
"min_value": "کم سے کم: ${value} ${currency}", "min_value": "کم سے کم: ${value} ${currency}",
@ -661,7 +664,13 @@
"show_keys": "بیج / چابیاں دکھائیں۔", "show_keys": "بیج / چابیاں دکھائیں۔",
"show_market_place": "بازار دکھائیں۔", "show_market_place": "بازار دکھائیں۔",
"show_seed": "بیج دکھائیں۔", "show_seed": "بیج دکھائیں۔",
"sign_message": "سائن پیغام",
"sign_up": "سائن اپ", "sign_up": "سائن اپ",
"sign_verify_message": "پیغام پر دستخط کریں یا تصدیق کریں",
"sign_verify_message_sub": "اپنی نجی کلید کا استعمال کرتے ہوئے کسی پیغام پر دستخط کریں یا اس کی تصدیق کریں",
"sign_verify_title": "سائن / تصدیق کریں",
"signature": "دستخط",
"signature_invalid_error": "دستخط دیئے گئے پیغام کے لئے درست نہیں ہے",
"signTransaction": "۔ﮟﯾﺮﮐ ﻂﺨﺘﺳﺩ ﺮﭘ ﻦﯾﺩ ﻦﯿﻟ", "signTransaction": "۔ﮟﯾﺮﮐ ﻂﺨﺘﺳﺩ ﺮﭘ ﻦﯾﺩ ﻦﯿﻟ",
"signup_for_card_accept_terms": "کارڈ کے لیے سائن اپ کریں اور شرائط کو قبول کریں۔", "signup_for_card_accept_terms": "کارڈ کے لیے سائن اپ کریں اور شرائط کو قبول کریں۔",
"silent_payments": "خاموش ادائیگی", "silent_payments": "خاموش ادائیگی",
@ -822,6 +831,7 @@
"value_type": "قدر کی قسم", "value_type": "قدر کی قسم",
"variable_pair_not_supported": "یہ متغیر جوڑا منتخب ایکسچینجز کے ساتھ تعاون یافتہ نہیں ہے۔", "variable_pair_not_supported": "یہ متغیر جوڑا منتخب ایکسچینجز کے ساتھ تعاون یافتہ نہیں ہے۔",
"verification": "تصدیق", "verification": "تصدیق",
"verify_message": "پیغام کی تصدیق کریں",
"verify_with_2fa": "کیک 2FA سے تصدیق کریں۔", "verify_with_2fa": "کیک 2FA سے تصدیق کریں۔",
"version": "ورژن ${currentVersion}", "version": "ورژن ${currentVersion}",
"view_all": "سب دیکھیں", "view_all": "سب دیکھیں",

View file

@ -339,6 +339,8 @@
"incoming": "Wọ́n tó ń bọ̀", "incoming": "Wọ́n tó ń bọ̀",
"incorrect_seed": "Ọ̀rọ̀ tí a tẹ̀ kì í ṣe èyí.", "incorrect_seed": "Ọ̀rọ̀ tí a tẹ̀ kì í ṣe èyí.",
"inputs": "Igbewọle", "inputs": "Igbewọle",
"insufficient_lamport_for_tx": "O ko ni sosi to lati bo idunadura ati idiyele iṣowo rẹ. Fi agbara kun Sol diẹ sii si apamọwọ rẹ tabi dinku sodo naa ti o \\ 'tun n firanṣẹ.",
"insufficient_lamports": "O ko ni sosi to lati bo idunadura ati idiyele iṣowo rẹ. O nilo o kere ju ${solValueNeeded}. Fi agbara kun Sol diẹ sii si apamọwọ rẹ tabi dinku soso ti o n firanṣẹ",
"insufficientFundsForRentError": "O ko ni Sol kan lati bo owo isanwo naa ki o yalo fun iroyin naa. Fi agbara kun Sol diẹ sii si apamọwọ rẹ tabi dinku soso naa ti o \\ 'tun n firanṣẹ", "insufficientFundsForRentError": "O ko ni Sol kan lati bo owo isanwo naa ki o yalo fun iroyin naa. Fi agbara kun Sol diẹ sii si apamọwọ rẹ tabi dinku soso naa ti o \\ 'tun n firanṣẹ",
"introducing_cake_pay": "Ẹ bá Cake Pay!", "introducing_cake_pay": "Ẹ bá Cake Pay!",
"invalid_input": "Iṣawọle ti ko tọ", "invalid_input": "Iṣawọle ti ko tọ",
@ -369,6 +371,7 @@
"max_value": "kò gbọ́dọ̀ tóbi ju ${value} ${currency}", "max_value": "kò gbọ́dọ̀ tóbi ju ${value} ${currency}",
"memo": "Àkọsílẹ̀:", "memo": "Àkọsílẹ̀:",
"message": "Ifiranṣẹ", "message": "Ifiranṣẹ",
"message_verified": "Ifiranṣẹ naa ni aṣeyọri ni ifijišẹ",
"methods": "Awọn ọna", "methods": "Awọn ọna",
"min_amount": "kò kéré ju: ${value}", "min_amount": "kò kéré ju: ${value}",
"min_value": "kò gbọ́dọ̀ kéré ju ${value} ${currency}", "min_value": "kò gbọ́dọ̀ kéré ju ${value} ${currency}",
@ -660,7 +663,13 @@
"show_keys": "Wo hóró / àwọn kọ́kọ́rọ́", "show_keys": "Wo hóró / àwọn kọ́kọ́rọ́",
"show_market_place": "Wa Sopọ Pataki", "show_market_place": "Wa Sopọ Pataki",
"show_seed": "Wo hóró", "show_seed": "Wo hóró",
"sign_message": "Ifiranṣẹ Ami",
"sign_up": "Forúkọ sílẹ̀", "sign_up": "Forúkọ sílẹ̀",
"sign_verify_message": "Ami tabi ṣayẹwo ifiranṣẹ",
"sign_verify_message_sub": "Wọle tabi ṣayẹwo ifiranṣẹ kan nipa lilo bọtini ikọkọ rẹ",
"sign_verify_title": "Ami / Daju",
"signature": "Ibọwọlu",
"signature_invalid_error": "Ibuwọlu ko wulo fun ifiranṣẹ ti a fun",
"signTransaction": "Wole Idunadura", "signTransaction": "Wole Idunadura",
"signup_for_card_accept_terms": "Ẹ f'orúkọ sílẹ̀ láti gba káàdì àti àjọrò.", "signup_for_card_accept_terms": "Ẹ f'orúkọ sílẹ̀ láti gba káàdì àti àjọrò.",
"silent_payments": "Awọn sisanwo ipalọlọ", "silent_payments": "Awọn sisanwo ipalọlọ",
@ -821,6 +830,7 @@
"value_type": "Iru iye", "value_type": "Iru iye",
"variable_pair_not_supported": "A kì í ṣe k'á fi àwọn ilé pàṣípààrọ̀ yìí ṣe pàṣípààrọ̀ irú owó méji yìí", "variable_pair_not_supported": "A kì í ṣe k'á fi àwọn ilé pàṣípààrọ̀ yìí ṣe pàṣípààrọ̀ irú owó méji yìí",
"verification": "Ìjẹ́rìísí", "verification": "Ìjẹ́rìísí",
"verify_message": "Daju ifiranṣẹ",
"verify_with_2fa": "Ṣeẹda pẹlu Cake 2FA", "verify_with_2fa": "Ṣeẹda pẹlu Cake 2FA",
"version": "Àtúnse ${currentVersion}", "version": "Àtúnse ${currentVersion}",
"view_all": "Wo gbogbo nǹkan kan", "view_all": "Wo gbogbo nǹkan kan",

View file

@ -338,6 +338,8 @@
"incoming": "收到", "incoming": "收到",
"incorrect_seed": "输入的文字无效。", "incorrect_seed": "输入的文字无效。",
"inputs": "输入", "inputs": "输入",
"insufficient_lamport_for_tx": "您没有足够的溶胶来支付交易及其交易费用。请在您的钱包中添加更多溶胶或减少您发送的溶胶量。",
"insufficient_lamports": "您没有足够的溶胶来支付交易及其交易费用。您至少需要${solValueNeeded} sol。请在您的钱包中添加更多溶胶或减少您发送的溶胶量",
"insufficientFundsForRentError": "您没有足够的溶胶来支付该帐户的交易费和租金。请在钱包中添加更多溶胶或减少您发送的溶胶量", "insufficientFundsForRentError": "您没有足够的溶胶来支付该帐户的交易费和租金。请在钱包中添加更多溶胶或减少您发送的溶胶量",
"introducing_cake_pay": "介绍 Cake Pay!", "introducing_cake_pay": "介绍 Cake Pay!",
"invalid_input": "输入无效", "invalid_input": "输入无效",
@ -368,6 +370,7 @@
"max_value": "最大: ${value} ${currency}", "max_value": "最大: ${value} ${currency}",
"memo": "备忘录:", "memo": "备忘录:",
"message": "信息", "message": "信息",
"message_verified": "该消息已成功验证",
"methods": "方法", "methods": "方法",
"min_amount": "最小值: ${value}", "min_amount": "最小值: ${value}",
"min_value": "最小: ${value} ${currency}", "min_value": "最小: ${value} ${currency}",
@ -659,7 +662,13 @@
"show_keys": "显示种子/密钥", "show_keys": "显示种子/密钥",
"show_market_place": "显示市场", "show_market_place": "显示市场",
"show_seed": "显示种子", "show_seed": "显示种子",
"sign_message": "标志消息",
"sign_up": "注册", "sign_up": "注册",
"sign_verify_message": "签名或验证消息",
"sign_verify_message_sub": "使用您的私钥签名或验证消息",
"sign_verify_title": "签名 /验证",
"signature": "签名",
"signature_invalid_error": "签名对于给出的消息无效",
"signTransaction": "签署交易", "signTransaction": "签署交易",
"signup_for_card_accept_terms": "注册卡并接受条款。", "signup_for_card_accept_terms": "注册卡并接受条款。",
"silent_payments": "无声付款", "silent_payments": "无声付款",
@ -820,6 +829,7 @@
"value_type": "值类型", "value_type": "值类型",
"variable_pair_not_supported": "所选交易所不支持此变量对", "variable_pair_not_supported": "所选交易所不支持此变量对",
"verification": "验证", "verification": "验证",
"verify_message": "验证消息",
"verify_with_2fa": "用 Cake 2FA 验证", "verify_with_2fa": "用 Cake 2FA 验证",
"version": "版本 ${currentVersion}", "version": "版本 ${currentVersion}",
"view_all": "查看全部", "view_all": "查看全部",

View file

@ -15,15 +15,15 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
APP_ANDROID_TYPE=$1 APP_ANDROID_TYPE=$1
MONERO_COM_NAME="Monero.com" MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="1.16.3" MONERO_COM_VERSION="1.16.4"
MONERO_COM_BUILD_NUMBER=97 MONERO_COM_BUILD_NUMBER=98
MONERO_COM_BUNDLE_ID="com.monero.app" MONERO_COM_BUNDLE_ID="com.monero.app"
MONERO_COM_PACKAGE="com.monero.app" MONERO_COM_PACKAGE="com.monero.app"
MONERO_COM_SCHEME="monero.com" MONERO_COM_SCHEME="monero.com"
CAKEWALLET_NAME="Cake Wallet" CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="4.19.3" CAKEWALLET_VERSION="4.19.4"
CAKEWALLET_BUILD_NUMBER=224 CAKEWALLET_BUILD_NUMBER=225
CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet" CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet" CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
CAKEWALLET_SCHEME="cakewallet" CAKEWALLET_SCHEME="cakewallet"

View file

@ -13,13 +13,13 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
APP_IOS_TYPE=$1 APP_IOS_TYPE=$1
MONERO_COM_NAME="Monero.com" MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="1.16.3" MONERO_COM_VERSION="1.16.4"
MONERO_COM_BUILD_NUMBER=95 MONERO_COM_BUILD_NUMBER=96
MONERO_COM_BUNDLE_ID="com.cakewallet.monero" MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
CAKEWALLET_NAME="Cake Wallet" CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="4.19.3" CAKEWALLET_VERSION="4.19.4"
CAKEWALLET_BUILD_NUMBER=262 CAKEWALLET_BUILD_NUMBER=263
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
HAVEN_NAME="Haven" HAVEN_NAME="Haven"

View file

@ -14,8 +14,8 @@ if [ -n "$1" ]; then
fi fi
CAKEWALLET_NAME="Cake Wallet" CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="1.9.2" CAKEWALLET_VERSION="1.9.4"
CAKEWALLET_BUILD_NUMBER=30 CAKEWALLET_BUILD_NUMBER=31
if ! [[ " ${TYPES[*]} " =~ " ${APP_LINUX_TYPE} " ]]; then if ! [[ " ${TYPES[*]} " =~ " ${APP_LINUX_TYPE} " ]]; then
echo "Wrong app type." echo "Wrong app type."

View file

@ -16,13 +16,13 @@ if [ -n "$1" ]; then
fi fi
MONERO_COM_NAME="Monero.com" MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="1.6.2" MONERO_COM_VERSION="1.6.4"
MONERO_COM_BUILD_NUMBER=27 MONERO_COM_BUILD_NUMBER=28
MONERO_COM_BUNDLE_ID="com.cakewallet.monero" MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
CAKEWALLET_NAME="Cake Wallet" CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="1.12.2" CAKEWALLET_VERSION="1.12.4"
CAKEWALLET_BUILD_NUMBER=83 CAKEWALLET_BUILD_NUMBER=85
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then

View file

@ -23,12 +23,14 @@ then
done done
else else
if [[ "x$1" == "xuniversal" ]]; then if [[ "x$1" == "xuniversal" ]]; then
ARCHS=(arm64 x86_64) ARCHS=(x86_64 arm64)
else else
ARCHS=$(uname -m) ARCHS=$(uname -m)
fi fi
for COIN in monero wownero; for COIN in monero wownero;
do do
MONERO_LIBS=""
WOWNERO_LIBS=""
for ARCH in "${ARCHS[@]}"; for ARCH in "${ARCHS[@]}";
do do
if [[ "$ARCH" == "arm64" ]]; then if [[ "$ARCH" == "arm64" ]]; then
@ -39,17 +41,18 @@ else
HOST="${ARCH}-host-apple-darwin" HOST="${ARCH}-host-apple-darwin"
fi fi
MONERO_LIBS=" -arch ${ARCH} ${MONEROC_RELEASE_DIR}/${HOST}_libwallet2_api_c.dylib" MONERO_LIBS="$MONERO_LIBS -arch ${ARCH} ${MONEROC_RELEASE_DIR}/${HOST}_libwallet2_api_c.dylib"
WOWNERO_LIBS=" -arch ${ARCH} ${WOWNEROC_RELEASE_DIR}/${HOST}_libwallet2_api_c.dylib" WOWNERO_LIBS="$WOWNERO_LIBS -arch ${ARCH} ${WOWNEROC_RELEASE_DIR}/${HOST}_libwallet2_api_c.dylib"
if [[ ! $(uname -m) == $ARCH ]]; then if [[ ! $(uname -m) == $ARCH ]]; then
PRC="arch -${ARCH}" PRC="arch -${ARCH}"
else
PRC=""
fi fi
pushd ../monero_c pushd ../monero_c
$PRC ./build_single.sh ${COIN} ${HOST} $NPROC $PRC ./build_single.sh ${COIN} ${HOST} $NPROC
unxz -f ./release/${COIN}/${HOST}_libwallet2_api_c.dylib.xz unxz -f ./release/${COIN}/${HOST}_libwallet2_api_c.dylib.xz
popd popd
done done
done done

View file

@ -8,7 +8,7 @@ if [[ ! -d "monero_c" ]];
then then
git clone https://github.com/mrcyjanek/monero_c --branch rewrite-wip git clone https://github.com/mrcyjanek/monero_c --branch rewrite-wip
cd monero_c cd monero_c
git checkout bcb328a4956105dc182afd0ce2e48fe263f5f20b git checkout 5de323b1ba7387cf73973042f06383d4dbe619f5
git reset --hard git reset --hard
git submodule update --init --force --recursive git submodule update --init --force --recursive
./apply_patches.sh monero ./apply_patches.sh monero

View file

@ -1,5 +1,5 @@
#define MyAppName "Cake Wallet" #define MyAppName "Cake Wallet"
#define MyAppVersion "0.0.4" #define MyAppVersion "0.0.5"
#define MyAppPublisher "Cake Labs LLC" #define MyAppPublisher "Cake Labs LLC"
#define MyAppURL "https://cakewallet.com/" #define MyAppURL "https://cakewallet.com/"
#define MyAppExeName "CakeWallet.exe" #define MyAppExeName "CakeWallet.exe"