mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-06-28 20:39:51 +00:00
Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
cd0844dcc1
60 changed files with 1080 additions and 779 deletions
22
assets/images/passphrase_key.svg
Normal file
22
assets/images/passphrase_key.svg
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<svg width="158" height="158" viewBox="0 0 158 158" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_3076_287)">
|
||||||
|
<path d="M59.8674 111.213C61.104 109.782 62.8874 109.123 64.6415 109.237L69.6321 103.461C69.1122 101.951 69.369 100.216 70.4903 98.9183C71.6101 97.6223 73.2894 97.1164 74.8608 97.4098L79.8316 91.6568L65.7827 79.5181L42.7631 106.16C41.9574 107.093 41.5571 108.305 41.6467 109.532L41.9828 114.163L48.3733 119.684L53.4019 119.732C54.767 119.746 56.0685 119.159 56.9607 118.127L58.6055 116.223C58.2383 114.504 58.6308 112.644 59.8674 111.213Z" fill="url(#paint0_linear_3076_287)"/>
|
||||||
|
<path d="M115.362 82.4834C126.257 69.8745 124.867 50.823 112.258 39.9285C99.6491 29.0339 80.5975 30.4236 69.703 43.0325C69.1902 43.6261 68.7318 44.2453 68.2752 44.866L68.1857 44.7886L56.0469 58.8375C52.6951 62.7168 53.1228 68.5796 57.002 71.9314L88.6121 99.2435C92.4913 102.595 98.3541 102.168 101.706 98.2884L113.845 84.2395L113.755 84.1621C114.303 83.6203 114.849 83.077 115.362 82.4834ZM104.671 48.709C108.551 52.0608 108.978 57.9236 105.626 61.8029C102.275 65.6821 96.4118 66.1098 92.5325 62.758C88.6532 59.4061 88.2256 53.5434 91.5774 49.6641C94.9292 45.7849 100.792 45.3572 104.671 48.709Z" fill="url(#paint1_linear_3076_287)"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="paint0_linear_3076_287" x1="72.8481" y1="85.54" x2="45.4677" y2="117.229" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#E5A505"/>
|
||||||
|
<stop offset="0.01" stop-color="#E9A804"/>
|
||||||
|
<stop offset="0.06" stop-color="#F4B102"/>
|
||||||
|
<stop offset="0.129" stop-color="#FBB600"/>
|
||||||
|
<stop offset="0.323" stop-color="#FDB700"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="paint1_linear_3076_287" x1="91.8949" y1="31.3914" x2="84.3571" y2="99.6065" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#FEDE00"/>
|
||||||
|
<stop offset="1" stop-color="#FFD000"/>
|
||||||
|
</linearGradient>
|
||||||
|
<clipPath id="clip0_3076_287">
|
||||||
|
<rect width="111.4" height="111.4" fill="white" transform="translate(73.146) rotate(40.8281)"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
|
@ -1,6 +1,7 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'package:path/path.dart' as p;
|
||||||
import 'package:cw_core/exceptions.dart';
|
import 'package:cw_core/exceptions.dart';
|
||||||
import 'package:cw_core/transaction_direction.dart';
|
import 'package:cw_core/transaction_direction.dart';
|
||||||
import 'package:cw_core/utils/print_verbose.dart';
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
|
@ -602,7 +603,25 @@ abstract class DecredWalletBase
|
||||||
throw "wallet already exists at $newDirPath";
|
throw "wallet already exists at $newDirPath";
|
||||||
}
|
}
|
||||||
|
|
||||||
await Directory(currentDirPath).rename(newDirPath);
|
final sourceDir = Directory(currentDirPath);
|
||||||
|
final targetDir = Directory(newDirPath);
|
||||||
|
|
||||||
|
if (!targetDir.existsSync()) {
|
||||||
|
await targetDir.create(recursive: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
await for (final entity in sourceDir.list(recursive: true)) {
|
||||||
|
final relativePath = entity.path.substring(sourceDir.path.length+1);
|
||||||
|
final targetPath = p.join(targetDir.path, relativePath);
|
||||||
|
|
||||||
|
if (entity is File) {
|
||||||
|
await entity.rename(targetPath);
|
||||||
|
} else if (entity is Directory) {
|
||||||
|
await Directory(targetPath).create(recursive: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await sourceDir.delete(recursive: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -118,6 +118,10 @@ class DecredWalletService extends WalletService<
|
||||||
currentWalletInfo.derivationInfo?.derivationPath == pubkeyRestorePathTestnet
|
currentWalletInfo.derivationInfo?.derivationPath == pubkeyRestorePathTestnet
|
||||||
? testnet
|
? testnet
|
||||||
: mainnet;
|
: mainnet;
|
||||||
|
if (libwallet == null) {
|
||||||
|
libwallet = await Libwallet.spawn();
|
||||||
|
libwallet!.initLibdcrwallet("", "err");
|
||||||
|
}
|
||||||
final currentWallet = DecredWallet(
|
final currentWallet = DecredWallet(
|
||||||
currentWalletInfo, password, this.unspentCoinsInfoSource, libwallet!, closeLibwallet);
|
currentWalletInfo, password, this.unspentCoinsInfoSource, libwallet!, closeLibwallet);
|
||||||
|
|
||||||
|
|
|
@ -2,31 +2,31 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:cw_monero/api/wallet.dart';
|
import 'package:cw_monero/api/wallet.dart';
|
||||||
import 'package:cw_monero/monero_account_list.dart';
|
import 'package:cw_monero/monero_account_list.dart';
|
||||||
import 'package:monero/monero.dart' as monero;
|
import 'package:monero/src/wallet2.dart';
|
||||||
|
import 'package:monero/src/monero.dart';
|
||||||
|
|
||||||
monero.wallet? wptr = null;
|
Wallet2Wallet? currentWallet = null;
|
||||||
bool get isViewOnly => int.tryParse(monero.Wallet_secretSpendKey(wptr!)) == 0;
|
bool get isViewOnly => int.tryParse(currentWallet!.secretSpendKey()) == 0;
|
||||||
|
|
||||||
int _wlptrForW = 0;
|
int _wlptrForW = 0;
|
||||||
monero.WalletListener? _wlptr = null;
|
Wallet2WalletListener? _wlptr = null;
|
||||||
|
|
||||||
monero.WalletListener? getWlptr() {
|
Wallet2WalletListener? getWlptr() {
|
||||||
if (wptr == null) return null;
|
if (currentWallet == null) return null;
|
||||||
if (wptr!.address == _wlptrForW) return _wlptr!;
|
_wlptrForW = currentWallet!.ffiAddress();
|
||||||
_wlptrForW = wptr!.address;
|
_wlptr = currentWallet!.getWalletListener();
|
||||||
_wlptr = monero.MONERO_cw_getWalletListener(wptr!);
|
|
||||||
return _wlptr!;
|
return _wlptr!;
|
||||||
}
|
}
|
||||||
|
|
||||||
monero.SubaddressAccount? subaddressAccount;
|
Wallet2SubaddressAccount? subaddressAccount;
|
||||||
|
|
||||||
bool isUpdating = false;
|
bool isUpdating = false;
|
||||||
|
|
||||||
void refreshAccounts() {
|
void refreshAccounts() {
|
||||||
try {
|
try {
|
||||||
isUpdating = true;
|
isUpdating = true;
|
||||||
subaddressAccount = monero.Wallet_subaddressAccount(wptr!);
|
subaddressAccount = currentWallet!.subaddressAccount();
|
||||||
monero.SubaddressAccount_refresh(subaddressAccount!);
|
subaddressAccount!.refresh();
|
||||||
isUpdating = false;
|
isUpdating = false;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
isUpdating = false;
|
isUpdating = false;
|
||||||
|
@ -34,45 +34,28 @@ void refreshAccounts() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<monero.SubaddressAccountRow> getAllAccount() {
|
List<Wallet2SubaddressAccountRow> getAllAccount() {
|
||||||
// final size = monero.Wallet_numSubaddressAccounts(wptr!);
|
// final size = monero.Wallet_numSubaddressAccounts(wptr!);
|
||||||
refreshAccounts();
|
refreshAccounts();
|
||||||
int size = monero.SubaddressAccount_getAll_size(subaddressAccount!);
|
int size = subaddressAccount!.getAll_size();
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
monero.Wallet_addSubaddressAccount(wptr!);
|
currentWallet!.addSubaddressAccount();
|
||||||
monero.Wallet_status(wptr!);
|
currentWallet!.status();
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return List.generate(size, (index) {
|
return List.generate(size, (index) {
|
||||||
return monero.SubaddressAccount_getAll_byIndex(subaddressAccount!, index: index);
|
return subaddressAccount!.getAll_byIndex(index);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void addAccountSync({required String label}) {
|
void addAccount({required String label}) {
|
||||||
monero.Wallet_addSubaddressAccount(wptr!, label: label);
|
currentWallet!.addSubaddressAccount(label: label);
|
||||||
|
unawaited(store());
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLabelForAccountSync({required int accountIndex, required String label}) {
|
void setLabelForAccount({required int accountIndex, required String label}) {
|
||||||
monero.SubaddressAccount_setLabel(subaddressAccount!, accountIndex: accountIndex, label: label);
|
subaddressAccount!.setLabel(accountIndex: accountIndex, label: label);
|
||||||
MoneroAccountListBase.cachedAccounts[wptr!.address] = [];
|
MoneroAccountListBase.cachedAccounts[currentWallet!.ffiAddress()] = [];
|
||||||
refreshAccounts();
|
refreshAccounts();
|
||||||
}
|
|
||||||
|
|
||||||
void _addAccount(String label) => addAccountSync(label: label);
|
|
||||||
|
|
||||||
void _setLabelForAccount(Map<String, dynamic> args) {
|
|
||||||
final label = args['label'] as String;
|
|
||||||
final accountIndex = args['accountIndex'] as int;
|
|
||||||
|
|
||||||
setLabelForAccountSync(label: label, accountIndex: accountIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> addAccount({required String label}) async {
|
|
||||||
_addAccount(label);
|
|
||||||
unawaited(store());
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> setLabelForAccount({required int accountIndex, required String label}) async {
|
|
||||||
_setLabelForAccount({'accountIndex': accountIndex, 'label': label});
|
|
||||||
unawaited(store());
|
unawaited(store());
|
||||||
}
|
}
|
|
@ -3,17 +3,18 @@ import 'dart:isolate';
|
||||||
|
|
||||||
import 'package:cw_monero/api/account_list.dart';
|
import 'package:cw_monero/api/account_list.dart';
|
||||||
import 'package:monero/monero.dart' as monero;
|
import 'package:monero/monero.dart' as monero;
|
||||||
|
import 'package:monero/src/wallet2.dart';
|
||||||
import 'package:mutex/mutex.dart';
|
import 'package:mutex/mutex.dart';
|
||||||
|
|
||||||
monero.Coins? coins = null;
|
Wallet2Coins? coins = null;
|
||||||
final coinsMutex = Mutex();
|
final coinsMutex = Mutex();
|
||||||
|
|
||||||
Future<void> refreshCoins(int accountIndex) async {
|
Future<void> refreshCoins(int accountIndex) async {
|
||||||
if (coinsMutex.isLocked) {
|
if (coinsMutex.isLocked) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
coins = monero.Wallet_coins(wptr!);
|
coins = currentWallet!.coins();
|
||||||
final coinsPtr = coins!.address;
|
final coinsPtr = coins!.ffiAddress();
|
||||||
await coinsMutex.acquire();
|
await coinsMutex.acquire();
|
||||||
await Isolate.run(() => monero.Coins_refresh(Pointer.fromAddress(coinsPtr)));
|
await Isolate.run(() => monero.Coins_refresh(Pointer.fromAddress(coinsPtr)));
|
||||||
coinsMutex.release();
|
coinsMutex.release();
|
||||||
|
@ -21,14 +22,14 @@ Future<void> refreshCoins(int accountIndex) async {
|
||||||
|
|
||||||
Future<int> countOfCoins() async {
|
Future<int> countOfCoins() async {
|
||||||
await coinsMutex.acquire();
|
await coinsMutex.acquire();
|
||||||
final count = monero.Coins_count(coins!);
|
final count = coins!.count();
|
||||||
coinsMutex.release();
|
coinsMutex.release();
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<monero.CoinsInfo> getCoin(int index) async {
|
Future<Wallet2CoinsInfo> getCoin(int index) async {
|
||||||
await coinsMutex.acquire();
|
await coinsMutex.acquire();
|
||||||
final coin = monero.Coins_coin(coins!, index);
|
final coin = coins!.coin(index);
|
||||||
coinsMutex.release();
|
coinsMutex.release();
|
||||||
return coin;
|
return coin;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +38,7 @@ Future<int?> getCoinByKeyImage(String keyImage) async {
|
||||||
final count = await countOfCoins();
|
final count = await countOfCoins();
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
final coin = await getCoin(i);
|
final coin = await getCoin(i);
|
||||||
final coinAddress = monero.CoinsInfo_keyImage(coin);
|
final coinAddress = coin.keyImage;
|
||||||
if (keyImage == coinAddress) {
|
if (keyImage == coinAddress) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -47,14 +48,14 @@ Future<int?> getCoinByKeyImage(String keyImage) async {
|
||||||
|
|
||||||
Future<void> freezeCoin(int index) async {
|
Future<void> freezeCoin(int index) async {
|
||||||
await coinsMutex.acquire();
|
await coinsMutex.acquire();
|
||||||
final coinsPtr = coins!.address;
|
final coinsPtr = coins!.ffiAddress();
|
||||||
await Isolate.run(() => monero.Coins_setFrozen(Pointer.fromAddress(coinsPtr), index: index));
|
await Isolate.run(() => monero.Coins_setFrozen(Pointer.fromAddress(coinsPtr), index: index));
|
||||||
coinsMutex.release();
|
coinsMutex.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> thawCoin(int index) async {
|
Future<void> thawCoin(int index) async {
|
||||||
await coinsMutex.acquire();
|
await coinsMutex.acquire();
|
||||||
final coinsPtr = coins!.address;
|
final coinsPtr = coins!.ffiAddress();
|
||||||
await Isolate.run(() => monero.Coins_thaw(Pointer.fromAddress(coinsPtr), index: index));
|
await Isolate.run(() => monero.Coins_thaw(Pointer.fromAddress(coinsPtr), index: index));
|
||||||
coinsMutex.release();
|
coinsMutex.release();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
import 'package:cw_monero/api/account_list.dart';
|
import 'package:cw_monero/api/account_list.dart';
|
||||||
import 'package:cw_monero/api/transaction_history.dart';
|
import 'package:cw_monero/api/transaction_history.dart';
|
||||||
import 'package:cw_monero/api/wallet.dart';
|
import 'package:cw_monero/api/wallet.dart';
|
||||||
import 'package:monero/monero.dart' as monero;
|
import 'package:monero/monero.dart';
|
||||||
|
import 'package:monero/src/monero.dart';
|
||||||
|
|
||||||
bool isUpdating = false;
|
bool isUpdating = false;
|
||||||
|
|
||||||
|
@ -16,7 +17,7 @@ class SubaddressInfoMetadata {
|
||||||
SubaddressInfoMetadata? subaddress = null;
|
SubaddressInfoMetadata? subaddress = null;
|
||||||
|
|
||||||
String getRawLabel({required int accountIndex, required int addressIndex}) {
|
String getRawLabel({required int accountIndex, required int addressIndex}) {
|
||||||
return monero.Wallet_getSubaddressLabel(wptr!, accountIndex: accountIndex, addressIndex: addressIndex);
|
return currentWallet!.getSubaddressLabel(accountIndex: accountIndex, addressIndex: addressIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void refreshSubaddresses({required int accountIndex}) {
|
void refreshSubaddresses({required int accountIndex}) {
|
||||||
|
@ -46,7 +47,7 @@ class Subaddress {
|
||||||
final int received;
|
final int received;
|
||||||
final int txCount;
|
final int txCount;
|
||||||
String get label {
|
String get label {
|
||||||
final localLabel = monero.Wallet_getSubaddressLabel(wptr!, accountIndex: accountIndex, addressIndex: addressIndex);
|
final localLabel = currentWallet!.getSubaddressLabel(accountIndex: accountIndex, addressIndex: addressIndex);
|
||||||
if (localLabel.startsWith("#$addressIndex")) return localLabel; // don't duplicate the ID if it was user-providen
|
if (localLabel.startsWith("#$addressIndex")) return localLabel; // don't duplicate the ID if it was user-providen
|
||||||
return "#$addressIndex ${localLabel}".trim();
|
return "#$addressIndex ${localLabel}".trim();
|
||||||
}
|
}
|
||||||
|
@ -66,26 +67,26 @@ int lastTxCount = 0;
|
||||||
List<TinyTransactionDetails> ttDetails = [];
|
List<TinyTransactionDetails> ttDetails = [];
|
||||||
|
|
||||||
List<Subaddress> getAllSubaddresses() {
|
List<Subaddress> getAllSubaddresses() {
|
||||||
txhistory = monero.Wallet_history(wptr!);
|
txhistory = currentWallet!.history();
|
||||||
final txCount = monero.TransactionHistory_count(txhistory!);
|
final txCount = txhistory!.count();
|
||||||
if (lastTxCount != txCount && lastWptr != wptr!.address) {
|
if (lastTxCount != txCount && lastWptr != currentWallet!.ffiAddress()) {
|
||||||
final List<TinyTransactionDetails> newttDetails = [];
|
final List<TinyTransactionDetails> newttDetails = [];
|
||||||
lastTxCount = txCount;
|
lastTxCount = txCount;
|
||||||
lastWptr = wptr!.address;
|
lastWptr = currentWallet!.ffiAddress();
|
||||||
for (var i = 0; i < txCount; i++) {
|
for (var i = 0; i < txCount; i++) {
|
||||||
final tx = monero.TransactionHistory_transaction(txhistory!, index: i);
|
final tx = txhistory!.transaction(i);
|
||||||
if (monero.TransactionInfo_direction(tx) == monero.TransactionInfo_Direction.Out) continue;
|
if (tx.direction() == TransactionInfo_Direction.Out.index) continue;
|
||||||
final subaddrs = monero.TransactionInfo_subaddrIndex(tx).split(",");
|
final subaddrs = tx.subaddrIndex().split(",");
|
||||||
final account = monero.TransactionInfo_subaddrAccount(tx);
|
final account = tx.subaddrAccount();
|
||||||
newttDetails.add(TinyTransactionDetails(
|
newttDetails.add(TinyTransactionDetails(
|
||||||
address: List.generate(subaddrs.length, (index) => getAddress(accountIndex: account, addressIndex: int.tryParse(subaddrs[index])??0)),
|
address: List.generate(subaddrs.length, (index) => getAddress(accountIndex: account, addressIndex: int.tryParse(subaddrs[index])??0)),
|
||||||
amount: monero.TransactionInfo_amount(tx),
|
amount: tx.amount(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
ttDetails.clear();
|
ttDetails.clear();
|
||||||
ttDetails.addAll(newttDetails);
|
ttDetails.addAll(newttDetails);
|
||||||
}
|
}
|
||||||
final size = monero.Wallet_numSubaddresses(wptr!, accountIndex: subaddress!.accountIndex);
|
final size = currentWallet!.numSubaddresses(accountIndex: subaddress!.accountIndex);
|
||||||
final list = List.generate(size, (index) {
|
final list = List.generate(size, (index) {
|
||||||
final ttDetailsLocal = ttDetails.where((element) {
|
final ttDetailsLocal = ttDetails.where((element) {
|
||||||
final address = getAddress(
|
final address = getAddress(
|
||||||
|
@ -119,46 +120,17 @@ List<Subaddress> getAllSubaddresses() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int numSubaddresses(int subaccountIndex) {
|
int numSubaddresses(int subaccountIndex) {
|
||||||
return monero.Wallet_numSubaddresses(wptr!, accountIndex: subaccountIndex);
|
return currentWallet!.numSubaddresses(accountIndex: subaccountIndex);
|
||||||
}
|
|
||||||
|
|
||||||
void addSubaddressSync({required int accountIndex, required String label}) {
|
|
||||||
monero.Wallet_addSubaddress(wptr!, accountIndex: accountIndex, label: label);
|
|
||||||
refreshSubaddresses(accountIndex: accountIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setLabelForSubaddressSync(
|
|
||||||
{required int accountIndex, required int addressIndex, required String label}) {
|
|
||||||
monero.Wallet_setSubaddressLabel(wptr!, accountIndex: accountIndex, addressIndex: addressIndex, label: label);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _addSubaddress(Map<String, dynamic> args) {
|
|
||||||
final label = args['label'] as String;
|
|
||||||
final accountIndex = args['accountIndex'] as int;
|
|
||||||
|
|
||||||
addSubaddressSync(accountIndex: accountIndex, label: label);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _setLabelForSubaddress(Map<String, dynamic> args) {
|
|
||||||
final label = args['label'] as String;
|
|
||||||
final accountIndex = args['accountIndex'] as int;
|
|
||||||
final addressIndex = args['addressIndex'] as int;
|
|
||||||
|
|
||||||
setLabelForSubaddressSync(
|
|
||||||
accountIndex: accountIndex, addressIndex: addressIndex, label: label);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> addSubaddress({required int accountIndex, required String label}) async {
|
Future<void> addSubaddress({required int accountIndex, required String label}) async {
|
||||||
_addSubaddress({'accountIndex': accountIndex, 'label': label});
|
currentWallet!.addSubaddress(accountIndex: accountIndex, label: label);
|
||||||
|
refreshSubaddresses(accountIndex: accountIndex);
|
||||||
await store();
|
await store();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> setLabelForSubaddress(
|
Future<void> setLabelForSubaddress(
|
||||||
{required int accountIndex, required int addressIndex, required String label}) async {
|
{required int accountIndex, required int addressIndex, required String label}) async {
|
||||||
_setLabelForSubaddress({
|
currentWallet!.setSubaddressLabel(accountIndex: accountIndex, addressIndex: addressIndex, label: label);
|
||||||
'accountIndex': accountIndex,
|
|
||||||
'addressIndex': addressIndex,
|
|
||||||
'label': label
|
|
||||||
});
|
|
||||||
await store();
|
await store();
|
||||||
}
|
}
|
|
@ -9,36 +9,38 @@ import 'package:cw_monero/api/structs/pending_transaction.dart';
|
||||||
import 'package:cw_monero/api/wallet.dart';
|
import 'package:cw_monero/api/wallet.dart';
|
||||||
import 'package:cw_monero/exceptions/monero_transaction_creation_exception.dart';
|
import 'package:cw_monero/exceptions/monero_transaction_creation_exception.dart';
|
||||||
import 'package:ffi/ffi.dart';
|
import 'package:ffi/ffi.dart';
|
||||||
|
import 'package:monero/src/monero.dart';
|
||||||
import 'package:monero/monero.dart' as monero;
|
import 'package:monero/monero.dart' as monero;
|
||||||
|
import 'package:monero/src/wallet2.dart';
|
||||||
import 'package:monero/src/generated_bindings_monero.g.dart' as monero_gen;
|
import 'package:monero/src/generated_bindings_monero.g.dart' as monero_gen;
|
||||||
import 'package:mutex/mutex.dart';
|
import 'package:mutex/mutex.dart';
|
||||||
|
|
||||||
|
|
||||||
Map<int, Map<String, String>> txKeys = {};
|
Map<int, Map<String, String>> txKeys = {};
|
||||||
String getTxKey(String txId) {
|
String getTxKey(String txId) {
|
||||||
txKeys[wptr!.address] ??= {};
|
txKeys[currentWallet!.ffiAddress()] ??= {};
|
||||||
if (txKeys[wptr!.address]![txId] != null) {
|
if (txKeys[currentWallet!.ffiAddress()]![txId] != null) {
|
||||||
return txKeys[wptr!.address]![txId]!;
|
return txKeys[currentWallet!.ffiAddress()]![txId]!;
|
||||||
}
|
}
|
||||||
final txKey = monero.Wallet_getTxKey(wptr!, txid: txId);
|
final txKey = currentWallet!.getTxKey(txid: txId);
|
||||||
final status = monero.Wallet_status(wptr!);
|
final status = currentWallet!.status();
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
monero.Wallet_errorString(wptr!);
|
currentWallet!.errorString();
|
||||||
txKeys[wptr!.address]![txId] = "";
|
txKeys[currentWallet!.ffiAddress()]![txId] = "";
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
txKeys[wptr!.address]![txId] = txKey;
|
txKeys[currentWallet!.ffiAddress()]![txId] = txKey;
|
||||||
return txKey;
|
return txKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
final txHistoryMutex = Mutex();
|
final txHistoryMutex = Mutex();
|
||||||
monero.TransactionHistory? txhistory;
|
Wallet2TransactionHistory? txhistory;
|
||||||
bool isRefreshingTx = false;
|
bool isRefreshingTx = false;
|
||||||
Future<void> refreshTransactions() async {
|
Future<void> refreshTransactions() async {
|
||||||
if (isRefreshingTx == true) return;
|
if (isRefreshingTx == true) return;
|
||||||
isRefreshingTx = true;
|
isRefreshingTx = true;
|
||||||
txhistory ??= monero.Wallet_history(wptr!);
|
txhistory ??= currentWallet!.history();
|
||||||
final ptr = txhistory!.address;
|
final ptr = txhistory!.ffiAddress();
|
||||||
await txHistoryMutex.acquire();
|
await txHistoryMutex.acquire();
|
||||||
await Isolate.run(() {
|
await Isolate.run(() {
|
||||||
monero.TransactionHistory_refresh(Pointer.fromAddress(ptr));
|
monero.TransactionHistory_refresh(Pointer.fromAddress(ptr));
|
||||||
|
@ -48,14 +50,14 @@ Future<void> refreshTransactions() async {
|
||||||
isRefreshingTx = false;
|
isRefreshingTx = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int countOfTransactions() => monero.TransactionHistory_count(txhistory!);
|
int countOfTransactions() => txhistory!.count();
|
||||||
|
|
||||||
Future<List<Transaction>> getAllTransactions() async {
|
Future<List<Transaction>> getAllTransactions() async {
|
||||||
List<Transaction> dummyTxs = [];
|
List<Transaction> dummyTxs = [];
|
||||||
|
|
||||||
await txHistoryMutex.acquire();
|
await txHistoryMutex.acquire();
|
||||||
txhistory ??= monero.Wallet_history(wptr!);
|
txhistory ??= currentWallet!.history();
|
||||||
final startAddress = txhistory!.address * wptr!.address;
|
final startAddress = txhistory!.ffiAddress() * currentWallet!.ffiAddress();
|
||||||
int size = countOfTransactions();
|
int size = countOfTransactions();
|
||||||
final list = <Transaction>[];
|
final list = <Transaction>[];
|
||||||
for (int index = 0; index < size; index++) {
|
for (int index = 0; index < size; index++) {
|
||||||
|
@ -63,21 +65,21 @@ Future<List<Transaction>> getAllTransactions() async {
|
||||||
// Give main thread a chance to do other things.
|
// Give main thread a chance to do other things.
|
||||||
await Future.delayed(Duration.zero);
|
await Future.delayed(Duration.zero);
|
||||||
}
|
}
|
||||||
if (txhistory!.address * wptr!.address != startAddress) {
|
if (txhistory!.ffiAddress() * currentWallet!.ffiAddress() != startAddress) {
|
||||||
printV("Loop broken because txhistory!.address * wptr!.address != startAddress");
|
printV("Loop broken because txhistory!.address * wptr!.address != startAddress");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
final txInfo = monero.TransactionHistory_transaction(txhistory!, index: index);
|
final txInfo = txhistory!.transaction(index);
|
||||||
final txHash = monero.TransactionInfo_hash(txInfo);
|
final txHash = txInfo.hash();
|
||||||
txCache[wptr!.address] ??= {};
|
txCache[currentWallet!.ffiAddress()] ??= {};
|
||||||
txCache[wptr!.address]![txHash] = Transaction(txInfo: txInfo);
|
txCache[currentWallet!.ffiAddress()]![txHash] = Transaction(txInfo: txInfo);
|
||||||
list.add(txCache[wptr!.address]![txHash]!);
|
list.add(txCache[currentWallet!.ffiAddress()]![txHash]!);
|
||||||
}
|
}
|
||||||
txHistoryMutex.release();
|
txHistoryMutex.release();
|
||||||
final accts = monero.Wallet_numSubaddressAccounts(wptr!);
|
final accts = currentWallet!.numSubaddressAccounts();
|
||||||
for (var i = 0; i < accts; i++) {
|
for (var i = 0; i < accts; i++) {
|
||||||
final fullBalance = monero.Wallet_balance(wptr!, accountIndex: i);
|
final fullBalance = currentWallet!.balance(accountIndex: i);
|
||||||
final availBalance = monero.Wallet_unlockedBalance(wptr!, accountIndex: i);
|
final availBalance = currentWallet!.unlockedBalance(accountIndex: i);
|
||||||
if (fullBalance > availBalance) {
|
if (fullBalance > availBalance) {
|
||||||
if (list.where((element) => element.accountIndex == i && element.isConfirmed == false).isEmpty) {
|
if (list.where((element) => element.accountIndex == i && element.isConfirmed == false).isEmpty) {
|
||||||
dummyTxs.add(
|
dummyTxs.add(
|
||||||
|
@ -95,7 +97,7 @@ Future<List<Transaction>> getAllTransactions() async {
|
||||||
isSpend: false,
|
isSpend: false,
|
||||||
hash: "pending",
|
hash: "pending",
|
||||||
key: "",
|
key: "",
|
||||||
txInfo: Pointer.fromAddress(0),
|
txInfo: DummyTransaction(),
|
||||||
)..timeStamp = DateTime.now()
|
)..timeStamp = DateTime.now()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -105,16 +107,21 @@ Future<List<Transaction>> getAllTransactions() async {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DummyTransaction implements Wallet2TransactionInfo {
|
||||||
|
@override
|
||||||
|
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
|
||||||
|
}
|
||||||
|
|
||||||
Map<int, Map<String, Transaction>> txCache = {};
|
Map<int, Map<String, Transaction>> txCache = {};
|
||||||
Future<Transaction> getTransaction(String txId) async {
|
Future<Transaction> getTransaction(String txId) async {
|
||||||
if (txCache[wptr!.address] != null && txCache[wptr!.address]![txId] != null) {
|
if (txCache[currentWallet!.ffiAddress()] != null && txCache[currentWallet!.ffiAddress()]![txId] != null) {
|
||||||
return txCache[wptr!.address]![txId]!;
|
return txCache[currentWallet!.ffiAddress()]![txId]!;
|
||||||
}
|
}
|
||||||
await txHistoryMutex.acquire();
|
await txHistoryMutex.acquire();
|
||||||
final tx = monero.TransactionHistory_transactionById(txhistory!, txid: txId);
|
final tx = txhistory!.transactionById(txId);
|
||||||
final txDart = Transaction(txInfo: tx);
|
final txDart = Transaction(txInfo: tx);
|
||||||
txCache[wptr!.address] ??= {};
|
txCache[currentWallet!.ffiAddress()] ??= {};
|
||||||
txCache[wptr!.address]![txId] = txDart;
|
txCache[currentWallet!.ffiAddress()]![txId] = txDart;
|
||||||
txHistoryMutex.release();
|
txHistoryMutex.release();
|
||||||
return txDart;
|
return txDart;
|
||||||
}
|
}
|
||||||
|
@ -127,9 +134,9 @@ Future<PendingTransactionDescription> createTransactionSync(
|
||||||
int accountIndex = 0,
|
int accountIndex = 0,
|
||||||
List<String> preferredInputs = const []}) async {
|
List<String> preferredInputs = const []}) async {
|
||||||
|
|
||||||
final amt = amount == null ? 0 : monero.Wallet_amountFromString(amount);
|
final amt = amount == null ? 0 : currentWallet!.amountFromString(amount);
|
||||||
|
|
||||||
final waddr = wptr!.address;
|
final waddr = currentWallet!.ffiAddress();
|
||||||
|
|
||||||
// force reconnection in case the os killed the connection?
|
// force reconnection in case the os killed the connection?
|
||||||
// fixes failed to get block height error.
|
// fixes failed to get block height error.
|
||||||
|
@ -149,7 +156,7 @@ Future<PendingTransactionDescription> createTransactionSync(
|
||||||
final paymentIdAddr = paymentId_.address;
|
final paymentIdAddr = paymentId_.address;
|
||||||
final preferredInputsAddr = preferredInputs_.address;
|
final preferredInputsAddr = preferredInputs_.address;
|
||||||
final spaddr = monero.defaultSeparator.address;
|
final spaddr = monero.defaultSeparator.address;
|
||||||
final pendingTx = Pointer<Void>.fromAddress(await Isolate.run(() {
|
final pendingTxPtr = Pointer<Void>.fromAddress(await Isolate.run(() {
|
||||||
final tx = monero_gen.MoneroC(DynamicLibrary.open(monero.libPath)).MONERO_Wallet_createTransaction(
|
final tx = monero_gen.MoneroC(DynamicLibrary.open(monero.libPath)).MONERO_Wallet_createTransaction(
|
||||||
Pointer.fromAddress(waddr),
|
Pointer.fromAddress(waddr),
|
||||||
Pointer.fromAddress(addraddr).cast(),
|
Pointer.fromAddress(addraddr).cast(),
|
||||||
|
@ -163,15 +170,16 @@ Future<PendingTransactionDescription> createTransactionSync(
|
||||||
);
|
);
|
||||||
return tx.address;
|
return tx.address;
|
||||||
}));
|
}));
|
||||||
|
final Wallet2PendingTransaction pendingTx = MoneroPendingTransaction(pendingTxPtr);
|
||||||
calloc.free(address_);
|
calloc.free(address_);
|
||||||
calloc.free(paymentId_);
|
calloc.free(paymentId_);
|
||||||
calloc.free(preferredInputs_);
|
calloc.free(preferredInputs_);
|
||||||
final String? error = (() {
|
final String? error = (() {
|
||||||
final status = monero.PendingTransaction_status(pendingTx);
|
final status = pendingTx.status();
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return monero.PendingTransaction_errorString(pendingTx);
|
return pendingTx.errorString();
|
||||||
})();
|
})();
|
||||||
|
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
|
@ -182,10 +190,10 @@ Future<PendingTransactionDescription> createTransactionSync(
|
||||||
throw CreationTransactionException(message: message);
|
throw CreationTransactionException(message: message);
|
||||||
}
|
}
|
||||||
|
|
||||||
final rAmt = monero.PendingTransaction_amount(pendingTx);
|
final rAmt = pendingTx.amount();
|
||||||
final rFee = monero.PendingTransaction_fee(pendingTx);
|
final rFee = pendingTx.fee();
|
||||||
final rHash = monero.PendingTransaction_txid(pendingTx, '');
|
final rHash = pendingTx.txid('');
|
||||||
final rHex = monero.PendingTransaction_hex(pendingTx, '');
|
final rHex = pendingTx.hex('');
|
||||||
final rTxKey = rHash;
|
final rTxKey = rHash;
|
||||||
|
|
||||||
return PendingTransactionDescription(
|
return PendingTransactionDescription(
|
||||||
|
@ -194,7 +202,7 @@ Future<PendingTransactionDescription> createTransactionSync(
|
||||||
hash: rHash,
|
hash: rHash,
|
||||||
hex: rHex,
|
hex: rHex,
|
||||||
txKey: rTxKey,
|
txKey: rTxKey,
|
||||||
pointerAddress: pendingTx.address,
|
pointerAddress: pendingTx.ffiAddress(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,9 +214,9 @@ Future<PendingTransactionDescription> createTransactionMultDest(
|
||||||
List<String> preferredInputs = const []}) async {
|
List<String> preferredInputs = const []}) async {
|
||||||
|
|
||||||
final dstAddrs = outputs.map((e) => e.address).toList();
|
final dstAddrs = outputs.map((e) => e.address).toList();
|
||||||
final amounts = outputs.map((e) => monero.Wallet_amountFromString(e.amount)).toList();
|
final amounts = outputs.map((e) => currentWallet!.amountFromString(e.amount)).toList();
|
||||||
|
|
||||||
final waddr = wptr!.address;
|
final waddr = currentWallet!.ffiAddress();
|
||||||
|
|
||||||
// force reconnection in case the os killed the connection
|
// force reconnection in case the os killed the connection
|
||||||
Isolate.run(() async {
|
Isolate.run(() async {
|
||||||
|
@ -227,49 +235,50 @@ Future<PendingTransactionDescription> createTransactionMultDest(
|
||||||
).address;
|
).address;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (monero.PendingTransaction_status(txptr) != 0) {
|
final Wallet2PendingTransaction tx = MoneroPendingTransaction(txptr);
|
||||||
throw CreationTransactionException(message: monero.PendingTransaction_errorString(txptr));
|
|
||||||
|
if (tx.status() != 0) {
|
||||||
|
throw CreationTransactionException(message: tx.errorString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return PendingTransactionDescription(
|
return PendingTransactionDescription(
|
||||||
amount: monero.PendingTransaction_amount(txptr),
|
amount: tx.amount(),
|
||||||
fee: monero.PendingTransaction_fee(txptr),
|
fee: tx.fee(),
|
||||||
hash: monero.PendingTransaction_txid(txptr, ''),
|
hash: tx.txid(''),
|
||||||
hex: monero.PendingTransaction_hex(txptr, ''),
|
hex: tx.hex(''),
|
||||||
txKey: monero.PendingTransaction_txid(txptr, ''),
|
txKey: tx.txid(''),
|
||||||
pointerAddress: txptr.address,
|
pointerAddress: tx.ffiAddress(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String? commitTransactionFromPointerAddress({required int address, required bool useUR}) =>
|
String? commitTransactionFromPointerAddress({required int address, required bool useUR}) =>
|
||||||
commitTransaction(transactionPointer: monero.PendingTransaction.fromAddress(address), useUR: useUR);
|
commitTransaction(tx: MoneroPendingTransaction(Pointer.fromAddress(address)), useUR: useUR);
|
||||||
|
|
||||||
String? commitTransaction({required monero.PendingTransaction transactionPointer, required bool useUR}) {
|
String? commitTransaction({required Wallet2PendingTransaction tx, required bool useUR}) {
|
||||||
final transactionPointerAddress = transactionPointer.address;
|
|
||||||
final txCommit = useUR
|
final txCommit = useUR
|
||||||
? monero.PendingTransaction_commitUR(transactionPointer, 120)
|
? tx.commitUR(120)
|
||||||
: Isolate.run(() {
|
: Isolate.run(() {
|
||||||
monero.PendingTransaction_commit(
|
monero.PendingTransaction_commit(
|
||||||
Pointer.fromAddress(transactionPointerAddress),
|
Pointer.fromAddress(tx.ffiAddress()),
|
||||||
filename: '',
|
filename: '',
|
||||||
overwrite: false,
|
overwrite: false,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
String? error = (() {
|
String? error = (() {
|
||||||
final status = monero.PendingTransaction_status(transactionPointer.cast());
|
final status = tx.status();
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return monero.PendingTransaction_errorString(transactionPointer.cast());
|
return tx.errorString();
|
||||||
})();
|
})();
|
||||||
if (error == null) {
|
if (error == null) {
|
||||||
error = (() {
|
error = (() {
|
||||||
final status = monero.Wallet_status(wptr!);
|
final status = currentWallet!.status();
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return monero.Wallet_errorString(wptr!);
|
return currentWallet!.errorString();
|
||||||
})();
|
})();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -283,43 +292,9 @@ String? commitTransaction({required monero.PendingTransaction transactionPointer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<PendingTransactionDescription> _createTransactionSync(Map args) async {
|
|
||||||
final address = args['address'] as String;
|
|
||||||
final paymentId = args['paymentId'] as String;
|
|
||||||
final amount = args['amount'] as String?;
|
|
||||||
final priorityRaw = args['priorityRaw'] as int;
|
|
||||||
final accountIndex = args['accountIndex'] as int;
|
|
||||||
final preferredInputs = args['preferredInputs'] as List<String>;
|
|
||||||
|
|
||||||
return createTransactionSync(
|
|
||||||
address: address,
|
|
||||||
paymentId: paymentId,
|
|
||||||
amount: amount,
|
|
||||||
priorityRaw: priorityRaw,
|
|
||||||
accountIndex: accountIndex,
|
|
||||||
preferredInputs: preferredInputs);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<PendingTransactionDescription> createTransaction(
|
|
||||||
{required String address,
|
|
||||||
required int priorityRaw,
|
|
||||||
String? amount,
|
|
||||||
String paymentId = '',
|
|
||||||
int accountIndex = 0,
|
|
||||||
List<String> preferredInputs = const []}) async =>
|
|
||||||
_createTransactionSync({
|
|
||||||
'address': address,
|
|
||||||
'paymentId': paymentId,
|
|
||||||
'amount': amount,
|
|
||||||
'priorityRaw': priorityRaw,
|
|
||||||
'accountIndex': accountIndex,
|
|
||||||
'preferredInputs': preferredInputs
|
|
||||||
});
|
|
||||||
|
|
||||||
class Transaction {
|
class Transaction {
|
||||||
final String displayLabel;
|
final String displayLabel;
|
||||||
late final String subaddressLabel = monero.Wallet_getSubaddressLabel(
|
late final String subaddressLabel = currentWallet!.getSubaddressLabel(
|
||||||
wptr!,
|
|
||||||
accountIndex: accountIndex,
|
accountIndex: accountIndex,
|
||||||
addressIndex: addressIndex,
|
addressIndex: addressIndex,
|
||||||
);
|
);
|
||||||
|
@ -372,26 +347,26 @@ class Transaction {
|
||||||
// final SubAddress? subAddress;
|
// final SubAddress? subAddress;
|
||||||
// List<Transfer> transfers = [];
|
// List<Transfer> transfers = [];
|
||||||
// final int txIndex;
|
// final int txIndex;
|
||||||
final monero.TransactionInfo txInfo;
|
final Wallet2TransactionInfo txInfo;
|
||||||
Transaction({
|
Transaction({
|
||||||
required this.txInfo,
|
required this.txInfo,
|
||||||
}) : displayLabel = monero.TransactionInfo_label(txInfo),
|
}) : displayLabel = txInfo.label(),
|
||||||
hash = monero.TransactionInfo_hash(txInfo),
|
hash = txInfo.hash(),
|
||||||
timeStamp = DateTime.fromMillisecondsSinceEpoch(
|
timeStamp = DateTime.fromMillisecondsSinceEpoch(
|
||||||
monero.TransactionInfo_timestamp(txInfo) * 1000,
|
txInfo.timestamp() * 1000,
|
||||||
),
|
),
|
||||||
isSpend = monero.TransactionInfo_direction(txInfo) ==
|
isSpend = txInfo.direction() ==
|
||||||
monero.TransactionInfo_Direction.Out,
|
monero.TransactionInfo_Direction.Out.index,
|
||||||
amount = monero.TransactionInfo_amount(txInfo),
|
amount = txInfo.amount(),
|
||||||
paymentId = monero.TransactionInfo_paymentId(txInfo),
|
paymentId = txInfo.paymentId(),
|
||||||
accountIndex = monero.TransactionInfo_subaddrAccount(txInfo),
|
accountIndex = txInfo.subaddrAccount(),
|
||||||
addressIndex = int.tryParse(monero.TransactionInfo_subaddrIndex(txInfo).split(", ")[0]) ?? 0,
|
addressIndex = int.tryParse(txInfo.subaddrIndex().split(", ")[0]) ?? 0,
|
||||||
addressIndexList = monero.TransactionInfo_subaddrIndex(txInfo).split(", ").map((e) => int.tryParse(e) ?? 0).toList(),
|
addressIndexList = txInfo.subaddrIndex().split(", ").map((e) => int.tryParse(e) ?? 0).toList(),
|
||||||
blockheight = monero.TransactionInfo_blockHeight(txInfo),
|
blockheight = txInfo.blockHeight(),
|
||||||
confirmations = monero.TransactionInfo_confirmations(txInfo),
|
confirmations = txInfo.confirmations(),
|
||||||
fee = monero.TransactionInfo_fee(txInfo),
|
fee = txInfo.fee(),
|
||||||
description = monero.TransactionInfo_description(txInfo),
|
description = txInfo.description(),
|
||||||
key = getTxKey(monero.TransactionInfo_hash(txInfo));
|
key = getTxKey(txInfo.hash());
|
||||||
|
|
||||||
Transaction.dummy({
|
Transaction.dummy({
|
||||||
required this.displayLabel,
|
required this.displayLabel,
|
||||||
|
|
|
@ -5,8 +5,6 @@ import 'dart:isolate';
|
||||||
import 'package:cw_core/utils/print_verbose.dart';
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_monero/api/account_list.dart';
|
import 'package:cw_monero/api/account_list.dart';
|
||||||
import 'package:cw_monero/api/exceptions/setup_wallet_exception.dart';
|
import 'package:cw_monero/api/exceptions/setup_wallet_exception.dart';
|
||||||
import 'package:cw_monero/api/wallet_manager.dart';
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:monero/monero.dart' as monero;
|
import 'package:monero/monero.dart' as monero;
|
||||||
import 'package:mutex/mutex.dart';
|
import 'package:mutex/mutex.dart';
|
||||||
import 'package:polyseed/polyseed.dart';
|
import 'package:polyseed/polyseed.dart';
|
||||||
|
@ -15,36 +13,37 @@ bool debugMonero = false;
|
||||||
|
|
||||||
int getSyncingHeight() {
|
int getSyncingHeight() {
|
||||||
// final height = monero.MONERO_cw_WalletListener_height(getWlptr());
|
// final height = monero.MONERO_cw_WalletListener_height(getWlptr());
|
||||||
final h2 = monero.Wallet_blockChainHeight(wptr!);
|
if (currentWallet == null) return 0;
|
||||||
|
final h2 = currentWallet!.blockChainHeight();
|
||||||
// printV("height: $height / $h2");
|
// printV("height: $height / $h2");
|
||||||
return h2;
|
return h2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isNeededToRefresh() {
|
bool isNeededToRefresh() {
|
||||||
final wlptr = getWlptr();
|
final wl = getWlptr();
|
||||||
if (wlptr == null) return false;
|
if (wl == null) return false;
|
||||||
final ret = monero.MONERO_cw_WalletListener_isNeedToRefresh(wlptr);
|
final ret = wl.isNeedToRefresh();
|
||||||
monero.MONERO_cw_WalletListener_resetNeedToRefresh(wlptr);
|
wl.resetNeedToRefresh();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isNewTransactionExist() {
|
bool isNewTransactionExist() {
|
||||||
final wlptr = getWlptr();
|
final wlptr = getWlptr();
|
||||||
if (wlptr == null) return false;
|
if (wlptr == null) return false;
|
||||||
final ret = monero.MONERO_cw_WalletListener_isNewTransactionExist(wlptr);
|
final ret = wlptr.isNewTransactionExist();
|
||||||
monero.MONERO_cw_WalletListener_resetIsNewTransactionExist(wlptr);
|
wlptr.resetIsNewTransactionExist();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
String getFilename() => monero.Wallet_filename(wptr!);
|
String getFilename() => currentWallet!.filename();
|
||||||
|
|
||||||
String getSeed() {
|
String getSeed() {
|
||||||
// monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed);
|
// monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed);
|
||||||
final cakepolyseed =
|
final cakepolyseed =
|
||||||
monero.Wallet_getCacheAttribute(wptr!, key: "cakewallet.seed");
|
currentWallet!.getCacheAttribute(key: "cakewallet.seed");
|
||||||
final cakepassphrase = getPassphrase();
|
final cakepassphrase = getPassphrase();
|
||||||
|
|
||||||
final weirdPolyseed = monero.Wallet_getPolyseed(wptr!, passphrase: cakepassphrase);
|
final weirdPolyseed = currentWallet!.getPolyseed(passphrase: cakepassphrase);
|
||||||
if (weirdPolyseed != "") return weirdPolyseed;
|
if (weirdPolyseed != "") return weirdPolyseed;
|
||||||
|
|
||||||
if (cakepolyseed != "") {
|
if (cakepolyseed != "") {
|
||||||
|
@ -63,7 +62,7 @@ String getSeed() {
|
||||||
return cakepolyseed;
|
return cakepolyseed;
|
||||||
}
|
}
|
||||||
|
|
||||||
final bip39 = monero.Wallet_getCacheAttribute(wptr!, key: "cakewallet.seed.bip39");
|
final bip39 = currentWallet!.getCacheAttribute(key: "cakewallet.seed.bip39");
|
||||||
|
|
||||||
if(bip39.isNotEmpty) return bip39;
|
if(bip39.isNotEmpty) return bip39;
|
||||||
|
|
||||||
|
@ -85,29 +84,29 @@ String? getSeedLanguage(String? language) {
|
||||||
String getSeedLegacy(String? language) {
|
String getSeedLegacy(String? language) {
|
||||||
final cakepassphrase = getPassphrase();
|
final cakepassphrase = getPassphrase();
|
||||||
language = getSeedLanguage(language);
|
language = getSeedLanguage(language);
|
||||||
var legacy = monero.Wallet_seed(wptr!, seedOffset: cakepassphrase);
|
var legacy = currentWallet!.seed(seedOffset: cakepassphrase);
|
||||||
if (monero.Wallet_status(wptr!) != 0) {
|
if (currentWallet!.status() != 0) {
|
||||||
if (monero.Wallet_errorString(wptr!).contains("seed_language")) {
|
if (currentWallet!.errorString().contains("seed_language")) {
|
||||||
monero.Wallet_setSeedLanguage(wptr!, language: "English");
|
currentWallet!.setSeedLanguage(language: "English");
|
||||||
legacy = monero.Wallet_seed(wptr!, seedOffset: cakepassphrase);
|
legacy = currentWallet!.seed(seedOffset: cakepassphrase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (language != null) {
|
if (language != null) {
|
||||||
monero.Wallet_setSeedLanguage(wptr!, language: language);
|
currentWallet!.setSeedLanguage(language: language);
|
||||||
final status = monero.Wallet_status(wptr!);
|
final status = currentWallet!.status();
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
final err = monero.Wallet_errorString(wptr!);
|
final err = currentWallet!.errorString();
|
||||||
if (legacy.isNotEmpty) {
|
if (legacy.isNotEmpty) {
|
||||||
return "$err\n\n$legacy";
|
return "$err\n\n$legacy";
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
legacy = monero.Wallet_seed(wptr!, seedOffset: cakepassphrase);
|
legacy = currentWallet!.seed(seedOffset: cakepassphrase);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (monero.Wallet_status(wptr!) != 0) {
|
if (currentWallet!.status() != 0) {
|
||||||
final err = monero.Wallet_errorString(wptr!);
|
final err = currentWallet!.errorString();
|
||||||
if (legacy.isNotEmpty) {
|
if (legacy.isNotEmpty) {
|
||||||
return "$err\n\n$legacy";
|
return "$err\n\n$legacy";
|
||||||
}
|
}
|
||||||
|
@ -117,7 +116,7 @@ String getSeedLegacy(String? language) {
|
||||||
}
|
}
|
||||||
|
|
||||||
String getPassphrase() {
|
String getPassphrase() {
|
||||||
return monero.Wallet_getCacheAttribute(wptr!, key: "cakewallet.passphrase");
|
return currentWallet!.getCacheAttribute(key: "cakewallet.passphrase");
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<int, Map<int, Map<int, String>>> addressCache = {};
|
Map<int, Map<int, Map<int, String>>> addressCache = {};
|
||||||
|
@ -125,31 +124,31 @@ Map<int, Map<int, Map<int, String>>> addressCache = {};
|
||||||
String getAddress({int accountIndex = 0, int addressIndex = 0}) {
|
String getAddress({int accountIndex = 0, int addressIndex = 0}) {
|
||||||
// printV("getaddress: ${accountIndex}/${addressIndex}: ${monero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex)}: ${monero.Wallet_address(wptr!, accountIndex: accountIndex, addressIndex: addressIndex)}");
|
// printV("getaddress: ${accountIndex}/${addressIndex}: ${monero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex)}: ${monero.Wallet_address(wptr!, accountIndex: accountIndex, addressIndex: addressIndex)}");
|
||||||
// this could be a while loop, but I'm in favor of making it if to not cause freezes
|
// this could be a while loop, but I'm in favor of making it if to not cause freezes
|
||||||
if (monero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex)-1 < addressIndex) {
|
if (currentWallet!.numSubaddresses(accountIndex: accountIndex)-1 < addressIndex) {
|
||||||
if (monero.Wallet_numSubaddressAccounts(wptr!) < accountIndex) {
|
if (currentWallet!.numSubaddressAccounts() < accountIndex) {
|
||||||
monero.Wallet_addSubaddressAccount(wptr!);
|
currentWallet!.addSubaddressAccount();
|
||||||
} else {
|
} else {
|
||||||
monero.Wallet_addSubaddress(wptr!, accountIndex: accountIndex);
|
currentWallet!.addSubaddress(accountIndex: accountIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addressCache[wptr!.address] ??= {};
|
addressCache[currentWallet!.ffiAddress()] ??= {};
|
||||||
addressCache[wptr!.address]![accountIndex] ??= {};
|
addressCache[currentWallet!.ffiAddress()]![accountIndex] ??= {};
|
||||||
addressCache[wptr!.address]![accountIndex]![addressIndex] ??= monero.Wallet_address(wptr!,
|
addressCache[currentWallet!.ffiAddress()]![accountIndex]![addressIndex] ??= currentWallet!.address(
|
||||||
accountIndex: accountIndex, addressIndex: addressIndex);
|
accountIndex: accountIndex, addressIndex: addressIndex);
|
||||||
return addressCache[wptr!.address]![accountIndex]![addressIndex]!;
|
return addressCache[currentWallet!.ffiAddress()]![accountIndex]![addressIndex]!;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getFullBalance({int accountIndex = 0}) =>
|
int getFullBalance({int accountIndex = 0}) =>
|
||||||
monero.Wallet_balance(wptr!, accountIndex: accountIndex);
|
currentWallet!.balance(accountIndex: accountIndex);
|
||||||
|
|
||||||
int getUnlockedBalance({int accountIndex = 0}) =>
|
int getUnlockedBalance({int accountIndex = 0}) =>
|
||||||
monero.Wallet_unlockedBalance(wptr!, accountIndex: accountIndex);
|
currentWallet!.unlockedBalance(accountIndex: accountIndex);
|
||||||
|
|
||||||
int getCurrentHeight() => monero.Wallet_blockChainHeight(wptr!);
|
int getCurrentHeight() => currentWallet!.blockChainHeight();
|
||||||
|
|
||||||
int getNodeHeightSync() => monero.Wallet_daemonBlockChainHeight(wptr!);
|
int getNodeHeightSync() => currentWallet!.daemonBlockChainHeight();
|
||||||
|
|
||||||
bool isConnectedSync() => monero.Wallet_connected(wptr!) != 0;
|
bool isConnectedSync() => currentWallet!.connected() != 0;
|
||||||
|
|
||||||
Future<bool> setupNodeSync(
|
Future<bool> setupNodeSync(
|
||||||
{required String address,
|
{required String address,
|
||||||
|
@ -168,7 +167,7 @@ Future<bool> setupNodeSync(
|
||||||
daemonPassword: $password ?? ''
|
daemonPassword: $password ?? ''
|
||||||
}
|
}
|
||||||
''');
|
''');
|
||||||
final addr = wptr!.address;
|
final addr = currentWallet!.ffiAddress();
|
||||||
printV("init: start");
|
printV("init: start");
|
||||||
await Isolate.run(() {
|
await Isolate.run(() {
|
||||||
monero.Wallet_init(Pointer.fromAddress(addr),
|
monero.Wallet_init(Pointer.fromAddress(addr),
|
||||||
|
@ -180,10 +179,10 @@ Future<bool> setupNodeSync(
|
||||||
});
|
});
|
||||||
printV("init: end");
|
printV("init: end");
|
||||||
|
|
||||||
final status = monero.Wallet_status(wptr!);
|
final status = currentWallet!.status();
|
||||||
|
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
final error = monero.Wallet_errorString(wptr!);
|
final error = currentWallet!.errorString();
|
||||||
if (error != "no tx keys found for this txid") {
|
if (error != "no tx keys found for this txid") {
|
||||||
printV("error: $error");
|
printV("error: $error");
|
||||||
throw SetupWalletException(message: error);
|
throw SetupWalletException(message: error);
|
||||||
|
@ -191,8 +190,8 @@ Future<bool> setupNodeSync(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
monero.Wallet_init3(
|
currentWallet!.init3(
|
||||||
wptr!, argv0: '',
|
argv0: '',
|
||||||
defaultLogBaseName: 'moneroc',
|
defaultLogBaseName: 'moneroc',
|
||||||
console: true,
|
console: true,
|
||||||
logPath: '',
|
logPath: '',
|
||||||
|
@ -203,19 +202,19 @@ Future<bool> setupNodeSync(
|
||||||
}
|
}
|
||||||
|
|
||||||
void startRefreshSync() {
|
void startRefreshSync() {
|
||||||
monero.Wallet_refreshAsync(wptr!);
|
currentWallet!.refreshAsync();
|
||||||
monero.Wallet_startRefresh(wptr!);
|
currentWallet!.startRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void setRefreshFromBlockHeight({required int height}) {
|
void setRefreshFromBlockHeight({required int height}) {
|
||||||
monero.Wallet_setRefreshFromBlockHeight(wptr!,
|
currentWallet!.setRefreshFromBlockHeight(
|
||||||
refresh_from_block_height: height);
|
refresh_from_block_height: height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setRecoveringFromSeed({required bool isRecovery}) {
|
void setRecoveringFromSeed({required bool isRecovery}) {
|
||||||
monero.Wallet_setRecoveringFromSeed(wptr!, recoveringFromSeed: isRecovery);
|
currentWallet!.setRecoveringFromSeed(recoveringFromSeed: isRecovery);
|
||||||
monero.Wallet_store(wptr!);
|
currentWallet!.store();
|
||||||
}
|
}
|
||||||
|
|
||||||
final storeMutex = Mutex();
|
final storeMutex = Mutex();
|
||||||
|
@ -224,18 +223,18 @@ final storeMutex = Mutex();
|
||||||
int lastStorePointer = 0;
|
int lastStorePointer = 0;
|
||||||
int lastStoreHeight = 0;
|
int lastStoreHeight = 0;
|
||||||
void storeSync({bool force = false}) async {
|
void storeSync({bool force = false}) async {
|
||||||
final addr = wptr!.address;
|
final addr = currentWallet!.ffiAddress();
|
||||||
final synchronized = await Isolate.run(() {
|
final synchronized = await Isolate.run(() {
|
||||||
return monero.Wallet_synchronized(Pointer.fromAddress(addr));
|
return monero.Wallet_synchronized(Pointer.fromAddress(addr));
|
||||||
});
|
});
|
||||||
if (lastStorePointer == wptr!.address &&
|
if (lastStorePointer == addr &&
|
||||||
lastStoreHeight + 5000 > monero.Wallet_blockChainHeight(wptr!) &&
|
lastStoreHeight + 5000 > currentWallet!.blockChainHeight() &&
|
||||||
!synchronized &&
|
!synchronized &&
|
||||||
!force) {
|
!force) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lastStorePointer = wptr!.address;
|
lastStorePointer = currentWallet!.ffiAddress();
|
||||||
lastStoreHeight = monero.Wallet_blockChainHeight(wptr!);
|
lastStoreHeight = currentWallet!.blockChainHeight();
|
||||||
await storeMutex.acquire();
|
await storeMutex.acquire();
|
||||||
await Isolate.run(() {
|
await Isolate.run(() {
|
||||||
monero.Wallet_store(Pointer.fromAddress(addr));
|
monero.Wallet_store(Pointer.fromAddress(addr));
|
||||||
|
@ -244,25 +243,25 @@ void storeSync({bool force = false}) async {
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPasswordSync(String password) {
|
void setPasswordSync(String password) {
|
||||||
monero.Wallet_setPassword(wptr!, password: password);
|
currentWallet!.setPassword(password: password);
|
||||||
|
|
||||||
final status = monero.Wallet_status(wptr!);
|
final status = currentWallet!.status();
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
throw Exception(monero.Wallet_errorString(wptr!));
|
throw Exception(currentWallet!.errorString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void closeCurrentWallet() {
|
void closeCurrentWallet() {
|
||||||
monero.Wallet_stop(wptr!);
|
currentWallet!.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
String getSecretViewKey() => monero.Wallet_secretViewKey(wptr!);
|
String getSecretViewKey() => currentWallet!.secretViewKey();
|
||||||
|
|
||||||
String getPublicViewKey() => monero.Wallet_publicViewKey(wptr!);
|
String getPublicViewKey() => currentWallet!.publicViewKey();
|
||||||
|
|
||||||
String getSecretSpendKey() => monero.Wallet_secretSpendKey(wptr!);
|
String getSecretSpendKey() => currentWallet!.secretSpendKey();
|
||||||
|
|
||||||
String getPublicSpendKey() => monero.Wallet_publicSpendKey(wptr!);
|
String getPublicSpendKey() => currentWallet!.publicSpendKey();
|
||||||
|
|
||||||
class SyncListener {
|
class SyncListener {
|
||||||
SyncListener(this.onNewBlock, this.onNewTransaction)
|
SyncListener(this.onNewBlock, this.onNewTransaction)
|
||||||
|
@ -360,52 +359,32 @@ Future<bool> _setupNodeSync(Map<String, Object?> args) async {
|
||||||
socksProxyAddress: socksProxyAddress);
|
socksProxyAddress: socksProxyAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _isConnected(Object _) => isConnectedSync();
|
|
||||||
|
|
||||||
int _getNodeHeight(Object _) => getNodeHeightSync();
|
|
||||||
|
|
||||||
void startRefresh() => startRefreshSync();
|
void startRefresh() => startRefreshSync();
|
||||||
|
|
||||||
Future<void> setupNode(
|
|
||||||
{required String address,
|
|
||||||
String? login,
|
|
||||||
String? password,
|
|
||||||
bool useSSL = false,
|
|
||||||
String? socksProxyAddress,
|
|
||||||
bool isLightWallet = false}) async =>
|
|
||||||
_setupNodeSync({
|
|
||||||
'address': address,
|
|
||||||
'login': login,
|
|
||||||
'password': password,
|
|
||||||
'useSSL': useSSL,
|
|
||||||
'isLightWallet': isLightWallet,
|
|
||||||
'socksProxyAddress': socksProxyAddress
|
|
||||||
});
|
|
||||||
|
|
||||||
Future<void> store() async => _storeSync(0);
|
Future<void> store() async => _storeSync(0);
|
||||||
|
|
||||||
Future<bool> isConnected() async => _isConnected(0);
|
Future<bool> isConnected() async => isConnectedSync();
|
||||||
|
|
||||||
Future<int> getNodeHeight() async => _getNodeHeight(0);
|
Future<int> getNodeHeight() async => getNodeHeightSync();
|
||||||
|
|
||||||
void rescanBlockchainAsync() => monero.Wallet_rescanBlockchainAsync(wptr!);
|
void rescanBlockchainAsync() => currentWallet!.rescanBlockchainAsync();
|
||||||
|
|
||||||
String getSubaddressLabel(int accountIndex, int addressIndex) {
|
String getSubaddressLabel(int accountIndex, int addressIndex) {
|
||||||
return monero.Wallet_getSubaddressLabel(wptr!,
|
return currentWallet!.getSubaddressLabel(
|
||||||
accountIndex: accountIndex, addressIndex: addressIndex);
|
accountIndex: accountIndex, addressIndex: addressIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future setTrustedDaemon(bool trusted) async =>
|
Future setTrustedDaemon(bool trusted) async =>
|
||||||
monero.Wallet_setTrustedDaemon(wptr!, arg: trusted);
|
currentWallet!.setTrustedDaemon(arg: trusted);
|
||||||
|
|
||||||
Future<bool> trustedDaemon() async => monero.Wallet_trustedDaemon(wptr!);
|
Future<bool> trustedDaemon() async => currentWallet!.trustedDaemon();
|
||||||
|
|
||||||
String signMessage(String message, {String address = ""}) {
|
String signMessage(String message, {String address = ""}) {
|
||||||
return monero.Wallet_signMessage(wptr!, message: message, address: address);
|
return currentWallet!.signMessage(message: message, address: address);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool verifyMessage(String message, String address, String signature) {
|
bool verifyMessage(String message, String address, String signature) {
|
||||||
return monero.Wallet_verifySignedMessage(wptr!, message: message, address: address, signature: signature);
|
return currentWallet!.verifySignedMessage(message: message, address: address, signature: signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, List<int>> debugCallLength() => monero.debugCallLength;
|
Map<String, List<int>> debugCallLength() => monero.debugCallLength;
|
||||||
|
|
|
@ -12,6 +12,8 @@ import 'package:cw_monero/api/transaction_history.dart';
|
||||||
import 'package:cw_monero/api/wallet.dart';
|
import 'package:cw_monero/api/wallet.dart';
|
||||||
import 'package:cw_monero/ledger.dart';
|
import 'package:cw_monero/ledger.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:monero/src/monero.dart';
|
||||||
|
import 'package:monero/src/wallet2.dart';
|
||||||
import 'package:monero/monero.dart' as monero;
|
import 'package:monero/monero.dart' as monero;
|
||||||
|
|
||||||
class MoneroCException implements Exception {
|
class MoneroCException implements Exception {
|
||||||
|
@ -24,9 +26,10 @@ class MoneroCException implements Exception {
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkIfMoneroCIsFine() {
|
void checkIfMoneroCIsFine() {
|
||||||
final cppCsCpp = monero.MONERO_checksum_wallet2_api_c_cpp();
|
final checksum = MoneroWalletChecksum();
|
||||||
final cppCsH = monero.MONERO_checksum_wallet2_api_c_h();
|
final cppCsCpp = checksum.checksum_wallet2_api_c_cpp();
|
||||||
final cppCsExp = monero.MONERO_checksum_wallet2_api_c_exp();
|
final cppCsH = checksum.checksum_wallet2_api_c_h();
|
||||||
|
final cppCsExp = checksum.checksum_wallet2_api_c_exp();
|
||||||
|
|
||||||
final dartCsCpp = monero.wallet2_api_c_cpp_sha256;
|
final dartCsCpp = monero.wallet2_api_c_cpp_sha256;
|
||||||
final dartCsH = monero.wallet2_api_c_h_sha256;
|
final dartCsH = monero.wallet2_api_c_h_sha256;
|
||||||
|
@ -44,36 +47,35 @@ void checkIfMoneroCIsFine() {
|
||||||
throw MoneroCException("monero_c and monero.dart wrapper export list mismatch.\nLogic errors can occur.\nRefusing to run in release mode.\ncpp: '$cppCsExp'\ndart: '$dartCsExp'");
|
throw MoneroCException("monero_c and monero.dart wrapper export list mismatch.\nLogic errors can occur.\nRefusing to run in release mode.\ncpp: '$cppCsExp'\ndart: '$dartCsExp'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
monero.WalletManager? _wmPtr;
|
Wallet2WalletManager? _wmPtr;
|
||||||
final monero.WalletManager wmPtr = Pointer.fromAddress((() {
|
Wallet2WalletManager wmPtr = (() {
|
||||||
try {
|
try {
|
||||||
// Problems with the wallet? Crashes? Lags? this will print all calls to xmr
|
// Problems with the wallet? Crashes? Lags? this will print all calls to xmr
|
||||||
// codebase, so it will be easier to debug what happens. At least easier
|
// codebase, so it will be easier to debug what happens. At least easier
|
||||||
// than plugging gdb in. Especially on windows/android.
|
// than plugging gdb in. Especially on windows/android.
|
||||||
monero.printStarts = false;
|
monero.printStarts = false;
|
||||||
if (kDebugMode && debugMonero) {
|
if (kDebugMode && debugMonero) {
|
||||||
monero.WalletManagerFactory_setLogLevel(4);
|
MoneroWalletManagerFactory().setLogLevel(4);
|
||||||
}
|
}
|
||||||
_wmPtr ??= monero.WalletManagerFactory_getWalletManager();
|
_wmPtr ??= MoneroWalletManagerFactory().getWalletManager();
|
||||||
if (kDebugMode && debugMonero) {
|
if (kDebugMode && debugMonero) {
|
||||||
monero.WalletManagerFactory_setLogLevel(4);
|
MoneroWalletManagerFactory().setLogLevel(4);
|
||||||
}
|
}
|
||||||
printV("ptr: $_wmPtr");
|
printV("ptr: $_wmPtr");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
printV(e);
|
printV(e);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
return _wmPtr!.address;
|
return _wmPtr!;
|
||||||
})());
|
})();
|
||||||
|
|
||||||
void createWalletPointer() {
|
Wallet2Wallet createWalletPointer() {
|
||||||
final newWptr = monero.WalletManager_createWallet(wmPtr,
|
final newWptr = wmPtr.createWallet(
|
||||||
path: "", password: "", language: "", networkType: 0);
|
path: "", password: "", language: "", networkType: 0);
|
||||||
|
return newWptr;
|
||||||
wptr = newWptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void createWalletSync(
|
void createWallet(
|
||||||
{required String path,
|
{required String path,
|
||||||
required String password,
|
required String password,
|
||||||
required String language,
|
required String language,
|
||||||
|
@ -81,28 +83,25 @@ void createWalletSync(
|
||||||
int nettype = 0}) {
|
int nettype = 0}) {
|
||||||
txhistory = null;
|
txhistory = null;
|
||||||
language = getSeedLanguage(language)!;
|
language = getSeedLanguage(language)!;
|
||||||
final newWptr = monero.WalletManager_createWallet(wmPtr,
|
final newW = wmPtr.createWallet(
|
||||||
path: path, password: password, language: language, networkType: 0);
|
path: path, password: password, language: language, networkType: 0);
|
||||||
|
|
||||||
int status = monero.Wallet_status(newWptr);
|
int status = newW.status();
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
throw WalletCreationException(message: monero.Wallet_errorString(newWptr));
|
throw WalletCreationException(message: newW.errorString());
|
||||||
}
|
}
|
||||||
|
|
||||||
setupBackgroundSync(password, newWptr);
|
setupBackgroundSync(password, newW);
|
||||||
|
|
||||||
wptr = newWptr;
|
currentWallet = newW;
|
||||||
monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.passphrase", value: passphrase);
|
currentWallet!.setCacheAttribute(key: "cakewallet.passphrase", value: passphrase);
|
||||||
monero.Wallet_store(wptr!, path: path);
|
currentWallet!.store(path: path);
|
||||||
openedWalletsByPath[path] = wptr!;
|
openedWalletsByPath[path] = currentWallet!;
|
||||||
_lastOpenedWallet = path;
|
_lastOpenedWallet = path;
|
||||||
|
|
||||||
// is the line below needed?
|
|
||||||
// setupNodeSync(address: "node.moneroworld.com:18089");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isWalletExistSync({required String path}) {
|
bool isWalletExist({required String path}) {
|
||||||
return monero.WalletManager_walletExists(wmPtr, path);
|
return wmPtr.walletExists(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void restoreWalletFromSeedSync(
|
void restoreWalletFromSeedSync(
|
||||||
|
@ -113,8 +112,7 @@ void restoreWalletFromSeedSync(
|
||||||
int nettype = 0,
|
int nettype = 0,
|
||||||
int restoreHeight = 0}) {
|
int restoreHeight = 0}) {
|
||||||
txhistory = null;
|
txhistory = null;
|
||||||
final newWptr = monero.WalletManager_recoveryWallet(
|
final newW = wmPtr.recoveryWallet(
|
||||||
wmPtr,
|
|
||||||
path: path,
|
path: path,
|
||||||
password: password,
|
password: password,
|
||||||
mnemonic: seed,
|
mnemonic: seed,
|
||||||
|
@ -123,10 +121,10 @@ void restoreWalletFromSeedSync(
|
||||||
networkType: 0,
|
networkType: 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
final status = monero.Wallet_status(newWptr);
|
final status = newW.status();
|
||||||
|
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
final error = monero.Wallet_errorString(newWptr);
|
final error = newW.errorString();
|
||||||
if (error.contains('word list failed verification')) {
|
if (error.contains('word list failed verification')) {
|
||||||
throw WalletRestoreFromSeedException(
|
throw WalletRestoreFromSeedException(
|
||||||
message: "Seed verification failed, please make sure you entered the correct seed with the correct words order",
|
message: "Seed verification failed, please make sure you entered the correct seed with the correct words order",
|
||||||
|
@ -134,20 +132,20 @@ void restoreWalletFromSeedSync(
|
||||||
}
|
}
|
||||||
throw WalletRestoreFromSeedException(message: error);
|
throw WalletRestoreFromSeedException(message: error);
|
||||||
}
|
}
|
||||||
wptr = newWptr;
|
currentWallet = newW;
|
||||||
|
|
||||||
setRefreshFromBlockHeight(height: restoreHeight);
|
setRefreshFromBlockHeight(height: restoreHeight);
|
||||||
setupBackgroundSync(password, newWptr);
|
setupBackgroundSync(password, newW);
|
||||||
|
|
||||||
monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.passphrase", value: passphrase);
|
currentWallet!.setCacheAttribute(key: "cakewallet.passphrase", value: passphrase);
|
||||||
|
|
||||||
openedWalletsByPath[path] = wptr!;
|
openedWalletsByPath[path] = currentWallet!;
|
||||||
|
|
||||||
monero.Wallet_store(wptr!);
|
currentWallet!.store(path: path);
|
||||||
_lastOpenedWallet = path;
|
_lastOpenedWallet = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
void restoreWalletFromKeysSync(
|
void restoreWalletFromKeys(
|
||||||
{required String path,
|
{required String path,
|
||||||
required String password,
|
required String password,
|
||||||
required String language,
|
required String language,
|
||||||
|
@ -157,8 +155,8 @@ void restoreWalletFromKeysSync(
|
||||||
int nettype = 0,
|
int nettype = 0,
|
||||||
int restoreHeight = 0}) {
|
int restoreHeight = 0}) {
|
||||||
txhistory = null;
|
txhistory = null;
|
||||||
var newWptr = (spendKey != "")
|
var newW = (spendKey != "")
|
||||||
? monero.WalletManager_createDeterministicWalletFromSpendKey(wmPtr,
|
? wmPtr.createDeterministicWalletFromSpendKey(
|
||||||
path: path,
|
path: path,
|
||||||
password: password,
|
password: password,
|
||||||
language: language,
|
language: language,
|
||||||
|
@ -166,8 +164,7 @@ void restoreWalletFromKeysSync(
|
||||||
newWallet: true,
|
newWallet: true,
|
||||||
// TODO(mrcyjanek): safe to remove
|
// TODO(mrcyjanek): safe to remove
|
||||||
restoreHeight: restoreHeight)
|
restoreHeight: restoreHeight)
|
||||||
: monero.WalletManager_createWalletFromKeys(
|
: wmPtr.createWalletFromKeys(
|
||||||
wmPtr,
|
|
||||||
path: path,
|
path: path,
|
||||||
password: password,
|
password: password,
|
||||||
restoreHeight: restoreHeight,
|
restoreHeight: restoreHeight,
|
||||||
|
@ -177,22 +174,21 @@ void restoreWalletFromKeysSync(
|
||||||
nettype: 0,
|
nettype: 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
int status = monero.Wallet_status(newWptr);
|
int status = newW.status();
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
throw WalletRestoreFromKeysException(
|
throw WalletRestoreFromKeysException(
|
||||||
message: monero.Wallet_errorString(newWptr));
|
message: newW.errorString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// CW-712 - Try to restore deterministic wallet first, if the view key doesn't
|
// CW-712 - Try to restore deterministic wallet first, if the view key doesn't
|
||||||
// match the view key provided
|
// match the view key provided
|
||||||
if (spendKey != "") {
|
if (spendKey != "") {
|
||||||
final viewKeyRestored = monero.Wallet_secretViewKey(newWptr);
|
final viewKeyRestored = newW.secretViewKey();
|
||||||
if (viewKey != viewKeyRestored && viewKey != "") {
|
if (viewKey != viewKeyRestored && viewKey != "") {
|
||||||
monero.WalletManager_closeWallet(wmPtr, newWptr, false);
|
wmPtr.closeWallet(newW, false);
|
||||||
File(path).deleteSync();
|
File(path).deleteSync();
|
||||||
File(path + ".keys").deleteSync();
|
File(path + ".keys").deleteSync();
|
||||||
newWptr = monero.WalletManager_createWalletFromKeys(
|
newW = wmPtr.createWalletFromKeys(
|
||||||
wmPtr,
|
|
||||||
path: path,
|
path: path,
|
||||||
password: password,
|
password: password,
|
||||||
restoreHeight: restoreHeight,
|
restoreHeight: restoreHeight,
|
||||||
|
@ -201,19 +197,19 @@ void restoreWalletFromKeysSync(
|
||||||
spendKeyString: spendKey,
|
spendKeyString: spendKey,
|
||||||
nettype: 0,
|
nettype: 0,
|
||||||
);
|
);
|
||||||
int status = monero.Wallet_status(newWptr);
|
int status = newW.status();
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
throw WalletRestoreFromKeysException(
|
throw WalletRestoreFromKeysException(
|
||||||
message: monero.Wallet_errorString(newWptr));
|
message: newW.errorString());
|
||||||
}
|
}
|
||||||
|
|
||||||
setupBackgroundSync(password, newWptr);
|
setupBackgroundSync(password, newW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wptr = newWptr;
|
currentWallet = newW;
|
||||||
|
|
||||||
openedWalletsByPath[path] = wptr!;
|
openedWalletsByPath[path] = currentWallet!;
|
||||||
_lastOpenedWallet = path;
|
_lastOpenedWallet = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,8 +224,7 @@ void restoreWalletFromPolyseedWithOffset(
|
||||||
int nettype = 0}) {
|
int nettype = 0}) {
|
||||||
|
|
||||||
txhistory = null;
|
txhistory = null;
|
||||||
final newWptr = monero.WalletManager_createWalletFromPolyseed(
|
final newW = wmPtr.createWalletFromPolyseed(
|
||||||
wmPtr,
|
|
||||||
path: path,
|
path: path,
|
||||||
password: password,
|
password: password,
|
||||||
networkType: nettype,
|
networkType: nettype,
|
||||||
|
@ -240,24 +235,24 @@ void restoreWalletFromPolyseedWithOffset(
|
||||||
kdfRounds: 1,
|
kdfRounds: 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
int status = monero.Wallet_status(newWptr);
|
int status = newW.status();
|
||||||
|
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
final err = monero.Wallet_errorString(newWptr);
|
final err = newW.errorString();
|
||||||
printV("err: $err");
|
printV("err: $err");
|
||||||
throw WalletRestoreFromKeysException(message: err);
|
throw WalletRestoreFromKeysException(message: err);
|
||||||
}
|
}
|
||||||
|
|
||||||
wptr = newWptr;
|
currentWallet = newW;
|
||||||
|
|
||||||
monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed);
|
currentWallet!.setCacheAttribute(key: "cakewallet.seed", value: seed);
|
||||||
monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.passphrase", value: seedOffset);
|
currentWallet!.setCacheAttribute(key: "cakewallet.passphrase", value: seedOffset);
|
||||||
monero.Wallet_store(wptr!);
|
currentWallet!.store(path: path);
|
||||||
|
|
||||||
setupBackgroundSync(password, newWptr);
|
setupBackgroundSync(password, currentWallet!);
|
||||||
storeSync();
|
storeSync();
|
||||||
|
|
||||||
openedWalletsByPath[path] = wptr!;
|
openedWalletsByPath[path] = currentWallet!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -282,8 +277,7 @@ void restoreWalletFromSpendKeySync(
|
||||||
// );
|
// );
|
||||||
|
|
||||||
txhistory = null;
|
txhistory = null;
|
||||||
final newWptr = monero.WalletManager_createDeterministicWalletFromSpendKey(
|
final newW = wmPtr.createDeterministicWalletFromSpendKey(
|
||||||
wmPtr,
|
|
||||||
path: path,
|
path: path,
|
||||||
password: password,
|
password: password,
|
||||||
language: language,
|
language: language,
|
||||||
|
@ -292,23 +286,23 @@ void restoreWalletFromSpendKeySync(
|
||||||
restoreHeight: restoreHeight,
|
restoreHeight: restoreHeight,
|
||||||
);
|
);
|
||||||
|
|
||||||
int status = monero.Wallet_status(newWptr);
|
int status = newW.status();
|
||||||
|
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
final err = monero.Wallet_errorString(newWptr);
|
final err = newW.errorString();
|
||||||
printV("err: $err");
|
printV("err: $err");
|
||||||
throw WalletRestoreFromKeysException(message: err);
|
throw WalletRestoreFromKeysException(message: err);
|
||||||
}
|
}
|
||||||
|
|
||||||
wptr = newWptr;
|
currentWallet = newW;
|
||||||
|
|
||||||
monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed);
|
currentWallet!.setCacheAttribute(key: "cakewallet.seed", value: seed);
|
||||||
|
|
||||||
storeSync();
|
storeSync();
|
||||||
|
|
||||||
setupBackgroundSync(password, newWptr);
|
setupBackgroundSync(password, currentWallet!);
|
||||||
|
|
||||||
openedWalletsByPath[path] = wptr!;
|
openedWalletsByPath[path] = currentWallet!;
|
||||||
_lastOpenedWallet = path;
|
_lastOpenedWallet = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,41 +315,42 @@ Future<void> restoreWalletFromHardwareWallet(
|
||||||
int nettype = 0,
|
int nettype = 0,
|
||||||
int restoreHeight = 0}) async {
|
int restoreHeight = 0}) async {
|
||||||
txhistory = null;
|
txhistory = null;
|
||||||
|
final wmPtr = MoneroWalletManagerFactory().getWalletManager().ffiAddress();
|
||||||
final newWptrAddr = await Isolate.run(() {
|
final newWptrAddr = await Isolate.run(() {
|
||||||
return monero.WalletManager_createWalletFromDevice(wmPtr,
|
return monero.WalletManager_createWalletFromDevice(Pointer.fromAddress(wmPtr),
|
||||||
path: path,
|
path: path,
|
||||||
password: password,
|
password: password,
|
||||||
restoreHeight: restoreHeight,
|
restoreHeight: restoreHeight,
|
||||||
deviceName: deviceName)
|
deviceName: deviceName)
|
||||||
.address;
|
.address;
|
||||||
});
|
});
|
||||||
final newWptr = Pointer<Void>.fromAddress(newWptrAddr);
|
final newW = MoneroWallet(Pointer.fromAddress(newWptrAddr));
|
||||||
|
|
||||||
final status = monero.Wallet_status(newWptr);
|
final status = newW.status();
|
||||||
|
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
final error = monero.Wallet_errorString(newWptr);
|
final error = newW.errorString();
|
||||||
throw WalletRestoreFromSeedException(message: error);
|
throw WalletRestoreFromSeedException(message: error);
|
||||||
}
|
}
|
||||||
|
|
||||||
wptr = newWptr;
|
currentWallet = newW;
|
||||||
|
currentWallet!.store(path: path);
|
||||||
_lastOpenedWallet = path;
|
_lastOpenedWallet = path;
|
||||||
openedWalletsByPath[path] = wptr!;
|
openedWalletsByPath[path] = currentWallet!;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, monero.wallet> openedWalletsByPath = {};
|
Map<String, Wallet2Wallet> openedWalletsByPath = {};
|
||||||
|
|
||||||
Future<void> loadWallet(
|
Future<void> loadWallet(
|
||||||
{required String path, required String password, int nettype = 0}) async {
|
{required String path, required String password, int nettype = 0}) async {
|
||||||
if (openedWalletsByPath[path] != null) {
|
if (openedWalletsByPath[path] != null) {
|
||||||
txhistory = null;
|
txhistory = null;
|
||||||
wptr = openedWalletsByPath[path]!;
|
currentWallet = openedWalletsByPath[path]!;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (wptr == null || path != _lastOpenedWallet) {
|
if (currentWallet == null || path != _lastOpenedWallet) {
|
||||||
if (wptr != null) {
|
if (currentWallet != null) {
|
||||||
final addr = wptr!.address;
|
final addr = currentWallet!.ffiAddress();
|
||||||
Isolate.run(() {
|
Isolate.run(() {
|
||||||
monero.Wallet_store(Pointer.fromAddress(addr));
|
monero.Wallet_store(Pointer.fromAddress(addr));
|
||||||
});
|
});
|
||||||
|
@ -366,20 +361,25 @@ Future<void> loadWallet(
|
||||||
/// 0: Software Wallet
|
/// 0: Software Wallet
|
||||||
/// 1: Ledger
|
/// 1: Ledger
|
||||||
/// 2: Trezor
|
/// 2: Trezor
|
||||||
late final deviceType;
|
var deviceType = 0;
|
||||||
|
|
||||||
if (Platform.isAndroid || Platform.isIOS) {
|
if (Platform.isAndroid || Platform.isIOS) {
|
||||||
deviceType = monero.WalletManager_queryWalletDevice(
|
deviceType = wmPtr.queryWalletDevice(
|
||||||
wmPtr,
|
|
||||||
keysFileName: "$path.keys",
|
keysFileName: "$path.keys",
|
||||||
password: password,
|
password: password,
|
||||||
kdfRounds: 1,
|
kdfRounds: 1,
|
||||||
);
|
);
|
||||||
final status = monero.WalletManager_errorString(wmPtr);
|
final status = wmPtr.errorString();
|
||||||
if (status != "") {
|
if (status != "") {
|
||||||
printV("loadWallet:"+status);
|
printV("loadWallet:"+status);
|
||||||
|
// This is most likely closeWallet call leaking error. This is fine.
|
||||||
|
if (status.contains("failed to save file")) {
|
||||||
|
printV("loadWallet: error leaked: $status");
|
||||||
|
deviceType = 0;
|
||||||
|
} else {
|
||||||
throw WalletOpeningException(message: status);
|
throw WalletOpeningException(message: status);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
deviceType = 0;
|
deviceType = 0;
|
||||||
}
|
}
|
||||||
|
@ -388,107 +388,47 @@ Future<void> loadWallet(
|
||||||
if (gLedger == null) {
|
if (gLedger == null) {
|
||||||
throw Exception("Tried to open a ledger wallet with no ledger connected");
|
throw Exception("Tried to open a ledger wallet with no ledger connected");
|
||||||
}
|
}
|
||||||
final dummyWPtr = wptr ??
|
final dummyWPtr = (currentWallet ??
|
||||||
monero.WalletManager_openWallet(wmPtr, path: '', password: '');
|
wmPtr.openWallet(path: '', password: ''));
|
||||||
enableLedgerExchange(dummyWPtr, gLedger!);
|
enableLedgerExchange(dummyWPtr, gLedger!);
|
||||||
}
|
}
|
||||||
|
|
||||||
final addr = wmPtr.address;
|
final addr = wmPtr.ffiAddress();
|
||||||
final newWptrAddr = await Isolate.run(() {
|
final newWptrAddr = await Isolate.run(() {
|
||||||
return monero.WalletManager_openWallet(Pointer.fromAddress(addr),
|
return monero.WalletManager_openWallet(Pointer.fromAddress(addr),
|
||||||
path: path, password: password)
|
path: path, password: password)
|
||||||
.address;
|
.address;
|
||||||
});
|
});
|
||||||
|
|
||||||
final newWptr = Pointer<Void>.fromAddress(newWptrAddr);
|
final newW = MoneroWallet(Pointer.fromAddress(newWptrAddr));
|
||||||
|
|
||||||
int status = monero.Wallet_status(newWptr);
|
int status = newW.status();
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
final err = monero.Wallet_errorString(newWptr);
|
final err = newW.errorString();
|
||||||
printV("loadWallet:"+err);
|
printV("loadWallet:"+err);
|
||||||
throw WalletOpeningException(message: err);
|
throw WalletOpeningException(message: err);
|
||||||
}
|
}
|
||||||
if (deviceType == 0) {
|
if (deviceType == 0) {
|
||||||
setupBackgroundSync(password, newWptr);
|
setupBackgroundSync(password, newW);
|
||||||
}
|
}
|
||||||
|
|
||||||
wptr = newWptr;
|
currentWallet = newW;
|
||||||
_lastOpenedWallet = path;
|
_lastOpenedWallet = path;
|
||||||
openedWalletsByPath[path] = wptr!;
|
openedWalletsByPath[path] = currentWallet!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupBackgroundSync(String password, Pointer<Void>? wptrOverride) {
|
void setupBackgroundSync(String password, Wallet2Wallet wallet) {
|
||||||
if (isViewOnlyBySpendKey(wptrOverride)) {
|
if (isViewOnlyBySpendKey(wallet)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
monero.Wallet_setupBackgroundSync(wptrOverride ?? wptr!, backgroundSyncType: 2, walletPassword: password, backgroundCachePassword: '');
|
wallet.setupBackgroundSync(backgroundSyncType: 2, walletPassword: password, backgroundCachePassword: '');
|
||||||
if (monero.Wallet_status(wptrOverride ?? wptr!) != 0) {
|
if (wallet.status() != 0) {
|
||||||
// We simply ignore the error.
|
// We simply ignore the error.
|
||||||
printV("setupBackgroundSync: ${monero.Wallet_errorString(wptrOverride ?? wptr!)}");
|
printV("setupBackgroundSync: ${wallet.errorString()}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _createWallet(Map<String, dynamic> args) {
|
|
||||||
final path = args['path'] as String;
|
|
||||||
final password = args['password'] as String;
|
|
||||||
final language = args['language'] as String;
|
|
||||||
final passphrase = args['passphrase'] as String;
|
|
||||||
|
|
||||||
createWalletSync(path: path, password: password, language: language, passphrase: passphrase);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _restoreFromSeed(Map<String, dynamic> args) {
|
|
||||||
final path = args['path'] as String;
|
|
||||||
final password = args['password'] as String;
|
|
||||||
final passphrase = args['passphrase'] as String;
|
|
||||||
final seed = args['seed'] as String;
|
|
||||||
final restoreHeight = args['restoreHeight'] as int;
|
|
||||||
|
|
||||||
return restoreWalletFromSeedSync(
|
|
||||||
path: path, password: password, passphrase: passphrase, seed: seed, restoreHeight: restoreHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _restoreFromKeys(Map<String, dynamic> args) {
|
|
||||||
final path = args['path'] as String;
|
|
||||||
final password = args['password'] as String;
|
|
||||||
final language = args['language'] as String;
|
|
||||||
final restoreHeight = args['restoreHeight'] as int;
|
|
||||||
final address = args['address'] as String;
|
|
||||||
final viewKey = args['viewKey'] as String;
|
|
||||||
final spendKey = args['spendKey'] as String;
|
|
||||||
|
|
||||||
restoreWalletFromKeysSync(
|
|
||||||
path: path,
|
|
||||||
password: password,
|
|
||||||
language: language,
|
|
||||||
restoreHeight: restoreHeight,
|
|
||||||
address: address,
|
|
||||||
viewKey: viewKey,
|
|
||||||
spendKey: spendKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _restoreFromSpendKey(Map<String, dynamic> args) {
|
|
||||||
final path = args['path'] as String;
|
|
||||||
final password = args['password'] as String;
|
|
||||||
final seed = args['seed'] as String;
|
|
||||||
final language = args['language'] as String;
|
|
||||||
final spendKey = args['spendKey'] as String;
|
|
||||||
final restoreHeight = args['restoreHeight'] as int;
|
|
||||||
|
|
||||||
restoreWalletFromSpendKeySync(
|
|
||||||
path: path,
|
|
||||||
password: password,
|
|
||||||
seed: seed,
|
|
||||||
language: language,
|
|
||||||
restoreHeight: restoreHeight,
|
|
||||||
spendKey: spendKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _openWallet(Map<String, String> args) async => loadWallet(
|
|
||||||
path: args['path'] as String, password: args['password'] as String);
|
|
||||||
|
|
||||||
bool _isWalletExist(String path) => isWalletExistSync(path: path);
|
|
||||||
|
|
||||||
Future<void> openWallet(
|
Future<void> openWallet(
|
||||||
{required String path,
|
{required String path,
|
||||||
|
@ -496,77 +436,4 @@ Future<void> openWallet(
|
||||||
int nettype = 0}) async =>
|
int nettype = 0}) async =>
|
||||||
loadWallet(path: path, password: password, nettype: nettype);
|
loadWallet(path: path, password: password, nettype: nettype);
|
||||||
|
|
||||||
Future<void> openWalletAsync(Map<String, String> args) async =>
|
bool isViewOnlyBySpendKey(Wallet2Wallet? wallet) => int.tryParse((wallet??currentWallet!).secretSpendKey()) == 0;
|
||||||
_openWallet(args);
|
|
||||||
|
|
||||||
Future<void> createWallet(
|
|
||||||
{required String path,
|
|
||||||
required String password,
|
|
||||||
required String language,
|
|
||||||
required String passphrase,
|
|
||||||
int nettype = 0}) async =>
|
|
||||||
_createWallet({
|
|
||||||
'path': path,
|
|
||||||
'password': password,
|
|
||||||
'language': language,
|
|
||||||
'passphrase': passphrase,
|
|
||||||
'nettype': nettype
|
|
||||||
});
|
|
||||||
|
|
||||||
void restoreFromSeed(
|
|
||||||
{required String path,
|
|
||||||
required String password,
|
|
||||||
required String passphrase,
|
|
||||||
required String seed,
|
|
||||||
int nettype = 0,
|
|
||||||
int restoreHeight = 0}) =>
|
|
||||||
_restoreFromSeed({
|
|
||||||
'path': path,
|
|
||||||
'password': password,
|
|
||||||
'passphrase': passphrase,
|
|
||||||
'seed': seed,
|
|
||||||
'nettype': nettype,
|
|
||||||
'restoreHeight': restoreHeight
|
|
||||||
});
|
|
||||||
|
|
||||||
Future<void> restoreFromKeys(
|
|
||||||
{required String path,
|
|
||||||
required String password,
|
|
||||||
required String language,
|
|
||||||
required String address,
|
|
||||||
required String viewKey,
|
|
||||||
required String spendKey,
|
|
||||||
int nettype = 0,
|
|
||||||
int restoreHeight = 0}) async =>
|
|
||||||
_restoreFromKeys({
|
|
||||||
'path': path,
|
|
||||||
'password': password,
|
|
||||||
'language': language,
|
|
||||||
'address': address,
|
|
||||||
'viewKey': viewKey,
|
|
||||||
'spendKey': spendKey,
|
|
||||||
'nettype': nettype,
|
|
||||||
'restoreHeight': restoreHeight
|
|
||||||
});
|
|
||||||
|
|
||||||
Future<void> restoreFromSpendKey(
|
|
||||||
{required String path,
|
|
||||||
required String password,
|
|
||||||
required String seed,
|
|
||||||
required String language,
|
|
||||||
required String spendKey,
|
|
||||||
int nettype = 0,
|
|
||||||
int restoreHeight = 0}) async =>
|
|
||||||
_restoreFromSpendKey({
|
|
||||||
'path': path,
|
|
||||||
'password': password,
|
|
||||||
'seed': seed,
|
|
||||||
'language': language,
|
|
||||||
'spendKey': spendKey,
|
|
||||||
'nettype': nettype,
|
|
||||||
'restoreHeight': restoreHeight
|
|
||||||
});
|
|
||||||
|
|
||||||
bool isWalletExist({required String path}) => _isWalletExist(path);
|
|
||||||
|
|
||||||
bool isViewOnlyBySpendKey(Pointer<Void>? wptrOverride) => int.tryParse(monero.Wallet_secretSpendKey(wptrOverride ?? wptr!)) == 0;
|
|
||||||
|
|
|
@ -7,26 +7,26 @@ import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:ffi/ffi.dart';
|
import 'package:ffi/ffi.dart';
|
||||||
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
|
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
|
||||||
import 'package:ledger_flutter_plus/ledger_flutter_plus_dart.dart';
|
import 'package:ledger_flutter_plus/ledger_flutter_plus_dart.dart';
|
||||||
import 'package:monero/monero.dart' as monero;
|
import 'package:monero/src/wallet2.dart';
|
||||||
|
|
||||||
LedgerConnection? gLedger;
|
LedgerConnection? gLedger;
|
||||||
|
|
||||||
Timer? _ledgerExchangeTimer;
|
Timer? _ledgerExchangeTimer;
|
||||||
Timer? _ledgerKeepAlive;
|
Timer? _ledgerKeepAlive;
|
||||||
|
|
||||||
void enableLedgerExchange(monero.wallet ptr, LedgerConnection connection) {
|
void enableLedgerExchange(Wallet2Wallet wallet, LedgerConnection connection) {
|
||||||
_ledgerExchangeTimer?.cancel();
|
_ledgerExchangeTimer?.cancel();
|
||||||
_ledgerExchangeTimer = Timer.periodic(Duration(milliseconds: 1), (_) async {
|
_ledgerExchangeTimer = Timer.periodic(Duration(milliseconds: 1), (_) async {
|
||||||
final ledgerRequestLength = monero.Wallet_getSendToDeviceLength(ptr);
|
final ledgerRequestLength = wallet.getSendToDeviceLength();
|
||||||
final ledgerRequest = monero.Wallet_getSendToDevice(ptr)
|
final ledgerRequest = wallet.getSendToDevice()
|
||||||
.cast<Uint8>()
|
.cast<Uint8>()
|
||||||
.asTypedList(ledgerRequestLength);
|
.asTypedList(ledgerRequestLength);
|
||||||
if (ledgerRequestLength > 0) {
|
if (ledgerRequestLength > 0) {
|
||||||
_ledgerKeepAlive?.cancel();
|
_ledgerKeepAlive?.cancel();
|
||||||
|
|
||||||
final Pointer<Uint8> emptyPointer = malloc<Uint8>(0);
|
final Pointer<Uint8> emptyPointer = malloc<Uint8>(0);
|
||||||
monero.Wallet_setDeviceSendData(
|
wallet.setDeviceSendData(
|
||||||
ptr, emptyPointer.cast<UnsignedChar>(), 0);
|
emptyPointer.cast<UnsignedChar>(), 0);
|
||||||
malloc.free(emptyPointer);
|
malloc.free(emptyPointer);
|
||||||
|
|
||||||
_logLedgerCommand(ledgerRequest, false);
|
_logLedgerCommand(ledgerRequest, false);
|
||||||
|
@ -45,8 +45,8 @@ void enableLedgerExchange(monero.wallet ptr, LedgerConnection connection) {
|
||||||
result.asTypedList(response.length)[i] = response[i];
|
result.asTypedList(response.length)[i] = response[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
monero.Wallet_setDeviceReceivedData(
|
wallet.setDeviceReceivedData(
|
||||||
ptr, result.cast<UnsignedChar>(), response.length);
|
result.cast<UnsignedChar>(), response.length);
|
||||||
malloc.free(result);
|
malloc.free(result);
|
||||||
keepAlive(connection);
|
keepAlive(connection);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import 'package:cw_monero/api/wallet_manager.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:cw_core/account.dart';
|
import 'package:cw_core/account.dart';
|
||||||
import 'package:cw_monero/api/account_list.dart' as account_list;
|
import 'package:cw_monero/api/account_list.dart' as account_list;
|
||||||
import 'package:monero/monero.dart' as monero;
|
import 'package:monero/src/monero.dart';
|
||||||
|
|
||||||
part 'monero_account_list.g.dart';
|
part 'monero_account_list.g.dart';
|
||||||
|
|
||||||
|
@ -50,32 +50,32 @@ abstract class MoneroAccountListBase with Store {
|
||||||
List<Account> getAll() {
|
List<Account> getAll() {
|
||||||
final allAccounts = account_list.getAllAccount();
|
final allAccounts = account_list.getAllAccount();
|
||||||
final currentCount = allAccounts.length;
|
final currentCount = allAccounts.length;
|
||||||
cachedAccounts[account_list.wptr!.address] ??= [];
|
cachedAccounts[account_list.currentWallet!.ffiAddress()] ??= [];
|
||||||
|
|
||||||
if (cachedAccounts[account_list.wptr!.address]!.length == currentCount) {
|
if (cachedAccounts[account_list.currentWallet!.ffiAddress()]!.length == currentCount) {
|
||||||
return cachedAccounts[account_list.wptr!.address]!;
|
return cachedAccounts[account_list.currentWallet!.ffiAddress()]!;
|
||||||
}
|
}
|
||||||
|
|
||||||
cachedAccounts[account_list.wptr!.address] = allAccounts.map((accountRow) {
|
cachedAccounts[account_list.currentWallet!.ffiAddress()] = allAccounts.map((accountRow) {
|
||||||
final balance = monero.SubaddressAccountRow_getUnlockedBalance(accountRow);
|
final balance = accountRow.getUnlockedBalance();
|
||||||
|
|
||||||
return Account(
|
return Account(
|
||||||
id: monero.SubaddressAccountRow_getRowId(accountRow),
|
id: accountRow.getRowId(),
|
||||||
label: monero.SubaddressAccountRow_getLabel(accountRow),
|
label: accountRow.getLabel(),
|
||||||
balance: moneroAmountToString(amount: monero.Wallet_amountFromString(balance)),
|
balance: moneroAmountToString(amount: account_list.currentWallet!.amountFromString(balance)),
|
||||||
);
|
);
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
return cachedAccounts[account_list.wptr!.address]!;
|
return cachedAccounts[account_list.currentWallet!.ffiAddress()]!;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> addAccount({required String label}) async {
|
void addAccount({required String label}) {
|
||||||
await account_list.addAccount(label: label);
|
account_list.addAccount(label: label);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> setLabelAccount({required int accountIndex, required String label}) async {
|
void setLabelAccount({required int accountIndex, required String label}) {
|
||||||
await account_list.setLabelForAccount(accountIndex: accountIndex, label: label);
|
account_list.setLabelForAccount(accountIndex: accountIndex, label: label);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import 'package:cw_core/unspent_transaction_output.dart';
|
import 'package:cw_core/unspent_transaction_output.dart';
|
||||||
import 'package:cw_core/utils/print_verbose.dart';
|
import 'package:cw_core/utils/print_verbose.dart';
|
||||||
import 'package:cw_monero/api/coins_info.dart';
|
import 'package:cw_monero/api/coins_info.dart';
|
||||||
import 'package:monero/monero.dart' as monero;
|
import 'package:monero/src/monero.dart';
|
||||||
|
|
||||||
class MoneroUnspent extends Unspent {
|
class MoneroUnspent extends Unspent {
|
||||||
static Future<MoneroUnspent> fromUnspent(String address, String hash, String keyImage, int value, bool isFrozen, bool isUnlocked) async {
|
static Future<MoneroUnspent> fromUnspent(String address, String hash, String keyImage, int value, bool isFrozen, bool isUnlocked) async {
|
||||||
|
|
|
@ -39,6 +39,7 @@ import 'package:flutter/foundation.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
|
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
|
import 'package:monero/src/monero.dart' as m;
|
||||||
import 'package:monero/monero.dart' as monero;
|
import 'package:monero/monero.dart' as monero;
|
||||||
|
|
||||||
part 'monero_wallet.g.dart';
|
part 'monero_wallet.g.dart';
|
||||||
|
@ -84,7 +85,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
monero_wallet.getUnlockedBalance(accountIndex: account.id))
|
monero_wallet.getUnlockedBalance(accountIndex: account.id))
|
||||||
});
|
});
|
||||||
_updateSubAddress(isEnabledAutoGenerateSubaddress, account: account);
|
_updateSubAddress(isEnabledAutoGenerateSubaddress, account: account);
|
||||||
_askForUpdateTransactionHistory();
|
unawaited(updateTransactions());
|
||||||
});
|
});
|
||||||
|
|
||||||
reaction((_) => isEnabledAutoGenerateSubaddress, (bool enabled) {
|
reaction((_) => isEnabledAutoGenerateSubaddress, (bool enabled) {
|
||||||
|
@ -139,7 +140,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
passphrase: monero_wallet.getPassphrase());
|
passphrase: monero_wallet.getPassphrase());
|
||||||
|
|
||||||
int? get restoreHeight =>
|
int? get restoreHeight =>
|
||||||
transactionHistory.transactions.values.firstOrNull?.height ?? monero.Wallet_getRefreshFromBlockHeight(wptr!);
|
transactionHistory.transactions.values.firstOrNull?.height ?? currentWallet?.getRefreshFromBlockHeight();
|
||||||
|
|
||||||
monero_wallet.SyncListener? _listener;
|
monero_wallet.SyncListener? _listener;
|
||||||
ReactionDisposer? _onAccountChangeReaction;
|
ReactionDisposer? _onAccountChangeReaction;
|
||||||
|
@ -169,7 +170,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
if (monero_wallet.getCurrentHeight() <= 1) {
|
if (monero_wallet.getCurrentHeight() <= 1) {
|
||||||
monero_wallet.setRefreshFromBlockHeight(
|
monero_wallet.setRefreshFromBlockHeight(
|
||||||
height: walletInfo.restoreHeight);
|
height: walletInfo.restoreHeight);
|
||||||
setupBackgroundSync(password, wptr!);
|
setupBackgroundSync(password, currentWallet!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,14 +190,23 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
final currentWalletDirPath = await pathForWalletDir(name: name, type: type);
|
final currentWalletDirPath = await pathForWalletDir(name: name, type: type);
|
||||||
if (openedWalletsByPath["$currentWalletDirPath/$name"] != null) {
|
if (openedWalletsByPath["$currentWalletDirPath/$name"] != null) {
|
||||||
printV("closing wallet");
|
printV("closing wallet");
|
||||||
final wmaddr = wmPtr.address;
|
final wmaddr = wmPtr.ffiAddress();
|
||||||
final waddr = openedWalletsByPath["$currentWalletDirPath/$name"]!.address;
|
final waddr = openedWalletsByPath["$currentWalletDirPath/$name"]!.ffiAddress();
|
||||||
|
openedWalletsByPath.remove("$currentWalletDirPath/$name");
|
||||||
|
if (Platform.isWindows) {
|
||||||
await Isolate.run(() {
|
await Isolate.run(() {
|
||||||
monero.WalletManager_closeWallet(
|
monero.WalletManager_closeWallet(
|
||||||
Pointer.fromAddress(wmaddr), Pointer.fromAddress(waddr), true);
|
Pointer.fromAddress(wmaddr), Pointer.fromAddress(waddr), true);
|
||||||
|
monero.WalletManager_errorString(Pointer.fromAddress(wmaddr));
|
||||||
});
|
});
|
||||||
openedWalletsByPath.remove("$currentWalletDirPath/$name");
|
} else {
|
||||||
wptr = null;
|
unawaited(Isolate.run(() {
|
||||||
|
monero.WalletManager_closeWallet(
|
||||||
|
Pointer.fromAddress(wmaddr), Pointer.fromAddress(waddr), true);
|
||||||
|
monero.WalletManager_errorString(Pointer.fromAddress(wmaddr));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
currentWallet = null;
|
||||||
printV("wallet closed");
|
printV("wallet closed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,7 +221,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
Future<void> connectToNode({required Node node}) async {
|
Future<void> connectToNode({required Node node}) async {
|
||||||
try {
|
try {
|
||||||
syncStatus = ConnectingSyncStatus();
|
syncStatus = ConnectingSyncStatus();
|
||||||
await monero_wallet.setupNode(
|
await monero_wallet.setupNodeSync(
|
||||||
address: node.uri.toString(),
|
address: node.uri.toString(),
|
||||||
login: node.login,
|
login: node.login,
|
||||||
password: node.password,
|
password: node.password,
|
||||||
|
@ -237,10 +247,10 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
isBackgroundSyncRunning = true;
|
isBackgroundSyncRunning = true;
|
||||||
await save();
|
await save();
|
||||||
|
|
||||||
monero.Wallet_startBackgroundSync(wptr!);
|
currentWallet!.startBackgroundSync();
|
||||||
final status = monero.Wallet_status(wptr!);
|
final status = currentWallet!.status();
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
final err = monero.Wallet_errorString(wptr!);
|
final err = currentWallet!.errorString();
|
||||||
isBackgroundSyncRunning = false;
|
isBackgroundSyncRunning = false;
|
||||||
printV("startBackgroundSync: $err");
|
printV("startBackgroundSync: $err");
|
||||||
}
|
}
|
||||||
|
@ -256,9 +266,9 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
Future<void> stopSync() async {
|
Future<void> stopSync() async {
|
||||||
if (isBackgroundSyncRunning) {
|
if (isBackgroundSyncRunning) {
|
||||||
printV("Stopping background sync");
|
printV("Stopping background sync");
|
||||||
monero.Wallet_store(wptr!);
|
currentWallet!.store();
|
||||||
monero.Wallet_stopBackgroundSync(wptr!, '');
|
currentWallet!.stopBackgroundSync('');
|
||||||
monero_wallet.store();
|
currentWallet!.store();
|
||||||
isBackgroundSyncRunning = false;
|
isBackgroundSyncRunning = false;
|
||||||
}
|
}
|
||||||
await save();
|
await save();
|
||||||
|
@ -269,9 +279,9 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
Future<void> stopBackgroundSync(String password) async {
|
Future<void> stopBackgroundSync(String password) async {
|
||||||
if (isBackgroundSyncRunning) {
|
if (isBackgroundSyncRunning) {
|
||||||
printV("Stopping background sync");
|
printV("Stopping background sync");
|
||||||
monero.Wallet_store(wptr!);
|
currentWallet!.store();
|
||||||
monero.Wallet_stopBackgroundSync(wptr!, password);
|
currentWallet!.stopBackgroundSync(password);
|
||||||
monero.Wallet_store(wptr!);
|
currentWallet!.store();
|
||||||
isBackgroundSyncRunning = false;
|
isBackgroundSyncRunning = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -308,44 +318,44 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> submitTransactionUR(String ur) async {
|
Future<bool> submitTransactionUR(String ur) async {
|
||||||
final retStatus = monero.Wallet_submitTransactionUR(wptr!, ur);
|
final retStatus = currentWallet!.submitTransactionUR(ur);
|
||||||
final status = monero.Wallet_status(wptr!);
|
final status = currentWallet!.status();
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
final err = monero.Wallet_errorString(wptr!);
|
final err = currentWallet!.errorString();
|
||||||
throw MoneroTransactionCreationException("unable to broadcast signed transaction: $err");
|
throw MoneroTransactionCreationException("unable to broadcast signed transaction: $err");
|
||||||
}
|
}
|
||||||
return retStatus;
|
return retStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool importKeyImagesUR(String ur) {
|
bool importKeyImagesUR(String ur) {
|
||||||
final retStatus = monero.Wallet_importKeyImagesUR(wptr!, ur);
|
final retStatus = currentWallet!.importKeyImagesUR(ur);
|
||||||
final status = monero.Wallet_status(wptr!);
|
final status = currentWallet!.status();
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
final err = monero.Wallet_errorString(wptr!);
|
final err = currentWallet!.errorString();
|
||||||
throw Exception("unable to import key images: $err");
|
throw Exception("unable to import key images: $err");
|
||||||
}
|
}
|
||||||
return retStatus;
|
return retStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
String exportOutputsUR(bool all) {
|
String exportOutputsUR(bool all) {
|
||||||
final str = monero.Wallet_exportOutputsUR(wptr!, all: all);
|
final str = currentWallet!.exportOutputsUR(all: all);
|
||||||
final status = monero.Wallet_status(wptr!);
|
final status = currentWallet!.status();
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
final err = monero.Wallet_errorString(wptr!);
|
final err = currentWallet!.errorString();
|
||||||
throw MoneroTransactionCreationException("unable to export UR: $err");
|
throw MoneroTransactionCreationException("unable to export UR: $err");
|
||||||
}
|
}
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool needExportOutputs(int amount) {
|
bool needExportOutputs(int amount) {
|
||||||
if (int.tryParse(monero.Wallet_secretSpendKey(wptr!)) != 0) {
|
if (int.tryParse(currentWallet!.secretSpendKey()) != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// viewOnlyBalance - balance that we can spend
|
// viewOnlyBalance - balance that we can spend
|
||||||
// TODO(mrcyjanek): remove hasUnknownKeyImages when we cleanup coin control
|
// TODO(mrcyjanek): remove hasUnknownKeyImages when we cleanup coin control
|
||||||
return (monero.Wallet_viewOnlyBalance(wptr!,
|
return (currentWallet!.viewOnlyBalance(
|
||||||
accountIndex: walletAddresses.account!.id) < amount) ||
|
accountIndex: walletAddresses.account!.id) < amount) ||
|
||||||
monero.Wallet_hasUnknownKeyImages(wptr!);
|
currentWallet!.hasUnknownKeyImages();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -425,12 +435,13 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
if (inputs.isEmpty) MoneroTransactionCreationException(
|
if (inputs.isEmpty) MoneroTransactionCreationException(
|
||||||
'No inputs selected');
|
'No inputs selected');
|
||||||
pendingTransactionDescription =
|
pendingTransactionDescription =
|
||||||
await transaction_history.createTransaction(
|
await transaction_history.createTransactionSync(
|
||||||
address: address!,
|
address: address!,
|
||||||
amount: amount,
|
amount: amount,
|
||||||
priorityRaw: _credentials.priority.serialize(),
|
priorityRaw: _credentials.priority.serialize(),
|
||||||
accountIndex: walletAddresses.account!.id,
|
accountIndex: walletAddresses.account!.id,
|
||||||
preferredInputs: inputs);
|
preferredInputs: inputs,
|
||||||
|
paymentId: '');
|
||||||
}
|
}
|
||||||
|
|
||||||
// final status = monero.PendingTransaction_status(pendingTransactionDescription);
|
// final status = monero.PendingTransaction_status(pendingTransactionDescription);
|
||||||
|
@ -485,14 +496,25 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
final currentWalletDirPath = await pathForWalletDir(name: name, type: type);
|
final currentWalletDirPath = await pathForWalletDir(name: name, type: type);
|
||||||
if (openedWalletsByPath["$currentWalletDirPath/$name"] != null) {
|
if (openedWalletsByPath["$currentWalletDirPath/$name"] != null) {
|
||||||
// NOTE: this is realistically only required on windows.
|
// NOTE: this is realistically only required on windows.
|
||||||
|
// That's why we await it only on that platform - other platforms actually understand
|
||||||
|
// the concept of a file properly...
|
||||||
printV("closing wallet");
|
printV("closing wallet");
|
||||||
final wmaddr = wmPtr.address;
|
final wmaddr = wmPtr.ffiAddress();
|
||||||
final waddr = openedWalletsByPath["$currentWalletDirPath/$name"]!.address;
|
final waddr = openedWalletsByPath["$currentWalletDirPath/$name"]!.ffiAddress();
|
||||||
|
openedWalletsByPath.remove("$currentWalletDirPath/$name");
|
||||||
|
if (Platform.isWindows) {
|
||||||
await Isolate.run(() {
|
await Isolate.run(() {
|
||||||
monero.WalletManager_closeWallet(
|
monero.WalletManager_closeWallet(
|
||||||
Pointer.fromAddress(wmaddr), Pointer.fromAddress(waddr), true);
|
Pointer.fromAddress(wmaddr), Pointer.fromAddress(waddr), true);
|
||||||
|
monero.WalletManager_errorString(Pointer.fromAddress(wmaddr));
|
||||||
});
|
});
|
||||||
openedWalletsByPath.remove("$currentWalletDirPath/$name");
|
} else {
|
||||||
|
unawaited(Isolate.run(() {
|
||||||
|
monero.WalletManager_closeWallet(
|
||||||
|
Pointer.fromAddress(wmaddr), Pointer.fromAddress(waddr), true);
|
||||||
|
monero.WalletManager_errorString(Pointer.fromAddress(wmaddr));
|
||||||
|
}));
|
||||||
|
}
|
||||||
printV("wallet closed");
|
printV("wallet closed");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@ -501,32 +523,33 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
Directory(await pathForWalletDir(name: name, type: type));
|
Directory(await pathForWalletDir(name: name, type: type));
|
||||||
final newWalletDirPath =
|
final newWalletDirPath =
|
||||||
await pathForWalletDir(name: newWalletName, type: type);
|
await pathForWalletDir(name: newWalletName, type: type);
|
||||||
await currentWalletDir.rename(newWalletDirPath);
|
|
||||||
|
|
||||||
// -- use new waller folder to rename files with old names still --
|
// Create new directory if it doesn't exist
|
||||||
final renamedWalletPath = newWalletDirPath + '/$name';
|
await Directory(newWalletDirPath).create(recursive: true);
|
||||||
|
|
||||||
final currentCacheFile = File(renamedWalletPath);
|
// -- use new waller folder to copy files with old names still --
|
||||||
final currentKeysFile = File('$renamedWalletPath.keys');
|
final currentWalletPath = currentWalletDir.path + '/$name';
|
||||||
final currentAddressListFile = File('$renamedWalletPath.address.txt');
|
|
||||||
final backgroundSyncFile = File('$renamedWalletPath.background');
|
|
||||||
|
|
||||||
final newWalletPath =
|
final currentCacheFile = File(currentWalletPath);
|
||||||
await pathForWallet(name: newWalletName, type: type);
|
final currentKeysFile = File('$currentWalletPath.keys');
|
||||||
|
final currentAddressListFile = File('$currentWalletPath.address.txt');
|
||||||
|
final backgroundSyncFile = File('$currentWalletPath.background');
|
||||||
|
|
||||||
if (currentCacheFile.existsSync()) {
|
if (currentCacheFile.existsSync()) {
|
||||||
await currentCacheFile.rename(newWalletPath);
|
await currentCacheFile.copy("${newWalletDirPath}/$newWalletName");
|
||||||
}
|
}
|
||||||
if (currentKeysFile.existsSync()) {
|
if (currentKeysFile.existsSync()) {
|
||||||
await currentKeysFile.rename('$newWalletPath.keys');
|
await currentKeysFile.copy("${newWalletDirPath}/$newWalletName.keys");
|
||||||
}
|
}
|
||||||
if (currentAddressListFile.existsSync()) {
|
if (currentAddressListFile.existsSync()) {
|
||||||
await currentAddressListFile.rename('$newWalletPath.address.txt');
|
await currentAddressListFile.copy("${newWalletDirPath}/$newWalletName.address.txt");
|
||||||
}
|
}
|
||||||
if (backgroundSyncFile.existsSync()) {
|
if (backgroundSyncFile.existsSync()) {
|
||||||
await backgroundSyncFile.rename('$newWalletPath.background');
|
await backgroundSyncFile.copy("${newWalletDirPath}/$newWalletName.background");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await currentWalletDir.delete(recursive: true);
|
||||||
|
|
||||||
await backupWalletFiles(newWalletName);
|
await backupWalletFiles(newWalletName);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
final currentWalletPath = await pathForWallet(name: name, type: type);
|
final currentWalletPath = await pathForWallet(name: name, type: type);
|
||||||
|
@ -572,12 +595,12 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
walletInfo.restoreHeight = height;
|
walletInfo.restoreHeight = height;
|
||||||
walletInfo.isRecovery = true;
|
walletInfo.isRecovery = true;
|
||||||
monero_wallet.setRefreshFromBlockHeight(height: height);
|
monero_wallet.setRefreshFromBlockHeight(height: height);
|
||||||
setupBackgroundSync(password, wptr!);
|
setupBackgroundSync(password, currentWallet!);
|
||||||
monero_wallet.rescanBlockchainAsync();
|
monero_wallet.rescanBlockchainAsync();
|
||||||
await startSync();
|
await startSync();
|
||||||
_askForUpdateBalance();
|
_askForUpdateBalance();
|
||||||
walletAddresses.accountList.update();
|
walletAddresses.accountList.update();
|
||||||
await _askForUpdateTransactionHistory();
|
await updateTransactions();
|
||||||
await save();
|
await save();
|
||||||
await walletInfo.save();
|
await walletInfo.save();
|
||||||
}
|
}
|
||||||
|
@ -591,15 +614,15 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
final coinCount = await countOfCoins();
|
final coinCount = await countOfCoins();
|
||||||
for (var i = 0; i < coinCount; i++) {
|
for (var i = 0; i < coinCount; i++) {
|
||||||
final coin = await getCoin(i);
|
final coin = await getCoin(i);
|
||||||
final coinSpent = monero.CoinsInfo_spent(coin);
|
final coinSpent = coin.spent();
|
||||||
if (coinSpent == false && monero.CoinsInfo_subaddrAccount(coin) == walletAddresses.account!.id) {
|
if (coinSpent == false && coin.subaddrAccount() == walletAddresses.account!.id) {
|
||||||
final unspent = await MoneroUnspent.fromUnspent(
|
final unspent = await MoneroUnspent.fromUnspent(
|
||||||
monero.CoinsInfo_address(coin),
|
coin.address(),
|
||||||
monero.CoinsInfo_hash(coin),
|
coin.hash(),
|
||||||
monero.CoinsInfo_keyImage(coin),
|
coin.keyImage(),
|
||||||
monero.CoinsInfo_amount(coin),
|
coin.amount(),
|
||||||
monero.CoinsInfo_frozen(coin),
|
coin.frozen(),
|
||||||
monero.CoinsInfo_unlocked(coin),
|
coin.unlocked(),
|
||||||
);
|
);
|
||||||
// TODO: double-check the logic here
|
// TODO: double-check the logic here
|
||||||
if (unspent.hash.isNotEmpty) {
|
if (unspent.hash.isNotEmpty) {
|
||||||
|
@ -704,6 +727,8 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
acc[tx.id] = tx;
|
acc[tx.id] = tx;
|
||||||
return acc;
|
return acc;
|
||||||
});
|
});
|
||||||
|
// This is needed to update the transaction history when new transaction is made.
|
||||||
|
unawaited(updateTransactions());
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -792,7 +817,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
|
|
||||||
monero_wallet.setRecoveringFromSeed(isRecovery: true);
|
monero_wallet.setRecoveringFromSeed(isRecovery: true);
|
||||||
monero_wallet.setRefreshFromBlockHeight(height: height);
|
monero_wallet.setRefreshFromBlockHeight(height: height);
|
||||||
setupBackgroundSync(password, wptr!);
|
setupBackgroundSync(password, currentWallet!);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _getHeightDistance(DateTime date) {
|
int _getHeightDistance(DateTime date) {
|
||||||
|
@ -831,9 +856,6 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _askForUpdateTransactionHistory() async =>
|
|
||||||
await updateTransactions();
|
|
||||||
|
|
||||||
int _getUnlockedBalance() => monero_wallet.getUnlockedBalance(
|
int _getUnlockedBalance() => monero_wallet.getUnlockedBalance(
|
||||||
accountIndex: walletAddresses.account!.id);
|
accountIndex: walletAddresses.account!.id);
|
||||||
|
|
||||||
|
@ -852,13 +874,13 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
printV("onNewBlock: $height, $blocksLeft, $ptc");
|
printV("onNewBlock: $height, $blocksLeft, $ptc");
|
||||||
try {
|
try {
|
||||||
if (walletInfo.isRecovery) {
|
if (walletInfo.isRecovery) {
|
||||||
await _askForUpdateTransactionHistory();
|
await updateTransactions();
|
||||||
_askForUpdateBalance();
|
_askForUpdateBalance();
|
||||||
walletAddresses.accountList.update();
|
walletAddresses.accountList.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blocksLeft < 100) {
|
if (blocksLeft < 100) {
|
||||||
await _askForUpdateTransactionHistory();
|
await updateTransactions();
|
||||||
_askForUpdateBalance();
|
_askForUpdateBalance();
|
||||||
walletAddresses.accountList.update();
|
walletAddresses.accountList.update();
|
||||||
syncStatus = SyncedSyncStatus();
|
syncStatus = SyncedSyncStatus();
|
||||||
|
@ -881,7 +903,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
|
|
||||||
void _onNewTransaction() async {
|
void _onNewTransaction() async {
|
||||||
try {
|
try {
|
||||||
await _askForUpdateTransactionHistory();
|
await updateTransactions();
|
||||||
_askForUpdateBalance();
|
_askForUpdateBalance();
|
||||||
await Future<void>.delayed(Duration(seconds: 1));
|
await Future<void>.delayed(Duration(seconds: 1));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -917,8 +939,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLedgerConnection(LedgerConnection connection) {
|
void setLedgerConnection(LedgerConnection connection) {
|
||||||
final dummyWPtr = wptr ??
|
final dummyWPtr = createWalletPointer();
|
||||||
monero.WalletManager_openWallet(wmPtr, path: '', password: '');
|
|
||||||
enableLedgerExchange(dummyWPtr, connection);
|
enableLedgerExchange(dummyWPtr, connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
import 'dart:async';
|
||||||
import 'dart:ffi';
|
import 'dart:ffi';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'dart:isolate';
|
||||||
|
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:cw_core/get_height_by_date.dart';
|
import 'package:cw_core/get_height_by_date.dart';
|
||||||
|
@ -20,6 +22,7 @@ import 'package:cw_monero/ledger.dart';
|
||||||
import 'package:cw_monero/monero_wallet.dart';
|
import 'package:cw_monero/monero_wallet.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
|
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
|
||||||
|
import 'package:monero/src/monero.dart' as m;
|
||||||
import 'package:monero/monero.dart' as monero;
|
import 'package:monero/monero.dart' as monero;
|
||||||
import 'package:polyseed/polyseed.dart';
|
import 'package:polyseed/polyseed.dart';
|
||||||
|
|
||||||
|
@ -139,7 +142,7 @@ class MoneroWalletService extends WalletService<
|
||||||
overrideHeight: heightOverride, passphrase: credentials.passphrase);
|
overrideHeight: heightOverride, passphrase: credentials.passphrase);
|
||||||
}
|
}
|
||||||
|
|
||||||
await monero_wallet_manager.createWallet(
|
monero_wallet_manager.createWallet(
|
||||||
path: path,
|
path: path,
|
||||||
password: credentials.password!,
|
password: credentials.password!,
|
||||||
language: credentials.language,
|
language: credentials.language,
|
||||||
|
@ -179,7 +182,7 @@ class MoneroWalletService extends WalletService<
|
||||||
if (walletFilesExist(path)) await repairOldAndroidWallet(name);
|
if (walletFilesExist(path)) await repairOldAndroidWallet(name);
|
||||||
|
|
||||||
await monero_wallet_manager
|
await monero_wallet_manager
|
||||||
.openWalletAsync({'path': path, 'password': password});
|
.openWallet(path: path, password: password);
|
||||||
final walletInfo = walletInfoSource.values
|
final walletInfo = walletInfoSource.values
|
||||||
.firstWhere((info) => info.id == WalletBase.idFor(name, getType()));
|
.firstWhere((info) => info.id == WalletBase.idFor(name, getType()));
|
||||||
final wallet = MoneroWallet(
|
final wallet = MoneroWallet(
|
||||||
|
@ -217,13 +220,23 @@ class MoneroWalletService extends WalletService<
|
||||||
if (openedWalletsByPath["$path/$wallet"] != null) {
|
if (openedWalletsByPath["$path/$wallet"] != null) {
|
||||||
// NOTE: this is realistically only required on windows.
|
// NOTE: this is realistically only required on windows.
|
||||||
printV("closing wallet");
|
printV("closing wallet");
|
||||||
final wmaddr = wmPtr.address;
|
final w = openedWalletsByPath["$path/$wallet"]!;
|
||||||
final waddr = openedWalletsByPath["$path/$wallet"]!.address;
|
final wmaddr = wmPtr.ffiAddress();
|
||||||
// await Isolate.run(() {
|
final waddr = w.ffiAddress();
|
||||||
monero.WalletManager_closeWallet(
|
|
||||||
Pointer.fromAddress(wmaddr), Pointer.fromAddress(waddr), false);
|
|
||||||
// });
|
|
||||||
openedWalletsByPath.remove("$path/$wallet");
|
openedWalletsByPath.remove("$path/$wallet");
|
||||||
|
if (Platform.isWindows) {
|
||||||
|
await Isolate.run(() {
|
||||||
|
monero.WalletManager_closeWallet(
|
||||||
|
Pointer.fromAddress(wmaddr), Pointer.fromAddress(waddr), true);
|
||||||
|
monero.WalletManager_errorString(Pointer.fromAddress(wmaddr));
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
unawaited(Isolate.run(() {
|
||||||
|
monero.WalletManager_closeWallet(
|
||||||
|
Pointer.fromAddress(wmaddr), Pointer.fromAddress(waddr), true);
|
||||||
|
monero.WalletManager_errorString(Pointer.fromAddress(wmaddr));
|
||||||
|
}));
|
||||||
|
}
|
||||||
printV("wallet closed");
|
printV("wallet closed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,7 +276,7 @@ class MoneroWalletService extends WalletService<
|
||||||
{bool? isTestnet}) async {
|
{bool? isTestnet}) async {
|
||||||
try {
|
try {
|
||||||
final path = await pathForWallet(name: credentials.name, type: getType());
|
final path = await pathForWallet(name: credentials.name, type: getType());
|
||||||
await monero_wallet_manager.restoreFromKeys(
|
monero_wallet_manager.restoreWalletFromKeys(
|
||||||
path: path,
|
path: path,
|
||||||
password: credentials.password!,
|
password: credentials.password!,
|
||||||
language: credentials.language,
|
language: credentials.language,
|
||||||
|
@ -293,9 +306,13 @@ class MoneroWalletService extends WalletService<
|
||||||
final password = credentials.password;
|
final password = credentials.password;
|
||||||
final height = credentials.height;
|
final height = credentials.height;
|
||||||
|
|
||||||
if (wptr == null) monero_wallet_manager.createWalletPointer();
|
if (currentWallet == null) {
|
||||||
|
final tmpWptr = monero_wallet_manager.createWalletPointer();
|
||||||
|
enableLedgerExchange(tmpWptr, credentials.ledgerConnection);
|
||||||
|
} else {
|
||||||
|
enableLedgerExchange(currentWallet!, credentials.ledgerConnection);
|
||||||
|
}
|
||||||
|
|
||||||
enableLedgerExchange(wptr!, credentials.ledgerConnection);
|
|
||||||
await monero_wallet_manager.restoreWalletFromHardwareWallet(
|
await monero_wallet_manager.restoreWalletFromHardwareWallet(
|
||||||
path: path,
|
path: path,
|
||||||
password: password!,
|
password: password!,
|
||||||
|
@ -352,7 +369,7 @@ class MoneroWalletService extends WalletService<
|
||||||
try {
|
try {
|
||||||
final path = await pathForWallet(name: credentials.name, type: getType());
|
final path = await pathForWallet(name: credentials.name, type: getType());
|
||||||
|
|
||||||
monero_wallet_manager.restoreFromSeed(
|
monero_wallet_manager.restoreWalletFromSeedSync(
|
||||||
path: path,
|
path: path,
|
||||||
password: credentials.password!,
|
password: credentials.password!,
|
||||||
passphrase: credentials.passphrase,
|
passphrase: credentials.passphrase,
|
||||||
|
@ -393,7 +410,7 @@ class MoneroWalletService extends WalletService<
|
||||||
walletInfo.isRecovery = true;
|
walletInfo.isRecovery = true;
|
||||||
walletInfo.restoreHeight = height;
|
walletInfo.restoreHeight = height;
|
||||||
|
|
||||||
monero_wallet_manager.restoreFromSeed(
|
monero_wallet_manager.restoreWalletFromSeedSync(
|
||||||
path: path,
|
path: path,
|
||||||
password: password,
|
password: password,
|
||||||
passphrase: '',
|
passphrase: '',
|
||||||
|
@ -401,12 +418,12 @@ class MoneroWalletService extends WalletService<
|
||||||
restoreHeight: height,
|
restoreHeight: height,
|
||||||
);
|
);
|
||||||
|
|
||||||
monero.Wallet_setCacheAttribute(wptr!,
|
currentWallet!.setCacheAttribute(
|
||||||
key: "cakewallet.seed.bip39", value: mnemonic);
|
key: "cakewallet.seed.bip39", value: mnemonic);
|
||||||
monero.Wallet_setCacheAttribute(wptr!,
|
currentWallet!.setCacheAttribute(
|
||||||
key: "cakewallet.passphrase", value: passphrase ?? '');
|
key: "cakewallet.passphrase", value: passphrase ?? '');
|
||||||
|
|
||||||
monero.Wallet_store(wptr!);
|
currentWallet!.store();
|
||||||
|
|
||||||
final wallet = MoneroWallet(
|
final wallet = MoneroWallet(
|
||||||
walletInfo: walletInfo,
|
walletInfo: walletInfo,
|
||||||
|
@ -472,7 +489,7 @@ class MoneroWalletService extends WalletService<
|
||||||
walletInfo.isRecovery = true;
|
walletInfo.isRecovery = true;
|
||||||
walletInfo.restoreHeight = height;
|
walletInfo.restoreHeight = height;
|
||||||
|
|
||||||
await monero_wallet_manager.restoreFromSpendKey(
|
monero_wallet_manager.restoreWalletFromSpendKeySync(
|
||||||
path: path,
|
path: path,
|
||||||
password: password,
|
password: password,
|
||||||
seed: seed,
|
seed: seed,
|
||||||
|
@ -481,8 +498,8 @@ class MoneroWalletService extends WalletService<
|
||||||
spendKey: spendKey);
|
spendKey: spendKey);
|
||||||
|
|
||||||
|
|
||||||
monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed);
|
currentWallet!.setCacheAttribute(key: "cakewallet.seed", value: seed);
|
||||||
monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.passphrase", value: passphrase??'');
|
currentWallet!.setCacheAttribute(key: "cakewallet.passphrase", value: passphrase??'');
|
||||||
|
|
||||||
final wallet = MoneroWallet(
|
final wallet = MoneroWallet(
|
||||||
walletInfo: walletInfo,
|
walletInfo: walletInfo,
|
||||||
|
@ -529,7 +546,7 @@ class MoneroWalletService extends WalletService<
|
||||||
if (walletFilesExist(path)) await repairOldAndroidWallet(name);
|
if (walletFilesExist(path)) await repairOldAndroidWallet(name);
|
||||||
|
|
||||||
await monero_wallet_manager
|
await monero_wallet_manager
|
||||||
.openWalletAsync({'path': path, 'password': password});
|
.openWallet(path: path, password: password);
|
||||||
final walletInfo = walletInfoSource.values
|
final walletInfo = walletInfoSource.values
|
||||||
.firstWhere((info) => info.id == WalletBase.idFor(name, getType()));
|
.firstWhere((info) => info.id == WalletBase.idFor(name, getType()));
|
||||||
final wallet = MoneroWallet(
|
final wallet = MoneroWallet(
|
||||||
|
|
|
@ -573,8 +573,8 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: "impls/monero.dart"
|
path: "impls/monero.dart"
|
||||||
ref: "84e52393e395d75f449bcd81e23028889538118f"
|
ref: b335585a7fb94b315eb52bd88f2da6d3489fa508
|
||||||
resolved-ref: "84e52393e395d75f449bcd81e23028889538118f"
|
resolved-ref: b335585a7fb94b315eb52bd88f2da6d3489fa508
|
||||||
url: "https://github.com/mrcyjanek/monero_c"
|
url: "https://github.com/mrcyjanek/monero_c"
|
||||||
source: git
|
source: git
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
|
|
@ -27,7 +27,7 @@ dependencies:
|
||||||
monero:
|
monero:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/mrcyjanek/monero_c
|
url: https://github.com/mrcyjanek/monero_c
|
||||||
ref: 84e52393e395d75f449bcd81e23028889538118f
|
ref: b335585a7fb94b315eb52bd88f2da6d3489fa508
|
||||||
path: impls/monero.dart
|
path: impls/monero.dart
|
||||||
mutex: ^3.1.0
|
mutex: ^3.1.0
|
||||||
ledger_flutter_plus: ^1.4.1
|
ledger_flutter_plus: ^1.4.1
|
||||||
|
|
|
@ -480,8 +480,8 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: "impls/monero.dart"
|
path: "impls/monero.dart"
|
||||||
ref: "84e52393e395d75f449bcd81e23028889538118f"
|
ref: b335585a7fb94b315eb52bd88f2da6d3489fa508
|
||||||
resolved-ref: "84e52393e395d75f449bcd81e23028889538118f"
|
resolved-ref: b335585a7fb94b315eb52bd88f2da6d3489fa508
|
||||||
url: "https://github.com/mrcyjanek/monero_c"
|
url: "https://github.com/mrcyjanek/monero_c"
|
||||||
source: git
|
source: git
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
|
|
@ -25,7 +25,7 @@ dependencies:
|
||||||
monero:
|
monero:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/mrcyjanek/monero_c
|
url: https://github.com/mrcyjanek/monero_c
|
||||||
ref: 84e52393e395d75f449bcd81e23028889538118f # monero_c hash
|
ref: b335585a7fb94b315eb52bd88f2da6d3489fa508 # monero_c hash
|
||||||
path: impls/monero.dart
|
path: impls/monero.dart
|
||||||
mutex: ^3.1.0
|
mutex: ^3.1.0
|
||||||
|
|
||||||
|
|
|
@ -485,8 +485,8 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: "impls/monero.dart"
|
path: "impls/monero.dart"
|
||||||
ref: "84e52393e395d75f449bcd81e23028889538118f"
|
ref: b335585a7fb94b315eb52bd88f2da6d3489fa508
|
||||||
resolved-ref: "84e52393e395d75f449bcd81e23028889538118f"
|
resolved-ref: b335585a7fb94b315eb52bd88f2da6d3489fa508
|
||||||
url: "https://github.com/mrcyjanek/monero_c"
|
url: "https://github.com/mrcyjanek/monero_c"
|
||||||
source: git
|
source: git
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
|
|
@ -26,7 +26,7 @@ dependencies:
|
||||||
monero:
|
monero:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/mrcyjanek/monero_c
|
url: https://github.com/mrcyjanek/monero_c
|
||||||
ref: 84e52393e395d75f449bcd81e23028889538118f # monero_c hash
|
ref: b335585a7fb94b315eb52bd88f2da6d3489fa508 # monero_c hash
|
||||||
path: impls/monero.dart
|
path: impls/monero.dart
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
@ -208,42 +208,40 @@ EXTERNAL SOURCES:
|
||||||
:path: ".symlinks/plugins/wakelock_plus/ios"
|
:path: ".symlinks/plugins/wakelock_plus/ios"
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
connectivity_plus: 2a701ffec2c0ae28a48cf7540e279787e77c447d
|
connectivity_plus: 481668c94744c30c53b8895afb39159d1e619bdf
|
||||||
CryptoSwift: e64e11850ede528a02a0f3e768cec8e9d92ecb90
|
CryptoSwift: e64e11850ede528a02a0f3e768cec8e9d92ecb90
|
||||||
cw_decred: 9c0e1df74745b51a1289ec5e91fb9e24b68fa14a
|
cw_decred: a02cf30175a46971c1e2fa22c48407534541edc6
|
||||||
cw_mweb: 22cd01dfb8ad2d39b15332006f22046aaa8352a3
|
cw_mweb: 3aea2fb35b2bd04d8b2d21b83216f3b8fb768d85
|
||||||
device_display_brightness: 1510e72c567a1f6ce6ffe393dcd9afd1426034f7
|
device_display_brightness: 04374ebd653619292c1d996f00f42877ea19f17f
|
||||||
device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6
|
device_info_plus: 335f3ce08d2e174b9fdc3db3db0f4e3b1f66bd89
|
||||||
devicelocale: 35ba84dc7f45f527c3001535d8c8d104edd5d926
|
devicelocale: bd64aa714485a8afdaded0892c1e7d5b7f680cf8
|
||||||
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
|
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
|
||||||
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
|
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
|
||||||
fast_scanner: 44c00940355a51258cd6c2085734193cd23d95bc
|
fast_scanner: 2cb1ad3e69e645e9980fb4961396ce5804caa3e3
|
||||||
file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655
|
file_picker: 9b3292d7c8bc68c8a7bf8eb78f730e49c8efc517
|
||||||
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
||||||
flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4
|
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
|
||||||
flutter_local_authentication: 1172a4dd88f6306dadce067454e2c4caf07977bb
|
flutter_local_authentication: 989278c681612f1ee0e36019e149137f114b9d7f
|
||||||
flutter_local_notifications: ff50f8405aaa0ccdc7dcfb9022ca192e8ad9688f
|
flutter_mailer: 3a8cd4f36c960fb04528d5471097270c19fec1c4
|
||||||
flutter_mailer: 2ef5a67087bc8c6c4cefd04a178bf1ae2c94cd83
|
flutter_secure_storage: 2c2ff13db9e0a5647389bff88b0ecac56e3f3418
|
||||||
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
|
fluttertoast: 2c67e14dce98bbdb200df9e1acf610d7a6264ea1
|
||||||
fluttertoast: 21eecd6935e7064cc1fcb733a4c5a428f3f24f0f
|
in_app_review: 5596fe56fab799e8edb3561c03d053363ab13457
|
||||||
in_app_review: a31b5257259646ea78e0e35fc914979b0031d011
|
integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e
|
||||||
integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573
|
|
||||||
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
|
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
|
||||||
package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4
|
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
|
||||||
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
|
||||||
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
|
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
|
||||||
reown_yttrium: c0e87e5965fa60a3559564cc35cffbba22976089
|
ReachabilitySwift: 32793e867593cfc1177f5d16491e3a197d2fccda
|
||||||
SDWebImage: 73c6079366fea25fa4bb9640d5fb58f0893facd8
|
SDWebImage: 73c6079366fea25fa4bb9640d5fb58f0893facd8
|
||||||
sensitive_clipboard: d4866e5d176581536c27bb1618642ee83adca986
|
sensitive_clipboard: 161e9abc3d56b3131309d8a321eb4690a803c16b
|
||||||
share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f
|
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
|
||||||
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
|
||||||
sp_scanner: eaa617fa827396b967116b7f1f43549ca62e9a12
|
sp_scanner: b1bc9321690980bdb44bba7ec85d5543e716d1b5
|
||||||
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
|
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
|
||||||
uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
|
uni_links: ed8c961e47ed9ce42b6d91e1de8049e38a4b3152
|
||||||
universal_ble: cf52a7b3fd2e7c14d6d7262e9fdadb72ab6b88a6
|
universal_ble: ff19787898040d721109c6324472e5dd4bc86adc
|
||||||
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
|
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
|
||||||
wakelock_plus: 76957ab028e12bfa4e66813c99e46637f367fc7e
|
wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556
|
||||||
YttriumWrapper: 31e937fe9fbe0f1314d2ca6be9ce9b379a059966
|
|
||||||
|
|
||||||
PODFILE CHECKSUM: 5296465b1c6d14d506230356756826012f65d97a
|
PODFILE CHECKSUM: 5296465b1c6d14d506230356756826012f65d97a
|
||||||
|
|
||||||
|
|
|
@ -32,17 +32,18 @@ class WalletLoadingService {
|
||||||
|
|
||||||
Future<void> renameWallet(WalletType type, String name, String newName,
|
Future<void> renameWallet(WalletType type, String name, String newName,
|
||||||
{String? password}) async {
|
{String? password}) async {
|
||||||
|
try {
|
||||||
final walletService = walletServiceFactory.call(type);
|
final walletService = walletServiceFactory.call(type);
|
||||||
final walletPassword = password ?? (await keyService.getWalletPassword(walletName: name));
|
final walletPassword = password ?? (await keyService.getWalletPassword(walletName: name));
|
||||||
|
|
||||||
// Save the current wallet's password to the new wallet name's key
|
// Save the current wallet's password to the new wallet name's key
|
||||||
await keyService.saveWalletPassword(walletName: newName, password: walletPassword);
|
await keyService.saveWalletPassword(walletName: newName, password: walletPassword);
|
||||||
|
|
||||||
|
await walletService.rename(name, walletPassword, newName);
|
||||||
// Delete previous wallet name from keyService to keep only new wallet's name
|
// Delete previous wallet name from keyService to keep only new wallet's name
|
||||||
// otherwise keeps duplicate (old and new names)
|
// otherwise keeps duplicate (old and new names)
|
||||||
await keyService.deleteWalletPassword(walletName: name);
|
await keyService.deleteWalletPassword(walletName: name);
|
||||||
|
|
||||||
await walletService.rename(name, walletPassword, newName);
|
|
||||||
|
|
||||||
// set shared preferences flag based on previous wallet name
|
// set shared preferences flag based on previous wallet name
|
||||||
if (type == WalletType.monero) {
|
if (type == WalletType.monero) {
|
||||||
final oldNameKey = PreferencesKey.moneroWalletUpdateV1Key(name);
|
final oldNameKey = PreferencesKey.moneroWalletUpdateV1Key(name);
|
||||||
|
@ -50,6 +51,10 @@ class WalletLoadingService {
|
||||||
final newNameKey = PreferencesKey.moneroWalletUpdateV1Key(newName);
|
final newNameKey = PreferencesKey.moneroWalletUpdateV1Key(newName);
|
||||||
await sharedPreferences.setBool(newNameKey, isPasswordUpdated);
|
await sharedPreferences.setBool(newNameKey, isPasswordUpdated);
|
||||||
}
|
}
|
||||||
|
} catch (error, stack) {
|
||||||
|
await ExceptionHandler.resetLastPopupDate();
|
||||||
|
await ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stack));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<WalletBase> load(WalletType type, String name, {String? password, bool isBackground = false}) async {
|
Future<WalletBase> load(WalletType type, String name, {String? password, bool isBackground = false}) async {
|
||||||
|
|
|
@ -39,14 +39,14 @@ class CWMoneroAccountList extends MoneroAccountList {
|
||||||
@override
|
@override
|
||||||
Future<void> addAccount(Object wallet, {required String label}) async {
|
Future<void> addAccount(Object wallet, {required String label}) async {
|
||||||
final moneroWallet = wallet as MoneroWallet;
|
final moneroWallet = wallet as MoneroWallet;
|
||||||
await moneroWallet.walletAddresses.accountList.addAccount(label: label);
|
moneroWallet.walletAddresses.accountList.addAccount(label: label);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> setLabelAccount(Object wallet,
|
Future<void> setLabelAccount(Object wallet,
|
||||||
{required int accountIndex, required String label}) async {
|
{required int accountIndex, required String label}) async {
|
||||||
final moneroWallet = wallet as MoneroWallet;
|
final moneroWallet = wallet as MoneroWallet;
|
||||||
await moneroWallet.walletAddresses.accountList
|
moneroWallet.walletAddresses.accountList
|
||||||
.setLabelAccount(accountIndex: accountIndex, label: label);
|
.setLabelAccount(accountIndex: accountIndex, label: label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,7 +204,7 @@ class _AdvancedPrivacySettingsBodyState extends State<_AdvancedPrivacySettingsBo
|
||||||
);
|
);
|
||||||
return Container();
|
return Container();
|
||||||
}),
|
}),
|
||||||
if (widget.privacySettingsViewModel.hasPassphraseOption)
|
if (widget.privacySettingsViewModel.hasPassphraseOption && !widget.isFromRestore)
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.all(24),
|
padding: EdgeInsets.all(24),
|
||||||
child: Form(
|
child: Form(
|
||||||
|
|
|
@ -5,10 +5,14 @@ import 'package:cake_wallet/src/screens/base_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/restore/wallet_restore_from_keys_form.dart';
|
import 'package:cake_wallet/src/screens/restore/wallet_restore_from_keys_form.dart';
|
||||||
import 'package:cake_wallet/src/screens/restore/wallet_restore_from_seed_form.dart';
|
import 'package:cake_wallet/src/screens/restore/wallet_restore_from_seed_form.dart';
|
||||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/bottom_sheet/add_passphrase_bottom_sheet_widget.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/src/widgets/primary_button.dart';
|
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/standard_checkbox.dart';
|
||||||
|
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||||
|
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
||||||
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
|
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
|
||||||
import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
|
import 'package:cake_wallet/themes/theme_base.dart';
|
||||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||||
import 'package:cake_wallet/view_model/restore/restore_mode.dart';
|
import 'package:cake_wallet/view_model/restore/restore_mode.dart';
|
||||||
|
@ -52,7 +56,6 @@ class WalletRestorePage extends BasePage {
|
||||||
// String? derivationPath = null;
|
// String? derivationPath = null;
|
||||||
DerivationInfo? derivationInfo;
|
DerivationInfo? derivationInfo;
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Function(BuildContext)? get popWidget => (context) => seedSettingsViewModel.setPassphrase(null);
|
Function(BuildContext)? get popWidget => (context) => seedSettingsViewModel.setPassphrase(null);
|
||||||
|
|
||||||
|
@ -102,37 +105,81 @@ class WalletRestorePage extends BasePage {
|
||||||
padding: EdgeInsets.only(top: 20, bottom: 24, left: 24, right: 24),
|
padding: EdgeInsets.only(top: 20, bottom: 24, left: 24, right: 24),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
|
Observer(
|
||||||
|
builder: (context) {
|
||||||
|
return walletRestoreViewModel.mode == WalletRestoreMode.seed
|
||||||
|
? StandardCheckbox(
|
||||||
|
value: walletRestoreViewModel.hasPassphrase,
|
||||||
|
caption: S.of(context).wallet_has_passphrase,
|
||||||
|
onChanged: (value) {
|
||||||
|
walletRestoreViewModel.hasPassphrase = value;
|
||||||
|
},
|
||||||
|
)
|
||||||
|
: SizedBox.shrink();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
SizedBox(height: 16),
|
||||||
|
PrimaryButton(
|
||||||
|
key: ValueKey('wallet_restore_advanced_settings_button_key'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pushNamed(
|
||||||
|
Routes.advancedPrivacySettings,
|
||||||
|
arguments: {
|
||||||
|
'isFromRestore': true,
|
||||||
|
'type': walletRestoreViewModel.type,
|
||||||
|
'useTestnet': walletRestoreViewModel.useTestnet,
|
||||||
|
'toggleTestnet': walletRestoreViewModel.toggleUseTestnet
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
text: S.of(context).advanced_settings,
|
||||||
|
color: Theme.of(context).cardColor,
|
||||||
|
textColor: Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor,
|
||||||
|
),
|
||||||
|
SizedBox(height: 8),
|
||||||
Observer(
|
Observer(
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return LoadingPrimaryButton(
|
return LoadingPrimaryButton(
|
||||||
key: ValueKey('wallet_restore_seed_or_key_restore_button_key'),
|
key: ValueKey('wallet_restore_seed_or_key_restore_button_key'),
|
||||||
onPressed: () async => await _confirmForm(context),
|
onPressed: () async {
|
||||||
text: S.of(context).restore_recover,
|
if (walletRestoreViewModel.hasPassphrase) {
|
||||||
color: Theme.of(context)
|
await showModalBottomSheet<void>(
|
||||||
.extension<WalletListTheme>()!
|
context: context,
|
||||||
.createNewWalletButtonBackgroundColor,
|
isDismissible: false,
|
||||||
textColor: Theme.of(context)
|
isScrollControlled: true,
|
||||||
.extension<WalletListTheme>()!
|
builder: (BuildContext bottomSheetContext) {
|
||||||
.restoreWalletButtonTextColor,
|
return Padding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
bottom: MediaQuery.of(bottomSheetContext).viewInsets.bottom,
|
||||||
|
),
|
||||||
|
child: AddPassphraseBottomSheet(
|
||||||
|
currentTheme: currentTheme,
|
||||||
|
titleText: S.of(context).add_passphrase,
|
||||||
|
onRestoreButtonPressed: (passphrase) async {
|
||||||
|
await _onPassphraseBottomSheetRestoreButtonPressed(
|
||||||
|
passphrase,
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
await _confirmForm(context);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
text: walletRestoreViewModel.hasPassphrase
|
||||||
|
? S.of(context).add_passphrase
|
||||||
|
: S.of(context).restore_recover,
|
||||||
|
color: Theme.of(context).primaryColor,
|
||||||
|
textColor: Colors.white,
|
||||||
isLoading: walletRestoreViewModel.state is IsExecutingState,
|
isLoading: walletRestoreViewModel.state is IsExecutingState,
|
||||||
isDisabled: !walletRestoreViewModel.isButtonEnabled,
|
isDisabled: !walletRestoreViewModel.isButtonEnabled,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(height: 25),
|
const SizedBox(height: 24),
|
||||||
GestureDetector(
|
|
||||||
key: ValueKey('wallet_restore_advanced_settings_button_key'),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.of(context)
|
|
||||||
.pushNamed(Routes.advancedPrivacySettings, arguments: {
|
|
||||||
'isFromRestore': true,
|
|
||||||
'type': walletRestoreViewModel.type,
|
|
||||||
'useTestnet': walletRestoreViewModel.useTestnet,
|
|
||||||
'toggleTestnet': walletRestoreViewModel.toggleUseTestnet
|
|
||||||
});
|
|
||||||
},
|
|
||||||
child: Text(S.of(context).advanced_settings),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -144,6 +191,14 @@ class WalletRestorePage extends BasePage {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _onPassphraseBottomSheetRestoreButtonPressed(
|
||||||
|
String passphrase,
|
||||||
|
BuildContext context,
|
||||||
|
) async {
|
||||||
|
walletRestoreViewModel.seedSettingsViewModel.setPassphrase(passphrase);
|
||||||
|
await _confirmForm(context);
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, dynamic> _credentials() {
|
Map<String, dynamic> _credentials() {
|
||||||
final credentials = <String, dynamic>{};
|
final credentials = <String, dynamic>{};
|
||||||
|
|
||||||
|
@ -172,7 +227,8 @@ class WalletRestorePage extends BasePage {
|
||||||
walletRestoreFromKeysFormKey.currentState!.nameTextEditingController.text;
|
walletRestoreFromKeysFormKey.currentState!.nameTextEditingController.text;
|
||||||
credentials['viewKey'] = walletRestoreFromKeysFormKey.currentState!.viewKeyController.text;
|
credentials['viewKey'] = walletRestoreFromKeysFormKey.currentState!.viewKeyController.text;
|
||||||
if (walletRestoreViewModel.type != WalletType.decred) {
|
if (walletRestoreViewModel.type != WalletType.decred) {
|
||||||
credentials['address'] = walletRestoreFromKeysFormKey.currentState!.addressController.text;
|
credentials['address'] =
|
||||||
|
walletRestoreFromKeysFormKey.currentState!.addressController.text;
|
||||||
credentials['spendKey'] =
|
credentials['spendKey'] =
|
||||||
walletRestoreFromKeysFormKey.currentState!.spendKeyController.text;
|
walletRestoreFromKeysFormKey.currentState!.spendKeyController.text;
|
||||||
credentials['height'] =
|
credentials['height'] =
|
||||||
|
@ -527,42 +583,30 @@ class _WalletRestorePageBodyState extends State<_WalletRestorePageBody>
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _isValidSeed() {
|
bool _isValidSeed() {
|
||||||
final seedPhrase = walletRestoreFromSeedFormKey
|
final seedPhrase =
|
||||||
.currentState!.seedWidgetStateKey.currentState!.text;
|
walletRestoreFromSeedFormKey.currentState!.seedWidgetStateKey.currentState!.text;
|
||||||
if (walletRestoreViewModel.isPolyseed(seedPhrase)) return true;
|
if (walletRestoreViewModel.isPolyseed(seedPhrase)) return true;
|
||||||
|
|
||||||
final seedWords = seedPhrase.split(' ');
|
final seedWords = seedPhrase.split(' ');
|
||||||
|
|
||||||
if (seedWords.length == 14 &&
|
if (seedWords.length == 14 && walletRestoreViewModel.type == WalletType.wownero) return true;
|
||||||
walletRestoreViewModel.type == WalletType.wownero) return true;
|
if (seedWords.length == 26 && walletRestoreViewModel.type == WalletType.zano) return true;
|
||||||
if (seedWords.length == 26 &&
|
|
||||||
walletRestoreViewModel.type == WalletType.zano) return true;
|
|
||||||
|
|
||||||
if (seedWords.length == 12 &&
|
if (seedWords.length == 12 && walletRestoreViewModel.type == WalletType.monero) {
|
||||||
walletRestoreViewModel.type == WalletType.monero) {
|
return walletRestoreFromSeedFormKey.currentState?.blockchainHeightKey.currentState
|
||||||
return walletRestoreFromSeedFormKey
|
?.restoreHeightController.text.isNotEmpty ==
|
||||||
.currentState
|
true;
|
||||||
?.blockchainHeightKey
|
|
||||||
.currentState
|
|
||||||
?.restoreHeightController
|
|
||||||
.text
|
|
||||||
.isNotEmpty == true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([WalletType.monero, WalletType.wownero, WalletType.haven]
|
if ([WalletType.monero, WalletType.wownero, WalletType.haven]
|
||||||
.contains(walletRestoreViewModel.type) &&
|
.contains(walletRestoreViewModel.type) &&
|
||||||
seedWords.length ==
|
seedWords.length == WalletRestoreViewModelBase.moneroSeedMnemonicLength) {
|
||||||
WalletRestoreViewModelBase.moneroSeedMnemonicLength) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// bip39:
|
// bip39:
|
||||||
final validBip39SeedLengths = [12, 18, 24];
|
final validBip39SeedLengths = [12, 18, 24];
|
||||||
final nonBip39WalletTypes = [
|
final nonBip39WalletTypes = [WalletType.wownero, WalletType.haven, WalletType.decred];
|
||||||
WalletType.wownero,
|
|
||||||
WalletType.haven,
|
|
||||||
WalletType.decred
|
|
||||||
];
|
|
||||||
// if it's a bip39 wallet and the length is not valid return false
|
// if it's a bip39 wallet and the length is not valid return false
|
||||||
if (!nonBip39WalletTypes.contains(walletRestoreViewModel.type) &&
|
if (!nonBip39WalletTypes.contains(walletRestoreViewModel.type) &&
|
||||||
!(validBip39SeedLengths.contains(seedWords.length))) {
|
!(validBip39SeedLengths.contains(seedWords.length))) {
|
||||||
|
@ -570,14 +614,12 @@ class _WalletRestorePageBodyState extends State<_WalletRestorePageBody>
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((walletRestoreViewModel.type == WalletType.decred) &&
|
if ((walletRestoreViewModel.type == WalletType.decred) &&
|
||||||
seedWords.length !=
|
seedWords.length != WalletRestoreViewModelBase.decredSeedMnemonicLength) {
|
||||||
WalletRestoreViewModelBase.decredSeedMnemonicLength) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final words = walletRestoreFromSeedFormKey
|
final words =
|
||||||
.currentState!.seedWidgetStateKey.currentState!.words
|
walletRestoreFromSeedFormKey.currentState!.seedWidgetStateKey.currentState!.words.toSet();
|
||||||
.toSet();
|
|
||||||
return seedWords.toSet().difference(words).toSet().isEmpty;
|
return seedWords.toSet().difference(words).toSet().isEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@ class BaseTextFormField extends StatelessWidget {
|
||||||
this.textColor,
|
this.textColor,
|
||||||
this.hintColor,
|
this.hintColor,
|
||||||
this.borderColor,
|
this.borderColor,
|
||||||
|
this.fillColor,
|
||||||
|
this.filled,
|
||||||
this.prefix,
|
this.prefix,
|
||||||
this.prefixIcon,
|
this.prefixIcon,
|
||||||
this.suffix,
|
this.suffix,
|
||||||
|
@ -44,6 +46,8 @@ class BaseTextFormField extends StatelessWidget {
|
||||||
final Color? textColor;
|
final Color? textColor;
|
||||||
final Color? hintColor;
|
final Color? hintColor;
|
||||||
final Color? borderColor;
|
final Color? borderColor;
|
||||||
|
final Color? fillColor;
|
||||||
|
bool? filled;
|
||||||
final Widget? prefix;
|
final Widget? prefix;
|
||||||
final Widget? prefixIcon;
|
final Widget? prefixIcon;
|
||||||
final Widget? suffix;
|
final Widget? suffix;
|
||||||
|
@ -89,6 +93,8 @@ class BaseTextFormField extends StatelessWidget {
|
||||||
prefixIcon: prefixIcon,
|
prefixIcon: prefixIcon,
|
||||||
suffix: suffix,
|
suffix: suffix,
|
||||||
suffixIcon: suffixIcon,
|
suffixIcon: suffixIcon,
|
||||||
|
fillColor: fillColor,
|
||||||
|
filled: filled,
|
||||||
hintStyle: placeholderTextStyle ??
|
hintStyle: placeholderTextStyle ??
|
||||||
TextStyle(
|
TextStyle(
|
||||||
color: hintColor ?? Theme.of(context).hintColor,
|
color: hintColor ?? Theme.of(context).hintColor,
|
||||||
|
|
|
@ -0,0 +1,220 @@
|
||||||
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
|
import 'package:cake_wallet/palette.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||||
|
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||||
|
import 'package:cake_wallet/themes/theme_base.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
|
||||||
|
class AddPassphraseBottomSheet extends StatefulWidget {
|
||||||
|
AddPassphraseBottomSheet({
|
||||||
|
required String titleText,
|
||||||
|
required this.currentTheme,
|
||||||
|
required this.onRestoreButtonPressed,
|
||||||
|
});
|
||||||
|
|
||||||
|
final void Function(String) onRestoreButtonPressed;
|
||||||
|
final ThemeBase currentTheme;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<AddPassphraseBottomSheet> createState() => _AddPassphraseBottomSheetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AddPassphraseBottomSheetState extends State<AddPassphraseBottomSheet> {
|
||||||
|
late final TextEditingController passphraseController;
|
||||||
|
late final TextEditingController confirmPassphraseController;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
passphraseController = TextEditingController();
|
||||||
|
confirmPassphraseController = TextEditingController();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
passphraseController.dispose();
|
||||||
|
confirmPassphraseController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool obscurePassphrase = true;
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: const BorderRadius.vertical(top: Radius.circular(30.0)),
|
||||||
|
color: Theme.of(context).dialogBackgroundColor,
|
||||||
|
),
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
const Spacer(flex: 4),
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: Container(
|
||||||
|
height: 6,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
color:
|
||||||
|
Theme.of(context).extension<CakeTextTheme>()!.titleColor.withOpacity(0.6),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Spacer(flex: 4),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 16),
|
||||||
|
Text(
|
||||||
|
S.of(context).add_passphrase,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
fontFamily: 'Lato',
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||||
|
decoration: TextDecoration.none,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SvgPicture.asset('assets/images/passphrase_key.svg'),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
|
child: Text.rich(
|
||||||
|
TextSpan(
|
||||||
|
children: [
|
||||||
|
TextSpan(
|
||||||
|
text: '${S.of(context).warning.toUpperCase()}: ',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontFamily: 'Lato',
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
color: Palette.red,
|
||||||
|
decoration: TextDecoration.none,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextSpan(
|
||||||
|
text: S.of(context).add_passphrase_warning_text,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontFamily: 'Lato',
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor.withOpacity(0.7),
|
||||||
|
decoration: TextDecoration.none,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 24),
|
||||||
|
TextFormField(
|
||||||
|
key: ValueKey('add_passphrase_bottom_sheet_widget_passphrase_textfield_key'),
|
||||||
|
controller: passphraseController,
|
||||||
|
obscureText: obscurePassphrase,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
contentPadding: EdgeInsets.symmetric(horizontal: 12),
|
||||||
|
filled: true,
|
||||||
|
fillColor: Theme.of(context).cardColor,
|
||||||
|
hintText: S.of(context).required_passphrase,
|
||||||
|
suffixIcon: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
obscurePassphrase = !obscurePassphrase;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Icon(
|
||||||
|
obscurePassphrase ? Icons.visibility_off : Icons.visibility,
|
||||||
|
size: 24,
|
||||||
|
color: Theme.of(context).textTheme.bodyLarge?.color?.withOpacity(0.6),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide.none,
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 8),
|
||||||
|
TextFormField(
|
||||||
|
key: ValueKey('add_passphrase_bottom_sheet_widget_confirm_passphrase_textfield_key'),
|
||||||
|
controller: confirmPassphraseController,
|
||||||
|
obscureText: obscurePassphrase,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
contentPadding: EdgeInsets.symmetric(horizontal: 12),
|
||||||
|
filled: true,
|
||||||
|
fillColor: Theme.of(context).cardColor,
|
||||||
|
hintText: S.of(context).confirm_passphrase,
|
||||||
|
suffixIcon: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
obscurePassphrase = !obscurePassphrase;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Icon(
|
||||||
|
obscurePassphrase ? Icons.visibility_off : Icons.visibility,
|
||||||
|
size: 24,
|
||||||
|
color: Theme.of(context).textTheme.bodyLarge?.color?.withOpacity(0.6),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide.none,
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
validator: (text) {
|
||||||
|
if (text == passphraseController.text) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S.of(context).passphrases_doesnt_match;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
SizedBox(height: 16),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.only(right: 8.0, top: 8.0),
|
||||||
|
child: PrimaryButton(
|
||||||
|
key: ValueKey('add_passphrase_bottom_sheet_widget_cancel_button_key'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
text: S.of(context).cancel,
|
||||||
|
color: Theme.of(context).cardColor,
|
||||||
|
textColor: Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.only(left: 8.0, top: 8.0),
|
||||||
|
child: PrimaryButton(
|
||||||
|
key: ValueKey('add_passphrase_bottom_sheet_widget_restore_button_key'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
widget.onRestoreButtonPressed(passphraseController.text);
|
||||||
|
},
|
||||||
|
text: S.of(context).restore,
|
||||||
|
color: Theme.of(context).primaryColor,
|
||||||
|
textColor: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 24),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -57,7 +57,11 @@ abstract class ContactViewModelBase with Store {
|
||||||
state = IsExecutingState();
|
state = IsExecutingState();
|
||||||
final now = DateTime.now();
|
final now = DateTime.now();
|
||||||
|
|
||||||
if (doesContactNameExist(name)) {
|
final nameExists = _contact == null
|
||||||
|
? doesContactNameExist(name)
|
||||||
|
: doesContactNameExist(name) && _contact.original.name != name;
|
||||||
|
|
||||||
|
if (nameExists) {
|
||||||
state = FailureState(S.current.contact_name_exists);
|
state = FailureState(S.current.contact_name_exists);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -271,10 +271,19 @@ abstract class DashboardViewModelBase with Store {
|
||||||
});
|
});
|
||||||
|
|
||||||
_transactionDisposer?.reaction.dispose();
|
_transactionDisposer?.reaction.dispose();
|
||||||
_transactionDisposer = reaction(
|
_transactionDisposer = reaction((_) {
|
||||||
(_) => appStore.wallet!.transactionHistory.transactions.length,
|
final length = appStore.wallet!.transactionHistory.transactions.length;
|
||||||
_transactionDisposerCallback,
|
if (length == 0) {
|
||||||
);
|
return 0;
|
||||||
|
}
|
||||||
|
int confirmations = 1;
|
||||||
|
if (![WalletType.solana, WalletType.tron].contains(wallet.type)) {
|
||||||
|
try {
|
||||||
|
confirmations = appStore.wallet!.transactionHistory.transactions.values.first.confirmations + 1;
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
return length * confirmations;
|
||||||
|
}, _transactionDisposerCallback);
|
||||||
|
|
||||||
if (hasSilentPayments) {
|
if (hasSilentPayments) {
|
||||||
silentPaymentsScanningActive = bitcoin!.getScanningActive(wallet);
|
silentPaymentsScanningActive = bitcoin!.getScanningActive(wallet);
|
||||||
|
@ -891,8 +900,19 @@ abstract class DashboardViewModelBase with Store {
|
||||||
|
|
||||||
_transactionDisposer?.reaction.dispose();
|
_transactionDisposer?.reaction.dispose();
|
||||||
|
|
||||||
_transactionDisposer = reaction((_) => appStore.wallet!.transactionHistory.transactions.length,
|
_transactionDisposer = reaction((_) {
|
||||||
_transactionDisposerCallback);
|
final length = appStore.wallet!.transactionHistory.transactions.length;
|
||||||
|
if (length == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int confirmations = 1;
|
||||||
|
if (![WalletType.solana, WalletType.tron].contains(wallet.type)) {
|
||||||
|
try {
|
||||||
|
confirmations = appStore.wallet!.transactionHistory.transactions.values.first.confirmations + 1;
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
return length * confirmations;
|
||||||
|
}, _transactionDisposerCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||||
import 'package:cake_wallet/core/address_validator.dart';
|
import 'package:cake_wallet/core/address_validator.dart';
|
||||||
import 'package:cake_wallet/core/amount_validator.dart';
|
import 'package:cake_wallet/core/amount_validator.dart';
|
||||||
|
@ -591,7 +593,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||||
}
|
}
|
||||||
final sharedPreferences = await SharedPreferences.getInstance();
|
final sharedPreferences = await SharedPreferences.getInstance();
|
||||||
await sharedPreferences.setString(PreferencesKey.backgroundSyncLastTrigger(wallet.name), DateTime.now().add(Duration(minutes: 1)).toIso8601String());
|
await sharedPreferences.setString(PreferencesKey.backgroundSyncLastTrigger(wallet.name), DateTime.now().add(Duration(minutes: 1)).toIso8601String());
|
||||||
|
unawaited(wallet.fetchTransactions());
|
||||||
state = TransactionCommitted();
|
state = TransactionCommitted();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
state = FailureState(translateErrorMessage(e, wallet.type, wallet.currency));
|
state = FailureState(translateErrorMessage(e, wallet.type, wallet.currency));
|
||||||
|
|
|
@ -43,6 +43,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||||
type == WalletType.solana ||
|
type == WalletType.solana ||
|
||||||
type == WalletType.tron,
|
type == WalletType.tron,
|
||||||
isButtonEnabled = false,
|
isButtonEnabled = false,
|
||||||
|
hasPassphrase = false,
|
||||||
mode = restoredWallet?.restoreMode ?? WalletRestoreMode.seed,
|
mode = restoredWallet?.restoreMode ?? WalletRestoreMode.seed,
|
||||||
super(appStore, walletInfoSource, walletCreationService, seedSettingsViewModel,
|
super(appStore, walletInfoSource, walletCreationService, seedSettingsViewModel,
|
||||||
type: type, isRecovery: true) {
|
type: type, isRecovery: true) {
|
||||||
|
@ -89,6 +90,9 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||||
@observable
|
@observable
|
||||||
WalletRestoreMode mode;
|
WalletRestoreMode mode;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
bool hasPassphrase;
|
||||||
|
|
||||||
@observable
|
@observable
|
||||||
bool isButtonEnabled;
|
bool isButtonEnabled;
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "أضف أموالاً مدفوعة مسبقًا إلى البطاقات (حتى ${value})",
|
"add_fund_to_card": "أضف أموالاً مدفوعة مسبقًا إلى البطاقات (حتى ${value})",
|
||||||
"add_new_node": "أضافة عقدة جديدة",
|
"add_new_node": "أضافة عقدة جديدة",
|
||||||
"add_new_word": "أضف كلمة جديدة",
|
"add_new_word": "أضف كلمة جديدة",
|
||||||
|
"add_passphrase": "أضف عبارة المرور",
|
||||||
|
"add_passphrase_warning_text": "أدخل عبارة المرور فقط إذا كنت قد استخدمت واحدة لهذه المحفظة في الماضي. إذا أدخلت عبارة الممر الخاطئ أو لم تستخدم عبارة تمريرة من قبل على هذه المحفظة ، فلن ترى أيًا من الأموال أو التاريخ الحالي.",
|
||||||
"add_receiver": "أضف مستقبل آخر (اختياري)",
|
"add_receiver": "أضف مستقبل آخر (اختياري)",
|
||||||
"add_secret_code": " ﺔﻗﺩﺎﺼﻤﻟﺍ ﻖﻴﺒﻄﺗ ﻰﻟﺇ ﻱﺮﺴﻟﺍ ﺰﻣﺮﻟﺍ ﺍﺬﻫ ﻒﺿﺃ ﻭﺃ",
|
"add_secret_code": " ﺔﻗﺩﺎﺼﻤﻟﺍ ﻖﻴﺒﻄﺗ ﻰﻟﺇ ﻱﺮﺴﻟﺍ ﺰﻣﺮﻟﺍ ﺍﺬﻫ ﻒﺿﺃ ﻭﺃ",
|
||||||
"add_tip": "أضف بقشيش",
|
"add_tip": "أضف بقشيش",
|
||||||
|
@ -621,10 +623,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "تتطلب عمليات الإرسال إلى المحافظ الداخلية",
|
"require_for_sends_to_internal_wallets": "تتطلب عمليات الإرسال إلى المحافظ الداخلية",
|
||||||
"require_for_sends_to_non_contacts": "تتطلب لارسال لغير جهات الاتصال",
|
"require_for_sends_to_non_contacts": "تتطلب لارسال لغير جهات الاتصال",
|
||||||
"require_pin_after": "طلب PIN بعد",
|
"require_pin_after": "طلب PIN بعد",
|
||||||
|
"required_passphrase": "عبارة المرور",
|
||||||
"rescan": "إعادة الفحص",
|
"rescan": "إعادة الفحص",
|
||||||
"resend_code": "الرجاء إعادة إرسالها",
|
"resend_code": "الرجاء إعادة إرسالها",
|
||||||
"reset": "إعادة",
|
"reset": "إعادة",
|
||||||
"reset_password": "إعادة تعيين كلمة المرور",
|
"reset_password": "إعادة تعيين كلمة المرور",
|
||||||
|
"restore": "يعيد",
|
||||||
"restore_active_seed": "السييد النشطة",
|
"restore_active_seed": "السييد النشطة",
|
||||||
"restore_address": "العنوان",
|
"restore_address": "العنوان",
|
||||||
"restore_bitcoin_description_from_keys": "قم باستعادة محفظتك من سلسلة WIF التي تم إنشاؤها من مفاتيحك الخاصة",
|
"restore_bitcoin_description_from_keys": "قم باستعادة محفظتك من سلسلة WIF التي تم إنشاؤها من مفاتيحك الخاصة",
|
||||||
|
@ -999,6 +1003,7 @@
|
||||||
"wallet_group_description_view_seed": "يمكنك دائمًا عرض هذه البذرة مرة أخرى تحت",
|
"wallet_group_description_view_seed": "يمكنك دائمًا عرض هذه البذرة مرة أخرى تحت",
|
||||||
"wallet_group_empty_state_text_one": "يبدو أنه ليس لديك أي مجموعات محفظة متوافقة !\n\n انقر",
|
"wallet_group_empty_state_text_one": "يبدو أنه ليس لديك أي مجموعات محفظة متوافقة !\n\n انقر",
|
||||||
"wallet_group_empty_state_text_two": "أدناه لجعل واحدة جديدة.",
|
"wallet_group_empty_state_text_two": "أدناه لجعل واحدة جديدة.",
|
||||||
|
"wallet_has_passphrase": "هذه المحفظة تحتوي على عبارة ممر",
|
||||||
"wallet_keys": "سييد المحفظة / المفاتيح",
|
"wallet_keys": "سييد المحفظة / المفاتيح",
|
||||||
"wallet_list_create_new_wallet": "إنشاء محفظة جديدة",
|
"wallet_list_create_new_wallet": "إنشاء محفظة جديدة",
|
||||||
"wallet_list_edit_group_name": "تحرير اسم المجموعة",
|
"wallet_list_edit_group_name": "تحرير اسم المجموعة",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "Добавете предплатени средства в картите (до ${value})",
|
"add_fund_to_card": "Добавете предплатени средства в картите (до ${value})",
|
||||||
"add_new_node": "Добави нов node",
|
"add_new_node": "Добави нов node",
|
||||||
"add_new_word": "Добавяне на нова дума",
|
"add_new_word": "Добавяне на нова дума",
|
||||||
|
"add_passphrase": "Добавете парола",
|
||||||
|
"add_passphrase_warning_text": "Въведете парола само ако сте използвали такава за този портфейл в миналото. Ако въведете грешна парола или не сте използвали парола преди в този портфейл, няма да видите нито един от съществуващите средства или история.",
|
||||||
"add_receiver": "Добавяне на друг получател (не е задължително)",
|
"add_receiver": "Добавяне на друг получател (не е задължително)",
|
||||||
"add_secret_code": "Или добавете този таен код към приложение за удостоверяване",
|
"add_secret_code": "Или добавете този таен код към приложение за удостоверяване",
|
||||||
"add_tip": "Add Tip",
|
"add_tip": "Add Tip",
|
||||||
|
@ -621,10 +623,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "Изискване за изпращане до вътрешни портфейли",
|
"require_for_sends_to_internal_wallets": "Изискване за изпращане до вътрешни портфейли",
|
||||||
"require_for_sends_to_non_contacts": "Изискване за изпращане до лица без контакт",
|
"require_for_sends_to_non_contacts": "Изискване за изпращане до лица без контакт",
|
||||||
"require_pin_after": "Въведете PIN след",
|
"require_pin_after": "Въведете PIN след",
|
||||||
|
"required_passphrase": "Парола",
|
||||||
"rescan": "Сканирай отново",
|
"rescan": "Сканирай отново",
|
||||||
"resend_code": "Повторно изпращане",
|
"resend_code": "Повторно изпращане",
|
||||||
"reset": "Нулиране",
|
"reset": "Нулиране",
|
||||||
"reset_password": "Нулиране на парола",
|
"reset_password": "Нулиране на парола",
|
||||||
|
"restore": "Възстановяване",
|
||||||
"restore_active_seed": "Активиране на seed",
|
"restore_active_seed": "Активиране на seed",
|
||||||
"restore_address": "Адреси",
|
"restore_address": "Адреси",
|
||||||
"restore_bitcoin_description_from_keys": "Възстановяване на портфейл чрез WIF, изведен от Вашите private keys",
|
"restore_bitcoin_description_from_keys": "Възстановяване на портфейл чрез WIF, изведен от Вашите private keys",
|
||||||
|
@ -999,6 +1003,7 @@
|
||||||
"wallet_group_description_view_seed": "Винаги можете да видите това семе отново под",
|
"wallet_group_description_view_seed": "Винаги можете да видите това семе отново под",
|
||||||
"wallet_group_empty_state_text_one": "Изглежда, че нямате съвместими групи портфейли !\n\n tap",
|
"wallet_group_empty_state_text_one": "Изглежда, че нямате съвместими групи портфейли !\n\n tap",
|
||||||
"wallet_group_empty_state_text_two": "по -долу, за да се направи нов.",
|
"wallet_group_empty_state_text_two": "по -долу, за да се направи нов.",
|
||||||
|
"wallet_has_passphrase": "Този портфейл има парола",
|
||||||
"wallet_keys": "Seed/keys на портфейла",
|
"wallet_keys": "Seed/keys на портфейла",
|
||||||
"wallet_list_create_new_wallet": "Създаване на нов портфейл",
|
"wallet_list_create_new_wallet": "Създаване на нов портфейл",
|
||||||
"wallet_list_edit_group_name": "Редактиране на име на групата",
|
"wallet_list_edit_group_name": "Редактиране на име на групата",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "Všechny předplacené prostředky na kartě (až ${value})",
|
"add_fund_to_card": "Všechny předplacené prostředky na kartě (až ${value})",
|
||||||
"add_new_node": "Přidat nový uzel",
|
"add_new_node": "Přidat nový uzel",
|
||||||
"add_new_word": "Přidat nové slovo",
|
"add_new_word": "Přidat nové slovo",
|
||||||
|
"add_passphrase": "Přidejte přístupovou frázi",
|
||||||
|
"add_passphrase_warning_text": "Zadejte přístupovou frázi pouze tehdy, pokud jste ji v minulosti použili pro tuto peněženku. Pokud zadáte nesprávnou přístupovou frázi nebo jste na této peněžence nepoužili přístupovou frázi, neuvidíte žádnou existující fondy nebo historii.",
|
||||||
"add_receiver": "Přidat dalšího příjemce (nepovinné)",
|
"add_receiver": "Přidat dalšího příjemce (nepovinné)",
|
||||||
"add_secret_code": "Nebo přidejte tento tajný kód do ověřovací aplikace",
|
"add_secret_code": "Nebo přidejte tento tajný kód do ověřovací aplikace",
|
||||||
"add_tip": "Přidat spropitné",
|
"add_tip": "Přidat spropitné",
|
||||||
|
@ -621,10 +623,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "Vyžadovat pro odesílání do interních peněženek",
|
"require_for_sends_to_internal_wallets": "Vyžadovat pro odesílání do interních peněženek",
|
||||||
"require_for_sends_to_non_contacts": "Vyžadovat pro odesílání nekontaktním osobám",
|
"require_for_sends_to_non_contacts": "Vyžadovat pro odesílání nekontaktním osobám",
|
||||||
"require_pin_after": "Vyžadovat PIN po",
|
"require_pin_after": "Vyžadovat PIN po",
|
||||||
|
"required_passphrase": "Passphrase",
|
||||||
"rescan": "Znovu prohledat",
|
"rescan": "Znovu prohledat",
|
||||||
"resend_code": "Prosím poslat znovu",
|
"resend_code": "Prosím poslat znovu",
|
||||||
"reset": "Vymazat",
|
"reset": "Vymazat",
|
||||||
"reset_password": "Resetovat heslo",
|
"reset_password": "Resetovat heslo",
|
||||||
|
"restore": "Obnovit",
|
||||||
"restore_active_seed": "Aktivní seed",
|
"restore_active_seed": "Aktivní seed",
|
||||||
"restore_address": "Adresa",
|
"restore_address": "Adresa",
|
||||||
"restore_bitcoin_description_from_keys": "Obnovte svou peněženku pomocí vygenerovaného WIF řetězce z vašich soukromých klíčů",
|
"restore_bitcoin_description_from_keys": "Obnovte svou peněženku pomocí vygenerovaného WIF řetězce z vašich soukromých klíčů",
|
||||||
|
@ -999,6 +1003,7 @@
|
||||||
"wallet_group_description_view_seed": "Toto semeno si můžete vždy znovu prohlédnout",
|
"wallet_group_description_view_seed": "Toto semeno si můžete vždy znovu prohlédnout",
|
||||||
"wallet_group_empty_state_text_one": "Vypadá to, že nemáte žádné kompatibilní skupiny peněženky !\n\n",
|
"wallet_group_empty_state_text_one": "Vypadá to, že nemáte žádné kompatibilní skupiny peněženky !\n\n",
|
||||||
"wallet_group_empty_state_text_two": "Níže vytvořit nový.",
|
"wallet_group_empty_state_text_two": "Níže vytvořit nový.",
|
||||||
|
"wallet_has_passphrase": "Tato peněženka má přístupovou frázi",
|
||||||
"wallet_keys": "Seed/klíče peněženky",
|
"wallet_keys": "Seed/klíče peněženky",
|
||||||
"wallet_list_create_new_wallet": "Vytvořit novou peněženku",
|
"wallet_list_create_new_wallet": "Vytvořit novou peněženku",
|
||||||
"wallet_list_edit_group_name": "Upravit název skupiny",
|
"wallet_list_edit_group_name": "Upravit název skupiny",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "Prepaid-Guthaben zu den Karten hinzufügen (bis zu ${value})",
|
"add_fund_to_card": "Prepaid-Guthaben zu den Karten hinzufügen (bis zu ${value})",
|
||||||
"add_new_node": "Neuen Knoten hinzufügen",
|
"add_new_node": "Neuen Knoten hinzufügen",
|
||||||
"add_new_word": "Neues Wort hinzufügen",
|
"add_new_word": "Neues Wort hinzufügen",
|
||||||
|
"add_passphrase": "Fügen Sie Passphrase hinzu",
|
||||||
|
"add_passphrase_warning_text": "Geben Sie nur eine Passphrase ein, wenn Sie in der Vergangenheit eine für diese Brieftasche verwendet haben. Wenn Sie die falsche Passphrase eingeben oder in dieser Brieftasche noch keine Passphrase verwendet haben, werden Sie keine vorhandenen Gelder oder Geschichte sehen.",
|
||||||
"add_receiver": "Fügen Sie einen weiteren Empfänger hinzu (optional)",
|
"add_receiver": "Fügen Sie einen weiteren Empfänger hinzu (optional)",
|
||||||
"add_secret_code": "Oder fügen Sie diesen Geheimcode einer Authentifizierungs-App hinzu",
|
"add_secret_code": "Oder fügen Sie diesen Geheimcode einer Authentifizierungs-App hinzu",
|
||||||
"add_tip": "Tipp hinzufügen",
|
"add_tip": "Tipp hinzufügen",
|
||||||
|
@ -73,10 +75,10 @@
|
||||||
"awaiting_payment_confirmation": "Warten auf Zahlungsbestätigung",
|
"awaiting_payment_confirmation": "Warten auf Zahlungsbestätigung",
|
||||||
"background_sync": "Hintergrundsynchronisation",
|
"background_sync": "Hintergrundsynchronisation",
|
||||||
"background_sync_mode": "Hintergrundsynchronisierungsmodus",
|
"background_sync_mode": "Hintergrundsynchronisierungsmodus",
|
||||||
"background_sync_on_battery_low": "Synchronisieren Sie einen niedrigen Akku",
|
"background_sync_on_battery_low": "Bei niedrigem Akkustand synchronisieren",
|
||||||
"background_sync_on_charging": "Nur beim Laden synchronisieren",
|
"background_sync_on_charging": "Nur beim Laden synchronisieren",
|
||||||
"background_sync_on_device_idle": "Nur dann synchronisieren, wenn das Gerät nicht verwendet wird",
|
"background_sync_on_device_idle": "Nur dann synchronisieren, wenn das Gerät nicht verwendet wird",
|
||||||
"background_sync_on_unmetered_network": "Erfordern ein nicht modisches Netzwerk",
|
"background_sync_on_unmetered_network": "Erfordere ein ungetaktetes Netzwerk",
|
||||||
"backup": "Sicherung",
|
"backup": "Sicherung",
|
||||||
"backup_file": "Sicherungsdatei",
|
"backup_file": "Sicherungsdatei",
|
||||||
"backup_password": "Passwort sichern",
|
"backup_password": "Passwort sichern",
|
||||||
|
@ -276,7 +278,7 @@
|
||||||
"enable_mempool_api": "Mempool-API für genaue Gebühren und Daten",
|
"enable_mempool_api": "Mempool-API für genaue Gebühren und Daten",
|
||||||
"enable_replace_by_fee": "Aktivieren Sie Ersatz für Fee",
|
"enable_replace_by_fee": "Aktivieren Sie Ersatz für Fee",
|
||||||
"enable_silent_payments_scanning": "Scannen Sie nach Silent Payments ihrer Adresse",
|
"enable_silent_payments_scanning": "Scannen Sie nach Silent Payments ihrer Adresse",
|
||||||
"enabled": "Ermöglicht",
|
"enabled": "Aktiviert",
|
||||||
"enter_amount": "Betrag eingeben",
|
"enter_amount": "Betrag eingeben",
|
||||||
"enter_backup_password": "Sicherungskennwort hier eingeben",
|
"enter_backup_password": "Sicherungskennwort hier eingeben",
|
||||||
"enter_code": "Code eingeben",
|
"enter_code": "Code eingeben",
|
||||||
|
@ -622,10 +624,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "Erforderlich für Sendungen an interne Wallets",
|
"require_for_sends_to_internal_wallets": "Erforderlich für Sendungen an interne Wallets",
|
||||||
"require_for_sends_to_non_contacts": "Erforderlich für Versendungen an Nichtkontakte",
|
"require_for_sends_to_non_contacts": "Erforderlich für Versendungen an Nichtkontakte",
|
||||||
"require_pin_after": "PIN anfordern nach",
|
"require_pin_after": "PIN anfordern nach",
|
||||||
|
"required_passphrase": "Passphrase",
|
||||||
"rescan": "Erneut scannen",
|
"rescan": "Erneut scannen",
|
||||||
"resend_code": "Bitte erneut senden",
|
"resend_code": "Bitte erneut senden",
|
||||||
"reset": "Zurücksetzen",
|
"reset": "Zurücksetzen",
|
||||||
"reset_password": "Passwort zurücksetzen",
|
"reset_password": "Passwort zurücksetzen",
|
||||||
|
"restore": "Wiederherstellen",
|
||||||
"restore_active_seed": "Aktiver Seed",
|
"restore_active_seed": "Aktiver Seed",
|
||||||
"restore_address": "Adresse",
|
"restore_address": "Adresse",
|
||||||
"restore_bitcoin_description_from_keys": "Stellen Sie Ihre Wallet aus der generierten WIF-Zeichenfolge aus Ihren privaten Schlüsseln wieder her",
|
"restore_bitcoin_description_from_keys": "Stellen Sie Ihre Wallet aus der generierten WIF-Zeichenfolge aus Ihren privaten Schlüsseln wieder her",
|
||||||
|
@ -1002,6 +1006,7 @@
|
||||||
"wallet_group_description_view_seed": "Sie können diesen Seed immer wieder untersuchen",
|
"wallet_group_description_view_seed": "Sie können diesen Seed immer wieder untersuchen",
|
||||||
"wallet_group_empty_state_text_one": "Sieht so aus, als hätten Sie keine kompatiblen Walletgruppen !\n\n TAP",
|
"wallet_group_empty_state_text_one": "Sieht so aus, als hätten Sie keine kompatiblen Walletgruppen !\n\n TAP",
|
||||||
"wallet_group_empty_state_text_two": "unten, um einen neuen zu machen.",
|
"wallet_group_empty_state_text_two": "unten, um einen neuen zu machen.",
|
||||||
|
"wallet_has_passphrase": "Diese Brieftasche hat eine Passphrase",
|
||||||
"wallet_keys": "Wallet-Seed/-Schlüssel",
|
"wallet_keys": "Wallet-Seed/-Schlüssel",
|
||||||
"wallet_list_create_new_wallet": "Neue Wallet erstellen",
|
"wallet_list_create_new_wallet": "Neue Wallet erstellen",
|
||||||
"wallet_list_edit_group_name": "Gruppenname bearbeiten",
|
"wallet_list_edit_group_name": "Gruppenname bearbeiten",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "Add prepaid funds to the cards (up to ${value})",
|
"add_fund_to_card": "Add prepaid funds to the cards (up to ${value})",
|
||||||
"add_new_node": "Add new node",
|
"add_new_node": "Add new node",
|
||||||
"add_new_word": "Add new word",
|
"add_new_word": "Add new word",
|
||||||
|
"add_passphrase": "Add Passphrase",
|
||||||
|
"add_passphrase_warning_text": "Only enter a passphrase if you have used one for this wallet in the past. If you enter the wrong passphrase or have not used a passphrase before on this wallet, you won't see any of existing funds or history.",
|
||||||
"add_receiver": "Add another receiver (optional)",
|
"add_receiver": "Add another receiver (optional)",
|
||||||
"add_secret_code": "Or, add this secret code to an authenticator app",
|
"add_secret_code": "Or, add this secret code to an authenticator app",
|
||||||
"add_tip": "Add Tip",
|
"add_tip": "Add Tip",
|
||||||
|
@ -76,7 +78,7 @@
|
||||||
"background_sync_on_battery_low": "Synchronize on low battery",
|
"background_sync_on_battery_low": "Synchronize on low battery",
|
||||||
"background_sync_on_charging": "Synchronize only when charging",
|
"background_sync_on_charging": "Synchronize only when charging",
|
||||||
"background_sync_on_device_idle": "Synchronize only when device is not being used",
|
"background_sync_on_device_idle": "Synchronize only when device is not being used",
|
||||||
"background_sync_on_unmetered_network": "Require unmetred network",
|
"background_sync_on_unmetered_network": "Require unmetered network",
|
||||||
"backup": "Backup",
|
"backup": "Backup",
|
||||||
"backup_file": "Backup file",
|
"backup_file": "Backup file",
|
||||||
"backup_password": "Backup password",
|
"backup_password": "Backup password",
|
||||||
|
@ -622,10 +624,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "Require for sends to internal wallets",
|
"require_for_sends_to_internal_wallets": "Require for sends to internal wallets",
|
||||||
"require_for_sends_to_non_contacts": "Require for sends to non-contacts",
|
"require_for_sends_to_non_contacts": "Require for sends to non-contacts",
|
||||||
"require_pin_after": "Require PIN after",
|
"require_pin_after": "Require PIN after",
|
||||||
|
"required_passphrase": "Passphrase",
|
||||||
"rescan": "Rescan",
|
"rescan": "Rescan",
|
||||||
"resend_code": "Please resend it",
|
"resend_code": "Please resend it",
|
||||||
"reset": "Reset",
|
"reset": "Reset",
|
||||||
"reset_password": "Reset Password",
|
"reset_password": "Reset Password",
|
||||||
|
"restore": "Restore",
|
||||||
"restore_active_seed": "Active seed",
|
"restore_active_seed": "Active seed",
|
||||||
"restore_address": "Address",
|
"restore_address": "Address",
|
||||||
"restore_bitcoin_description_from_keys": "Restore your wallet from generated WIF string from your private keys",
|
"restore_bitcoin_description_from_keys": "Restore your wallet from generated WIF string from your private keys",
|
||||||
|
@ -1000,6 +1004,7 @@
|
||||||
"wallet_group_description_view_seed": "You can always view this seed again under",
|
"wallet_group_description_view_seed": "You can always view this seed again under",
|
||||||
"wallet_group_empty_state_text_one": "Looks like you don't have any compatible wallet groups!\n\nTap",
|
"wallet_group_empty_state_text_one": "Looks like you don't have any compatible wallet groups!\n\nTap",
|
||||||
"wallet_group_empty_state_text_two": "below to make a new one.",
|
"wallet_group_empty_state_text_two": "below to make a new one.",
|
||||||
|
"wallet_has_passphrase": "This wallet has a passphrase",
|
||||||
"wallet_keys": "Wallet seed/keys",
|
"wallet_keys": "Wallet seed/keys",
|
||||||
"wallet_list_create_new_wallet": "Create New Wallet",
|
"wallet_list_create_new_wallet": "Create New Wallet",
|
||||||
"wallet_list_edit_group_name": "Edit Group Name",
|
"wallet_list_edit_group_name": "Edit Group Name",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "Agregar fondos prepagos a las tarjetas (hasta ${value})",
|
"add_fund_to_card": "Agregar fondos prepagos a las tarjetas (hasta ${value})",
|
||||||
"add_new_node": "Agregar nuevo nodo",
|
"add_new_node": "Agregar nuevo nodo",
|
||||||
"add_new_word": "Agregar palabra nueva",
|
"add_new_word": "Agregar palabra nueva",
|
||||||
|
"add_passphrase": "Agregar frase de pases",
|
||||||
|
"add_passphrase_warning_text": "Solo ingrese una frase de pases si ha usado una para esta billetera en el pasado. Si ingresa a la frase de pases incorrecta o no ha utilizado una frase de pases antes en esta billetera, no verá ninguno de los fondos o historial existentes.",
|
||||||
"add_receiver": "Agregar otro receptor (opcional)",
|
"add_receiver": "Agregar otro receptor (opcional)",
|
||||||
"add_secret_code": "O agregue este código secreto a una aplicación de autenticación",
|
"add_secret_code": "O agregue este código secreto a una aplicación de autenticación",
|
||||||
"add_tip": "Agregar sugerencia",
|
"add_tip": "Agregar sugerencia",
|
||||||
|
@ -622,10 +624,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "Requerido para envíos a billeteras internas",
|
"require_for_sends_to_internal_wallets": "Requerido para envíos a billeteras internas",
|
||||||
"require_for_sends_to_non_contacts": "Requerido para envíos a no contactos",
|
"require_for_sends_to_non_contacts": "Requerido para envíos a no contactos",
|
||||||
"require_pin_after": "Requerir PIN después de",
|
"require_pin_after": "Requerir PIN después de",
|
||||||
|
"required_passphrase": "Frase",
|
||||||
"rescan": "Reescanear",
|
"rescan": "Reescanear",
|
||||||
"resend_code": "Por favor reenvíalo",
|
"resend_code": "Por favor reenvíalo",
|
||||||
"reset": "Reiniciar",
|
"reset": "Reiniciar",
|
||||||
"reset_password": "Restablecer contraseña",
|
"reset_password": "Restablecer contraseña",
|
||||||
|
"restore": "Restaurar",
|
||||||
"restore_active_seed": "Semilla activa",
|
"restore_active_seed": "Semilla activa",
|
||||||
"restore_address": "Dirección",
|
"restore_address": "Dirección",
|
||||||
"restore_bitcoin_description_from_keys": "Restaure su billetera a partir de una cadena WIF generada a partir de sus claves privadas",
|
"restore_bitcoin_description_from_keys": "Restaure su billetera a partir de una cadena WIF generada a partir de sus claves privadas",
|
||||||
|
@ -1000,6 +1004,7 @@
|
||||||
"wallet_group_description_view_seed": "Siempre puedes ver esta semilla nuevamente debajo",
|
"wallet_group_description_view_seed": "Siempre puedes ver esta semilla nuevamente debajo",
|
||||||
"wallet_group_empty_state_text_one": "Parece que no tienes ningún grupo de billetera compatible !\n\n toque",
|
"wallet_group_empty_state_text_one": "Parece que no tienes ningún grupo de billetera compatible !\n\n toque",
|
||||||
"wallet_group_empty_state_text_two": "a continuación para hacer uno nuevo.",
|
"wallet_group_empty_state_text_two": "a continuación para hacer uno nuevo.",
|
||||||
|
"wallet_has_passphrase": "Esta billetera tiene una frase de pases",
|
||||||
"wallet_keys": "Billetera semilla/claves",
|
"wallet_keys": "Billetera semilla/claves",
|
||||||
"wallet_list_create_new_wallet": "Crear nueva billetera",
|
"wallet_list_create_new_wallet": "Crear nueva billetera",
|
||||||
"wallet_list_edit_group_name": "Editar nombre de grupo",
|
"wallet_list_edit_group_name": "Editar nombre de grupo",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "Ajouter des fonds prépayés aux cartes (jusqu'à ${value})",
|
"add_fund_to_card": "Ajouter des fonds prépayés aux cartes (jusqu'à ${value})",
|
||||||
"add_new_node": "Ajouter un nouveau nœud",
|
"add_new_node": "Ajouter un nouveau nœud",
|
||||||
"add_new_word": "Ajouter un nouveau mot",
|
"add_new_word": "Ajouter un nouveau mot",
|
||||||
|
"add_passphrase": "Ajouter la phrase secrète",
|
||||||
|
"add_passphrase_warning_text": "Entrez une phrase secrète si vous en avez utilisé un pour ce portefeuille dans le passé. Si vous entrez dans la mauvaise phrase de passe ou si vous n'avez pas utilisé de phrase de passe auparavant sur ce portefeuille, vous ne verrez aucun fonds ou historique existant.",
|
||||||
"add_receiver": "Ajouter un autre bénéficiaire (optionnel)",
|
"add_receiver": "Ajouter un autre bénéficiaire (optionnel)",
|
||||||
"add_secret_code": "Ou ajoutez ce code secret à une application d'authentification",
|
"add_secret_code": "Ou ajoutez ce code secret à une application d'authentification",
|
||||||
"add_tip": "Ajouter un pourboire",
|
"add_tip": "Ajouter un pourboire",
|
||||||
|
@ -621,10 +623,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "Exiger pour les envois vers des portefeuilles (wallets) internes",
|
"require_for_sends_to_internal_wallets": "Exiger pour les envois vers des portefeuilles (wallets) internes",
|
||||||
"require_for_sends_to_non_contacts": "Exiger pour les envois hors contacts",
|
"require_for_sends_to_non_contacts": "Exiger pour les envois hors contacts",
|
||||||
"require_pin_after": "Code PIN requis après",
|
"require_pin_after": "Code PIN requis après",
|
||||||
|
"required_passphrase": "Phrase secrète",
|
||||||
"rescan": "Analyser la blockchain",
|
"rescan": "Analyser la blockchain",
|
||||||
"resend_code": "Veuillez le renvoyer",
|
"resend_code": "Veuillez le renvoyer",
|
||||||
"reset": "Réinitialiser",
|
"reset": "Réinitialiser",
|
||||||
"reset_password": "Réinitialiser le mot de passe",
|
"reset_password": "Réinitialiser le mot de passe",
|
||||||
|
"restore": "Restaurer",
|
||||||
"restore_active_seed": "Phrase secrète (seed) active",
|
"restore_active_seed": "Phrase secrète (seed) active",
|
||||||
"restore_address": "Adresse",
|
"restore_address": "Adresse",
|
||||||
"restore_bitcoin_description_from_keys": "Restaurer votre portefeuille (wallet) d'après la chaîne WIF générée d'après vos clefs privées",
|
"restore_bitcoin_description_from_keys": "Restaurer votre portefeuille (wallet) d'après la chaîne WIF générée d'après vos clefs privées",
|
||||||
|
@ -999,6 +1003,7 @@
|
||||||
"wallet_group_description_view_seed": "Vous pouvez toujours revoir cette graine sous",
|
"wallet_group_description_view_seed": "Vous pouvez toujours revoir cette graine sous",
|
||||||
"wallet_group_empty_state_text_one": "On dirait que vous n'avez pas de groupes de portefeuilles compatibles !\n\n Tap",
|
"wallet_group_empty_state_text_one": "On dirait que vous n'avez pas de groupes de portefeuilles compatibles !\n\n Tap",
|
||||||
"wallet_group_empty_state_text_two": "Ci-dessous pour en faire un nouveau.",
|
"wallet_group_empty_state_text_two": "Ci-dessous pour en faire un nouveau.",
|
||||||
|
"wallet_has_passphrase": "Ce portefeuille a une phrase secrète",
|
||||||
"wallet_keys": "Phrase secrète (seed)/Clefs du portefeuille (wallet)",
|
"wallet_keys": "Phrase secrète (seed)/Clefs du portefeuille (wallet)",
|
||||||
"wallet_list_create_new_wallet": "Créer un Nouveau Portefeuille (Wallet)",
|
"wallet_list_create_new_wallet": "Créer un Nouveau Portefeuille (Wallet)",
|
||||||
"wallet_list_edit_group_name": "Modifier le nom du groupe",
|
"wallet_list_edit_group_name": "Modifier le nom du groupe",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "Ƙara kuɗin da aka riga aka biya a katunan (har zuwa ${value})",
|
"add_fund_to_card": "Ƙara kuɗin da aka riga aka biya a katunan (har zuwa ${value})",
|
||||||
"add_new_node": "Ƙara sabon node",
|
"add_new_node": "Ƙara sabon node",
|
||||||
"add_new_word": "Ƙara kalma sabuwa",
|
"add_new_word": "Ƙara kalma sabuwa",
|
||||||
|
"add_passphrase": "Addara fasphrase",
|
||||||
|
"add_passphrase_warning_text": "Kawai shigar da kalmar wucewa idan kun yi amfani da ɗaya don wannan walat a baya. Idan ka shigar da kalmar wucewa ko ba a yi amfani da kalmar wucewa ba kafin a wannan waljin, ba za ka ga wani kudaden da ake da su ba ko tarihi.",
|
||||||
"add_receiver": "Ƙara wani mai karɓa (na zaɓi)",
|
"add_receiver": "Ƙara wani mai karɓa (na zaɓi)",
|
||||||
"add_secret_code": "Ko, ƙara wannan lambar sirrin zuwa ƙa'idar mai tabbatarwa",
|
"add_secret_code": "Ko, ƙara wannan lambar sirrin zuwa ƙa'idar mai tabbatarwa",
|
||||||
"add_tip": "Ƙara Tukwici",
|
"add_tip": "Ƙara Tukwici",
|
||||||
|
@ -623,10 +625,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "Bukatar aika zuwa wallet na ciki",
|
"require_for_sends_to_internal_wallets": "Bukatar aika zuwa wallet na ciki",
|
||||||
"require_for_sends_to_non_contacts": "Bukatar aika zuwa waɗanda ba lambobin sadarwa ba",
|
"require_for_sends_to_non_contacts": "Bukatar aika zuwa waɗanda ba lambobin sadarwa ba",
|
||||||
"require_pin_after": "Bukatar PIN bayan",
|
"require_pin_after": "Bukatar PIN bayan",
|
||||||
|
"required_passphrase": "Mashiganya",
|
||||||
"rescan": "Rescan",
|
"rescan": "Rescan",
|
||||||
"resend_code": "Da fatan za a sake aika shi",
|
"resend_code": "Da fatan za a sake aika shi",
|
||||||
"reset": "Sake saiti",
|
"reset": "Sake saiti",
|
||||||
"reset_password": "Sake saita kalmar wucewa",
|
"reset_password": "Sake saita kalmar wucewa",
|
||||||
|
"restore": "Sabunta",
|
||||||
"restore_active_seed": "iri mai aiki",
|
"restore_active_seed": "iri mai aiki",
|
||||||
"restore_address": "Address",
|
"restore_address": "Address",
|
||||||
"restore_bitcoin_description_from_keys": "Dawo da kwalinku daga WIF string dake generate daga maɓallan sirri",
|
"restore_bitcoin_description_from_keys": "Dawo da kwalinku daga WIF string dake generate daga maɓallan sirri",
|
||||||
|
@ -1001,6 +1005,7 @@
|
||||||
"wallet_group_description_view_seed": "Koyaushe zaka iya duba wannan zuriya",
|
"wallet_group_description_view_seed": "Koyaushe zaka iya duba wannan zuriya",
|
||||||
"wallet_group_empty_state_text_one": "Kamar dai ba ku da wata ƙungiya matattara !\n\n Taɓa",
|
"wallet_group_empty_state_text_one": "Kamar dai ba ku da wata ƙungiya matattara !\n\n Taɓa",
|
||||||
"wallet_group_empty_state_text_two": "da ke ƙasa don yin sabo.",
|
"wallet_group_empty_state_text_two": "da ke ƙasa don yin sabo.",
|
||||||
|
"wallet_has_passphrase": "Wannan walat ɗin yana da kalmar wucewa",
|
||||||
"wallet_keys": "Iri/maɓalli na walat",
|
"wallet_keys": "Iri/maɓalli na walat",
|
||||||
"wallet_list_create_new_wallet": "Ƙirƙiri Sabon Wallet",
|
"wallet_list_create_new_wallet": "Ƙirƙiri Sabon Wallet",
|
||||||
"wallet_list_edit_group_name": "Shirya sunan rukuni",
|
"wallet_list_edit_group_name": "Shirya sunan rukuni",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "कार्ड में प्रीपेड धनराशि जोड़ें (${value} तक)",
|
"add_fund_to_card": "कार्ड में प्रीपेड धनराशि जोड़ें (${value} तक)",
|
||||||
"add_new_node": "नया नोड जोड़ें",
|
"add_new_node": "नया नोड जोड़ें",
|
||||||
"add_new_word": "नया शब्द जोड़ें",
|
"add_new_word": "नया शब्द जोड़ें",
|
||||||
|
"add_passphrase": "पासफ़्रेज़ जोड़ें",
|
||||||
|
"add_passphrase_warning_text": "यदि आपने अतीत में इस बटुए के लिए एक का उपयोग किया है, तो केवल एक पासफ्रेज़ दर्ज करें। यदि आप गलत पासफ्रेज़ में प्रवेश करते हैं या इस वॉलेट पर पहले पासफ्रेज़ का उपयोग नहीं करते हैं, तो आप मौजूदा फंड या इतिहास में से कोई भी नहीं देखेंगे।",
|
||||||
"add_receiver": "एक और रिसीवर जोड़ें (वैकल्पिक)",
|
"add_receiver": "एक और रिसीवर जोड़ें (वैकल्पिक)",
|
||||||
"add_secret_code": "या, इस गुप्त कोड को प्रमाणक ऐप में जोड़ें",
|
"add_secret_code": "या, इस गुप्त कोड को प्रमाणक ऐप में जोड़ें",
|
||||||
"add_tip": "टिप जोड़ें",
|
"add_tip": "टिप जोड़ें",
|
||||||
|
@ -623,10 +625,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "आंतरिक वॉलेट में भेजने की आवश्यकता है",
|
"require_for_sends_to_internal_wallets": "आंतरिक वॉलेट में भेजने की आवश्यकता है",
|
||||||
"require_for_sends_to_non_contacts": "गैर-संपर्कों को भेजने की आवश्यकता",
|
"require_for_sends_to_non_contacts": "गैर-संपर्कों को भेजने की आवश्यकता",
|
||||||
"require_pin_after": "इसके बाद पिन आवश्यक है",
|
"require_pin_after": "इसके बाद पिन आवश्यक है",
|
||||||
|
"required_passphrase": "पदबंध",
|
||||||
"rescan": "पुन: स्कैन",
|
"rescan": "पुन: स्कैन",
|
||||||
"resend_code": "कृपया इसे फिर से भेजें",
|
"resend_code": "कृपया इसे फिर से भेजें",
|
||||||
"reset": "रीसेट",
|
"reset": "रीसेट",
|
||||||
"reset_password": "पासवर्ड रीसेट करें",
|
"reset_password": "पासवर्ड रीसेट करें",
|
||||||
|
"restore": "पुनर्स्थापित करना",
|
||||||
"restore_active_seed": "सक्रिय बीज",
|
"restore_active_seed": "सक्रिय बीज",
|
||||||
"restore_address": "पता",
|
"restore_address": "पता",
|
||||||
"restore_bitcoin_description_from_keys": "अपने निजी कुंजी से उत्पन्न WIF स्ट्रिंग से अपने वॉलेट को पुनर्स्थापित करें",
|
"restore_bitcoin_description_from_keys": "अपने निजी कुंजी से उत्पन्न WIF स्ट्रिंग से अपने वॉलेट को पुनर्स्थापित करें",
|
||||||
|
@ -1001,6 +1005,7 @@
|
||||||
"wallet_group_description_view_seed": "आप हमेशा इस बीज को फिर से देख सकते हैं",
|
"wallet_group_description_view_seed": "आप हमेशा इस बीज को फिर से देख सकते हैं",
|
||||||
"wallet_group_empty_state_text_one": "लगता है कि आपके पास कोई संगत बटुआ समूह नहीं है!\n\nनल",
|
"wallet_group_empty_state_text_one": "लगता है कि आपके पास कोई संगत बटुआ समूह नहीं है!\n\nनल",
|
||||||
"wallet_group_empty_state_text_two": "नीचे एक नया बनाने के लिए।",
|
"wallet_group_empty_state_text_two": "नीचे एक नया बनाने के लिए।",
|
||||||
|
"wallet_has_passphrase": "इस बटुए में एक पासफ़्रेज़ है",
|
||||||
"wallet_keys": "बटुआ बीज / चाबियाँ",
|
"wallet_keys": "बटुआ बीज / चाबियाँ",
|
||||||
"wallet_list_create_new_wallet": "नया बटुआ बनाएँ",
|
"wallet_list_create_new_wallet": "नया बटुआ बनाएँ",
|
||||||
"wallet_list_edit_group_name": "समूह का नाम संपादित करें",
|
"wallet_list_edit_group_name": "समूह का नाम संपादित करें",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "Dodajte unaprijed uplaćena sredstva na kartice (do ${value})",
|
"add_fund_to_card": "Dodajte unaprijed uplaćena sredstva na kartice (do ${value})",
|
||||||
"add_new_node": "Dodaj novi node",
|
"add_new_node": "Dodaj novi node",
|
||||||
"add_new_word": "Dodaj novu riječ",
|
"add_new_word": "Dodaj novu riječ",
|
||||||
|
"add_passphrase": "Dodajte prolaznu frazu",
|
||||||
|
"add_passphrase_warning_text": "U prošlosti unesite samo prolaznu frazu ako ste je koristili za ovaj novčanik. Ako uđete u pogrešnu lozu ili niste prije koristili prolaznu frazu na ovom novčaniku, nećete vidjeti nijedno postojeće fondove ili povijest.",
|
||||||
"add_receiver": "Dodajte drugi prijemnik (izborno)",
|
"add_receiver": "Dodajte drugi prijemnik (izborno)",
|
||||||
"add_secret_code": "Ili dodajte ovaj tajni kod u aplikaciju za autentifikaciju",
|
"add_secret_code": "Ili dodajte ovaj tajni kod u aplikaciju za autentifikaciju",
|
||||||
"add_tip": "Dodaj savjet",
|
"add_tip": "Dodaj savjet",
|
||||||
|
@ -621,10 +623,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "Zahtijeva za slanje u interne novčanike",
|
"require_for_sends_to_internal_wallets": "Zahtijeva za slanje u interne novčanike",
|
||||||
"require_for_sends_to_non_contacts": "Zahtijeva za slanje nekontaktima",
|
"require_for_sends_to_non_contacts": "Zahtijeva za slanje nekontaktima",
|
||||||
"require_pin_after": "Zahtijevaj PIN nakon",
|
"require_pin_after": "Zahtijevaj PIN nakon",
|
||||||
|
"required_passphrase": "Prolazna fraza",
|
||||||
"rescan": "Ponovno skeniranje",
|
"rescan": "Ponovno skeniranje",
|
||||||
"resend_code": "Molimo da ga ponovno pošaljete",
|
"resend_code": "Molimo da ga ponovno pošaljete",
|
||||||
"reset": "Resetiraj",
|
"reset": "Resetiraj",
|
||||||
"reset_password": "Poništi lozinku",
|
"reset_password": "Poništi lozinku",
|
||||||
|
"restore": "Vratiti",
|
||||||
"restore_active_seed": "Aktivan pristupni izraz",
|
"restore_active_seed": "Aktivan pristupni izraz",
|
||||||
"restore_address": "Adresa",
|
"restore_address": "Adresa",
|
||||||
"restore_bitcoin_description_from_keys": "Oporavi novčanik pomoću WIF niza generiranog iz vlastitih privatnih ključeva (keys)",
|
"restore_bitcoin_description_from_keys": "Oporavi novčanik pomoću WIF niza generiranog iz vlastitih privatnih ključeva (keys)",
|
||||||
|
@ -999,6 +1003,7 @@
|
||||||
"wallet_group_description_view_seed": "Uvijek možete ponovo pogledati ovo sjeme ispod",
|
"wallet_group_description_view_seed": "Uvijek možete ponovo pogledati ovo sjeme ispod",
|
||||||
"wallet_group_empty_state_text_one": "Izgleda da nemate nikakve kompatibilne grupe novčanika !\n\n",
|
"wallet_group_empty_state_text_one": "Izgleda da nemate nikakve kompatibilne grupe novčanika !\n\n",
|
||||||
"wallet_group_empty_state_text_two": "Ispod da napravite novi.",
|
"wallet_group_empty_state_text_two": "Ispod da napravite novi.",
|
||||||
|
"wallet_has_passphrase": "Ovaj novčanik ima prolaznu frazu",
|
||||||
"wallet_keys": "Pristupni izraz/ključ novčanika",
|
"wallet_keys": "Pristupni izraz/ključ novčanika",
|
||||||
"wallet_list_create_new_wallet": "Izradi novi novčanik",
|
"wallet_list_create_new_wallet": "Izradi novi novčanik",
|
||||||
"wallet_list_edit_group_name": "Uredi naziv grupe",
|
"wallet_list_edit_group_name": "Uredi naziv grupe",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "Ավելացնել նախավճար քարտերի վրա (մինչև ${value})",
|
"add_fund_to_card": "Ավելացնել նախավճար քարտերի վրա (մինչև ${value})",
|
||||||
"add_new_node": "Ավելացնել նոր հանգույց",
|
"add_new_node": "Ավելացնել նոր հանգույց",
|
||||||
"add_new_word": "Ավելացնել նոր բառ",
|
"add_new_word": "Ավելացնել նոր բառ",
|
||||||
|
"add_passphrase": "Ավելացնել գաղտնաբառ",
|
||||||
|
"add_passphrase_warning_text": "Մուտքագրեք միայն գաղտնաբառ, եթե նախկինում այս դրամապանակի համար օգտագործեք մեկը: Եթե մուտքագրեք սխալ գաղտնաբառ կամ այս դրամապանակում նախկինում չեք օգտագործել գաղտնաբառ, ապա առկա միջոցներից կամ պատմություն չեք տեսնի:",
|
||||||
"add_receiver": "Ավելացնել ևս մեկ ստացող (ընտրովի)",
|
"add_receiver": "Ավելացնել ևս մեկ ստացող (ընտրովի)",
|
||||||
"add_secret_code": "Կամ ավելացրեք այս գաղտնի կոդը վավերացնող հավելվածում",
|
"add_secret_code": "Կամ ավելացրեք այս գաղտնի կոդը վավերացնող հավելվածում",
|
||||||
"add_tip": "Ավելացնել Թեյավճար",
|
"add_tip": "Ավելացնել Թեյավճար",
|
||||||
|
@ -620,10 +622,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "Պահանջվում է ներքին դրամապանակներ ուղարկելու համար",
|
"require_for_sends_to_internal_wallets": "Պահանջվում է ներքին դրամապանակներ ուղարկելու համար",
|
||||||
"require_for_sends_to_non_contacts": "Պահանջվում է ոչ կոնտակտ անձանց ուղարկելու համար",
|
"require_for_sends_to_non_contacts": "Պահանջվում է ոչ կոնտակտ անձանց ուղարկելու համար",
|
||||||
"require_pin_after": "Պահանջվում է PIN-ը հետո",
|
"require_pin_after": "Պահանջվում է PIN-ը հետո",
|
||||||
|
"required_passphrase": "Փոշի",
|
||||||
"rescan": "Վերասկանավորել",
|
"rescan": "Վերասկանավորել",
|
||||||
"resend_code": "Խնդրում ենք կրկին ուղարկել",
|
"resend_code": "Խնդրում ենք կրկին ուղարկել",
|
||||||
"reset": "Վերասահմանել",
|
"reset": "Վերասահմանել",
|
||||||
"reset_password": "Վերասահմանել գաղտնաբառը",
|
"reset_password": "Վերասահմանել գաղտնաբառը",
|
||||||
|
"restore": "Վերականգնել",
|
||||||
"restore_active_seed": "Ակտիվ սերմ",
|
"restore_active_seed": "Ակտիվ սերմ",
|
||||||
"restore_address": "Հասցե",
|
"restore_address": "Հասցե",
|
||||||
"restore_bitcoin_description_from_keys": "Վերականգնեք ձեր դրամապանակը ձեր գախտնի բանալիներից ստացված WIF տողից",
|
"restore_bitcoin_description_from_keys": "Վերականգնեք ձեր դրամապանակը ձեր գախտնի բանալիներից ստացված WIF տողից",
|
||||||
|
@ -997,6 +1001,7 @@
|
||||||
"wallet_group_description_view_seed": "Միշտ կարող եք կրկին դիտել այս սերմը ներքեւում",
|
"wallet_group_description_view_seed": "Միշտ կարող եք կրկին դիտել այս սերմը ներքեւում",
|
||||||
"wallet_group_empty_state_text_one": "Կարծես թե որեւէ համատեղելի դրամապանակի խմբեր չունեք:\n\nԹակել",
|
"wallet_group_empty_state_text_one": "Կարծես թե որեւէ համատեղելի դրամապանակի խմբեր չունեք:\n\nԹակել",
|
||||||
"wallet_group_empty_state_text_two": "ներքեւում `նորը կազմելու համար:",
|
"wallet_group_empty_state_text_two": "ներքեւում `նորը կազմելու համար:",
|
||||||
|
"wallet_has_passphrase": "Այս դրամապանակն ունի գաղտնաբառ",
|
||||||
"wallet_keys": "Դրամապանակի սերմ/բանալիներ",
|
"wallet_keys": "Դրամապանակի սերմ/բանալիներ",
|
||||||
"wallet_list_create_new_wallet": "Ստեղծել Նոր Դրամապանակ",
|
"wallet_list_create_new_wallet": "Ստեղծել Նոր Դրամապանակ",
|
||||||
"wallet_list_edit_group_name": "Խմբագրել խմբի անվանումը",
|
"wallet_list_edit_group_name": "Խմբագրել խմբի անվանումը",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "Tambahkan dana pra-bayar ke kartu (hingga ${value})",
|
"add_fund_to_card": "Tambahkan dana pra-bayar ke kartu (hingga ${value})",
|
||||||
"add_new_node": "Tambah node baru",
|
"add_new_node": "Tambah node baru",
|
||||||
"add_new_word": "Tambahkan kata baru",
|
"add_new_word": "Tambahkan kata baru",
|
||||||
|
"add_passphrase": "Tambahkan frasa sandi",
|
||||||
|
"add_passphrase_warning_text": "Hanya masukkan frasa sandi jika Anda telah menggunakan satu untuk dompet ini di masa lalu. Jika Anda memasukkan frasa sandi yang salah atau belum menggunakan frasa sandi sebelumnya di dompet ini, Anda tidak akan melihat dana atau sejarah yang ada.",
|
||||||
"add_receiver": "Tambahkan penerima lain (opsional)",
|
"add_receiver": "Tambahkan penerima lain (opsional)",
|
||||||
"add_secret_code": "Atau, tambahkan kode rahasia ini ke aplikasi autentikator",
|
"add_secret_code": "Atau, tambahkan kode rahasia ini ke aplikasi autentikator",
|
||||||
"add_tip": "Tambahkan Tip",
|
"add_tip": "Tambahkan Tip",
|
||||||
|
@ -623,10 +625,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "Diperlukan untuk mengirim ke dompet internal",
|
"require_for_sends_to_internal_wallets": "Diperlukan untuk mengirim ke dompet internal",
|
||||||
"require_for_sends_to_non_contacts": "Wajibkan untuk mengirim ke non-kontak",
|
"require_for_sends_to_non_contacts": "Wajibkan untuk mengirim ke non-kontak",
|
||||||
"require_pin_after": "Meminta PIN setelah",
|
"require_pin_after": "Meminta PIN setelah",
|
||||||
|
"required_passphrase": "Frasa sandi",
|
||||||
"rescan": "Pindai ulang",
|
"rescan": "Pindai ulang",
|
||||||
"resend_code": "Silakan kirim ulang",
|
"resend_code": "Silakan kirim ulang",
|
||||||
"reset": "Reset",
|
"reset": "Reset",
|
||||||
"reset_password": "Atur Ulang Kata Sandi",
|
"reset_password": "Atur Ulang Kata Sandi",
|
||||||
|
"restore": "Memulihkan",
|
||||||
"restore_active_seed": "Seed aktif",
|
"restore_active_seed": "Seed aktif",
|
||||||
"restore_address": "Alamat",
|
"restore_address": "Alamat",
|
||||||
"restore_bitcoin_description_from_keys": "Pulihkan dompet Anda dari string WIF yang dihasilkan dari private keys Anda",
|
"restore_bitcoin_description_from_keys": "Pulihkan dompet Anda dari string WIF yang dihasilkan dari private keys Anda",
|
||||||
|
@ -1002,6 +1006,7 @@
|
||||||
"wallet_group_description_view_seed": "Anda selalu dapat melihat benih ini lagi di bawah",
|
"wallet_group_description_view_seed": "Anda selalu dapat melihat benih ini lagi di bawah",
|
||||||
"wallet_group_empty_state_text_one": "Sepertinya Anda tidak memiliki grup dompet yang kompatibel !\n\n tap",
|
"wallet_group_empty_state_text_one": "Sepertinya Anda tidak memiliki grup dompet yang kompatibel !\n\n tap",
|
||||||
"wallet_group_empty_state_text_two": "di bawah ini untuk membuat yang baru.",
|
"wallet_group_empty_state_text_two": "di bawah ini untuk membuat yang baru.",
|
||||||
|
"wallet_has_passphrase": "Dompet ini memiliki frasa sandi",
|
||||||
"wallet_keys": "Seed/kunci dompet",
|
"wallet_keys": "Seed/kunci dompet",
|
||||||
"wallet_list_create_new_wallet": "Buat Dompet Baru",
|
"wallet_list_create_new_wallet": "Buat Dompet Baru",
|
||||||
"wallet_list_edit_group_name": "Edit Nama Grup",
|
"wallet_list_edit_group_name": "Edit Nama Grup",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "Aggiungi fondi prepagati alle carte (fino a ${value})",
|
"add_fund_to_card": "Aggiungi fondi prepagati alle carte (fino a ${value})",
|
||||||
"add_new_node": "Aggiungi nuovo nodo",
|
"add_new_node": "Aggiungi nuovo nodo",
|
||||||
"add_new_word": "Aggiungi nuova parola",
|
"add_new_word": "Aggiungi nuova parola",
|
||||||
|
"add_passphrase": "Aggiungi passphrase",
|
||||||
|
"add_passphrase_warning_text": "Inserisci una passphrase solo se ne hai usato uno per questo portafoglio in passato. Se si inserisce la passphrase sbagliata o non hai prima utilizzato una passphrase su questo portafoglio, non vedrai nessuno dei fondi o della storia esistenti.",
|
||||||
"add_receiver": "Aggiungi un altro ricevitore (opzionale)",
|
"add_receiver": "Aggiungi un altro ricevitore (opzionale)",
|
||||||
"add_secret_code": "Oppure aggiungi questo codice segreto a un'app di autenticazione",
|
"add_secret_code": "Oppure aggiungi questo codice segreto a un'app di autenticazione",
|
||||||
"add_tip": "Aggiungi suggerimento",
|
"add_tip": "Aggiungi suggerimento",
|
||||||
|
@ -622,10 +624,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "Richiedi per invii a portafogli interni",
|
"require_for_sends_to_internal_wallets": "Richiedi per invii a portafogli interni",
|
||||||
"require_for_sends_to_non_contacts": "Richiedi per invii a non contatti",
|
"require_for_sends_to_non_contacts": "Richiedi per invii a non contatti",
|
||||||
"require_pin_after": "Richiedi PIN dopo",
|
"require_pin_after": "Richiedi PIN dopo",
|
||||||
|
"required_passphrase": "Passphrase",
|
||||||
"rescan": "Scansiona di nuovo",
|
"rescan": "Scansiona di nuovo",
|
||||||
"resend_code": "Per favore, invialo nuovamente",
|
"resend_code": "Per favore, invialo nuovamente",
|
||||||
"reset": "Ripristina",
|
"reset": "Ripristina",
|
||||||
"reset_password": "Reimposta password",
|
"reset_password": "Reimposta password",
|
||||||
|
"restore": "Ripristinare",
|
||||||
"restore_active_seed": "Seme attivo",
|
"restore_active_seed": "Seme attivo",
|
||||||
"restore_address": "Indirizzo",
|
"restore_address": "Indirizzo",
|
||||||
"restore_bitcoin_description_from_keys": "Recupera il tuo portafoglio da una stringa WIF generata dalle tue chiavi private",
|
"restore_bitcoin_description_from_keys": "Recupera il tuo portafoglio da una stringa WIF generata dalle tue chiavi private",
|
||||||
|
@ -1001,6 +1005,7 @@
|
||||||
"wallet_group_description_view_seed": "Puoi sempre visualizzare di nuovo questo seme sotto",
|
"wallet_group_description_view_seed": "Puoi sempre visualizzare di nuovo questo seme sotto",
|
||||||
"wallet_group_empty_state_text_one": "Sembra che tu non abbia alcun gruppo di portafoglio compatibile!\n\nPremi",
|
"wallet_group_empty_state_text_one": "Sembra che tu non abbia alcun gruppo di portafoglio compatibile!\n\nPremi",
|
||||||
"wallet_group_empty_state_text_two": "Di seguito per crearne uno nuovo.",
|
"wallet_group_empty_state_text_two": "Di seguito per crearne uno nuovo.",
|
||||||
|
"wallet_has_passphrase": "Questo portafoglio ha una passphrase",
|
||||||
"wallet_keys": "Seme Portafoglio /chiavi",
|
"wallet_keys": "Seme Portafoglio /chiavi",
|
||||||
"wallet_list_create_new_wallet": "Crea Nuovo Portafoglio",
|
"wallet_list_create_new_wallet": "Crea Nuovo Portafoglio",
|
||||||
"wallet_list_edit_group_name": "Modifica nome del gruppo",
|
"wallet_list_edit_group_name": "Modifica nome del gruppo",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "プリペイド資金をカードに追加します(最大 ${value})",
|
"add_fund_to_card": "プリペイド資金をカードに追加します(最大 ${value})",
|
||||||
"add_new_node": "新しいノードを追加",
|
"add_new_node": "新しいノードを追加",
|
||||||
"add_new_word": "新しい単語を追加",
|
"add_new_word": "新しい単語を追加",
|
||||||
|
"add_passphrase": "パスフレーズを追加します",
|
||||||
|
"add_passphrase_warning_text": "過去にこのウォレットに使用した場合にのみ、パスフレーズを入力してください。間違ったパスフレーズに入ったり、このウォレットでパスフレーズを使用したことがない場合、既存の資金や歴史はありません。",
|
||||||
"add_receiver": "別のレシーバーを追加します(オプション)",
|
"add_receiver": "別のレシーバーを追加します(オプション)",
|
||||||
"add_secret_code": "または、このシークレット コードを認証アプリに追加します",
|
"add_secret_code": "または、このシークレット コードを認証アプリに追加します",
|
||||||
"add_tip": "ヒントを追加",
|
"add_tip": "ヒントを追加",
|
||||||
|
@ -622,10 +624,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "内部ウォレットへの送信に必須",
|
"require_for_sends_to_internal_wallets": "内部ウォレットへの送信に必須",
|
||||||
"require_for_sends_to_non_contacts": "非連絡先への送信に必須",
|
"require_for_sends_to_non_contacts": "非連絡先への送信に必須",
|
||||||
"require_pin_after": "後に PIN が必要",
|
"require_pin_after": "後に PIN が必要",
|
||||||
|
"required_passphrase": "パスフレーズ",
|
||||||
"rescan": "再スキャン",
|
"rescan": "再スキャン",
|
||||||
"resend_code": "再送してください",
|
"resend_code": "再送してください",
|
||||||
"reset": "リセットする",
|
"reset": "リセットする",
|
||||||
"reset_password": "パスワードのリセット",
|
"reset_password": "パスワードのリセット",
|
||||||
|
"restore": "復元する",
|
||||||
"restore_active_seed": "アクティブシード",
|
"restore_active_seed": "アクティブシード",
|
||||||
"restore_address": "住所",
|
"restore_address": "住所",
|
||||||
"restore_bitcoin_description_from_keys": "秘密鍵から生成されたWIF文字列からウォレットを復元します",
|
"restore_bitcoin_description_from_keys": "秘密鍵から生成されたWIF文字列からウォレットを復元します",
|
||||||
|
@ -1000,6 +1004,7 @@
|
||||||
"wallet_group_description_view_seed": "いつでもこの種を再び見ることができます",
|
"wallet_group_description_view_seed": "いつでもこの種を再び見ることができます",
|
||||||
"wallet_group_empty_state_text_one": "互換性のあるウォレットグループがないようです!\n\nタップ",
|
"wallet_group_empty_state_text_one": "互換性のあるウォレットグループがないようです!\n\nタップ",
|
||||||
"wallet_group_empty_state_text_two": "以下に新しいものを作るために。",
|
"wallet_group_empty_state_text_two": "以下に新しいものを作るために。",
|
||||||
|
"wallet_has_passphrase": "このウォレットにはパスフレーズがあります",
|
||||||
"wallet_keys": "ウォレットシード/キー",
|
"wallet_keys": "ウォレットシード/キー",
|
||||||
"wallet_list_create_new_wallet": "新しいウォレットを作成",
|
"wallet_list_create_new_wallet": "新しいウォレットを作成",
|
||||||
"wallet_list_edit_group_name": "グループ名を編集します",
|
"wallet_list_edit_group_name": "グループ名を編集します",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "카드에 선불 금액 추가(최대 ${value})",
|
"add_fund_to_card": "카드에 선불 금액 추가(최대 ${value})",
|
||||||
"add_new_node": "새 노드 추가",
|
"add_new_node": "새 노드 추가",
|
||||||
"add_new_word": "새로운 단어 추가",
|
"add_new_word": "새로운 단어 추가",
|
||||||
|
"add_passphrase": "암호를 추가하십시오",
|
||||||
|
"add_passphrase_warning_text": "과거 에이 지갑에 사용한 경우에만 암호를 입력하십시오. 이 지갑에서 잘못된 암호를 입력하거나 암호를 사용하지 않은 경우 기존 자금이나 이력이 보이지 않을 것입니다.",
|
||||||
"add_receiver": "다른 수신기 추가(선택 사항)",
|
"add_receiver": "다른 수신기 추가(선택 사항)",
|
||||||
"add_secret_code": "또는 이 비밀 코드를 인증 앱에 추가하세요.",
|
"add_secret_code": "또는 이 비밀 코드를 인증 앱에 추가하세요.",
|
||||||
"add_tip": "팁 추가",
|
"add_tip": "팁 추가",
|
||||||
|
@ -621,10 +623,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "내부 지갑으로 보내는 데 필요",
|
"require_for_sends_to_internal_wallets": "내부 지갑으로 보내는 데 필요",
|
||||||
"require_for_sends_to_non_contacts": "비접촉자에게 보내는 데 필요",
|
"require_for_sends_to_non_contacts": "비접촉자에게 보내는 데 필요",
|
||||||
"require_pin_after": "다음 이후에 PIN 필요",
|
"require_pin_after": "다음 이후에 PIN 필요",
|
||||||
|
"required_passphrase": "암호",
|
||||||
"rescan": "재검색",
|
"rescan": "재검색",
|
||||||
"resend_code": "다시 보내주세요",
|
"resend_code": "다시 보내주세요",
|
||||||
"reset": "다시 놓기",
|
"reset": "다시 놓기",
|
||||||
"reset_password": "비밀번호 재설정",
|
"reset_password": "비밀번호 재설정",
|
||||||
|
"restore": "복원하다",
|
||||||
"restore_active_seed": "활성 종자",
|
"restore_active_seed": "활성 종자",
|
||||||
"restore_address": "주소",
|
"restore_address": "주소",
|
||||||
"restore_bitcoin_description_from_keys": "개인 키에서 생성 된 WIF 문자열에서 지갑 복원",
|
"restore_bitcoin_description_from_keys": "개인 키에서 생성 된 WIF 문자열에서 지갑 복원",
|
||||||
|
@ -999,6 +1003,7 @@
|
||||||
"wallet_group_description_view_seed": "이 씨앗을 언제든지 다시 볼 수 있습니다",
|
"wallet_group_description_view_seed": "이 씨앗을 언제든지 다시 볼 수 있습니다",
|
||||||
"wallet_group_empty_state_text_one": "호환 지갑 그룹이없는 것 같습니다 !\n\n TAP",
|
"wallet_group_empty_state_text_one": "호환 지갑 그룹이없는 것 같습니다 !\n\n TAP",
|
||||||
"wallet_group_empty_state_text_two": "아래에서 새로운 것을 만들기 위해.",
|
"wallet_group_empty_state_text_two": "아래에서 새로운 것을 만들기 위해.",
|
||||||
|
"wallet_has_passphrase": "이 지갑에는 암호가 있습니다",
|
||||||
"wallet_keys": "지갑 시드 / 키",
|
"wallet_keys": "지갑 시드 / 키",
|
||||||
"wallet_list_create_new_wallet": "새 월렛 만들기",
|
"wallet_list_create_new_wallet": "새 월렛 만들기",
|
||||||
"wallet_list_edit_group_name": "그룹 이름 편집",
|
"wallet_list_edit_group_name": "그룹 이름 편집",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "ကတ်များသို့ ကြိုတင်ငွေပေးငွေများ ထည့်ပါ (${value} အထိ)",
|
"add_fund_to_card": "ကတ်များသို့ ကြိုတင်ငွေပေးငွေများ ထည့်ပါ (${value} အထိ)",
|
||||||
"add_new_node": "နှာခေါင်း အသစ်ထည့်ပါ။",
|
"add_new_node": "နှာခေါင်း အသစ်ထည့်ပါ။",
|
||||||
"add_new_word": "စကားလုံးအသစ်ထည့်ပါ။",
|
"add_new_word": "စကားလုံးအသစ်ထည့်ပါ။",
|
||||||
|
"add_passphrase": "passphrase ထည့်ပါ",
|
||||||
|
"add_passphrase_warning_text": "အကယ်. သင်သည်ယခင်ကဤပိုက်ဆံအိတ်အတွက်တစ်ခုသုံးခဲ့လျှင် passphrase တစ်ခုသာရိုက်ထည့်ပါ။ အကယ်. သင်သည်မှားယွင်းသော passphrase ကို 0 င်ရောက်ခြင်းသို့မဟုတ်ဤပိုက်ဆံအိတ်ပေါ်တွင် passphrase မသုံးပါကလက်ရှိရန်ပုံငွေများသို့မဟုတ်သမိုင်းကိုသင်မတွေ့ရပါ။",
|
||||||
"add_receiver": "အခြားလက်ခံသူ ထည့်ပါ (ချန်လှပ်ထားနိုင်သည်)",
|
"add_receiver": "အခြားလက်ခံသူ ထည့်ပါ (ချန်လှပ်ထားနိုင်သည်)",
|
||||||
"add_secret_code": "သို့မဟုတ် ဤလျှို့ဝှက်ကုဒ်ကို အထောက်အထားစိစစ်ခြင်းအက်ပ်တစ်ခုသို့ ထည့်ပါ။",
|
"add_secret_code": "သို့မဟုတ် ဤလျှို့ဝှက်ကုဒ်ကို အထောက်အထားစိစစ်ခြင်းအက်ပ်တစ်ခုသို့ ထည့်ပါ။",
|
||||||
"add_tip": "အကြံပြုချက်ထည့်ပါ။",
|
"add_tip": "အကြံပြုချက်ထည့်ပါ။",
|
||||||
|
@ -621,10 +623,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "အတွင်းပိုင်း ပိုက်ဆံအိတ်များသို့ ပေးပို့ရန် လိုအပ်သည်။",
|
"require_for_sends_to_internal_wallets": "အတွင်းပိုင်း ပိုက်ဆံအိတ်များသို့ ပေးပို့ရန် လိုအပ်သည်။",
|
||||||
"require_for_sends_to_non_contacts": "အဆက်အသွယ်မရှိသူများထံ ပေးပို့ရန် လိုအပ်သည်။",
|
"require_for_sends_to_non_contacts": "အဆက်အသွယ်မရှိသူများထံ ပေးပို့ရန် လိုအပ်သည်။",
|
||||||
"require_pin_after": "ပြီးနောက် PIN လိုအပ်ပါသည်။",
|
"require_pin_after": "ပြီးနောက် PIN လိုအပ်ပါသည်။",
|
||||||
|
"required_passphrase": "စကားဝှက်PPRase",
|
||||||
"rescan": "ပြန်စကင်န်လုပ်ပါ။",
|
"rescan": "ပြန်စကင်န်လုပ်ပါ။",
|
||||||
"resend_code": "ကျေးဇူးပြု၍ ပြန်ပို့ပါ။",
|
"resend_code": "ကျေးဇူးပြု၍ ပြန်ပို့ပါ။",
|
||||||
"reset": "ပြန်လည်သတ်မှတ်ပါ။",
|
"reset": "ပြန်လည်သတ်မှတ်ပါ။",
|
||||||
"reset_password": "လျှို့ဝှတ်နံပါတ်အားမူလအတိုင်းပြန်လုပ်သည်",
|
"reset_password": "လျှို့ဝှတ်နံပါတ်အားမူလအတိုင်းပြန်လုပ်သည်",
|
||||||
|
"restore": "ပြန်လည်တည်ထောင်",
|
||||||
"restore_active_seed": "တက်ကြွသောအစေ့",
|
"restore_active_seed": "တက်ကြွသောအစေ့",
|
||||||
"restore_address": "လိပ်စာ",
|
"restore_address": "လိပ်စာ",
|
||||||
"restore_bitcoin_description_from_keys": "သင့်ကိုယ်ပိုင်သော့များမှ ထုတ်လုပ်ထားသော WIF စာကြောင်းမှ သင့်ပိုက်ဆံအိတ်ကို ပြန်လည်ရယူပါ။",
|
"restore_bitcoin_description_from_keys": "သင့်ကိုယ်ပိုင်သော့များမှ ထုတ်လုပ်ထားသော WIF စာကြောင်းမှ သင့်ပိုက်ဆံအိတ်ကို ပြန်လည်ရယူပါ။",
|
||||||
|
@ -999,6 +1003,7 @@
|
||||||
"wallet_group_description_view_seed": "သင်သည်ဤမျိုးစေ့ကိုနောက်တဖန်ရှုမြင်နိုင်သည်",
|
"wallet_group_description_view_seed": "သင်သည်ဤမျိုးစေ့ကိုနောက်တဖန်ရှုမြင်နိုင်သည်",
|
||||||
"wallet_group_empty_state_text_one": "သင့်တွင်သဟဇာတဖြစ်သောပိုက်ဆံအိတ်အုပ်စုများမရှိပါ။ !\n\n ကိုအသာပုတ်ပါ",
|
"wallet_group_empty_state_text_one": "သင့်တွင်သဟဇာတဖြစ်သောပိုက်ဆံအိတ်အုပ်စုများမရှိပါ။ !\n\n ကိုအသာပုတ်ပါ",
|
||||||
"wallet_group_empty_state_text_two": "အသစ်တစ်ခုကိုတစ်ခုလုပ်ဖို့အောက်တွင်ဖော်ပြထားသော။",
|
"wallet_group_empty_state_text_two": "အသစ်တစ်ခုကိုတစ်ခုလုပ်ဖို့အောက်တွင်ဖော်ပြထားသော။",
|
||||||
|
"wallet_has_passphrase": "ဒီပိုက်ဆံအိတ်က passphrase ရှိတယ်",
|
||||||
"wallet_keys": "ပိုက်ဆံအိတ် အစေ့/သော့များ",
|
"wallet_keys": "ပိုက်ဆံအိတ် အစေ့/သော့များ",
|
||||||
"wallet_list_create_new_wallet": "Wallet အသစ်ဖန်တီးပါ။",
|
"wallet_list_create_new_wallet": "Wallet အသစ်ဖန်တီးပါ။",
|
||||||
"wallet_list_edit_group_name": "အုပ်စုအမည်ကိုတည်းဖြတ်ပါ",
|
"wallet_list_edit_group_name": "အုပ်စုအမည်ကိုတည်းဖြတ်ပါ",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "Voeg prepaid tegoed toe aan de kaarten (tot ${value})",
|
"add_fund_to_card": "Voeg prepaid tegoed toe aan de kaarten (tot ${value})",
|
||||||
"add_new_node": "Voeg een nieuw knooppunt toe",
|
"add_new_node": "Voeg een nieuw knooppunt toe",
|
||||||
"add_new_word": "Nieuw woord toevoegen",
|
"add_new_word": "Nieuw woord toevoegen",
|
||||||
|
"add_passphrase": "Voeg wachtwoordzin toe",
|
||||||
|
"add_passphrase_warning_text": "Voer alleen een wachtwoordzin in als u er in het verleden een voor deze portemonnee hebt gebruikt. Als u de verkeerde wachtwoordzin invoert of nog niet eerder op deze portemonnee een wachtwoordzin hebt gebruikt, ziet u geen bestaande fondsen of geschiedenis.",
|
||||||
"add_receiver": "Nog een ontvanger toevoegen (optioneel)",
|
"add_receiver": "Nog een ontvanger toevoegen (optioneel)",
|
||||||
"add_secret_code": "Of voeg deze geheime code toe aan een authenticator-app",
|
"add_secret_code": "Of voeg deze geheime code toe aan een authenticator-app",
|
||||||
"add_tip": "Tip toevoegen",
|
"add_tip": "Tip toevoegen",
|
||||||
|
@ -621,10 +623,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "Vereist voor verzendingen naar interne portefeuilles",
|
"require_for_sends_to_internal_wallets": "Vereist voor verzendingen naar interne portefeuilles",
|
||||||
"require_for_sends_to_non_contacts": "Vereist voor verzendingen naar niet-contacten",
|
"require_for_sends_to_non_contacts": "Vereist voor verzendingen naar niet-contacten",
|
||||||
"require_pin_after": "Pincode vereist na",
|
"require_pin_after": "Pincode vereist na",
|
||||||
|
"required_passphrase": "Wachtwoordzin",
|
||||||
"rescan": "Opnieuw scannen",
|
"rescan": "Opnieuw scannen",
|
||||||
"resend_code": "Stuur het alstublieft opnieuw",
|
"resend_code": "Stuur het alstublieft opnieuw",
|
||||||
"reset": "Reset",
|
"reset": "Reset",
|
||||||
"reset_password": "Wachtwoord resetten",
|
"reset_password": "Wachtwoord resetten",
|
||||||
|
"restore": "Herstellen",
|
||||||
"restore_active_seed": "Actief zaad",
|
"restore_active_seed": "Actief zaad",
|
||||||
"restore_address": "Adres",
|
"restore_address": "Adres",
|
||||||
"restore_bitcoin_description_from_keys": "Herstel uw portemonnee van de gegenereerde WIF-string van uw privésleutels",
|
"restore_bitcoin_description_from_keys": "Herstel uw portemonnee van de gegenereerde WIF-string van uw privésleutels",
|
||||||
|
@ -1000,6 +1004,7 @@
|
||||||
"wallet_group_description_view_seed": "Je kunt dit zaad altijd opnieuw bekijken",
|
"wallet_group_description_view_seed": "Je kunt dit zaad altijd opnieuw bekijken",
|
||||||
"wallet_group_empty_state_text_one": "Het lijkt erop dat je geen compatibele portemonnee -groepen hebt !\n\n TAP",
|
"wallet_group_empty_state_text_one": "Het lijkt erop dat je geen compatibele portemonnee -groepen hebt !\n\n TAP",
|
||||||
"wallet_group_empty_state_text_two": "hieronder om een nieuwe te maken.",
|
"wallet_group_empty_state_text_two": "hieronder om een nieuwe te maken.",
|
||||||
|
"wallet_has_passphrase": "Deze portemonnee heeft een wachtwoordzin",
|
||||||
"wallet_keys": "Portemonnee zaad/sleutels",
|
"wallet_keys": "Portemonnee zaad/sleutels",
|
||||||
"wallet_list_create_new_wallet": "Maak een nieuwe portemonnee",
|
"wallet_list_create_new_wallet": "Maak een nieuwe portemonnee",
|
||||||
"wallet_list_edit_group_name": "Groepsnaam bewerken",
|
"wallet_list_edit_group_name": "Groepsnaam bewerken",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "Dodaj przedpłacone środki do kart (do ${value})",
|
"add_fund_to_card": "Dodaj przedpłacone środki do kart (do ${value})",
|
||||||
"add_new_node": "Dodaj nowy węzeł",
|
"add_new_node": "Dodaj nowy węzeł",
|
||||||
"add_new_word": "Dodaj nowe słowo",
|
"add_new_word": "Dodaj nowe słowo",
|
||||||
|
"add_passphrase": "Dodaj hasło",
|
||||||
|
"add_passphrase_warning_text": "Wprowadź hasło tylko wtedy, gdy w przeszłości używałeś jednego do tego portfela. Jeśli wejdziesz do niewłaściwej hasła lub nie użyjesz wcześniejszego pensjonatu na tym portfelu, nie zobaczysz żadnego z istniejących funduszy ani historii.",
|
||||||
"add_receiver": "Dodaj kolejnego odbiorcę (opcjonalnie)",
|
"add_receiver": "Dodaj kolejnego odbiorcę (opcjonalnie)",
|
||||||
"add_secret_code": "Możesz też dodać ten tajny kod do aplikacji uwierzytelniającej",
|
"add_secret_code": "Możesz też dodać ten tajny kod do aplikacji uwierzytelniającej",
|
||||||
"add_tip": "Dodaj wskazówkę",
|
"add_tip": "Dodaj wskazówkę",
|
||||||
|
@ -621,10 +623,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "Wymagaj wysyłania do portfeli wewnętrznych",
|
"require_for_sends_to_internal_wallets": "Wymagaj wysyłania do portfeli wewnętrznych",
|
||||||
"require_for_sends_to_non_contacts": "Wymagaj wysyłania do osób niekontaktowych",
|
"require_for_sends_to_non_contacts": "Wymagaj wysyłania do osób niekontaktowych",
|
||||||
"require_pin_after": "Wymagaj kodu PIN po",
|
"require_pin_after": "Wymagaj kodu PIN po",
|
||||||
|
"required_passphrase": "Fraza",
|
||||||
"rescan": "Skanuj ponownie",
|
"rescan": "Skanuj ponownie",
|
||||||
"resend_code": "Wyślij go ponownie",
|
"resend_code": "Wyślij go ponownie",
|
||||||
"reset": "Wyczyść",
|
"reset": "Wyczyść",
|
||||||
"reset_password": "Zresetuj hasło",
|
"reset_password": "Zresetuj hasło",
|
||||||
|
"restore": "Przywrócić",
|
||||||
"restore_active_seed": "Aktywne seedy",
|
"restore_active_seed": "Aktywne seedy",
|
||||||
"restore_address": "Adres",
|
"restore_address": "Adres",
|
||||||
"restore_bitcoin_description_from_keys": "Przywróć swój portfel z klucza prywatnego",
|
"restore_bitcoin_description_from_keys": "Przywróć swój portfel z klucza prywatnego",
|
||||||
|
@ -999,6 +1003,7 @@
|
||||||
"wallet_group_description_view_seed": "Zawsze możesz ponownie zobaczyć to ziarno pod",
|
"wallet_group_description_view_seed": "Zawsze możesz ponownie zobaczyć to ziarno pod",
|
||||||
"wallet_group_empty_state_text_one": "Wygląda na to, że nie masz żadnych kompatybilnych grup portfeli !\n\n Tap",
|
"wallet_group_empty_state_text_one": "Wygląda na to, że nie masz żadnych kompatybilnych grup portfeli !\n\n Tap",
|
||||||
"wallet_group_empty_state_text_two": "poniżej, aby zrobić nowy.",
|
"wallet_group_empty_state_text_two": "poniżej, aby zrobić nowy.",
|
||||||
|
"wallet_has_passphrase": "Ten portfel ma panie",
|
||||||
"wallet_keys": "Klucze portfela",
|
"wallet_keys": "Klucze portfela",
|
||||||
"wallet_list_create_new_wallet": "Utwórz nowy portfel",
|
"wallet_list_create_new_wallet": "Utwórz nowy portfel",
|
||||||
"wallet_list_edit_group_name": "Edytuj nazwę grupy",
|
"wallet_list_edit_group_name": "Edytuj nazwę grupy",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "Adicionar fundos pré-pagos aos cartões (até ${value})",
|
"add_fund_to_card": "Adicionar fundos pré-pagos aos cartões (até ${value})",
|
||||||
"add_new_node": "Adicionar novo nó",
|
"add_new_node": "Adicionar novo nó",
|
||||||
"add_new_word": "Adicionar nova palavra",
|
"add_new_word": "Adicionar nova palavra",
|
||||||
|
"add_passphrase": "Adicione a senha",
|
||||||
|
"add_passphrase_warning_text": "Digite apenas uma senha se você usou uma para esta carteira no passado. Se você inserir a senha errada ou não já usou uma senha antes nesta carteira, não verá nenhum dos fundos ou histórico existentes.",
|
||||||
"add_receiver": "Adicione outro receptor (opcional)",
|
"add_receiver": "Adicione outro receptor (opcional)",
|
||||||
"add_secret_code": "Ou adicione este código secreto a um aplicativo autenticador",
|
"add_secret_code": "Ou adicione este código secreto a um aplicativo autenticador",
|
||||||
"add_tip": "Adicionar Dica",
|
"add_tip": "Adicionar Dica",
|
||||||
|
@ -623,10 +625,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "Exigir envios para carteiras internas",
|
"require_for_sends_to_internal_wallets": "Exigir envios para carteiras internas",
|
||||||
"require_for_sends_to_non_contacts": "Exigir para envios para não-contatos",
|
"require_for_sends_to_non_contacts": "Exigir para envios para não-contatos",
|
||||||
"require_pin_after": "Exigir PIN após",
|
"require_pin_after": "Exigir PIN após",
|
||||||
|
"required_passphrase": "Senha",
|
||||||
"rescan": "Reescanear",
|
"rescan": "Reescanear",
|
||||||
"resend_code": "Por favor, reenvie",
|
"resend_code": "Por favor, reenvie",
|
||||||
"reset": "Limpar",
|
"reset": "Limpar",
|
||||||
"reset_password": "Redefinir senha",
|
"reset_password": "Redefinir senha",
|
||||||
|
"restore": "Restaurar",
|
||||||
"restore_active_seed": "Semente ativa",
|
"restore_active_seed": "Semente ativa",
|
||||||
"restore_address": "Endereço",
|
"restore_address": "Endereço",
|
||||||
"restore_bitcoin_description_from_keys": "Restaure sua carteira a partir da string WIF gerada de suas chaves privadas",
|
"restore_bitcoin_description_from_keys": "Restaure sua carteira a partir da string WIF gerada de suas chaves privadas",
|
||||||
|
@ -1002,6 +1006,7 @@
|
||||||
"wallet_group_description_view_seed": "Você sempre pode ver esta semente novamente em",
|
"wallet_group_description_view_seed": "Você sempre pode ver esta semente novamente em",
|
||||||
"wallet_group_empty_state_text_one": "Parece que você não tem nenhum grupo de carteira compatível !\n\n Toque",
|
"wallet_group_empty_state_text_one": "Parece que você não tem nenhum grupo de carteira compatível !\n\n Toque",
|
||||||
"wallet_group_empty_state_text_two": "abaixo para fazer um novo.",
|
"wallet_group_empty_state_text_two": "abaixo para fazer um novo.",
|
||||||
|
"wallet_has_passphrase": "Esta carteira tem uma senha",
|
||||||
"wallet_keys": "Semente/chaves da carteira",
|
"wallet_keys": "Semente/chaves da carteira",
|
||||||
"wallet_list_create_new_wallet": "Criar nova carteira",
|
"wallet_list_create_new_wallet": "Criar nova carteira",
|
||||||
"wallet_list_edit_group_name": "Editar o nome do grupo",
|
"wallet_list_edit_group_name": "Editar o nome do grupo",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "Добавить предоплаченные средства на карты (до ${value})",
|
"add_fund_to_card": "Добавить предоплаченные средства на карты (до ${value})",
|
||||||
"add_new_node": "Добавить новую ноду",
|
"add_new_node": "Добавить новую ноду",
|
||||||
"add_new_word": "Добавить новое слово",
|
"add_new_word": "Добавить новое слово",
|
||||||
|
"add_passphrase": "Добавить пасфраз",
|
||||||
|
"add_passphrase_warning_text": "Введите фразу только в том случае, если вы использовали один для этого кошелька в прошлом. Если вы введете неверную пассисную фразу или не использовали пасфразу до этого кошелька, вы не увидите ни одного существующего фонда или истории.",
|
||||||
"add_receiver": "Добавить получателя (необязательно)",
|
"add_receiver": "Добавить получателя (необязательно)",
|
||||||
"add_secret_code": "Или добавьте этот секретный код в приложение для аутентификации.",
|
"add_secret_code": "Или добавьте этот секретный код в приложение для аутентификации.",
|
||||||
"add_tip": "Добавить подсказку",
|
"add_tip": "Добавить подсказку",
|
||||||
|
@ -622,10 +624,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "Требовать отправки на внутренние кошельки",
|
"require_for_sends_to_internal_wallets": "Требовать отправки на внутренние кошельки",
|
||||||
"require_for_sends_to_non_contacts": "Требовать для отправки не контактам",
|
"require_for_sends_to_non_contacts": "Требовать для отправки не контактам",
|
||||||
"require_pin_after": "Требовать ПИН после",
|
"require_pin_after": "Требовать ПИН после",
|
||||||
|
"required_passphrase": "Пасфраза",
|
||||||
"rescan": "Пересканировать",
|
"rescan": "Пересканировать",
|
||||||
"resend_code": "Пожалуйста, отправьте еще раз",
|
"resend_code": "Пожалуйста, отправьте еще раз",
|
||||||
"reset": "Сброс",
|
"reset": "Сброс",
|
||||||
"reset_password": "Сбросить пароль",
|
"reset_password": "Сбросить пароль",
|
||||||
|
"restore": "Восстановить",
|
||||||
"restore_active_seed": "Активная мнемоническая фраза",
|
"restore_active_seed": "Активная мнемоническая фраза",
|
||||||
"restore_address": "Адрес",
|
"restore_address": "Адрес",
|
||||||
"restore_bitcoin_description_from_keys": "Вы можете восстановить кошелёк с помощью WIF",
|
"restore_bitcoin_description_from_keys": "Вы можете восстановить кошелёк с помощью WIF",
|
||||||
|
@ -1000,6 +1004,7 @@
|
||||||
"wallet_group_description_view_seed": "Вы всегда можете просматривать это семя снова под",
|
"wallet_group_description_view_seed": "Вы всегда можете просматривать это семя снова под",
|
||||||
"wallet_group_empty_state_text_one": "Похоже, у вас нет никаких совместимых групп кошелька !\n\n tap",
|
"wallet_group_empty_state_text_one": "Похоже, у вас нет никаких совместимых групп кошелька !\n\n tap",
|
||||||
"wallet_group_empty_state_text_two": "ниже, чтобы сделать новый.",
|
"wallet_group_empty_state_text_two": "ниже, чтобы сделать новый.",
|
||||||
|
"wallet_has_passphrase": "Этот кошелек имеет фразу",
|
||||||
"wallet_keys": "Мнемоническая фраза/ключи кошелька",
|
"wallet_keys": "Мнемоническая фраза/ключи кошелька",
|
||||||
"wallet_list_create_new_wallet": "Создать новый кошелёк",
|
"wallet_list_create_new_wallet": "Создать новый кошелёк",
|
||||||
"wallet_list_edit_group_name": "Редактировать название группы",
|
"wallet_list_edit_group_name": "Редактировать название группы",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "เพิ่มเงินสำรองไว้บนบัตร (ถึง ${value})",
|
"add_fund_to_card": "เพิ่มเงินสำรองไว้บนบัตร (ถึง ${value})",
|
||||||
"add_new_node": "เพิ่มโหนดใหม่",
|
"add_new_node": "เพิ่มโหนดใหม่",
|
||||||
"add_new_word": "เพิ่มคำใหม่",
|
"add_new_word": "เพิ่มคำใหม่",
|
||||||
|
"add_passphrase": "เพิ่มวลีรหัสผ่าน",
|
||||||
|
"add_passphrase_warning_text": "ป้อนวลีรหัสผ่านเท่านั้นหากคุณเคยใช้สำหรับกระเป๋าเงินนี้ในอดีต หากคุณป้อนวลีรหัสผ่านที่ไม่ถูกต้องหรือไม่เคยใช้ข้อความรหัสผ่านมาก่อนในกระเป๋าเงินนี้คุณจะไม่เห็นเงินทุนหรือประวัติใด ๆ ที่มีอยู่",
|
||||||
"add_receiver": "เพิ่มผู้รับอื่น ๆ (ตัวเลือก)",
|
"add_receiver": "เพิ่มผู้รับอื่น ๆ (ตัวเลือก)",
|
||||||
"add_secret_code": "หรือเพิ่มรหัสลับนี้ลงในแอปตรวจสอบความถูกต้อง",
|
"add_secret_code": "หรือเพิ่มรหัสลับนี้ลงในแอปตรวจสอบความถูกต้อง",
|
||||||
"add_tip": "เพิ่มคำแนะนำ",
|
"add_tip": "เพิ่มคำแนะนำ",
|
||||||
|
@ -621,10 +623,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "จำเป็นต้องส่งไปยังกระเป๋าเงินภายใน",
|
"require_for_sends_to_internal_wallets": "จำเป็นต้องส่งไปยังกระเป๋าเงินภายใน",
|
||||||
"require_for_sends_to_non_contacts": "จำเป็นต้องส่งไปยังผู้ที่ไม่ได้ติดต่อ",
|
"require_for_sends_to_non_contacts": "จำเป็นต้องส่งไปยังผู้ที่ไม่ได้ติดต่อ",
|
||||||
"require_pin_after": "ต้องการ PIN หลังจาก",
|
"require_pin_after": "ต้องการ PIN หลังจาก",
|
||||||
|
"required_passphrase": "วรรณะ",
|
||||||
"rescan": "สแกนใหม่",
|
"rescan": "สแกนใหม่",
|
||||||
"resend_code": "โปรดส่งอีกครั้ง",
|
"resend_code": "โปรดส่งอีกครั้ง",
|
||||||
"reset": "รีเซ็ต",
|
"reset": "รีเซ็ต",
|
||||||
"reset_password": "รีเซ็ตรหัสผ่าน",
|
"reset_password": "รีเซ็ตรหัสผ่าน",
|
||||||
|
"restore": "คืนค่า",
|
||||||
"restore_active_seed": "ซีดที่ใช้งานอยู่",
|
"restore_active_seed": "ซีดที่ใช้งานอยู่",
|
||||||
"restore_address": "ที่อยู่",
|
"restore_address": "ที่อยู่",
|
||||||
"restore_bitcoin_description_from_keys": "กู้กระเป๋าของคุณจากสตริง WIF ที่สร้างขึ้นจากคีย์ส่วนตัวของคุณ",
|
"restore_bitcoin_description_from_keys": "กู้กระเป๋าของคุณจากสตริง WIF ที่สร้างขึ้นจากคีย์ส่วนตัวของคุณ",
|
||||||
|
@ -999,6 +1003,7 @@
|
||||||
"wallet_group_description_view_seed": "คุณสามารถดูเมล็ดพันธุ์นี้ได้อีกครั้งภายใต้",
|
"wallet_group_description_view_seed": "คุณสามารถดูเมล็ดพันธุ์นี้ได้อีกครั้งภายใต้",
|
||||||
"wallet_group_empty_state_text_one": "ดูเหมือนว่าคุณจะไม่มีกลุ่มกระเป๋าเงินที่เข้ากันได้ !\n\n แตะ",
|
"wallet_group_empty_state_text_one": "ดูเหมือนว่าคุณจะไม่มีกลุ่มกระเป๋าเงินที่เข้ากันได้ !\n\n แตะ",
|
||||||
"wallet_group_empty_state_text_two": "ด้านล่างเพื่อสร้างใหม่",
|
"wallet_group_empty_state_text_two": "ด้านล่างเพื่อสร้างใหม่",
|
||||||
|
"wallet_has_passphrase": "กระเป๋าเงินนี้มีข้อความรหัสผ่าน",
|
||||||
"wallet_keys": "ซีดของกระเป๋า/คีย์",
|
"wallet_keys": "ซีดของกระเป๋า/คีย์",
|
||||||
"wallet_list_create_new_wallet": "สร้างกระเป๋าใหม่",
|
"wallet_list_create_new_wallet": "สร้างกระเป๋าใหม่",
|
||||||
"wallet_list_edit_group_name": "แก้ไขชื่อกลุ่ม",
|
"wallet_list_edit_group_name": "แก้ไขชื่อกลุ่ม",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "Magdagdag ng mga prepaid na pondo sa card (hanggang sa ${value})",
|
"add_fund_to_card": "Magdagdag ng mga prepaid na pondo sa card (hanggang sa ${value})",
|
||||||
"add_new_node": "Magdagdag ng bagong node",
|
"add_new_node": "Magdagdag ng bagong node",
|
||||||
"add_new_word": "Magdagdag ng bagong salita",
|
"add_new_word": "Magdagdag ng bagong salita",
|
||||||
|
"add_passphrase": "Magdagdag ng passphrase",
|
||||||
|
"add_passphrase_warning_text": "Magpasok lamang ng isang passphrase kung ginamit mo ang isa para sa pitaka na ito sa nakaraan. Kung nagpasok ka ng maling passphrase o hindi pa gumamit ng isang passphrase bago sa pitaka na ito, hindi mo makikita ang alinman sa umiiral na pondo o kasaysayan.",
|
||||||
"add_receiver": "Magdagdag ng isa pang tatanggap (opsyonal)",
|
"add_receiver": "Magdagdag ng isa pang tatanggap (opsyonal)",
|
||||||
"add_secret_code": "O, idagdag ang sikretong code na ito sa isang authenticator app",
|
"add_secret_code": "O, idagdag ang sikretong code na ito sa isang authenticator app",
|
||||||
"add_tip": "Magdagdag ng Tip",
|
"add_tip": "Magdagdag ng Tip",
|
||||||
|
@ -621,10 +623,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "Nangangailangan para sa pagpapadala sa mga panloob na wallet",
|
"require_for_sends_to_internal_wallets": "Nangangailangan para sa pagpapadala sa mga panloob na wallet",
|
||||||
"require_for_sends_to_non_contacts": "Nangangailangan para sa pagpapadala sa mga hindi contact",
|
"require_for_sends_to_non_contacts": "Nangangailangan para sa pagpapadala sa mga hindi contact",
|
||||||
"require_pin_after": "Nangangailangan ng PIN pagkatapos",
|
"require_pin_after": "Nangangailangan ng PIN pagkatapos",
|
||||||
|
"required_passphrase": "Passphrase",
|
||||||
"rescan": "Muling i-scan",
|
"rescan": "Muling i-scan",
|
||||||
"resend_code": "Mangyaring ipadala ito muli",
|
"resend_code": "Mangyaring ipadala ito muli",
|
||||||
"reset": "I-reset",
|
"reset": "I-reset",
|
||||||
"reset_password": "I-reset ang password",
|
"reset_password": "I-reset ang password",
|
||||||
|
"restore": "Ibalik",
|
||||||
"restore_active_seed": "Aktibong seed",
|
"restore_active_seed": "Aktibong seed",
|
||||||
"restore_address": "Address",
|
"restore_address": "Address",
|
||||||
"restore_bitcoin_description_from_keys": "Ibalik ang iyong wallet mula sa nabuong WIF string mula sa iyong mga private key",
|
"restore_bitcoin_description_from_keys": "Ibalik ang iyong wallet mula sa nabuong WIF string mula sa iyong mga private key",
|
||||||
|
@ -999,6 +1003,7 @@
|
||||||
"wallet_group_description_view_seed": "Maaari mong palaging tingnan ang binhi na ito sa ilalim",
|
"wallet_group_description_view_seed": "Maaari mong palaging tingnan ang binhi na ito sa ilalim",
|
||||||
"wallet_group_empty_state_text_one": "Mukhang wala kang anumang mga katugmang pangkat ng pitaka!\n\ntap",
|
"wallet_group_empty_state_text_one": "Mukhang wala kang anumang mga katugmang pangkat ng pitaka!\n\ntap",
|
||||||
"wallet_group_empty_state_text_two": "sa ibaba upang gumawa ng bago.",
|
"wallet_group_empty_state_text_two": "sa ibaba upang gumawa ng bago.",
|
||||||
|
"wallet_has_passphrase": "Ang pitaka na ito ay may isang passphrase",
|
||||||
"wallet_keys": "Wallet seed/keys",
|
"wallet_keys": "Wallet seed/keys",
|
||||||
"wallet_list_create_new_wallet": "Lumikha ng bagong wallet",
|
"wallet_list_create_new_wallet": "Lumikha ng bagong wallet",
|
||||||
"wallet_list_edit_group_name": "I -edit ang Pangalan ng Grupo",
|
"wallet_list_edit_group_name": "I -edit ang Pangalan ng Grupo",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "Ön ödemeli kartlara para ekle (En fazla yüklenebilir tutar: ${value})",
|
"add_fund_to_card": "Ön ödemeli kartlara para ekle (En fazla yüklenebilir tutar: ${value})",
|
||||||
"add_new_node": "Yeni düğüm ekle",
|
"add_new_node": "Yeni düğüm ekle",
|
||||||
"add_new_word": "Yeni kelime ekle",
|
"add_new_word": "Yeni kelime ekle",
|
||||||
|
"add_passphrase": "Parola ekle",
|
||||||
|
"add_passphrase_warning_text": "Sadece geçmişte bu cüzdan için bir tane kullandıysanız bir parola girin. Yanlış parola girerseniz veya daha önce bu cüzdanda bir parola kullanmadıysanız, mevcut fonlardan veya geçmişi görmezsiniz.",
|
||||||
"add_receiver": "Başka bir alıcı ekle (isteğe bağlı)",
|
"add_receiver": "Başka bir alıcı ekle (isteğe bağlı)",
|
||||||
"add_secret_code": "Veya bu gizli kodu bir kimlik doğrulama uygulamasına ekleyin",
|
"add_secret_code": "Veya bu gizli kodu bir kimlik doğrulama uygulamasına ekleyin",
|
||||||
"add_tip": "Bahşiş Ekle",
|
"add_tip": "Bahşiş Ekle",
|
||||||
|
@ -621,10 +623,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "Dahili cüzdanlara yapılan gönderimler için gereklilik",
|
"require_for_sends_to_internal_wallets": "Dahili cüzdanlara yapılan gönderimler için gereklilik",
|
||||||
"require_for_sends_to_non_contacts": "Kişi olmayan kişilere göndermeler için gerekli kıl",
|
"require_for_sends_to_non_contacts": "Kişi olmayan kişilere göndermeler için gerekli kıl",
|
||||||
"require_pin_after": "Şu kadar süre sonra PIN iste",
|
"require_pin_after": "Şu kadar süre sonra PIN iste",
|
||||||
|
"required_passphrase": "Parola",
|
||||||
"rescan": "Yeniden Tara",
|
"rescan": "Yeniden Tara",
|
||||||
"resend_code": "Lütfen tekrar gönder",
|
"resend_code": "Lütfen tekrar gönder",
|
||||||
"reset": "Sıfırla",
|
"reset": "Sıfırla",
|
||||||
"reset_password": "Parolamı sıfırla",
|
"reset_password": "Parolamı sıfırla",
|
||||||
|
"restore": "Eski haline getirmek",
|
||||||
"restore_active_seed": "Tohumu aktifleştir",
|
"restore_active_seed": "Tohumu aktifleştir",
|
||||||
"restore_address": "Adres",
|
"restore_address": "Adres",
|
||||||
"restore_bitcoin_description_from_keys": "Cüzdanını, oluşturulan WIF dizesinden veya özel anahtarlarından geri yükle",
|
"restore_bitcoin_description_from_keys": "Cüzdanını, oluşturulan WIF dizesinden veya özel anahtarlarından geri yükle",
|
||||||
|
@ -999,6 +1003,7 @@
|
||||||
"wallet_group_description_view_seed": "Bu tohumu her zaman tekrar görebilirsiniz",
|
"wallet_group_description_view_seed": "Bu tohumu her zaman tekrar görebilirsiniz",
|
||||||
"wallet_group_empty_state_text_one": "Herhangi bir uyumlu cüzdan grubunuz yok gibi görünüyor !\n\n TAP",
|
"wallet_group_empty_state_text_one": "Herhangi bir uyumlu cüzdan grubunuz yok gibi görünüyor !\n\n TAP",
|
||||||
"wallet_group_empty_state_text_two": "Yeni bir tane yapmak için aşağıda.",
|
"wallet_group_empty_state_text_two": "Yeni bir tane yapmak için aşağıda.",
|
||||||
|
"wallet_has_passphrase": "Bu cüzdanın bir parola var",
|
||||||
"wallet_keys": "Cüzdan tohumu/anahtarları",
|
"wallet_keys": "Cüzdan tohumu/anahtarları",
|
||||||
"wallet_list_create_new_wallet": "Yeni Cüzdan Oluştur",
|
"wallet_list_create_new_wallet": "Yeni Cüzdan Oluştur",
|
||||||
"wallet_list_edit_group_name": "Grup Adını Düzenle",
|
"wallet_list_edit_group_name": "Grup Adını Düzenle",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "Додайте передплачені кошти на картки (до ${value})",
|
"add_fund_to_card": "Додайте передплачені кошти на картки (до ${value})",
|
||||||
"add_new_node": "Додати новий вузол",
|
"add_new_node": "Додати новий вузол",
|
||||||
"add_new_word": "Добавити нове слово",
|
"add_new_word": "Добавити нове слово",
|
||||||
|
"add_passphrase": "Додати фразу",
|
||||||
|
"add_passphrase_warning_text": "Введіть парольну фразу, якщо ви використовували її для цього гаманця в минулому. Якщо ви вводите неправильну пасфразу або раніше не використовували парольну фразу на цьому гаманці, ви не побачите жодного з існуючих коштів чи історії.",
|
||||||
"add_receiver": "Додати одержувача (необов'язково)",
|
"add_receiver": "Додати одержувача (необов'язково)",
|
||||||
"add_secret_code": "Або додайте цей секретний код до програми автентифікації",
|
"add_secret_code": "Або додайте цей секретний код до програми автентифікації",
|
||||||
"add_tip": "Додати підказку",
|
"add_tip": "Додати підказку",
|
||||||
|
@ -622,10 +624,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "Вимагати надсилання на внутрішні гаманці",
|
"require_for_sends_to_internal_wallets": "Вимагати надсилання на внутрішні гаманці",
|
||||||
"require_for_sends_to_non_contacts": "Вимагати для надсилання неконтактним особам",
|
"require_for_sends_to_non_contacts": "Вимагати для надсилання неконтактним особам",
|
||||||
"require_pin_after": "Вимагати PIN після",
|
"require_pin_after": "Вимагати PIN після",
|
||||||
|
"required_passphrase": "Пропуск",
|
||||||
"rescan": "Пересканувати",
|
"rescan": "Пересканувати",
|
||||||
"resend_code": "Будь ласка, надішліть його повторно",
|
"resend_code": "Будь ласка, надішліть його повторно",
|
||||||
"reset": "Скинути",
|
"reset": "Скинути",
|
||||||
"reset_password": "Скинути пароль",
|
"reset_password": "Скинути пароль",
|
||||||
|
"restore": "Відновити",
|
||||||
"restore_active_seed": "Активна мнемонічна фраза",
|
"restore_active_seed": "Активна мнемонічна фраза",
|
||||||
"restore_address": "Адреса",
|
"restore_address": "Адреса",
|
||||||
"restore_bitcoin_description_from_keys": "Ви можете відновити гаманець за допомогою WIF",
|
"restore_bitcoin_description_from_keys": "Ви можете відновити гаманець за допомогою WIF",
|
||||||
|
@ -1000,6 +1004,7 @@
|
||||||
"wallet_group_description_view_seed": "Ви завжди можете переглянути це насіння ще раз під",
|
"wallet_group_description_view_seed": "Ви завжди можете переглянути це насіння ще раз під",
|
||||||
"wallet_group_empty_state_text_one": "Схоже, у вас немає сумісних груп гаманця !\n\n Торкніться",
|
"wallet_group_empty_state_text_one": "Схоже, у вас немає сумісних груп гаманця !\n\n Торкніться",
|
||||||
"wallet_group_empty_state_text_two": "нижче, щоб зробити новий.",
|
"wallet_group_empty_state_text_two": "нижче, щоб зробити новий.",
|
||||||
|
"wallet_has_passphrase": "Цей гаманець має фразу",
|
||||||
"wallet_keys": "Мнемонічна фраза/ключі гаманця",
|
"wallet_keys": "Мнемонічна фраза/ключі гаманця",
|
||||||
"wallet_list_create_new_wallet": "Створити новий гаманець",
|
"wallet_list_create_new_wallet": "Створити новий гаманець",
|
||||||
"wallet_list_edit_group_name": "Назва групи редагування",
|
"wallet_list_edit_group_name": "Назва групи редагування",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "کارڈز میں پری پیڈ فنڈز شامل کریں (${value} تک)",
|
"add_fund_to_card": "کارڈز میں پری پیڈ فنڈز شامل کریں (${value} تک)",
|
||||||
"add_new_node": "نیا نوڈ شامل کریں۔",
|
"add_new_node": "نیا نوڈ شامل کریں۔",
|
||||||
"add_new_word": "نیا لفظ شامل کریں۔",
|
"add_new_word": "نیا لفظ شامل کریں۔",
|
||||||
|
"add_passphrase": "پاسفریز شامل کریں",
|
||||||
|
"add_passphrase_warning_text": "صرف ایک پاسفریز درج کریں اگر آپ نے ماضی میں اس پرس کے لئے ایک استعمال کیا ہو۔ اگر آپ غلط پاسفریس میں داخل ہوتے ہیں یا اس پرس سے پہلے پاس فیز کا استعمال نہیں کرتے ہیں تو ، آپ کو موجودہ فنڈز یا تاریخ میں سے کوئی بھی نظر نہیں آئے گا۔",
|
||||||
"add_receiver": "دوسرا وصول کنندہ شامل کریں (اختیاری)",
|
"add_receiver": "دوسرا وصول کنندہ شامل کریں (اختیاری)",
|
||||||
"add_secret_code": " ۔ﮟﯾﺮﮐ ﻞﻣﺎﺷ ﮟﯿﻣ ﭗﯾﺍ ﮦﺪﻨﻨﮐ ﻖﯾﺪﺼﺗ ﻮﮐ ﮈﻮﮐ ﮧﯿﻔﺧ ﺱﺍ ،ﺎﯾ",
|
"add_secret_code": " ۔ﮟﯾﺮﮐ ﻞﻣﺎﺷ ﮟﯿﻣ ﭗﯾﺍ ﮦﺪﻨﻨﮐ ﻖﯾﺪﺼﺗ ﻮﮐ ﮈﻮﮐ ﮧﯿﻔﺧ ﺱﺍ ،ﺎﯾ",
|
||||||
"add_tip": "ٹپ شامل کریں۔",
|
"add_tip": "ٹپ شامل کریں۔",
|
||||||
|
@ -623,10 +625,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "اندرونی بٹوے پر بھیجنے کے لیے درکار ہے۔",
|
"require_for_sends_to_internal_wallets": "اندرونی بٹوے پر بھیجنے کے لیے درکار ہے۔",
|
||||||
"require_for_sends_to_non_contacts": "غیر رابطوں کو بھیجنے کی ضرورت ہے۔",
|
"require_for_sends_to_non_contacts": "غیر رابطوں کو بھیجنے کی ضرورت ہے۔",
|
||||||
"require_pin_after": "اس کے بعد PIN کی ضرورت ہے۔",
|
"require_pin_after": "اس کے بعد PIN کی ضرورت ہے۔",
|
||||||
|
"required_passphrase": "پاسفریز",
|
||||||
"rescan": "دوبارہ اسکین کریں۔",
|
"rescan": "دوبارہ اسکین کریں۔",
|
||||||
"resend_code": "براہ کرم اسے دوبارہ بھیجیں۔",
|
"resend_code": "براہ کرم اسے دوبارہ بھیجیں۔",
|
||||||
"reset": "دوبارہ ترتیب دیں۔",
|
"reset": "دوبارہ ترتیب دیں۔",
|
||||||
"reset_password": "پاس ورڈ ری سیٹ",
|
"reset_password": "پاس ورڈ ری سیٹ",
|
||||||
|
"restore": "بحال کریں",
|
||||||
"restore_active_seed": "فعال بیج",
|
"restore_active_seed": "فعال بیج",
|
||||||
"restore_address": "پتہ",
|
"restore_address": "پتہ",
|
||||||
"restore_bitcoin_description_from_keys": "اپنی نجی کلیدوں سے تیار کردہ WIF سٹرنگ سے اپنے بٹوے کو بحال کریں۔",
|
"restore_bitcoin_description_from_keys": "اپنی نجی کلیدوں سے تیار کردہ WIF سٹرنگ سے اپنے بٹوے کو بحال کریں۔",
|
||||||
|
@ -1001,6 +1005,7 @@
|
||||||
"wallet_group_description_view_seed": "آپ ہمیشہ اس بیج کو دوبارہ دیکھ سکتے ہیں",
|
"wallet_group_description_view_seed": "آپ ہمیشہ اس بیج کو دوبارہ دیکھ سکتے ہیں",
|
||||||
"wallet_group_empty_state_text_one": "ایسا لگتا ہے کہ آپ کے پاس کوئی مطابقت پذیر والیٹ گروپس نہیں ہیں !\n\n نل",
|
"wallet_group_empty_state_text_one": "ایسا لگتا ہے کہ آپ کے پاس کوئی مطابقت پذیر والیٹ گروپس نہیں ہیں !\n\n نل",
|
||||||
"wallet_group_empty_state_text_two": "ایک نیا بنانے کے لئے ذیل میں.",
|
"wallet_group_empty_state_text_two": "ایک نیا بنانے کے لئے ذیل میں.",
|
||||||
|
"wallet_has_passphrase": "اس پرس میں پاسفریس ہے",
|
||||||
"wallet_keys": "بٹوے کے بیج / چابیاں",
|
"wallet_keys": "بٹوے کے بیج / چابیاں",
|
||||||
"wallet_list_create_new_wallet": "نیا والیٹ بنائیں",
|
"wallet_list_create_new_wallet": "نیا والیٹ بنائیں",
|
||||||
"wallet_list_edit_group_name": "گروپ کے نام میں ترمیم کریں",
|
"wallet_list_edit_group_name": "گروپ کے نام میں ترمیم کریں",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "Thêm tiền trả trước vào thẻ (tối đa ${value})",
|
"add_fund_to_card": "Thêm tiền trả trước vào thẻ (tối đa ${value})",
|
||||||
"add_new_node": "Thêm nút mới",
|
"add_new_node": "Thêm nút mới",
|
||||||
"add_new_word": "Thêm từ mới",
|
"add_new_word": "Thêm từ mới",
|
||||||
|
"add_passphrase": "Thêm cụm mật khẩu",
|
||||||
|
"add_passphrase_warning_text": "Chỉ nhập một cụm mật khẩu nếu bạn đã sử dụng một cái cho ví này trong quá khứ. Nếu bạn nhập sai cụm từ hoặc chưa sử dụng cụm mật khẩu trước đây trên ví này, bạn sẽ không thấy bất kỳ quỹ hoặc lịch sử hiện có nào.",
|
||||||
"add_receiver": "Thêm người nhận khác (tùy chọn)",
|
"add_receiver": "Thêm người nhận khác (tùy chọn)",
|
||||||
"add_secret_code": "Hoặc, thêm mã bí mật này vào ứng dụng xác thực",
|
"add_secret_code": "Hoặc, thêm mã bí mật này vào ứng dụng xác thực",
|
||||||
"add_tip": "Thêm tiền boa",
|
"add_tip": "Thêm tiền boa",
|
||||||
|
@ -619,10 +621,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "Yêu cầu khi gửi đến ví nội bộ",
|
"require_for_sends_to_internal_wallets": "Yêu cầu khi gửi đến ví nội bộ",
|
||||||
"require_for_sends_to_non_contacts": "Yêu cầu khi gửi đến người không phải danh bạ",
|
"require_for_sends_to_non_contacts": "Yêu cầu khi gửi đến người không phải danh bạ",
|
||||||
"require_pin_after": "Yêu cầu PIN sau",
|
"require_pin_after": "Yêu cầu PIN sau",
|
||||||
|
"required_passphrase": "Cụm cụm",
|
||||||
"rescan": "Quét lại",
|
"rescan": "Quét lại",
|
||||||
"resend_code": "Vui lòng gửi lại",
|
"resend_code": "Vui lòng gửi lại",
|
||||||
"reset": "Đặt lại",
|
"reset": "Đặt lại",
|
||||||
"reset_password": "Đặt lại mật khẩu",
|
"reset_password": "Đặt lại mật khẩu",
|
||||||
|
"restore": "Khôi phục",
|
||||||
"restore_active_seed": "Hạt giống hoạt động",
|
"restore_active_seed": "Hạt giống hoạt động",
|
||||||
"restore_address": "Địa chỉ",
|
"restore_address": "Địa chỉ",
|
||||||
"restore_bitcoin_description_from_keys": "Khôi phục ví của bạn từ chuỗi WIF được tạo từ khóa riêng của bạn",
|
"restore_bitcoin_description_from_keys": "Khôi phục ví của bạn từ chuỗi WIF được tạo từ khóa riêng của bạn",
|
||||||
|
@ -996,6 +1000,7 @@
|
||||||
"wallet_group_description_view_seed": "Bạn luôn có thể xem lại hạt giống này dưới",
|
"wallet_group_description_view_seed": "Bạn luôn có thể xem lại hạt giống này dưới",
|
||||||
"wallet_group_empty_state_text_one": "Có vẻ như bạn không có bất kỳ nhóm ví tương thích nào !\n\n Tap",
|
"wallet_group_empty_state_text_one": "Có vẻ như bạn không có bất kỳ nhóm ví tương thích nào !\n\n Tap",
|
||||||
"wallet_group_empty_state_text_two": "Dưới đây để làm một cái mới.",
|
"wallet_group_empty_state_text_two": "Dưới đây để làm một cái mới.",
|
||||||
|
"wallet_has_passphrase": "Ví này có một cụm từ",
|
||||||
"wallet_keys": "Hạt giống/khóa ví",
|
"wallet_keys": "Hạt giống/khóa ví",
|
||||||
"wallet_list_create_new_wallet": "Tạo ví mới",
|
"wallet_list_create_new_wallet": "Tạo ví mới",
|
||||||
"wallet_list_edit_group_name": "Chỉnh sửa tên nhóm",
|
"wallet_list_edit_group_name": "Chỉnh sửa tên nhóm",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "Ẹ fikún owó sí àwọn káàdì (kò tóbi ju ${value})",
|
"add_fund_to_card": "Ẹ fikún owó sí àwọn káàdì (kò tóbi ju ${value})",
|
||||||
"add_new_node": "Fi apẹka kún",
|
"add_new_node": "Fi apẹka kún",
|
||||||
"add_new_word": "Fikún ọ̀rọ̀ títun",
|
"add_new_word": "Fikún ọ̀rọ̀ títun",
|
||||||
|
"add_passphrase": "Ṣafikun Kọwe",
|
||||||
|
"add_passphrase_warning_text": "Tẹ ni iwe ikawe nikan ti o ba ti lo ọkan fun apamọwọ yii ni igba atijọ. Ti o ba tẹ iwe ọrọ kukuru ti ko tọ tabi ko lo iwe kukuru ṣaaju lori apamọwọ yii, iwọ kii yoo wo eyikeyi awọn owo tabi itan-akọọlẹ.",
|
||||||
"add_receiver": "Fikún àdírẹ́sì mìíràn (ìyàn nìyí)",
|
"add_receiver": "Fikún àdírẹ́sì mìíràn (ìyàn nìyí)",
|
||||||
"add_secret_code": "Tabi, ṣafikun koodu aṣiri yii si ohun elo onijeri kan",
|
"add_secret_code": "Tabi, ṣafikun koodu aṣiri yii si ohun elo onijeri kan",
|
||||||
"add_tip": "Fún owó àfikún",
|
"add_tip": "Fún owó àfikún",
|
||||||
|
@ -622,10 +624,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "Beere fun fifiranṣẹ si awọn apamọwọ inu",
|
"require_for_sends_to_internal_wallets": "Beere fun fifiranṣẹ si awọn apamọwọ inu",
|
||||||
"require_for_sends_to_non_contacts": "Beere fun fifiranṣẹ si awọn ti kii ṣe awọn olubasọrọ",
|
"require_for_sends_to_non_contacts": "Beere fun fifiranṣẹ si awọn ti kii ṣe awọn olubasọrọ",
|
||||||
"require_pin_after": "Ẹ nílò òǹkà ìdánimọ̀ àdáni láàárín",
|
"require_pin_after": "Ẹ nílò òǹkà ìdánimọ̀ àdáni láàárín",
|
||||||
|
"required_passphrase": "Kukurukọni",
|
||||||
"rescan": "Tún Wá",
|
"rescan": "Tún Wá",
|
||||||
"resend_code": "Ẹ jọ̀wọ́ tún un ránṣé",
|
"resend_code": "Ẹ jọ̀wọ́ tún un ránṣé",
|
||||||
"reset": "Tún ṣe",
|
"reset": "Tún ṣe",
|
||||||
"reset_password": "Tún ọ̀rọ̀ aṣínà ṣe",
|
"reset_password": "Tún ọ̀rọ̀ aṣínà ṣe",
|
||||||
|
"restore": "Mu pada",
|
||||||
"restore_active_seed": "Hóró lọ́wọ́",
|
"restore_active_seed": "Hóró lọ́wọ́",
|
||||||
"restore_address": "Àdírẹ́sì",
|
"restore_address": "Àdírẹ́sì",
|
||||||
"restore_bitcoin_description_from_keys": "Mú àpamọ́wọ́ yín padà láti ọ̀rọ̀ WIF t'á ti dá láti kọ́kọ́rọ́ àdáni yín",
|
"restore_bitcoin_description_from_keys": "Mú àpamọ́wọ́ yín padà láti ọ̀rọ̀ WIF t'á ti dá láti kọ́kọ́rọ́ àdáni yín",
|
||||||
|
@ -1000,6 +1004,7 @@
|
||||||
"wallet_group_description_view_seed": "O le nigbagbogbo wo irugbin yii lẹẹkansi labẹ",
|
"wallet_group_description_view_seed": "O le nigbagbogbo wo irugbin yii lẹẹkansi labẹ",
|
||||||
"wallet_group_empty_state_text_one": "O dabi pe o ko ni eyikeyi awọn ẹgbẹ ti o ni ibamu!\n\ntẹ ni kia kia",
|
"wallet_group_empty_state_text_one": "O dabi pe o ko ni eyikeyi awọn ẹgbẹ ti o ni ibamu!\n\ntẹ ni kia kia",
|
||||||
"wallet_group_empty_state_text_two": "ni isalẹ lati ṣe ọkan titun.",
|
"wallet_group_empty_state_text_two": "ni isalẹ lati ṣe ọkan titun.",
|
||||||
|
"wallet_has_passphrase": "Apamọwọ yii ni iwe kukuru kan",
|
||||||
"wallet_keys": "Hóró/kọ́kọ́rọ́ àpamọ́wọ́",
|
"wallet_keys": "Hóró/kọ́kọ́rọ́ àpamọ́wọ́",
|
||||||
"wallet_list_create_new_wallet": "Ṣe àpamọ́wọ́ títun",
|
"wallet_list_create_new_wallet": "Ṣe àpamọ́wọ́ títun",
|
||||||
"wallet_list_edit_group_name": "Ṣatunṣe Orukọ Ẹgbẹ",
|
"wallet_list_edit_group_name": "Ṣatunṣe Orukọ Ẹgbẹ",
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
"add_fund_to_card": "向卡中添加预付资金(最多 ${value})",
|
"add_fund_to_card": "向卡中添加预付资金(最多 ${value})",
|
||||||
"add_new_node": "添加新节点",
|
"add_new_node": "添加新节点",
|
||||||
"add_new_word": "添加新词",
|
"add_new_word": "添加新词",
|
||||||
|
"add_passphrase": "添加密码",
|
||||||
|
"add_passphrase_warning_text": "仅当您过去曾经为此钱包使用一个时,才输入密码。如果您在此钱包上输入错误的密码短语或在此钱包上之前没有使用过密码,则不会看到任何现有的资金或历史记录。",
|
||||||
"add_receiver": "添加另一個接收器(可選)",
|
"add_receiver": "添加另一個接收器(可選)",
|
||||||
"add_secret_code": "或者,将此密码添加到身份验证器应用程序中",
|
"add_secret_code": "或者,将此密码添加到身份验证器应用程序中",
|
||||||
"add_tip": "添加提示",
|
"add_tip": "添加提示",
|
||||||
|
@ -621,10 +623,12 @@
|
||||||
"require_for_sends_to_internal_wallets": "需要发送到内部钱包",
|
"require_for_sends_to_internal_wallets": "需要发送到内部钱包",
|
||||||
"require_for_sends_to_non_contacts": "需要发送给非联系人",
|
"require_for_sends_to_non_contacts": "需要发送给非联系人",
|
||||||
"require_pin_after": "之后需要 PIN",
|
"require_pin_after": "之后需要 PIN",
|
||||||
|
"required_passphrase": "密码",
|
||||||
"rescan": "重新扫描",
|
"rescan": "重新扫描",
|
||||||
"resend_code": "请重新发送",
|
"resend_code": "请重新发送",
|
||||||
"reset": "重置",
|
"reset": "重置",
|
||||||
"reset_password": "重置密码",
|
"reset_password": "重置密码",
|
||||||
|
"restore": "恢复",
|
||||||
"restore_active_seed": "活动种子",
|
"restore_active_seed": "活动种子",
|
||||||
"restore_address": "地址",
|
"restore_address": "地址",
|
||||||
"restore_bitcoin_description_from_keys": "从私钥中生成的WIF字符串恢复您钱包",
|
"restore_bitcoin_description_from_keys": "从私钥中生成的WIF字符串恢复您钱包",
|
||||||
|
@ -999,6 +1003,7 @@
|
||||||
"wallet_group_description_view_seed": "您可以随时再次在下面查看此种子",
|
"wallet_group_description_view_seed": "您可以随时再次在下面查看此种子",
|
||||||
"wallet_group_empty_state_text_one": "看起来您没有任何兼容的钱包组!\n\n tap",
|
"wallet_group_empty_state_text_one": "看起来您没有任何兼容的钱包组!\n\n tap",
|
||||||
"wallet_group_empty_state_text_two": "下面是一个新的。",
|
"wallet_group_empty_state_text_two": "下面是一个新的。",
|
||||||
|
"wallet_has_passphrase": "这个钱包有一个密码",
|
||||||
"wallet_keys": "钱包种子/密钥",
|
"wallet_keys": "钱包种子/密钥",
|
||||||
"wallet_list_create_new_wallet": "创建新钱包",
|
"wallet_list_create_new_wallet": "创建新钱包",
|
||||||
"wallet_list_edit_group_name": "编辑组名称",
|
"wallet_list_edit_group_name": "编辑组名称",
|
||||||
|
|
|
@ -8,7 +8,7 @@ if [[ ! -d "monero_c/.git" ]];
|
||||||
then
|
then
|
||||||
git clone https://github.com/mrcyjanek/monero_c --branch master monero_c
|
git clone https://github.com/mrcyjanek/monero_c --branch master monero_c
|
||||||
cd monero_c
|
cd monero_c
|
||||||
git checkout 84e52393e395d75f449bcd81e23028889538118f
|
git checkout b335585a7fb94b315eb52bd88f2da6d3489fa508
|
||||||
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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue