mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-22 11:39:22 +00:00
CW-224-Allow-Monero-proxy-in-node-settings (#966)
* update setupNodeSync func * minor fixes * localization * add request node with proxy * formatting
This commit is contained in:
parent
fcf4fbdc14
commit
d5c0012964
38 changed files with 180 additions and 27 deletions
|
@ -18,6 +18,7 @@ class Node extends HiveObject with Keyable {
|
|||
this.password,
|
||||
this.useSSL,
|
||||
this.trusted = false,
|
||||
this.socksProxyAddress,
|
||||
String? uri,
|
||||
WalletType? type,}) {
|
||||
if (uri != null) {
|
||||
|
@ -33,7 +34,8 @@ class Node extends HiveObject with Keyable {
|
|||
login = map['login'] as String?,
|
||||
password = map['password'] as String?,
|
||||
useSSL = map['useSSL'] as bool?,
|
||||
trusted = map['trusted'] as bool? ?? false;
|
||||
trusted = map['trusted'] as bool? ?? false,
|
||||
socksProxyAddress = map['socksProxyPort'] as String?;
|
||||
|
||||
static const typeId = 1;
|
||||
static const boxName = 'Nodes';
|
||||
|
@ -56,8 +58,13 @@ class Node extends HiveObject with Keyable {
|
|||
@HiveField(5, defaultValue: false)
|
||||
bool trusted;
|
||||
|
||||
@HiveField(6)
|
||||
String? socksProxyAddress;
|
||||
|
||||
bool get isSSL => useSSL ?? false;
|
||||
|
||||
bool get useSocksProxy => socksProxyAddress == null ? false : socksProxyAddress!.isNotEmpty;
|
||||
|
||||
Uri get uri {
|
||||
switch (type) {
|
||||
case WalletType.monero:
|
||||
|
@ -81,7 +88,8 @@ class Node extends HiveObject with Keyable {
|
|||
other.password == password &&
|
||||
other.typeRaw == typeRaw &&
|
||||
other.useSSL == useSSL &&
|
||||
other.trusted == trusted);
|
||||
other.trusted == trusted &&
|
||||
other.socksProxyAddress == socksProxyAddress);
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
|
@ -90,7 +98,8 @@ class Node extends HiveObject with Keyable {
|
|||
password.hashCode ^
|
||||
typeRaw.hashCode ^
|
||||
useSSL.hashCode ^
|
||||
trusted.hashCode;
|
||||
trusted.hashCode ^
|
||||
socksProxyAddress.hashCode;
|
||||
|
||||
@override
|
||||
dynamic get keyIndex {
|
||||
|
@ -108,7 +117,7 @@ class Node extends HiveObject with Keyable {
|
|||
try {
|
||||
switch (type) {
|
||||
case WalletType.monero:
|
||||
return requestMoneroNode();
|
||||
return useSocksProxy ? requestNodeWithProxy(socksProxyAddress ?? '') : requestMoneroNode();
|
||||
case WalletType.bitcoin:
|
||||
return requestElectrumServer();
|
||||
case WalletType.litecoin:
|
||||
|
@ -159,6 +168,22 @@ class Node extends HiveObject with Keyable {
|
|||
}
|
||||
}
|
||||
|
||||
Future<bool> requestNodeWithProxy(String proxy) async {
|
||||
|
||||
if (proxy.isEmpty || !proxy.contains(':')) {
|
||||
return false;
|
||||
}
|
||||
final proxyAddress = proxy.split(':')[0];
|
||||
final proxyPort = int.parse(proxy.split(':')[1]);
|
||||
try {
|
||||
final socket = await Socket.connect(proxyAddress, proxyPort, timeout: Duration(seconds: 5));
|
||||
socket.destroy();
|
||||
return true;
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> requestElectrumServer() async {
|
||||
try {
|
||||
await SecureSocket.connect(uri.host, uri.port,
|
||||
|
|
|
@ -39,7 +39,7 @@ typedef get_node_height = Int64 Function();
|
|||
typedef is_connected = Int8 Function();
|
||||
|
||||
typedef setup_node = Int8 Function(
|
||||
Pointer<Utf8>, Pointer<Utf8>?, Pointer<Utf8>?, Int8, Int8, Pointer<Utf8>);
|
||||
Pointer<Utf8>, Pointer<Utf8>?, Pointer<Utf8>?, Int8, Int8, Pointer<Utf8>?, Pointer<Utf8>);
|
||||
|
||||
typedef start_refresh = Void Function();
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ typedef GetNodeHeight = int Function();
|
|||
typedef IsConnected = int Function();
|
||||
|
||||
typedef SetupNode = int Function(
|
||||
Pointer<Utf8>, Pointer<Utf8>?, Pointer<Utf8>?, int, int, Pointer<Utf8>);
|
||||
Pointer<Utf8>, Pointer<Utf8>?, Pointer<Utf8>?, int, int, Pointer<Utf8>?, Pointer<Utf8>);
|
||||
|
||||
typedef StartRefresh = void Function();
|
||||
|
||||
|
|
|
@ -154,9 +154,11 @@ bool setupNodeSync(
|
|||
String? login,
|
||||
String? password,
|
||||
bool useSSL = false,
|
||||
bool isLightWallet = false}) {
|
||||
bool isLightWallet = false,
|
||||
String? socksProxyAddress}) {
|
||||
final addressPointer = address.toNativeUtf8();
|
||||
Pointer<Utf8>? loginPointer;
|
||||
Pointer<Utf8>? socksProxyAddressPointer;
|
||||
Pointer<Utf8>? passwordPointer;
|
||||
|
||||
if (login != null) {
|
||||
|
@ -167,6 +169,10 @@ bool setupNodeSync(
|
|||
passwordPointer = password.toNativeUtf8();
|
||||
}
|
||||
|
||||
if (socksProxyAddress != null) {
|
||||
socksProxyAddressPointer = socksProxyAddress.toNativeUtf8();
|
||||
}
|
||||
|
||||
final errorMessagePointer = ''.toNativeUtf8();
|
||||
final isSetupNode = setupNodeNative(
|
||||
addressPointer,
|
||||
|
@ -174,6 +180,7 @@ bool setupNodeSync(
|
|||
passwordPointer,
|
||||
_boolToInt(useSSL),
|
||||
_boolToInt(isLightWallet),
|
||||
socksProxyAddressPointer,
|
||||
errorMessagePointer) !=
|
||||
0;
|
||||
|
||||
|
@ -323,13 +330,15 @@ bool _setupNodeSync(Map args) {
|
|||
final password = (args['password'] ?? '') as String;
|
||||
final useSSL = args['useSSL'] as bool;
|
||||
final isLightWallet = args['isLightWallet'] as bool;
|
||||
final socksProxyAddress = (args['socksProxyAddress'] ?? '') as String;
|
||||
|
||||
return setupNodeSync(
|
||||
address: address,
|
||||
login: login,
|
||||
password: password,
|
||||
useSSL: useSSL,
|
||||
isLightWallet: isLightWallet);
|
||||
isLightWallet: isLightWallet,
|
||||
socksProxyAddress: socksProxyAddress);
|
||||
}
|
||||
|
||||
bool _isConnected(Object _) => isConnectedSync();
|
||||
|
@ -343,13 +352,15 @@ Future<void> setupNode(
|
|||
String? login,
|
||||
String? password,
|
||||
bool useSSL = false,
|
||||
String? socksProxyAddress,
|
||||
bool isLightWallet = false}) =>
|
||||
compute<Map<String, Object?>, void>(_setupNodeSync, {
|
||||
'address': address,
|
||||
'login': login,
|
||||
'password': password,
|
||||
'useSSL': useSSL,
|
||||
'isLightWallet': isLightWallet
|
||||
'isLightWallet': isLightWallet,
|
||||
'socksProxyAddress': socksProxyAddress
|
||||
});
|
||||
|
||||
Future<void> store() => compute<int, void>(_storeSync, 0);
|
||||
|
|
|
@ -125,7 +125,8 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
login: node.login,
|
||||
password: node.password,
|
||||
useSSL: node.useSSL ?? false,
|
||||
isLightWallet: false); // FIXME: hardcoded value
|
||||
isLightWallet: false, // FIXME: hardcoded value
|
||||
socksProxyAddress: node.socksProxyAddress);
|
||||
|
||||
haven_wallet.setTrustedDaemon(node.trusted);
|
||||
syncStatus = ConnectedSyncStatus();
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <unistd.h>
|
||||
#include <mutex>
|
||||
#include "thread"
|
||||
|
@ -405,13 +406,14 @@ extern "C"
|
|||
return is_connected;
|
||||
}
|
||||
|
||||
bool setup_node(char *address, char *login, char *password, bool use_ssl, bool is_light_wallet, char *error)
|
||||
bool setup_node(char *address, char *login, char *password, bool use_ssl, bool is_light_wallet, char *socksProxyAddress, char *error)
|
||||
{
|
||||
nice(19);
|
||||
Monero::Wallet *wallet = get_current_wallet();
|
||||
|
||||
std::string _login = "";
|
||||
std::string _password = "";
|
||||
std::string _socksProxyAddress = "";
|
||||
|
||||
if (login != nullptr)
|
||||
{
|
||||
|
@ -423,7 +425,12 @@ extern "C"
|
|||
_password = std::string(password);
|
||||
}
|
||||
|
||||
bool inited = wallet->init(std::string(address), 0, _login, _password, use_ssl, is_light_wallet);
|
||||
if (socksProxyAddress != nullptr)
|
||||
{
|
||||
_socksProxyAddress = std::string(socksProxyAddress);
|
||||
}
|
||||
|
||||
bool inited = wallet->init(std::string(address), 0, _login, _password, use_ssl, is_light_wallet, _socksProxyAddress);
|
||||
|
||||
if (!inited)
|
||||
{
|
||||
|
|
|
@ -35,7 +35,7 @@ typedef get_node_height = Int64 Function();
|
|||
typedef is_connected = Int8 Function();
|
||||
|
||||
typedef setup_node = Int8 Function(
|
||||
Pointer<Utf8>, Pointer<Utf8>?, Pointer<Utf8>?, Int8, Int8, Pointer<Utf8>);
|
||||
Pointer<Utf8>, Pointer<Utf8>?, Pointer<Utf8>?, Int8, Int8, Pointer<Utf8>?, Pointer<Utf8>);
|
||||
|
||||
typedef start_refresh = Void Function();
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ typedef GetNodeHeight = int Function();
|
|||
typedef IsConnected = int Function();
|
||||
|
||||
typedef SetupNode = int Function(
|
||||
Pointer<Utf8>, Pointer<Utf8>?, Pointer<Utf8>?, int, int, Pointer<Utf8>);
|
||||
Pointer<Utf8>, Pointer<Utf8>?, Pointer<Utf8>?, int, int, Pointer<Utf8>?, Pointer<Utf8>);
|
||||
|
||||
typedef StartRefresh = void Function();
|
||||
|
||||
|
|
|
@ -158,9 +158,11 @@ bool setupNodeSync(
|
|||
String? login,
|
||||
String? password,
|
||||
bool useSSL = false,
|
||||
bool isLightWallet = false}) {
|
||||
bool isLightWallet = false,
|
||||
String? socksProxyAddress}) {
|
||||
final addressPointer = address.toNativeUtf8();
|
||||
Pointer<Utf8>? loginPointer;
|
||||
Pointer<Utf8>? socksProxyAddressPointer;
|
||||
Pointer<Utf8>? passwordPointer;
|
||||
|
||||
if (login != null) {
|
||||
|
@ -171,6 +173,10 @@ bool setupNodeSync(
|
|||
passwordPointer = password.toNativeUtf8();
|
||||
}
|
||||
|
||||
if (socksProxyAddress != null) {
|
||||
socksProxyAddressPointer = socksProxyAddress.toNativeUtf8();
|
||||
}
|
||||
|
||||
final errorMessagePointer = ''.toNativeUtf8();
|
||||
final isSetupNode = setupNodeNative(
|
||||
addressPointer,
|
||||
|
@ -178,6 +184,7 @@ bool setupNodeSync(
|
|||
passwordPointer,
|
||||
_boolToInt(useSSL),
|
||||
_boolToInt(isLightWallet),
|
||||
socksProxyAddressPointer,
|
||||
errorMessagePointer) !=
|
||||
0;
|
||||
|
||||
|
@ -328,13 +335,15 @@ bool _setupNodeSync(Map<String, Object?> args) {
|
|||
final password = (args['password'] ?? '') as String;
|
||||
final useSSL = args['useSSL'] as bool;
|
||||
final isLightWallet = args['isLightWallet'] as bool;
|
||||
final socksProxyAddress = (args['socksProxyAddress'] ?? '') as String;
|
||||
|
||||
return setupNodeSync(
|
||||
address: address,
|
||||
login: login,
|
||||
password: password,
|
||||
useSSL: useSSL,
|
||||
isLightWallet: isLightWallet);
|
||||
isLightWallet: isLightWallet,
|
||||
socksProxyAddress: socksProxyAddress);
|
||||
}
|
||||
|
||||
bool _isConnected(Object _) => isConnectedSync();
|
||||
|
@ -348,13 +357,15 @@ Future<void> setupNode(
|
|||
String? login,
|
||||
String? password,
|
||||
bool useSSL = false,
|
||||
String? socksProxyAddress,
|
||||
bool isLightWallet = false}) =>
|
||||
compute<Map<String, Object?>, void>(_setupNodeSync, {
|
||||
'address': address,
|
||||
'login': login ,
|
||||
'password': password,
|
||||
'useSSL': useSSL,
|
||||
'isLightWallet': isLightWallet
|
||||
'isLightWallet': isLightWallet,
|
||||
'socksProxyAddress': socksProxyAddress
|
||||
});
|
||||
|
||||
Future<void> store() => compute<int, void>(_storeSync, 0);
|
||||
|
|
|
@ -138,7 +138,8 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
login: node.login,
|
||||
password: node.password,
|
||||
useSSL: node.isSSL,
|
||||
isLightWallet: false); // FIXME: hardcoded value
|
||||
isLightWallet: false, // FIXME: hardcoded value
|
||||
socksProxyAddress: node.socksProxyAddress);
|
||||
|
||||
monero_wallet.setTrustedDaemon(node.trusted);
|
||||
syncStatus = ConnectedSyncStatus();
|
||||
|
|
10
lib/core/socks_proxy_node_address_validator.dart
Normal file
10
lib/core/socks_proxy_node_address_validator.dart
Normal file
|
@ -0,0 +1,10 @@
|
|||
import 'package:cake_wallet/core/validator.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
|
||||
class SocksProxyNodeAddressValidator extends TextValidator {
|
||||
SocksProxyNodeAddressValidator()
|
||||
: super(
|
||||
errorMessage: S.current.error_text_node_proxy_address,
|
||||
pattern:
|
||||
'^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}:[0-9]+\$');
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:cake_wallet/core/node_address_validator.dart';
|
||||
import 'package:cake_wallet/core/node_port_validator.dart';
|
||||
import 'package:cake_wallet/core/socks_proxy_node_address_validator.dart';
|
||||
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
||||
import 'package:cake_wallet/src/widgets/standard_checkbox.dart';
|
||||
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
|
||||
|
@ -17,7 +18,8 @@ class NodeForm extends StatelessWidget {
|
|||
}) : _addressController = TextEditingController(text: editingNode?.uri.host.toString()),
|
||||
_portController = TextEditingController(text: editingNode?.uri.port.toString()),
|
||||
_loginController = TextEditingController(text: editingNode?.login),
|
||||
_passwordController = TextEditingController(text: editingNode?.password) {
|
||||
_passwordController = TextEditingController(text: editingNode?.password),
|
||||
_socksAddressController = TextEditingController(text: editingNode?.socksProxyAddress){
|
||||
if (editingNode != null) {
|
||||
nodeViewModel
|
||||
..setAddress((editingNode!.uri.host.toString()))
|
||||
|
@ -25,7 +27,9 @@ class NodeForm extends StatelessWidget {
|
|||
..setPassword((editingNode!.password ?? ''))
|
||||
..setLogin((editingNode!.login ?? ''))
|
||||
..setSSL((editingNode!.isSSL))
|
||||
..setTrusted((editingNode!.trusted));
|
||||
..setTrusted((editingNode!.trusted))
|
||||
..setSocksProxy((editingNode!.useSocksProxy))
|
||||
..setSocksProxyAddress((editingNode!.socksProxyAddress ?? ''));
|
||||
}
|
||||
if (nodeViewModel.hasAuthCredentials) {
|
||||
reaction((_) => nodeViewModel.login, (String login) {
|
||||
|
@ -45,6 +49,7 @@ class NodeForm extends StatelessWidget {
|
|||
_portController.addListener(() => nodeViewModel.port = _portController.text);
|
||||
_loginController.addListener(() => nodeViewModel.login = _loginController.text);
|
||||
_passwordController.addListener(() => nodeViewModel.password = _passwordController.text);
|
||||
_socksAddressController.addListener(() => nodeViewModel.socksProxyAddress = _socksAddressController.text);
|
||||
}
|
||||
|
||||
final NodeCreateOrEditViewModel nodeViewModel;
|
||||
|
@ -55,6 +60,7 @@ class NodeForm extends StatelessWidget {
|
|||
final TextEditingController _portController;
|
||||
final TextEditingController _loginController;
|
||||
final TextEditingController _passwordController;
|
||||
final TextEditingController _socksAddressController;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -138,6 +144,43 @@ class NodeForm extends StatelessWidget {
|
|||
],
|
||||
),
|
||||
),
|
||||
Observer(
|
||||
builder: (_) => Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 20),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
StandardCheckbox(
|
||||
value: nodeViewModel.useSocksProxy,
|
||||
onChanged: (value) {
|
||||
if (!value) {
|
||||
_socksAddressController.text = '';
|
||||
}
|
||||
nodeViewModel.useSocksProxy = value;
|
||||
},
|
||||
caption: 'SOCKS Proxy',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (nodeViewModel.useSocksProxy) ...[
|
||||
SizedBox(height: 10.0),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: BaseTextFormField(
|
||||
controller: _socksAddressController,
|
||||
hintText: '[<ip>:]<port>',
|
||||
validator: SocksProxyNodeAddressValidator(),
|
||||
))
|
||||
],
|
||||
),
|
||||
]
|
||||
],
|
||||
)),
|
||||
]
|
||||
],
|
||||
),
|
||||
|
|
|
@ -19,7 +19,9 @@ abstract class NodeCreateOrEditViewModelBase with Store {
|
|||
port = '',
|
||||
login = '',
|
||||
password = '',
|
||||
trusted = false;
|
||||
trusted = false,
|
||||
useSocksProxy = false,
|
||||
socksProxyAddress = '';
|
||||
|
||||
@observable
|
||||
ExecutionState state;
|
||||
|
@ -45,6 +47,12 @@ abstract class NodeCreateOrEditViewModelBase with Store {
|
|||
@observable
|
||||
bool trusted;
|
||||
|
||||
@observable
|
||||
bool useSocksProxy;
|
||||
|
||||
@observable
|
||||
String socksProxyAddress;
|
||||
|
||||
@computed
|
||||
bool get isReady => address.isNotEmpty && port.isNotEmpty;
|
||||
|
||||
|
@ -73,6 +81,8 @@ abstract class NodeCreateOrEditViewModelBase with Store {
|
|||
password = '';
|
||||
useSSL = false;
|
||||
trusted = false;
|
||||
useSocksProxy = false;
|
||||
socksProxyAddress = '';
|
||||
}
|
||||
|
||||
@action
|
||||
|
@ -93,6 +103,12 @@ abstract class NodeCreateOrEditViewModelBase with Store {
|
|||
@action
|
||||
void setTrusted(bool val) => trusted = val;
|
||||
|
||||
@action
|
||||
void setSocksProxy(bool val) => useSocksProxy = val;
|
||||
|
||||
@action
|
||||
void setSocksProxyAddress(String val) => socksProxyAddress = val;
|
||||
|
||||
@action
|
||||
Future<void> save({Node? editingNode, bool saveAsCurrent = false}) async {
|
||||
final node = Node(
|
||||
|
@ -101,7 +117,8 @@ abstract class NodeCreateOrEditViewModelBase with Store {
|
|||
login: login,
|
||||
password: password,
|
||||
useSSL: useSSL,
|
||||
trusted: trusted);
|
||||
trusted: trusted,
|
||||
socksProxyAddress: socksProxyAddress);
|
||||
try {
|
||||
state = IsExecutingState();
|
||||
if (editingNode != null) {
|
||||
|
@ -130,7 +147,8 @@ abstract class NodeCreateOrEditViewModelBase with Store {
|
|||
login: login,
|
||||
password: password,
|
||||
useSSL: useSSL,
|
||||
trusted: trusted);
|
||||
trusted: trusted,
|
||||
socksProxyAddress: socksProxyAddress);
|
||||
try {
|
||||
connectionState = IsExecutingState();
|
||||
final isAlive = await node.requestNode();
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "يجب أن يتوافق عنوان المحفظة مع نوع\nالعملة المشفرة",
|
||||
"error_text_node_address": "الرجاء إدخال عنوان IPv4",
|
||||
"error_text_node_port": "منفذ العقدة يمكن أن يحتوي فقط على أرقام بين 0 و 65535",
|
||||
"error_text_node_proxy_address": "الرجاء إدخال <عنوان IPv4>: <port> ، على سبيل المثال 127.0.0.1:9050",
|
||||
"error_text_payment_id": "يمكن أن يحتوي معرّف الدفع فقط من 16 إلى 64 حرفًا hex",
|
||||
"error_text_xmr": "لا يمكن أن تتجاوز قيمة XMR الرصيد المتاح.\nيجب أن يكون عدد الكسور أقل من أو يساوي 12",
|
||||
"error_text_fiat": "لا يمكن أن تتجاوز قيمة المبلغ الرصيد المتاح.\nيجب أن يكون عدد الكسور أقل أو يساوي 2",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "Адресът на портфейла трябва да отговаря \n на вида криптовалута",
|
||||
"error_text_node_address": "Моля, въведете iPv4 адрес",
|
||||
"error_text_node_port": "Node port-ът е цяло число между 0 и 65535",
|
||||
"error_text_node_proxy_address": "Моля, въведете <IPv4 адрес>:<порт>, например 127.0.0.1:9050",
|
||||
"error_text_payment_id": "Payment ID-то може да съдържа само между 16 и 64 шестнайсетични символа",
|
||||
"error_text_xmr": "XMR сумата не може да надхвърля наличния баланс.\nБроят на цифрите след десетичната запетая може да бъде най-много 12",
|
||||
"error_text_fiat": "Сумата не може да надвишава наличния баланс.\nThe number of fraction digits must be less or equal to 2",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "Adresa peněženky musí odpovídat typu\nkryptoměny",
|
||||
"error_text_node_address": "prosím zadejte IPv4 adresu",
|
||||
"error_text_node_port": "Port uzlu musí být číslo mezi 0 a 65535",
|
||||
"error_text_node_proxy_address": "Zadejte prosím <adresa IPv4>:<port>, například 127.0.0.1:9050",
|
||||
"error_text_payment_id": "ID platby se musí skládat z 16 až 64 hexadecimálních znaků",
|
||||
"error_text_xmr": "Hodnota XMR nemůže překročit dostupný zůstatek.\nPočet desetinných míst musí být menší, nebo roven 12",
|
||||
"error_text_fiat": "Částka nemůže překročit dostupný zůstatek.\nPočet desetinných míst musí být menší, nebo roven 2",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "Die Walletadresse muss dem Typ der Kryptowährung\nentsprechen",
|
||||
"error_text_node_address": "Bitte geben Sie eine iPv4-Adresse ein",
|
||||
"error_text_node_port": "Der Knotenport darf nur Nummern zwischen 0 und 65535 enthalten",
|
||||
"error_text_node_proxy_address": "Bitte geben Sie <IPv4-Adresse>:<Port> ein, zum Beispiel 127.0.0.1:9050",
|
||||
"error_text_payment_id": "Die Zahlungs-ID darf nur 16 bis 64 hexadezimale Zeichen enthalten",
|
||||
"error_text_xmr": "Der XMR-Wert darf das verfügbare Guthaben nicht überschreiten.\nDie Anzahl der Nachkommastellen muss kleiner oder gleich 12 sein",
|
||||
"error_text_fiat": "Der Wert des Betrags darf den verfügbaren Kontostand nicht überschreiten.\nDie Anzahl der Nachkommastellen muss kleiner oder gleich 2 sein",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "Wallet address must correspond to the type\nof cryptocurrency",
|
||||
"error_text_node_address": "Please enter a iPv4 address",
|
||||
"error_text_node_port": "Node port can only contain numbers between 0 and 65535",
|
||||
"error_text_node_proxy_address": "Please enter <IPv4 address>:<port>, for example 127.0.0.1:9050",
|
||||
"error_text_payment_id": "Payment ID can only contain from 16 to 64 chars in hex",
|
||||
"error_text_xmr": "XMR value can't exceed available balance.\nThe number of fraction digits must be less or equal to 12",
|
||||
"error_text_fiat": "Value of amount can't exceed available balance.\nThe number of fraction digits must be less or equal to 2",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "La dirección de la billetera debe corresponder al tipo \nde criptomoneda",
|
||||
"error_text_node_address": "Por favor, introduzca una dirección iPv4",
|
||||
"error_text_node_port": "El puerto de nodo solo puede contener números entre 0 y 65535",
|
||||
"error_text_node_proxy_address": "Ingrese <dirección IPv4>:<puerto>, por ejemplo 127.0.0.1:9050",
|
||||
"error_text_payment_id": "La ID de pago solo puede contener de 16 a 64 caracteres en hexadecimal",
|
||||
"error_text_xmr": "El valor XMR no puede exceder el saldo disponible.\nTEl número de dígitos de fracción debe ser menor o igual a 12",
|
||||
"error_text_fiat": "El valor de la cantidad no puede exceder el saldo disponible.\nEl número de dígitos de fracción debe ser menor o igual a 2",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "L'adresse du portefeuille (wallet) doit correspondre au type de\ncryptomonnaie",
|
||||
"error_text_node_address": "Merci d'entrer une adresse IPv4",
|
||||
"error_text_node_port": "Le port d'un nœud doit être un nombre compris entre 0 et 65535",
|
||||
"error_text_node_proxy_address": "Veuillez saisir <adresse IPv4> :<port>, par exemple 127.0.0.1:9050",
|
||||
"error_text_payment_id": "Un ID de paiement ne peut être constitué que de 16 à 64 caractères hexadécimaux",
|
||||
"error_text_xmr": "La valeur de XMR dépasse le solde disponible.\nLa partie décimale doit comporter au plus 12 chiffres",
|
||||
"error_text_fiat": "La valeur du montant ne peut dépasser le solde disponible.\nLa partie décimale doit comporter au plus 2 chiffres",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "Adireshin hujja ya kamata ya dace da irin\nna cryptocurrency",
|
||||
"error_text_node_address": "Da fatan a shigar da iPv4 adireshin",
|
||||
"error_text_node_port": "Node tashar jiragen ruwa zai iya ƙunsar lambobi tsakanin 0 zuwa 65535 kawai",
|
||||
"error_text_node_proxy_address": "Da fatan za a shigar da <IPv4 address>:<port>, misali 127.0.0.1:9050",
|
||||
"error_text_payment_id": "ID na biyan kudi kawai zai iya ɗaukar daga 16 zuwa 64 haruffa a cikin hex",
|
||||
"error_text_xmr": "XMR adadin ba zai iya wuce available balance.\nAdadin haruffan gaba zai kamata ya zama ko ƙasa daga na 12",
|
||||
"error_text_fiat": "Adadin kudin ba zai iya wuce available balance.\nAdadin haruffan gaba zai kamata ya zama ko ƙasa daga na 2",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "वॉलेट पता प्रकार के अनुरूप होना चाहिए\nक्रिप्टोकरेंसी का",
|
||||
"error_text_node_address": "कृपया एक IPv4 पता दर्ज करें",
|
||||
"error_text_node_port": "नोड पोर्ट में केवल 0 और 65535 के बीच संख्याएँ हो सकती हैं",
|
||||
"error_text_node_proxy_address": "कृपया <IPv4 पता> दर्ज करें: <पोर्ट>, उदाहरण के लिए 127.0.0.1:9050",
|
||||
"error_text_payment_id": "पेमेंट आईडी केवल हेक्स में 16 से 64 चार्ट तक हो सकती है",
|
||||
"error_text_xmr": "एक्सएमआर मूल्य उपलब्ध शेष राशि से अधिक नहीं हो सकता.\nअंश अंकों की संख्या 12 से कम या इसके बराबर होनी चाहिए",
|
||||
"error_text_fiat": "राशि का मूल्य उपलब्ध शेष राशि से अधिक नहीं हो सकता.\nअंश अंकों की संख्या कम या 2 के बराबर होनी चाहिए",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "Adresa novčanika mora odgovarati\nvrsti kriptovalute",
|
||||
"error_text_node_address": "Molimo unesite iPv4 adresu",
|
||||
"error_text_node_port": "Node port smije sadržavati samo brojeve između 0 i 65535",
|
||||
"error_text_node_proxy_address": "Unesite <IPv4 adresa>:<port>, na primjer 127.0.0.1:9050",
|
||||
"error_text_payment_id": "ID plaćanja smije sadržavati samo od 16 do 64 znakova hex vrijednosti",
|
||||
"error_text_xmr": "XMR vrijednost ne smije biti veća od raspoloživog iznosa.\nBroj decimala smije biti 12 ili manji.",
|
||||
"error_text_fiat": "Vrijednost iznosa ne smije biti veća od raspoloživog iznosa.\nBroj decimala smije biti 2 ili manji.",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "Alamat dompet harus sesuai dengan tipe\nmata uang kripto",
|
||||
"error_text_node_address": "Silakan masukkan alamat iPv4",
|
||||
"error_text_node_port": "Port node hanya dapat berisi angka antara 0 dan 65535",
|
||||
"error_text_node_proxy_address": "Masukkan <alamat IPv4>:<port>, misalnya 127.0.0.1:9050",
|
||||
"error_text_payment_id": "ID pembayaran hanya dapat berisi dari 16 hingga 64 karakter dalam hex",
|
||||
"error_text_xmr": "Nilai XMR tidak boleh melebihi saldo yang tersedia.\nJumlah digit pecahan harus kurang atau sama dengan 12",
|
||||
"error_text_fiat": "Nilai jumlah tidak boleh melebihi saldo yang tersedia.\nJumlah digit pecahan harus kurang atau sama dengan 2",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "L'indirizzo del Portafoglio deve corrispondere alla tipologia\ndi criptovaluta",
|
||||
"error_text_node_address": "Gentilmente inserisci un indirizzo iPv4",
|
||||
"error_text_node_port": "La porta del nodo può contenere solo numeri compresi tra 0 e 65535",
|
||||
"error_text_node_proxy_address": "Inserisci <indirizzo IPv4>:<porta>, ad esempio 127.0.0.1:9050",
|
||||
"error_text_payment_id": "L'ID del pagamento può contenere solo da 16 a 64 caratteri in esadecimale",
|
||||
"error_text_xmr": "Il valore in XMR non può eccedere il saldo disponibile.\nIl numero delle cifre decimali deve essere inferiore o uguale a 12",
|
||||
"error_text_fiat": "L'ammontare non può eccedere il saldo dispoinibile.\nIl numero di cifre decimali deve essere inferiore o uguale a 2",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "ウォレットアドレスは、\n暗号通貨",
|
||||
"error_text_node_address": "iPv4アドレスを入力してください",
|
||||
"error_text_node_port": "ノードポートには、0〜65535の数字のみを含めることができます",
|
||||
"error_text_node_proxy_address": "<IPv4 アドレス>:<ポート> を入力してください (例: 127.0.0.1:9050)",
|
||||
"error_text_payment_id": "支払いIDには、16進数で16〜64文字しか含めることができません",
|
||||
"error_text_xmr": "XMR値は利用可能な残高を超えることはできません.\n小数桁数は12以下でなければなりません",
|
||||
"error_text_fiat": "金額は利用可能な残高を超えることはできません.\n小数桁の数は2以下でなければなりません",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "지갑 주소는 유형과 일치해야합니다\n암호 화폐",
|
||||
"error_text_node_address": "iPv4 주소를 입력하십시오",
|
||||
"error_text_node_port": "노드 포트는 0에서 65535 사이의 숫자 만 포함 할 수 있습니다",
|
||||
"error_text_node_proxy_address": "<IPv4 주소>:<포트>를 입력하십시오(예: 127.0.0.1:9050).",
|
||||
"error_text_payment_id": "지불 ID는 16 ~ 64 자의 16 진 문자 만 포함 할 수 있습니다",
|
||||
"error_text_xmr": "XMR 값은 사용 가능한 잔액을 초과 할 수 없습니다.\n소수 자릿수는 12 이하 여야합니다",
|
||||
"error_text_fiat": "금액은 사용 가능한 잔액을 초과 할 수 없습니다.\n소수 자릿수는 2보다 작거나 같아야합니다",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "Wallet လိပ်စာသည် အမျိုးအစား\no cryptocurrency နှင့် ကိုက်ညီရပါမည်။",
|
||||
"error_text_node_address": "ကျေးဇူးပြု၍ iPv4 လိပ်စာကို ထည့်ပါ။",
|
||||
"error_text_node_port": "နော်ဒီဆိပ်ကမ်း တွင် 0 နှင့် 65535 အကြား နံပါတ်များသာ ပါဝင်နိုင်သည်။",
|
||||
"error_text_node_proxy_address": "ကျေးဇူးပြု၍ <IPv4 လိပ်စာ>:<port>၊ ဥပမာ 127.0.0.1:9050 ထည့်ပါ",
|
||||
"error_text_payment_id": "ငွေပေးချေမှု ID တွင် hex တွင် စာလုံး 16 လုံးမှ 64 လုံးသာ ပါဝင်နိုင်သည်။",
|
||||
"error_text_xmr": "XMR တန်ဖိုးသည် ရနိုင်သောလက်ကျန်ကို ကျော်လွန်၍မရပါ။\nအပိုင်းကိန်းဂဏန်းများ သည် 12 နှင့် လျော့နည်းရမည်",
|
||||
"error_text_fiat": "ပမာဏ၏တန်ဖိုးသည် ရနိုင်သောလက်ကျန်ကို မကျော်လွန်နိုင်ပါ။\nအပိုင်းကိန်းဂဏန်းအရေအတွက်သည် 2 နှင့် လျော့နည်းရမည်",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "Portemonnee-adres moet overeenkomen met het type\nvan cryptocurrency",
|
||||
"error_text_node_address": "Voer een iPv4-adres in",
|
||||
"error_text_node_port": "Knooppuntpoort kan alleen nummers tussen 0 en 65535 bevatten",
|
||||
"error_text_node_proxy_address": "Voer <IPv4-adres>:<poort> in, bijvoorbeeld 127.0.0.1:9050",
|
||||
"error_text_payment_id": "Betalings-ID kan alleen 16 tot 64 tekens bevatten in hexadecimale volgorde",
|
||||
"error_text_xmr": "XMR-waarde kan het beschikbare saldo niet overschrijden.\nHet aantal breukcijfers moet kleiner zijn dan of gelijk zijn aan 12",
|
||||
"error_text_fiat": "Waarde van bedrag kan het beschikbare saldo niet overschrijden.\nHet aantal breukcijfers moet kleiner zijn dan of gelijk zijn aan 2",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "Adres musi odpowiadać typowi kryptowaluty",
|
||||
"error_text_node_address": "Wpisz adres iPv4",
|
||||
"error_text_node_port": "Port węzła może zawierać tylko liczby od 0 do 65535",
|
||||
"error_text_node_proxy_address": "Wprowadź <adres IPv4>:<port>, na przykład 127.0.0.1:9050",
|
||||
"error_text_payment_id": "ID może zawierać od 16 do 64 znaków w formacie szesnastkowym",
|
||||
"error_text_xmr": "Wartość XMR nie może przekraczać dostępnego salda.\nLiczba cyfr ułamkowych musi być mniejsza lub równa 12",
|
||||
"error_text_fiat": "Wartość kwoty nie może przekroczyć dostępnego salda.\nLiczba cyfr ułamkowych musi być mniejsza lub równa 2",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "O endereço da carteira deve corresponder à\ncriptomoeda selecionada",
|
||||
"error_text_node_address": "Digite um endereço iPv4",
|
||||
"error_text_node_port": "A porta do nó deve conter apenas números entre 0 e 65535",
|
||||
"error_text_node_proxy_address": "Insira <endereço IPv4>:<porta>, por exemplo 127.0.0.1:9050",
|
||||
"error_text_payment_id": "O ID de pagamento pode conter apenas de 16 a 64 caracteres em hexadecimal",
|
||||
"error_text_xmr": "A quantia em XMR não pode exceder o saldo disponível.\nTO número de dígitos decimais deve ser menor ou igual a 12",
|
||||
"error_text_fiat": "O valor do valor não pode exceder o saldo disponível.\nO número de dígitos decimais deve ser menor ou igual a 2",
|
||||
|
|
|
@ -269,6 +269,8 @@
|
|||
"error_text_address": "Адрес кошелька должен соответствовать типу\nкриптовалюты",
|
||||
"error_text_node_address": "Пожалуйста, введите iPv4 адрес",
|
||||
"error_text_node_port": "Порт ноды может содержать только цифры от 0 до 65535",
|
||||
"error_text_node_proxy_address": "Введите <IPv4-адрес>:<порт>, например 127.0.0.1:9050.",
|
||||
|
||||
"error_text_payment_id": "Идентификатор платежа может содержать от 16 до 64 символов в hex",
|
||||
"error_text_xmr": "Значение XMR не может превышать доступный баланс.\nКоличество цифр после запятой должно быть меньше или равно 12",
|
||||
"error_text_fiat": "Значение суммы не может превышать доступный баланс.\nКоличество цифр после запятой должно быть меньше или равно 2",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "ที่อยู่กระเป๋าจะต้องสอดคล้องกับประเภท\nของเหรียญคริปโตเนียม",
|
||||
"error_text_node_address": "โปรดป้อนที่อยู่ iPv4",
|
||||
"error_text_node_port": "พอร์ตโหนดสามารถมีตัวเลขเท่านั้นระหว่าง 0 ถึง 65535",
|
||||
"error_text_node_proxy_address": "โปรดป้อน <ที่อยู่ IPv4>:<พอร์ต> เช่น 127.0.0.1:9050",
|
||||
"error_text_payment_id": "Payment ID สามารถมีขนาดระหว่าง 16 ถึง 64 ตัวอักษรตามแบบ hex",
|
||||
"error_text_xmr": "มูลค่า XMR ไม่สามารถเกินยอดคงเหลือได้\nจำนวนสตริงทศนิยมต้องน้อยกว่าหรือเท่ากับ 12",
|
||||
"error_text_fiat": "มูลค่าของจำนวนเงินไม่สามารถเกินยอดคงเหลือได้\nจำนวนสตริงทศนิยมต้องน้อยกว่าหรือเท่ากับ 2",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "Cüzdan adresi kripto para biriminin\ntürüne karşılık gelmelidir",
|
||||
"error_text_node_address": "Lütfen iPv4 adresi girin",
|
||||
"error_text_node_port": "Düğüm port'u yalnızca 0 ve 65535 arasında rakam içerebilir",
|
||||
"error_text_node_proxy_address": "Lütfen <IPv4 adresi>:<bağlantı noktası> girin, örneğin 127.0.0.1:9050",
|
||||
"error_text_payment_id": "Ödeme ID'si yalnızca onaltılık (hex) olarak 16 veya 64 karakter içerebilir",
|
||||
"error_text_xmr": "XMR miktarı kullanılabilir bakiyeyi aşamaz.\nKesir basamaklarının sayısı 12'ye eşit veya daha az olmalıdır",
|
||||
"error_text_fiat": "Tutarın değeri, mevcut bakiyeyi aşamaz.\nKesir basamaklarının sayısı 2'ye eşit veya daha az olmalıdır",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "Адреса гаманця повинна відповідати типу\nкриптовалюти",
|
||||
"error_text_node_address": "Будь ласка, введіть iPv4 адресу",
|
||||
"error_text_node_port": "Порт вузла може містити тільки цифри від 0 до 65535",
|
||||
"error_text_node_proxy_address": "Будь ласка, введіть <IPv4-адреса>:<порт>, наприклад 127.0.0.1:9050",
|
||||
"error_text_payment_id": "Ідентифікатор платежу може містити від 16 до 64 символів в hex",
|
||||
"error_text_xmr": "Значення XMR не може перевищувати доступний баланс.\nКількість цифр після коми повинно бути меншим або дорівнювати 12",
|
||||
"error_text_fiat": "Значення суми не може перевищувати доступний баланс.\nКількість цифр після коми повинно бути меншим або дорівнювати 2",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "والیٹ کا پتہ cryptocurrency کی قسم\\nکے مطابق ہونا چاہیے۔",
|
||||
"error_text_node_address": "براہ کرم ایک iPv4 پتہ درج کریں۔",
|
||||
"error_text_node_port": "نوڈ پورٹ میں صرف 0 اور 65535 کے درمیان نمبر ہوسکتے ہیں۔",
|
||||
"error_text_node_proxy_address": "براہ کرم <IPv4 ایڈریس>:<port> درج کریں، مثال کے طور پر 127.0.0.1:9050",
|
||||
"error_text_payment_id": "ادائیگی کی ID ہیکس میں صرف 16 سے 64 حروف پر مشتمل ہو سکتی ہے۔",
|
||||
"error_text_xmr": "XMR قدر دستیاب بیلنس سے زیادہ نہیں ہو سکتی۔\\nفرکشن ہندسوں کی تعداد 12 سے کم یا اس کے برابر ہونی چاہیے۔",
|
||||
"error_text_fiat": "رقم کی قدر دستیاب بیلنس سے زیادہ نہیں ہو سکتی۔\\nفرکشن ہندسوں کی تعداد 2 کے برابر یا کم ہونی چاہیے۔",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "Àdírẹ́sì àpamọ́wọ́ gbọ́dọ̀ báramu irú owó",
|
||||
"error_text_node_address": "Ẹ jọ̀wọ́ tẹ̀ àdírẹ́sì iPv4",
|
||||
"error_text_node_port": "Ojú ìkànpọ̀ apẹka lè ni nìkan nínú òǹkà l'áàárín òdo àti márùn-úndínlógojí lé ní ẹ̀ẹ́dẹgbẹ̀ta lé ní ọ̀kẹ́ mẹ́ta lé ní ẹ̀ẹ́dẹ́gbàta",
|
||||
"error_text_node_proxy_address": "Jọwọ tẹ <IPv4 adirẹsi>:<port>, fun apẹẹrẹ 127.0.0.1:9050",
|
||||
"error_text_payment_id": "Iye ẹyọ ọ̀rọ̀ nínú àmì ìdánimọ̀ àránṣẹ́ gbọ́dọ̀ wà l'áàárín aárùndínlógún dé ẹẹ́rinlélọ́gọ́ta.",
|
||||
"error_text_xmr": "Iye XMR kò lè tóbi ju ìyókù.\nIye díjíìtì léyìn ẹsẹ kò gbọ́dọ̀ tóbi ju eéjìlá.",
|
||||
"error_text_fiat": "Iye àránṣẹ́ kò tóbi ju ìyókù owó.\nIye díjíìtì léyìn ẹsẹ kò gbọ́dọ̀ tóbi ju eéjì.",
|
||||
|
|
|
@ -269,6 +269,7 @@
|
|||
"error_text_address": "钱包地址必须与类型对应\n加密货币",
|
||||
"error_text_node_address": "请输入一个IPv4地址",
|
||||
"error_text_node_port": "节点端口只能包含0到65535之间的数字",
|
||||
"error_text_node_proxy_address": "请输入<IPv4地址>:<端口>,例如127.0.0.1:9050",
|
||||
"error_text_payment_id": "付款ID只能包含16到64个字符(十六进制)",
|
||||
"error_text_xmr": "XMR值不能超过可用余额.\n小数位数必须小于或等于12",
|
||||
"error_text_fiat": "金额不能超过可用余额.\n小数位数必须小于或等于2",
|
||||
|
|
Loading…
Reference in a new issue