mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-06-29 12:59:52 +00:00
Old state (#999)
* Fix Bitcoin transactions not showing (#978) * handle multiple responses coming in a single event * Add timeout for getting transaction info, to allow other transactions to be returned in case of any failure or network issue * Handle other cases of receiving multiple messages in the same response * Fix shib and storj (#997) * Merge main branch * Add missing files --------- Co-authored-by: Justin Ehrenhofer <justin.ehrenhofer@gmail.com>
This commit is contained in:
parent
f55059ce61
commit
3bdc86ec67
21 changed files with 2181 additions and 2331 deletions
BIN
assets/images/shib_icon.png
Normal file
BIN
assets/images/shib_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.8 KiB |
|
@ -13,10 +13,8 @@ import 'package:cw_core/wallet_type.dart';
|
|||
import 'package:hive/hive.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
class BitcoinWalletService extends WalletService<
|
||||
BitcoinNewWalletCredentials,
|
||||
BitcoinRestoreWalletFromSeedCredentials,
|
||||
BitcoinRestoreWalletFromWIFCredentials> {
|
||||
class BitcoinWalletService extends WalletService<BitcoinNewWalletCredentials,
|
||||
BitcoinRestoreWalletFromSeedCredentials, BitcoinRestoreWalletFromWIFCredentials> {
|
||||
BitcoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource, this.isDirect);
|
||||
|
||||
final Box<WalletInfo> walletInfoSource;
|
||||
|
@ -45,10 +43,12 @@ class BitcoinWalletService extends WalletService<
|
|||
|
||||
@override
|
||||
Future<BitcoinWallet> openWallet(String name, String password) async {
|
||||
final walletInfo = walletInfoSource.values.firstWhereOrNull(
|
||||
(info) => info.id == WalletBase.idFor(name, getType()))!;
|
||||
final walletInfo = walletInfoSource.values
|
||||
.firstWhereOrNull((info) => info.id == WalletBase.idFor(name, getType()))!;
|
||||
final wallet = await BitcoinWalletBase.open(
|
||||
password: password, name: name, walletInfo: walletInfo,
|
||||
password: password,
|
||||
name: name,
|
||||
walletInfo: walletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource,
|
||||
encryptionFileUtils: encryptionFileUtilsFor(isDirect));
|
||||
await wallet.init();
|
||||
|
@ -56,18 +56,40 @@ class BitcoinWalletService extends WalletService<
|
|||
}
|
||||
|
||||
@override
|
||||
Future<void> remove(String wallet) async =>
|
||||
File(await pathForWalletDir(name: wallet, type: WalletType.bitcoin))
|
||||
.delete(recursive: true);
|
||||
Future<void> remove(String wallet) async {
|
||||
File(await pathForWalletDir(name: wallet, type: getType())).delete(recursive: true);
|
||||
final walletInfo = walletInfoSource.values
|
||||
.firstWhereOrNull((info) => info.id == WalletBase.idFor(wallet, getType()))!;
|
||||
await walletInfoSource.delete(walletInfo.key);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<BitcoinWallet> restoreFromKeys(
|
||||
BitcoinRestoreWalletFromWIFCredentials credentials) async =>
|
||||
Future<void> rename(String currentName, String password, String newName) async {
|
||||
final currentWalletInfo = walletInfoSource.values
|
||||
.firstWhereOrNull((info) => info.id == WalletBase.idFor(currentName, getType()))!;
|
||||
final currentWallet = await BitcoinWalletBase.open(
|
||||
password: password,
|
||||
name: currentName,
|
||||
walletInfo: currentWalletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource,
|
||||
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
|
||||
);
|
||||
|
||||
await currentWallet.renameWalletFiles(newName);
|
||||
|
||||
final newWalletInfo = currentWalletInfo;
|
||||
newWalletInfo.id = WalletBase.idFor(newName, getType());
|
||||
newWalletInfo.name = newName;
|
||||
|
||||
await walletInfoSource.put(currentWalletInfo.key, newWalletInfo);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<BitcoinWallet> restoreFromKeys(BitcoinRestoreWalletFromWIFCredentials credentials) async =>
|
||||
throw UnimplementedError();
|
||||
|
||||
@override
|
||||
Future<BitcoinWallet> restoreFromSeed(
|
||||
BitcoinRestoreWalletFromSeedCredentials credentials) async {
|
||||
Future<BitcoinWallet> restoreFromSeed(BitcoinRestoreWalletFromSeedCredentials credentials) async {
|
||||
if (!validateMnemonic(credentials.mnemonic)) {
|
||||
throw BitcoinMnemonicIsIncorrectException();
|
||||
}
|
||||
|
|
|
@ -66,54 +66,68 @@ class ElectrumClient {
|
|||
socket!.listen((Uint8List event) {
|
||||
try {
|
||||
final msg = utf8.decode(event.toList());
|
||||
final response =
|
||||
json.decode(msg) as Map<String, dynamic>;
|
||||
_handleResponse(response);
|
||||
} on FormatException catch (e) {
|
||||
final msg = e.message.toLowerCase();
|
||||
|
||||
if (e.source is String) {
|
||||
unterminatedString += e.source as String;
|
||||
}
|
||||
|
||||
if (msg.contains("not a subtype of type")) {
|
||||
unterminatedString += e.source as String;
|
||||
return;
|
||||
}
|
||||
|
||||
if (isJSONStringCorrect(unterminatedString)) {
|
||||
final response =
|
||||
json.decode(unterminatedString) as Map<String, dynamic>;
|
||||
_handleResponse(response);
|
||||
unterminatedString = '';
|
||||
}
|
||||
} on TypeError catch (e) {
|
||||
if (!e.toString().contains('Map<String, Object>') && !e.toString().contains('Map<String, dynamic>')) {
|
||||
return;
|
||||
}
|
||||
|
||||
final source = utf8.decode(event.toList());
|
||||
unterminatedString += source;
|
||||
|
||||
if (isJSONStringCorrect(unterminatedString)) {
|
||||
final response =
|
||||
json.decode(unterminatedString) as Map<String, dynamic>;
|
||||
_handleResponse(response);
|
||||
// unterminatedString = null;
|
||||
unterminatedString = '';
|
||||
final messagesList = msg.split("\n");
|
||||
for (var message in messagesList) {
|
||||
if (message.isEmpty) {
|
||||
continue;
|
||||
}
|
||||
_parseResponse(message);
|
||||
}
|
||||
} catch (e) {
|
||||
print(e.toString());
|
||||
}
|
||||
}, onError: (Object error) {
|
||||
print(error.toString());
|
||||
unterminatedString = '';
|
||||
_setIsConnected(false);
|
||||
}, onDone: () {
|
||||
unterminatedString = '';
|
||||
_setIsConnected(false);
|
||||
});
|
||||
keepAlive();
|
||||
}
|
||||
|
||||
void _parseResponse(String message) {
|
||||
try {
|
||||
final response = json.decode(message) as Map<String, dynamic>;
|
||||
_handleResponse(response);
|
||||
} on FormatException catch (e) {
|
||||
final msg = e.message.toLowerCase();
|
||||
|
||||
if (e.source is String) {
|
||||
unterminatedString += e.source as String;
|
||||
}
|
||||
|
||||
if (msg.contains("not a subtype of type")) {
|
||||
unterminatedString += e.source as String;
|
||||
return;
|
||||
}
|
||||
|
||||
if (isJSONStringCorrect(unterminatedString)) {
|
||||
final response =
|
||||
json.decode(unterminatedString) as Map<String, dynamic>;
|
||||
_handleResponse(response);
|
||||
unterminatedString = '';
|
||||
}
|
||||
} on TypeError catch (e) {
|
||||
if (!e.toString().contains('Map<String, Object>') && !e.toString().contains('Map<String, dynamic>')) {
|
||||
return;
|
||||
}
|
||||
|
||||
unterminatedString += message;
|
||||
|
||||
if (isJSONStringCorrect(unterminatedString)) {
|
||||
final response =
|
||||
json.decode(unterminatedString) as Map<String, dynamic>;
|
||||
_handleResponse(response);
|
||||
// unterminatedString = null;
|
||||
unterminatedString = '';
|
||||
}
|
||||
} catch (e) {
|
||||
print(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void keepAlive() {
|
||||
_aliveTimer?.cancel();
|
||||
_aliveTimer = Timer.periodic(aliveTimerDuration, (_) async => ping());
|
||||
|
@ -217,7 +231,7 @@ class ElectrumClient {
|
|||
|
||||
Future<Map<String, dynamic>> getTransactionRaw(
|
||||
{required String hash}) async =>
|
||||
call(method: 'blockchain.transaction.get', params: [hash, true])
|
||||
callWithTimeout(method: 'blockchain.transaction.get', params: [hash, true], timeout: 10000)
|
||||
.then((dynamic result) {
|
||||
if (result is Map<String, dynamic>) {
|
||||
return result;
|
||||
|
@ -228,7 +242,7 @@ class ElectrumClient {
|
|||
|
||||
Future<String> getTransactionHex(
|
||||
{required String hash}) async =>
|
||||
call(method: 'blockchain.transaction.get', params: [hash, false])
|
||||
callWithTimeout(method: 'blockchain.transaction.get', params: [hash, false], timeout: 10000)
|
||||
.then((dynamic result) {
|
||||
if (result is String) {
|
||||
return result;
|
||||
|
|
|
@ -13,10 +13,8 @@ import 'package:cw_core/wallet_info.dart';
|
|||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
class LitecoinWalletService extends WalletService<
|
||||
BitcoinNewWalletCredentials,
|
||||
BitcoinRestoreWalletFromSeedCredentials,
|
||||
BitcoinRestoreWalletFromWIFCredentials> {
|
||||
class LitecoinWalletService extends WalletService<BitcoinNewWalletCredentials,
|
||||
BitcoinRestoreWalletFromSeedCredentials, BitcoinRestoreWalletFromWIFCredentials> {
|
||||
LitecoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource, this.isDirect);
|
||||
|
||||
final Box<WalletInfo> walletInfoSource;
|
||||
|
@ -46,10 +44,12 @@ class LitecoinWalletService extends WalletService<
|
|||
|
||||
@override
|
||||
Future<LitecoinWallet> openWallet(String name, String password) async {
|
||||
final walletInfo = walletInfoSource.values.firstWhereOrNull(
|
||||
(info) => info.id == WalletBase.idFor(name, getType()))!;
|
||||
final walletInfo = walletInfoSource.values
|
||||
.firstWhereOrNull((info) => info.id == WalletBase.idFor(name, getType()))!;
|
||||
final wallet = await LitecoinWalletBase.open(
|
||||
password: password, name: name, walletInfo: walletInfo,
|
||||
password: password,
|
||||
name: name,
|
||||
walletInfo: walletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource,
|
||||
encryptionFileUtils: encryptionFileUtilsFor(isDirect));
|
||||
await wallet.init();
|
||||
|
@ -57,9 +57,33 @@ class LitecoinWalletService extends WalletService<
|
|||
}
|
||||
|
||||
@override
|
||||
Future<void> remove(String wallet) async =>
|
||||
File(await pathForWalletDir(name: wallet, type: getType()))
|
||||
.delete(recursive: true);
|
||||
Future<void> remove(String wallet) async {
|
||||
File(await pathForWalletDir(name: wallet, type: getType())).delete(recursive: true);
|
||||
final walletInfo = walletInfoSource.values
|
||||
.firstWhereOrNull((info) => info.id == WalletBase.idFor(wallet, getType()))!;
|
||||
await walletInfoSource.delete(walletInfo.key);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> rename(String currentName, String password, String newName) async {
|
||||
final currentWalletInfo = walletInfoSource.values
|
||||
.firstWhereOrNull((info) => info.id == WalletBase.idFor(currentName, getType()))!;
|
||||
final currentWallet = await LitecoinWalletBase.open(
|
||||
password: password,
|
||||
name: currentName,
|
||||
walletInfo: currentWalletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource,
|
||||
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
|
||||
);
|
||||
|
||||
await currentWallet.renameWalletFiles(newName);
|
||||
|
||||
final newWalletInfo = currentWalletInfo;
|
||||
newWalletInfo.id = WalletBase.idFor(newName, getType());
|
||||
newWalletInfo.name = newName;
|
||||
|
||||
await walletInfoSource.put(currentWalletInfo.key, newWalletInfo);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<LitecoinWallet> restoreFromKeys(
|
||||
|
|
|
@ -67,6 +67,29 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
|
|||
CryptoCurrency.uni,
|
||||
CryptoCurrency.stx,
|
||||
CryptoCurrency.btcln,
|
||||
CryptoCurrency.shib,
|
||||
CryptoCurrency.aave,
|
||||
CryptoCurrency.arb,
|
||||
CryptoCurrency.bat,
|
||||
CryptoCurrency.comp,
|
||||
CryptoCurrency.cro,
|
||||
CryptoCurrency.ens,
|
||||
CryptoCurrency.ftm,
|
||||
CryptoCurrency.frax,
|
||||
CryptoCurrency.gusd,
|
||||
CryptoCurrency.gtc,
|
||||
CryptoCurrency.grt,
|
||||
CryptoCurrency.ldo,
|
||||
CryptoCurrency.nexo,
|
||||
CryptoCurrency.cake,
|
||||
CryptoCurrency.pepe,
|
||||
CryptoCurrency.storj,
|
||||
CryptoCurrency.tusd,
|
||||
CryptoCurrency.wbtc,
|
||||
CryptoCurrency.weth,
|
||||
CryptoCurrency.zrx,
|
||||
CryptoCurrency.dydx,
|
||||
CryptoCurrency.steth,
|
||||
];
|
||||
|
||||
static const havenCurrencies = [
|
||||
|
@ -121,7 +144,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
|
|||
static const ape = CryptoCurrency(title: 'APE', tag: 'ETH', fullName: 'ApeCoin', raw: 30, name: 'ape', iconPath: 'assets/images/ape_icon.png');
|
||||
static const avaxc = CryptoCurrency(title: 'AVAX', tag: 'AVAXC', raw: 31, name: 'avaxc', iconPath: 'assets/images/avaxc_icon.png');
|
||||
static const btt = CryptoCurrency(title: 'BTT', tag: 'ETH', fullName: 'BitTorrent', raw: 32, name: 'btt', iconPath: 'assets/images/btt_icon.png');
|
||||
static const bttc = CryptoCurrency(title: 'BTTC', tag: 'TRX', fullName: 'BitTorrent-NEW', raw: 33, name: 'bttc', iconPath: 'assets/images/bttbsc_icon.png');
|
||||
static const bttc = CryptoCurrency(title: 'BTTC', tag: 'TRX', fullName: 'BitTorrent-NEW', raw: 33, name: 'bttc', iconPath: 'assets/images/btt_icon.png');
|
||||
static const doge = CryptoCurrency(title: 'DOGE', fullName: 'Dogecoin', raw: 34, name: 'doge', iconPath: 'assets/images/doge_icon.png');
|
||||
static const firo = CryptoCurrency(title: 'FIRO', raw: 35, name: 'firo', iconPath: 'assets/images/firo_icon.png');
|
||||
static const usdttrc20 = CryptoCurrency(title: 'USDT', tag: 'TRX', fullName: 'USDT Tether', raw: 36, name: 'usdttrc20', iconPath: 'assets/images/usdttrc20_icon.png');
|
||||
|
@ -129,9 +152,9 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
|
|||
static const sc = CryptoCurrency(title: 'SC', fullName: 'Siacoin', raw: 38, name: 'sc', iconPath: 'assets/images/sc_icon.png');
|
||||
static const sol = CryptoCurrency(title: 'SOL', fullName: 'Solana', raw: 39, name: 'sol', iconPath: 'assets/images/sol_icon.png');
|
||||
static const usdc = CryptoCurrency(title: 'USDC', tag: 'ETH', fullName: 'USD Coin', raw: 40, name: 'usdc', iconPath: 'assets/images/usdc_icon.png');
|
||||
static const usdcsol = CryptoCurrency(title: 'USDC', tag: 'SOL', fullName: 'USDC Coin', raw: 41, name: 'usdcsol', iconPath: 'assets/images/usdcsol_icon.png');
|
||||
static const zaddr = CryptoCurrency(title: 'ZZEC', tag: 'ZEC', fullName: 'Shielded Zcash', iconPath: 'assets/images/zaddr_icon.png', raw: 42, name: 'zaddr');
|
||||
static const zec = CryptoCurrency(title: 'TZEC', tag: 'ZEC', fullName: 'Transparent Zcash', iconPath: 'assets/images/zec_icon.png', raw: 43, name: 'zec');
|
||||
static const usdcsol = CryptoCurrency(title: 'USDC', tag: 'SOL', fullName: 'USDC Coin', raw: 41, name: 'usdcsol', iconPath: 'assets/images/usdc_icon.png');
|
||||
static const zaddr = CryptoCurrency(title: 'ZZEC', tag: 'ZEC', fullName: 'Shielded Zcash', raw: 42, name: 'zaddr', iconPath: 'assets/images/zec_icon.png');
|
||||
static const zec = CryptoCurrency(title: 'TZEC', tag: 'ZEC', fullName: 'Transparent Zcash', raw: 43, name: 'zec', iconPath: 'assets/images/zec_icon.png');
|
||||
static const zen = CryptoCurrency(title: 'ZEN', fullName: 'Horizen', raw: 44, name: 'zen', iconPath: 'assets/images/zen_icon.png');
|
||||
static const xvg = CryptoCurrency(title: 'XVG', fullName: 'Verge', raw: 45, name: 'xvg', iconPath: 'assets/images/xvg_icon.png');
|
||||
|
||||
|
@ -152,6 +175,29 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
|
|||
static const uni = CryptoCurrency(title: 'UNI', tag: 'ETH', fullName: 'Uniswap', raw: 60, name: 'uni', iconPath: 'assets/images/uni_icon.png');
|
||||
static const stx = CryptoCurrency(title: 'STX', fullName: 'Stacks', raw: 61, name: 'stx', iconPath: 'assets/images/stx_icon.png');
|
||||
static const btcln = CryptoCurrency(title: 'BTC', tag: 'LN', fullName: 'Bitcoin Lightning Network', raw: 62, name: 'btcln', iconPath: 'assets/images/btc.png');
|
||||
static const shib = CryptoCurrency(title: 'SHIB', tag: 'ETH', fullName: 'Shiba Inu', raw: 63, name: 'shib', iconPath: 'assets/images/shib_icon.png');
|
||||
static const aave = CryptoCurrency(title: 'AAVE', tag: 'ETH', fullName: 'Aave', raw: 64, name: 'aave', iconPath: 'assets/images/aave_icon.png');
|
||||
static const arb = CryptoCurrency(title: 'ARB', fullName: 'Arbitrum', raw: 65, name: 'arb', iconPath: 'assets/images/arb_icon.png');
|
||||
static const bat = CryptoCurrency(title: 'BAT', tag: 'ETH', fullName: 'Basic Attention Token', raw: 66, name: 'bat', iconPath: 'assets/images/bat_icon.png');
|
||||
static const comp = CryptoCurrency(title: 'COMP', tag: 'ETH', fullName: 'Compound', raw: 67, name: 'comp', iconPath: 'assets/images/comp_icon.png');
|
||||
static const cro = CryptoCurrency(title: 'CRO', tag: 'ETH', fullName: 'Crypto.com Cronos', raw: 68, name: 'cro', iconPath: 'assets/images/cro_icon.png');
|
||||
static const ens = CryptoCurrency(title: 'ENS', tag: 'ETH', fullName: 'Ethereum Name Service', raw: 69, name: 'ens', iconPath: 'assets/images/ens_icon.png');
|
||||
static const ftm = CryptoCurrency(title: 'FTM', tag: 'ETH', fullName: 'Fantom', raw: 70, name: 'ftm', iconPath: 'assets/images/ftm_icon.png');
|
||||
static const frax = CryptoCurrency(title: 'FRAX', tag: 'ETH', fullName: 'Frax', raw: 71, name: 'frax', iconPath: 'assets/images/frax_icon.png');
|
||||
static const gusd = CryptoCurrency(title: 'GUSD', tag: 'ETH', fullName: 'Gemini USD', raw: 72, name: 'gusd', iconPath: 'assets/images/gusd_icon.png');
|
||||
static const gtc = CryptoCurrency(title: 'GTC', tag: 'ETH', fullName: 'Gitcoin', raw: 73, name: 'gtc', iconPath: 'assets/images/gtc_icon.png');
|
||||
static const grt = CryptoCurrency(title: 'GRT', tag: 'ETH', fullName: 'The Graph', raw: 74, name: 'grt', iconPath: 'assets/images/grt_icon.png');
|
||||
static const ldo = CryptoCurrency(title: 'LDO', tag: 'ETH', fullName: 'Lido DAO', raw: 75, name: 'ldo', iconPath: 'assets/images/ldo_icon.png');
|
||||
static const nexo = CryptoCurrency(title: 'NEXO', tag: 'ETH', fullName: 'Nexo', raw: 76, name: 'nexo', iconPath: 'assets/images/nexo_icon.png');
|
||||
static const cake = CryptoCurrency(title: 'CAKE', tag: 'BSC', fullName: 'PancakeSwap', raw: 77, name: 'cake', iconPath: 'assets/images/cake_icon.png');
|
||||
static const pepe = CryptoCurrency(title: 'PEPE', tag: 'ETH', fullName: 'Pepe', raw: 78, name: 'pepe', iconPath: 'assets/images/pepe_icon.png');
|
||||
static const storj = CryptoCurrency(title: 'STORJ', tag: 'ETH', fullName: 'Storj', raw: 79, name: 'storj', iconPath: 'assets/images/storj_icon.png');
|
||||
static const tusd = CryptoCurrency(title: 'TUSD', tag: 'ETH', fullName: 'TrueUSD', raw: 80, name: 'tusd', iconPath: 'assets/images/tusd_icon.png');
|
||||
static const wbtc = CryptoCurrency(title: 'WBTC', tag: 'ETH', fullName: 'Wrapped Bitcoin', raw: 81, name: 'wbtc', iconPath: 'assets/images/wbtc_icon.png');
|
||||
static const weth = CryptoCurrency(title: 'WETH', tag: 'ETH', fullName: 'Wrapped Ethereum', raw: 82, name: 'weth', iconPath: 'assets/images/weth_icon.png');
|
||||
static const zrx = CryptoCurrency(title: 'ZRX', tag: 'ETH', fullName: '0x Protocol', raw: 83, name: 'zrx', iconPath: 'assets/images/zrx_icon.png');
|
||||
static const dydx = CryptoCurrency(title: 'DYDX', tag: 'ETH', fullName: 'dYdX', raw: 84, name: 'dydx', iconPath: 'assets/images/dydx_icon.png');
|
||||
static const steth = CryptoCurrency(title: 'STETH', tag: 'ETH', fullName: 'Lido Staked Ethereum', raw: 85, name: 'steth', iconPath: 'assets/images/steth_icon.png');
|
||||
|
||||
|
||||
static final Map<int, CryptoCurrency> _rawCurrencyMap =
|
||||
|
|
|
@ -3,7 +3,6 @@ import 'package:cw_core/wallet_base.dart';
|
|||
import 'package:cw_core/monero_wallet_utils.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager;
|
||||
import 'package:cw_monero/api/wallet.dart' as monero_wallet;
|
||||
import 'package:cw_monero/api/exceptions/wallet_opening_exception.dart';
|
||||
import 'package:cw_monero/monero_wallet.dart';
|
||||
import 'package:cw_core/wallet_credentials.dart';
|
||||
|
@ -150,6 +149,26 @@ class MoneroWalletService extends WalletService<
|
|||
if (isExist) {
|
||||
await file.delete(recursive: true);
|
||||
}
|
||||
|
||||
final walletInfo = walletInfoSource.values
|
||||
.firstWhere((info) => info.id == WalletBase.idFor(wallet, getType()));
|
||||
await walletInfoSource.delete(walletInfo.key);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> rename(
|
||||
String currentName, String password, String newName) async {
|
||||
final currentWalletInfo = walletInfoSource.values.firstWhere(
|
||||
(info) => info.id == WalletBase.idFor(currentName, getType()));
|
||||
final currentWallet = MoneroWallet(walletInfo: currentWalletInfo, password: password);
|
||||
|
||||
await currentWallet.renameWalletFiles(newName);
|
||||
|
||||
final newWalletInfo = currentWalletInfo;
|
||||
newWalletInfo.id = WalletBase.idFor(newName, getType());
|
||||
newWalletInfo.name = newName;
|
||||
|
||||
await walletInfoSource.put(currentWalletInfo.key, newWalletInfo);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -16,11 +16,11 @@ import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
|||
import 'package:cw_core/crypto_currency.dart';
|
||||
|
||||
class MoonPaySellProvider {
|
||||
MoonPaySellProvider({this.isTest = false})
|
||||
: baseUrl = isTest ? _baseTestUrl : _baseProductUrl;
|
||||
MoonPaySellProvider({this.isTest = false}) : baseUrl = isTest ? _baseTestUrl : _baseProductUrl;
|
||||
|
||||
static const _baseTestUrl = 'sell-sandbox.moonpay.com';
|
||||
static const _baseProductUrl = 'sell.moonpay.com';
|
||||
|
||||
static String themeToMoonPayTheme(ThemeBase theme) {
|
||||
switch (theme.type) {
|
||||
case ThemeType.bright:
|
||||
|
@ -31,16 +31,17 @@ class MoonPaySellProvider {
|
|||
return 'dark';
|
||||
}
|
||||
}
|
||||
static String get _apiKey => secrets.moonPayApiKey;
|
||||
static String get _secretKey => secrets.moonPaySecretKey;
|
||||
|
||||
static String get _apiKey => secrets.moonPayApiKey;
|
||||
|
||||
static String get _secretKey => secrets.moonPaySecretKey;
|
||||
final bool isTest;
|
||||
final String baseUrl;
|
||||
|
||||
Future<Uri> requestUrl(
|
||||
{required CryptoCurrency currency,
|
||||
required String refundWalletAddress,
|
||||
required SettingsStore settingsStore}) async {
|
||||
|
||||
required String refundWalletAddress,
|
||||
required SettingsStore settingsStore}) async {
|
||||
final customParams = {
|
||||
'theme': themeToMoonPayTheme(settingsStore.currentTheme),
|
||||
'language': settingsStore.languageCode,
|
||||
|
@ -50,11 +51,13 @@ class MoonPaySellProvider {
|
|||
};
|
||||
|
||||
final originalUri = Uri.https(
|
||||
baseUrl, '', <String, dynamic>{
|
||||
'apiKey': _apiKey,
|
||||
'defaultBaseCurrencyCode': currency.toString().toLowerCase(),
|
||||
'refundWalletAddress': refundWalletAddress
|
||||
}..addAll(customParams));
|
||||
baseUrl,
|
||||
'',
|
||||
<String, dynamic>{
|
||||
'apiKey': _apiKey,
|
||||
'defaultBaseCurrencyCode': currency.toString().toLowerCase(),
|
||||
'refundWalletAddress': refundWalletAddress
|
||||
}..addAll(customParams));
|
||||
final messageBytes = utf8.encode('?${originalUri.query}');
|
||||
final key = utf8.encode(_secretKey);
|
||||
final hmac = Hmac(sha256, key);
|
||||
|
@ -93,8 +96,7 @@ class MoonPayBuyProvider extends BuyProvider {
|
|||
@override
|
||||
BuyProviderDescription get description => BuyProviderDescription.moonPay;
|
||||
|
||||
String get currencyCode =>
|
||||
walletTypeToCryptoCurrency(walletType).title.toLowerCase();
|
||||
String get currencyCode => walletTypeToCryptoCurrency(walletType).title.toLowerCase();
|
||||
|
||||
@override
|
||||
String get trackUrl => baseUrl + '/transaction_receipt?transactionId=';
|
||||
|
@ -103,16 +105,24 @@ class MoonPayBuyProvider extends BuyProvider {
|
|||
|
||||
@override
|
||||
Future<String> requestUrl(String amount, String sourceCurrency) async {
|
||||
final enabledPaymentMethods =
|
||||
'credit_debit_card%2Capple_pay%2Cgoogle_pay%2Csamsung_pay'
|
||||
final enabledPaymentMethods = 'credit_debit_card%2Capple_pay%2Cgoogle_pay%2Csamsung_pay'
|
||||
'%2Csepa_bank_transfer%2Cgbp_bank_transfer%2Cgbp_open_banking_payment';
|
||||
|
||||
final suffix = '?apiKey=' + _apiKey + '¤cyCode=' +
|
||||
currencyCode + '&enabledPaymentMethods=' + enabledPaymentMethods +
|
||||
'&walletAddress=' + walletAddress +
|
||||
'&baseCurrencyCode=' + sourceCurrency.toLowerCase() +
|
||||
'&baseCurrencyAmount=' + amount + '&lockAmount=true' +
|
||||
'&showAllCurrencies=false' + '&showWalletAddressForm=false';
|
||||
final suffix = '?apiKey=' +
|
||||
_apiKey +
|
||||
'¤cyCode=' +
|
||||
currencyCode +
|
||||
'&enabledPaymentMethods=' +
|
||||
enabledPaymentMethods +
|
||||
'&walletAddress=' +
|
||||
walletAddress +
|
||||
'&baseCurrencyCode=' +
|
||||
sourceCurrency.toLowerCase() +
|
||||
'&baseCurrencyAmount=' +
|
||||
amount +
|
||||
'&lockAmount=true' +
|
||||
'&showAllCurrencies=false' +
|
||||
'&showWalletAddressForm=false';
|
||||
|
||||
final originalUrl = baseUrl + suffix;
|
||||
|
||||
|
@ -121,25 +131,28 @@ class MoonPayBuyProvider extends BuyProvider {
|
|||
final hmac = Hmac(sha256, key);
|
||||
final digest = hmac.convert(messageBytes);
|
||||
final signature = base64.encode(digest.bytes);
|
||||
final urlWithSignature = originalUrl +
|
||||
'&signature=${Uri.encodeComponent(signature)}';
|
||||
final urlWithSignature = originalUrl + '&signature=${Uri.encodeComponent(signature)}';
|
||||
|
||||
return isTestEnvironment ? originalUrl : urlWithSignature;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<BuyAmount> calculateAmount(String amount, String sourceCurrency) async {
|
||||
final url = _apiUrl + _currenciesSuffix + '/$currencyCode' +
|
||||
_quoteSuffix + '/?apiKey=' + _apiKey +
|
||||
'&baseCurrencyAmount=' + amount +
|
||||
'&baseCurrencyCode=' + sourceCurrency.toLowerCase();
|
||||
final url = _apiUrl +
|
||||
_currenciesSuffix +
|
||||
'/$currencyCode' +
|
||||
_quoteSuffix +
|
||||
'/?apiKey=' +
|
||||
_apiKey +
|
||||
'&baseCurrencyAmount=' +
|
||||
amount +
|
||||
'&baseCurrencyCode=' +
|
||||
sourceCurrency.toLowerCase();
|
||||
final uri = Uri.parse(url);
|
||||
final response = await get(uri);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw BuyException(
|
||||
description: description,
|
||||
text: 'Quote is not found!');
|
||||
throw BuyException(description: description, text: 'Quote is not found!');
|
||||
}
|
||||
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
@ -148,22 +161,17 @@ class MoonPayBuyProvider extends BuyProvider {
|
|||
final minSourceAmount = responseJSON['baseCurrency']['minAmount'] as int;
|
||||
|
||||
return BuyAmount(
|
||||
sourceAmount: sourceAmount,
|
||||
destAmount: destAmount,
|
||||
minAmount: minSourceAmount);
|
||||
sourceAmount: sourceAmount, destAmount: destAmount, minAmount: minSourceAmount);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Order> findOrderById(String id) async {
|
||||
final url = _apiUrl + _transactionsSuffix + '/$id' +
|
||||
'?apiKey=' + _apiKey;
|
||||
final url = _apiUrl + _transactionsSuffix + '/$id' + '?apiKey=' + _apiKey;
|
||||
final uri = Uri.parse(url);
|
||||
final response = await get(uri);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw BuyException(
|
||||
description: description,
|
||||
text: 'Transaction $id is not found!');
|
||||
throw BuyException(description: description, text: 'Transaction $id is not found!');
|
||||
}
|
||||
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
@ -181,8 +189,7 @@ class MoonPayBuyProvider extends BuyProvider {
|
|||
createdAt: createdAt,
|
||||
amount: amount.toString(),
|
||||
receiveAddress: walletAddress,
|
||||
walletId: walletId
|
||||
);
|
||||
walletId: walletId);
|
||||
}
|
||||
|
||||
static Future<bool> onEnabled() async {
|
||||
|
@ -201,4 +208,4 @@ class MoonPayBuyProvider extends BuyProvider {
|
|||
|
||||
return isBuyEnable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,19 +7,30 @@ import 'package:cw_core/wallet_type.dart';
|
|||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class WalletLoadingService {
|
||||
WalletLoadingService(
|
||||
this.sharedPreferences,
|
||||
this.keyService,
|
||||
this.walletServiceFactory);
|
||||
|
||||
final SharedPreferences sharedPreferences;
|
||||
final KeyService keyService;
|
||||
final WalletService Function(WalletType type) walletServiceFactory;
|
||||
WalletLoadingService(this.sharedPreferences, this.keyService, this.walletServiceFactory);
|
||||
|
||||
Future<WalletBase> load(WalletType type, String name, {String? password}) async {
|
||||
final walletService = walletServiceFactory.call(type);
|
||||
final walletPassword = password ?? (await keyService.getWalletPassword(walletName: name));
|
||||
final wallet = await walletService.openWallet(name, walletPassword);
|
||||
final SharedPreferences sharedPreferences;
|
||||
final KeyService keyService;
|
||||
final WalletService Function(WalletType type) walletServiceFactory;
|
||||
|
||||
Future<void> renameWallet(WalletType type, String name, String newName,
|
||||
{String? password}) async {
|
||||
final walletService = walletServiceFactory.call(type);
|
||||
final walletPassword = password ?? (await keyService.getWalletPassword(walletName: name));
|
||||
|
||||
// Save the current wallet's password to the new wallet name's key
|
||||
await keyService.saveWalletPassword(walletName: newName, password: walletPassword);
|
||||
// Delete previous wallet name from keyService to keep only new wallet's name
|
||||
// otherwise keeps duplicate (old and new names)
|
||||
await keyService.deleteWalletPassword(walletName: name);
|
||||
|
||||
await walletService.rename(name, walletPassword, newName);
|
||||
}
|
||||
|
||||
Future<WalletBase> load(WalletType type, String name, {String? password}) async {
|
||||
final walletService = walletServiceFactory.call(type);
|
||||
final walletPassword = password ?? (await keyService.getWalletPassword(walletName: name));
|
||||
final wallet = await walletService.openWallet(name, walletPassword);
|
||||
|
||||
if (type == WalletType.monero) {
|
||||
await updateMoneroWalletPassword(wallet);
|
||||
|
@ -36,14 +47,14 @@ class WalletLoadingService {
|
|||
return;
|
||||
}
|
||||
|
||||
final password = generateWalletPassword();
|
||||
// Save new generated password with backup key for case where
|
||||
// wallet will change password, but it will fail to update in secure storage
|
||||
final bakWalletName = '#__${wallet.name}_bak__#';
|
||||
await keyService.saveWalletPassword(walletName: bakWalletName, password: password);
|
||||
await wallet.changePassword(password);
|
||||
await keyService.saveWalletPassword(walletName: wallet.name, password: password);
|
||||
isPasswordUpdated = true;
|
||||
await sharedPreferences.setBool(key, isPasswordUpdated);
|
||||
}
|
||||
}
|
||||
final password = generateWalletPassword();
|
||||
// Save new generated password with backup key for case where
|
||||
// wallet will change password, but it will fail to update in secure storage
|
||||
final bakWalletName = '#__${wallet.name}_bak__#';
|
||||
await keyService.saveWalletPassword(walletName: bakWalletName, password: password);
|
||||
await wallet.changePassword(password);
|
||||
await keyService.saveWalletPassword(walletName: wallet.name, password: password);
|
||||
isPasswordUpdated = true;
|
||||
await sharedPreferences.setBool(key, isPasswordUpdated);
|
||||
}
|
||||
}
|
||||
|
|
27
lib/di.dart
27
lib/di.dart
|
@ -1,4 +1,3 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart';
|
||||
import 'package:cake_wallet/core/yat_service.dart';
|
||||
|
@ -7,11 +6,8 @@ import 'package:cake_wallet/entities/preferences_key.dart';
|
|||
import 'package:cake_wallet/anonpay/anonpay_api.dart';
|
||||
import 'package:cake_wallet/anonpay/anonpay_info_base.dart';
|
||||
import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart';
|
||||
import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart';
|
||||
import 'package:cake_wallet/buy/payfura/payfura_buy_provider.dart';
|
||||
import 'package:cake_wallet/core/yat_service.dart';
|
||||
import 'package:cake_wallet/entities/exchange_api_mode.dart';
|
||||
import 'package:cake_wallet/entities/parse_address_from_domain.dart';
|
||||
import 'package:cake_wallet/entities/receive_page_option.dart';
|
||||
import 'package:cake_wallet/ionia/ionia_anypay.dart';
|
||||
import 'package:cake_wallet/ionia/ionia_gift_card.dart';
|
||||
|
@ -23,8 +19,6 @@ import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_wallet
|
|||
import 'package:cake_wallet/src/screens/dashboard/widgets/transactions_page.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/desktop_dashboard_page.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/transactions_page.dart';
|
||||
import 'package:cake_wallet/src/screens/receive/anonpay_invoice_page.dart';
|
||||
import 'package:cake_wallet/src/screens/receive/anonpay_receive_page.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/display_settings_page.dart';
|
||||
|
@ -43,6 +37,7 @@ import 'package:cake_wallet/src/screens/setup_2fa/modify_2fa_page.dart';
|
|||
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_qr_page.dart';
|
||||
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa.dart';
|
||||
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_enter_code_page.dart';
|
||||
import 'package:cake_wallet/src/screens/wallet/wallet_edit_page.dart';
|
||||
import 'package:cake_wallet/themes/theme_list.dart';
|
||||
import 'package:cake_wallet/utils/device_info.dart';
|
||||
import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart';
|
||||
|
@ -79,6 +74,8 @@ import 'package:cake_wallet/view_model/settings/privacy_settings_view_model.dart
|
|||
import 'package:cake_wallet/view_model/settings/security_settings_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_item.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_list/wallet_edit_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_unlock_loadable_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_unlock_verifiable_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_unlock_view_model.dart';
|
||||
|
@ -174,7 +171,6 @@ import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
|
|||
import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_seed_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
|
@ -582,6 +578,21 @@ Future setup({
|
|||
authService: getIt.get<AuthService>(),
|
||||
));
|
||||
|
||||
getIt.registerFactoryParam<WalletEditViewModel, WalletListViewModel, void>(
|
||||
(WalletListViewModel walletListViewModel, _) => WalletEditViewModel(
|
||||
walletListViewModel, getIt.get<WalletLoadingService>()));
|
||||
|
||||
getIt.registerFactoryParam<WalletEditPage, List<dynamic>, void>((args, _) {
|
||||
final walletListViewModel = args.first as WalletListViewModel;
|
||||
final editingWallet = args.last as WalletListItem;
|
||||
return WalletEditPage(
|
||||
walletEditViewModel: getIt.get<WalletEditViewModel>(param1: walletListViewModel),
|
||||
authService: getIt.get<AuthService>(),
|
||||
walletNewVM: getIt.get<WalletNewVM>(param1: editingWallet.type),
|
||||
editingWallet: editingWallet);
|
||||
});
|
||||
|
||||
|
||||
getIt.registerFactory(() {
|
||||
final wallet = getIt.get<AppStore>().wallet!;
|
||||
|
||||
|
@ -926,7 +937,7 @@ Future setup({
|
|||
return IoniaVerifyIoniaOtp(getIt.get<IoniaAuthViewModel>(), email, isSignIn);
|
||||
});
|
||||
|
||||
getIt.registerFactory(() => IoniaWelcomePage());
|
||||
getIt.registerFactory(() => IoniaWelcomePage(getIt.get<IoniaGiftCardsListViewModel>()));
|
||||
|
||||
getIt.registerFactoryParam<IoniaBuyGiftCardPage, List, void>((List args, _) {
|
||||
final merchant = args.first as IoniaMerchant;
|
||||
|
|
|
@ -8,6 +8,7 @@ import 'package:cake_wallet/store/yat/yat_store.dart';
|
|||
import 'package:cake_wallet/utils/exception_handler.dart';
|
||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:cw_core/root_dir.dart';
|
||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cake_wallet/src/widgets/market_place_item.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/src/widgets/dashboard_card_widget.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart';
|
||||
|
@ -77,12 +77,13 @@ class MarketPlacePage extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
// TODO: Remove ionia flow/files if we will discard it
|
||||
void _navigatorToGiftCardsPage(BuildContext context) {
|
||||
final walletType = dashboardViewModel.type;
|
||||
|
||||
switch (walletType) {
|
||||
case WalletType.haven:
|
||||
showPopUp<void>(
|
||||
showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithOneAction(
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import 'package:cake_wallet/src/screens/dashboard/widgets/anonpay_transaction_row.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/order_row.dart';
|
||||
import 'package:cake_wallet/src/widgets/dashboard_card_widget.dart';
|
||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/anonpay_transaction_list_item.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/order_list_item.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/sync_status.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
|
@ -37,6 +39,25 @@ class TransactionsPage extends StatelessWidget {
|
|||
padding: EdgeInsets.only(top: 24, bottom: 24),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Observer(builder: (_) {
|
||||
final status = dashboardViewModel.status;
|
||||
if (status is SyncingSyncStatus) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(24, 0, 24, 8),
|
||||
child: DashBoardRoundedCardWidget(
|
||||
onTap: () => Navigator.of(context).pushNamed(Routes.webViewPage, arguments: [
|
||||
'',
|
||||
Uri.parse(
|
||||
'https://guides.cakewallet.com/docs/bugs-service-status/why_are_my_funds_not_appearing/')
|
||||
]),
|
||||
title: S.of(context).syncing_wallet_alert_title,
|
||||
subTitle: S.of(context).syncing_wallet_alert_content,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Container();
|
||||
}
|
||||
}),
|
||||
HeaderRow(dashboardViewModel: dashboardViewModel),
|
||||
Expanded(child: Observer(builder: (_) {
|
||||
final items = dashboardViewModel.items;
|
||||
|
@ -56,40 +77,34 @@ class TransactionsPage extends StatelessWidget {
|
|||
|
||||
return Observer(
|
||||
builder: (_) => TransactionRow(
|
||||
onTap: () => Navigator.of(context).pushNamed(
|
||||
Routes.transactionDetails,
|
||||
arguments: transaction),
|
||||
onTap: () => Navigator.of(context)
|
||||
.pushNamed(Routes.transactionDetails, arguments: transaction),
|
||||
direction: transaction.direction,
|
||||
formattedDate: DateFormat('HH:mm')
|
||||
.format(transaction.date),
|
||||
formattedDate: DateFormat('HH:mm').format(transaction.date),
|
||||
formattedAmount: item.formattedCryptoAmount,
|
||||
formattedFiatAmount: dashboardViewModel
|
||||
.balanceViewModel.isFiatDisabled
|
||||
? ''
|
||||
: item.formattedFiatAmount,
|
||||
formattedFiatAmount:
|
||||
dashboardViewModel.balanceViewModel.isFiatDisabled
|
||||
? ''
|
||||
: item.formattedFiatAmount,
|
||||
isPending: transaction.isPending,
|
||||
title: item.formattedTitle +
|
||||
item.formattedStatus));
|
||||
title: item.formattedTitle + item.formattedStatus));
|
||||
}
|
||||
|
||||
if (item is AnonpayTransactionListItem) {
|
||||
final transactionInfo = item.transaction;
|
||||
|
||||
return AnonpayTransactionRow(
|
||||
onTap: () => Navigator.of(context).pushNamed(
|
||||
Routes.anonPayDetailsPage,
|
||||
arguments: transactionInfo),
|
||||
onTap: () => Navigator.of(context)
|
||||
.pushNamed(Routes.anonPayDetailsPage, arguments: transactionInfo),
|
||||
currency: transactionInfo.fiatAmount != null
|
||||
? transactionInfo.fiatEquiv ?? ''
|
||||
: CryptoCurrency.fromFullName(
|
||||
transactionInfo.coinTo)
|
||||
: CryptoCurrency.fromFullName(transactionInfo.coinTo)
|
||||
.name
|
||||
.toUpperCase(),
|
||||
provider: transactionInfo.provider,
|
||||
amount: transactionInfo.fiatAmount?.toString() ??
|
||||
(transactionInfo.amountTo?.toString() ?? ''),
|
||||
createdAt: DateFormat('HH:mm')
|
||||
.format(transactionInfo.createdAt),
|
||||
createdAt: DateFormat('HH:mm').format(transactionInfo.createdAt),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -98,17 +113,14 @@ class TransactionsPage extends StatelessWidget {
|
|||
|
||||
return Observer(
|
||||
builder: (_) => TradeRow(
|
||||
onTap: () => Navigator.of(context).pushNamed(
|
||||
Routes.tradeDetails,
|
||||
arguments: trade),
|
||||
onTap: () => Navigator.of(context)
|
||||
.pushNamed(Routes.tradeDetails, arguments: trade),
|
||||
provider: trade.provider,
|
||||
from: trade.from,
|
||||
to: trade.to,
|
||||
createdAtFormattedDate:
|
||||
trade.createdAt != null
|
||||
? DateFormat('HH:mm')
|
||||
.format(trade.createdAt!)
|
||||
: null,
|
||||
createdAtFormattedDate: trade.createdAt != null
|
||||
? DateFormat('HH:mm').format(trade.createdAt!)
|
||||
: null,
|
||||
formattedAmount: item.tradeFormattedAmount));
|
||||
}
|
||||
|
||||
|
@ -118,13 +130,12 @@ class TransactionsPage extends StatelessWidget {
|
|||
return Observer(
|
||||
builder: (_) => OrderRow(
|
||||
onTap: () => Navigator.of(context)
|
||||
.pushNamed(Routes.orderDetails,
|
||||
arguments: order),
|
||||
.pushNamed(Routes.orderDetails, arguments: order),
|
||||
provider: order.provider,
|
||||
from: order.from!,
|
||||
to: order.to!,
|
||||
createdAtFormattedDate: DateFormat('HH:mm')
|
||||
.format(order.createdAt),
|
||||
createdAtFormattedDate:
|
||||
DateFormat('HH:mm').format(order.createdAt),
|
||||
formattedAmount: item.orderFormattedAmount,
|
||||
));
|
||||
}
|
||||
|
@ -136,10 +147,7 @@ class TransactionsPage extends StatelessWidget {
|
|||
S.of(context).placeholder_transactions,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.labelSmall!
|
||||
.decorationColor!),
|
||||
color: Theme.of(context).primaryTextTheme.labelSmall!.decorationColor!),
|
||||
),
|
||||
);
|
||||
}))
|
||||
|
|
|
@ -41,6 +41,7 @@ class AnonPayInvoicePage extends BasePage {
|
|||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
bool effectsInstalled = false;
|
||||
|
||||
@override
|
||||
Color get titleColor => Colors.white;
|
||||
|
||||
|
@ -85,34 +86,33 @@ class AnonPayInvoicePage extends BasePage {
|
|||
disableScroll: true,
|
||||
config: KeyboardActionsConfig(
|
||||
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
|
||||
keyboardBarColor: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.bodyLarge!
|
||||
.backgroundColor!,
|
||||
nextFocus: false,
|
||||
actions: [
|
||||
KeyboardActionsItem(
|
||||
focusNode: _amountFocusNode,
|
||||
toolbarButtons: [(_) => KeyboardDoneButton()],
|
||||
),
|
||||
]),
|
||||
child: Container(
|
||||
color: Theme.of(context).colorScheme.background,
|
||||
child: ScrollableWithBottomSection(
|
||||
contentPadding: EdgeInsets.only(bottom: 24),
|
||||
content: Container(
|
||||
decoration: ResponsiveLayoutUtil.instance.isMobile ? BoxDecoration(
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
Theme.of(context).primaryTextTheme!.titleSmall!.color!,
|
||||
Theme.of(context).primaryTextTheme!.titleSmall!.decorationColor!,
|
||||
],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
keyboardBarColor: Theme.of(context).accentTextTheme!.bodyLarge!.backgroundColor!,
|
||||
nextFocus: false,
|
||||
actions: [
|
||||
KeyboardActionsItem(
|
||||
focusNode: _amountFocusNode,
|
||||
toolbarButtons: [(_) => KeyboardDoneButton()],
|
||||
),
|
||||
) : null,
|
||||
]),
|
||||
child: Container(
|
||||
color: Theme.of(context).colorScheme.background,
|
||||
child: ScrollableWithBottomSection(
|
||||
contentPadding: EdgeInsets.only(bottom: 24),
|
||||
content: Container(
|
||||
decoration: ResponsiveLayoutUtil.instance.isMobile
|
||||
? BoxDecoration(
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
Theme.of(context).primaryTextTheme!.titleSmall!.color!,
|
||||
Theme.of(context).primaryTextTheme!.titleSmall!.decorationColor!,
|
||||
],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
child: Observer(builder: (_) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.fromLTRB(24, 120, 24, 0),
|
||||
|
@ -145,12 +145,10 @@ class AnonPayInvoicePage extends BasePage {
|
|||
: S.of(context).anonpay_description("a donation link", "donate"),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.displayLarge!
|
||||
.decorationColor!,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 12),
|
||||
color:
|
||||
Theme.of(context).primaryTextTheme!.displayLarge!.decorationColor!,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 12),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -176,10 +174,7 @@ class AnonPayInvoicePage extends BasePage {
|
|||
anonInvoicePageViewModel.generateDonationLink();
|
||||
}
|
||||
},
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.bodyLarge!
|
||||
.color!,
|
||||
color: Theme.of(context).accentTextTheme!.bodyLarge!.color!,
|
||||
textColor: Colors.white,
|
||||
isLoading: anonInvoicePageViewModel.state is IsExecutingState,
|
||||
),
|
||||
|
|
39
lib/utils/distribution_info.dart
Normal file
39
lib/utils/distribution_info.dart
Normal file
|
@ -0,0 +1,39 @@
|
|||
import 'dart:io';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
|
||||
enum DistributionType { googleplay, github, appstore, fdroid }
|
||||
|
||||
class DistributionInfo {
|
||||
DistributionInfo._();
|
||||
|
||||
static DistributionInfo get instance => DistributionInfo._();
|
||||
|
||||
Future<String> getDistributionPath() async {
|
||||
final isPlayStore = await isInstalledFromPlayStore();
|
||||
final distributionPath = _getDistributionPath(isPlayStore);
|
||||
|
||||
return distributionPath.name;
|
||||
}
|
||||
|
||||
DistributionType _getDistributionPath(bool isPlayStore) {
|
||||
if (isPlayStore) {
|
||||
return DistributionType.googleplay;
|
||||
} else if (Platform.isAndroid) {
|
||||
return DistributionType.github;
|
||||
} else if (Platform.isIOS) {
|
||||
return DistributionType.appstore;
|
||||
} else {
|
||||
return DistributionType.github;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> isInstalledFromPlayStore() async {
|
||||
try {
|
||||
final packageInfo = await PackageInfo.fromPlatform();
|
||||
return packageInfo.packageName == 'com.android.vending';
|
||||
} catch (e) {
|
||||
print('Error: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,5 @@
|
|||
import 'package:cake_wallet/core/auth_service.dart';
|
||||
import 'package:cake_wallet/core/wallet_loading_service.dart';
|
||||
import 'package:cw_core/balance.dart';
|
||||
import 'package:cw_core/transaction_history.dart';
|
||||
import 'package:cw_core/transaction_info.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
@ -26,7 +23,7 @@ abstract class WalletListViewModelBase with Store {
|
|||
this._authService,
|
||||
) : wallets = ObservableList<WalletListItem>() {
|
||||
_updateList();
|
||||
reaction((_) => _appStore.wallet, (_) => _updateList());
|
||||
reaction((_) => _appStore.wallet, (_) => updateList());
|
||||
}
|
||||
|
||||
@observable
|
||||
|
@ -41,7 +38,9 @@ abstract class WalletListViewModelBase with Store {
|
|||
|
||||
@action
|
||||
Future<void> loadWallet(WalletListItem walletItem) async {
|
||||
final wallet = await _walletLoadingService.load(walletItem.type, walletItem.name);
|
||||
final wallet =
|
||||
await _walletLoadingService.load(walletItem.type, walletItem.name);
|
||||
|
||||
_appStore.changeCurrentWallet(wallet);
|
||||
_updateList();
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import connectivity_plus_macos
|
|||
import cw_monero
|
||||
import device_info_plus
|
||||
import devicelocale
|
||||
import flutter_secure_storage_macos
|
||||
import in_app_review
|
||||
import package_info_plus
|
||||
import path_provider_foundation
|
||||
|
@ -25,7 +24,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
|||
CwMoneroPlugin.register(with: registry.registrar(forPlugin: "CwMoneroPlugin"))
|
||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||
DevicelocalePlugin.register(with: registry.registrar(forPlugin: "DevicelocalePlugin"))
|
||||
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
|
||||
InAppReviewPlugin.register(with: registry.registrar(forPlugin: "InAppReviewPlugin"))
|
||||
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
|
|
|
@ -28,7 +28,7 @@ PODS:
|
|||
- FlutterMacOS (1.0.0)
|
||||
- in_app_review (0.2.0):
|
||||
- FlutterMacOS
|
||||
- package_info_plus (0.0.1):
|
||||
- package_info (0.0.1):
|
||||
- FlutterMacOS
|
||||
- path_provider_foundation (0.0.1):
|
||||
- Flutter
|
||||
|
@ -56,7 +56,7 @@ DEPENDENCIES:
|
|||
- flutter_secure_storage_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos`)
|
||||
- FlutterMacOS (from `Flutter/ephemeral`)
|
||||
- in_app_review (from `Flutter/ephemeral/.symlinks/plugins/in_app_review/macos`)
|
||||
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
|
||||
- package_info (from `Flutter/ephemeral/.symlinks/plugins/package_info/macos`)
|
||||
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos`)
|
||||
- platform_device_id (from `Flutter/ephemeral/.symlinks/plugins/platform_device_id/macos`)
|
||||
- platform_device_id_macos (from `Flutter/ephemeral/.symlinks/plugins/platform_device_id_macos/macos`)
|
||||
|
@ -84,8 +84,8 @@ EXTERNAL SOURCES:
|
|||
:path: Flutter/ephemeral
|
||||
in_app_review:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/in_app_review/macos
|
||||
package_info_plus:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
|
||||
package_info:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/package_info/macos
|
||||
path_provider_foundation:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos
|
||||
platform_device_id:
|
||||
|
@ -109,8 +109,8 @@ SPEC CHECKSUMS:
|
|||
flutter_secure_storage_macos: d56e2d218c1130b262bef8b4a7d64f88d7f9c9ea
|
||||
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
||||
in_app_review: a850789fad746e89bce03d4aeee8078b45a53fd0
|
||||
package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce
|
||||
path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9
|
||||
package_info: 6eba2fd8d3371dda2d85c8db6fe97488f24b74b2
|
||||
path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8
|
||||
platform_device_id: 3e414428f45df149bbbfb623e2c0ca27c545b763
|
||||
platform_device_id_macos: f763bb55f088be804d61b96eb4710b8ab6598e94
|
||||
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
||||
|
@ -121,4 +121,4 @@ SPEC CHECKSUMS:
|
|||
|
||||
PODFILE CHECKSUM: 5107934592df7813b33d744aebc8ddc6b5a5445f
|
||||
|
||||
COCOAPODS: 1.11.2
|
||||
COCOAPODS: 1.12.1
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -5,19 +5,14 @@
|
|||
"please_make_selection": "Don Allah zaɓi ƙasa don ƙirƙira ko dawo da kwalinku.",
|
||||
"create_new": "Ƙirƙira Sabon Kwalinku",
|
||||
"restore_wallet": "Dawo da Kwalinku",
|
||||
|
||||
"monero_com": "Monero.com ta Cake Wallet",
|
||||
"monero_com_wallet_text": "Aikace-aikacen e-wallet ga Monero",
|
||||
|
||||
"haven_app": "Haven da Cake Wallet",
|
||||
"haven_app_wallet_text": "Aikace-aikacen e-wallet ga Haven",
|
||||
|
||||
"accounts": "Lissafi",
|
||||
"edit": "Gyara",
|
||||
"account": "Asusu",
|
||||
"add": "Ƙara",
|
||||
|
||||
|
||||
"address_book": "Littafin adireshi",
|
||||
"contact": "Tuntuɓar",
|
||||
"please_select": "Don Allah zaɓi:",
|
||||
|
@ -28,13 +23,9 @@
|
|||
"save": "Ajiye",
|
||||
"address_remove_contact": "Cire lamba",
|
||||
"address_remove_content": "Kuna tabbatar kuna so ku cire wannan Contact?",
|
||||
|
||||
|
||||
"authenticated": "Ingantacce",
|
||||
"authentication": "Tabbatarwa",
|
||||
"failed_authentication": "Binne wajen shiga. ${state_error}",
|
||||
|
||||
|
||||
"wallet_menu": "Menu",
|
||||
"Blocks_remaining": "${status} Katanga ya rage",
|
||||
"please_try_to_connect_to_another_node": "Don Allah yi ƙoƙarin haɗa da wani node",
|
||||
|
@ -62,8 +53,6 @@
|
|||
"address_book_menu": "Littafin adireshi",
|
||||
"reconnection": "Sake haɗawa",
|
||||
"reconnect_alert_text": "Shin kun tabbata kuna son sake haɗawa?",
|
||||
|
||||
|
||||
"exchange": "Exchange",
|
||||
"clear": "Share",
|
||||
"refund_address": "Adireshin maidowa",
|
||||
|
@ -80,7 +69,6 @@
|
|||
"change_currency": "Canja Kuɗi",
|
||||
"overwrite_amount": "Rubuta adadin",
|
||||
"qr_payment_amount": "Wannan QR code yana da adadin kuɗi. Kuna so ku overwrite wannan adadi?",
|
||||
|
||||
"copy_id": "Kwafi ID",
|
||||
"exchange_result_write_down_trade_id": "Da fatan za a kwafa ko rubuta ID ɗin ciniki don ci gaba.",
|
||||
"trade_id": "ID na kasuwanci:",
|
||||
|
@ -106,20 +94,13 @@
|
|||
"time": "${minutes}m ${seconds}s",
|
||||
"send_xmr": "Aika XMR",
|
||||
"exchange_new_template": "Sabon template",
|
||||
|
||||
"faq": "FAQ",
|
||||
|
||||
|
||||
"enter_your_pin": "Shigar da PIN",
|
||||
"loading_your_wallet": "Ana loda walat ɗin ku",
|
||||
|
||||
|
||||
"new_wallet": "Sabuwar Wallet",
|
||||
"wallet_name": "Sunan walat",
|
||||
"continue_text": "Ci gaba",
|
||||
"choose_wallet_currency": "Da fatan za a zaɓi kuɗin walat:",
|
||||
|
||||
|
||||
"node_new": "Sabon Node",
|
||||
"node_address": "Address Node",
|
||||
"node_port": "Node tashar jiragen ruwa",
|
||||
|
@ -140,24 +121,18 @@
|
|||
"node_connection_successful": "Haɗin ya yi nasara",
|
||||
"node_connection_failed": "Haɗin ya gaza",
|
||||
"new_node_testing": "Sabbin gwajin kumburi",
|
||||
|
||||
|
||||
"use": "Canja zuwa",
|
||||
"digit_pin": "-lambar PIN",
|
||||
|
||||
|
||||
"share_address": "Raba adireshin",
|
||||
"receive_amount": "Adadi",
|
||||
"subaddresses": "Subaddresses",
|
||||
"addresses": "Addresses",
|
||||
"scan_qr_code": "Duba lambar QR don samun adireshin",
|
||||
"scan_qr_code": "Gani QR kodin",
|
||||
"qr_fullscreen": "Matsa don buɗe lambar QR na cikakken allo",
|
||||
"rename": "Sake suna",
|
||||
"choose_account": "Zaɓi asusu",
|
||||
"create_new_account": "Ƙirƙiri sabon asusu",
|
||||
"accounts_subaddresses": "Accounts da subaddresses",
|
||||
|
||||
|
||||
"restore_restore_wallet": "Maida Wallet",
|
||||
"restore_title_from_seed_keys": "Dawo da iri/maɓallai",
|
||||
"restore_description_from_seed_keys": "Maido da walat ɗin ku daga iri/maɓallan da kuka adana don amintaccen wuri",
|
||||
|
@ -181,14 +156,10 @@
|
|||
"restore_bitcoin_description_from_keys": "Dawo da kwalinku daga WIF string dake generate daga maɓallan sirri",
|
||||
"restore_bitcoin_title_from_keys": "Dawo daga WIF",
|
||||
"restore_from_date_or_blockheight": "Don Allah shigar da wata kwanan a kafin ku ƙirƙirar wannan kwalinku. Ko idan kun san blockheight, don Allah shigar da shi",
|
||||
|
||||
|
||||
"seed_reminder": "Don Allah rubuta wadannan in case ka manta ko ka sake kwallon wayarka",
|
||||
"seed_title": "iri",
|
||||
"seed_share": "Raba iri",
|
||||
"copy": "Kwafi",
|
||||
|
||||
|
||||
"seed_language_choose": "Don Allah zaɓi harshen seed:",
|
||||
"seed_choose": "Zaɓi harshen seed",
|
||||
"seed_language_next": "Na gaba",
|
||||
|
@ -202,8 +173,6 @@
|
|||
"seed_language_spanish": "Spanish",
|
||||
"seed_language_french": "Faransanci",
|
||||
"seed_language_italian": "Italiyanci",
|
||||
|
||||
|
||||
"send_title": "Aika",
|
||||
"send_your_wallet": "Walat ɗin ku",
|
||||
"send_address": "${cryptoCurrency} address",
|
||||
|
@ -219,11 +188,9 @@
|
|||
"send_amount": "Adadi:",
|
||||
"send_fee": "Kudin:",
|
||||
"send_name": "Sunan",
|
||||
"send_got_it": "Gama",
|
||||
"got_it": "Gama",
|
||||
"send_sending": "Aika...",
|
||||
"send_success": "${crypto} kwalinku ya aika da nasara",
|
||||
|
||||
|
||||
"settings_title": "Saitunan",
|
||||
"settings_nodes": "Nodes",
|
||||
"settings_current_node": "Node yanzu",
|
||||
|
@ -247,13 +214,9 @@
|
|||
"settings_support": "Taimako",
|
||||
"settings_terms_and_conditions": "Sharuɗɗa da Ka'idoji",
|
||||
"pin_is_incorrect": "PIN ba daidai ba ne",
|
||||
|
||||
|
||||
"setup_pin": "Saita PIN",
|
||||
"enter_your_pin_again": "Shigar da PIN ɗinku na sake",
|
||||
"setup_successful": "An saita PIN ɗinku da nasara!",
|
||||
|
||||
|
||||
"wallet_keys": "Iri/maɓalli na walat",
|
||||
"wallet_seed": "kalmar sirri na walat",
|
||||
"private_key": "Keɓaɓɓen maɓalli",
|
||||
|
@ -263,17 +226,11 @@
|
|||
"spend_key_private": "makullin biya (maɓallin kalmar sirri)",
|
||||
"spend_key_public": "makullin biya (maɓallin jama'a)",
|
||||
"copied_key_to_clipboard": "An kwafa ${key} a cikin kwafin",
|
||||
|
||||
|
||||
"new_subaddress_title": "Adireshin sabuwa",
|
||||
"new_subaddress_label_name": "Lakabin suna",
|
||||
"new_subaddress_create": "Ƙirƙiri",
|
||||
|
||||
"address_label": "Labari adireshi",
|
||||
|
||||
"subaddress_title": "Jagorar subaddress",
|
||||
|
||||
|
||||
"trade_details_title": "Bayanai game da kasuwancin",
|
||||
"trade_details_id": "ID",
|
||||
"trade_details_state": "Matsayi",
|
||||
|
@ -282,11 +239,7 @@
|
|||
"trade_details_created_at": "An ƙirƙira a",
|
||||
"trade_details_pair": "miji da matarsa",
|
||||
"trade_details_copied": "${title} an kwafa zuwa cikin kwafin",
|
||||
|
||||
|
||||
"trade_history_title": "Tarihin kasuwancin",
|
||||
|
||||
|
||||
"transaction_details_title": "Bayanai game da aikace-aikacen",
|
||||
"transaction_details_transaction_id": "ID na kasuwanci",
|
||||
"transaction_details_date": "Kwanan wata",
|
||||
|
@ -295,28 +248,22 @@
|
|||
"transaction_details_fee": "Kudin",
|
||||
"transaction_details_copied": "${title} an kwafa zuwa cikin kwafin",
|
||||
"transaction_details_recipient_address": "Adireshin masu amfani",
|
||||
|
||||
|
||||
"wallet_list_title": "Monero walat",
|
||||
"wallet_list_create_new_wallet": "Ƙirƙiri Sabon Wallet",
|
||||
"wallet_list_edit_wallet" : "Gyara walat",
|
||||
"wallet_list_wallet_name" : "Sunan walat",
|
||||
"wallet_list_restore_wallet": "Maida Wallet",
|
||||
"wallet_list_load_wallet": "Ana loda wallet na Monero",
|
||||
"wallet_list_loading_wallet": "Ana loda ${wallet_name} walat",
|
||||
"wallet_list_failed_to_load": "An kasa loda ${wallet_name} walat. ${error}",
|
||||
"wallet_list_removing_wallet": "Cirewa ${wallet_name} walat",
|
||||
"wallet_list_failed_to_remove": "Ba a iya cirewa ${wallet_name} walat. ${error}",
|
||||
|
||||
|
||||
"widgets_address": "Adireshin",
|
||||
"widgets_restore_from_blockheight": "Sake dawo da daga blockheight",
|
||||
"widgets_restore_from_date": "Sake dawo da daga kwanan wata",
|
||||
"widgets_or": "ko",
|
||||
"widgets_seed": "iri",
|
||||
|
||||
|
||||
"router_no_route": "Babu wata hanya da aka bayyana don ${name}",
|
||||
|
||||
|
||||
"error_text_account_name": "Sunan ajiya zai iya ɗauka ne kawai da haruffa, lambobi\nkuma ya zama tsakanin 1 zuwa 15 haruffa",
|
||||
"error_text_contact_name": "Sunan kira ba zai iya ɗaukar ` , ' \" haruffa\nkuma ya zama tsakanin 1 zuwa 32 haruffa",
|
||||
"error_text_address": "Adireshin hujja ya kamata ya dace da irin\nna cryptocurrency",
|
||||
|
@ -334,21 +281,15 @@
|
|||
"error_text_maximum_limit": "Kasuwanci ga ${provider} ba a yi ba. Adadin shine fiye da ƙimanin: ${max} ${currency}",
|
||||
"error_text_limits_loading_failed": "Kasuwanci ga ${provider} ba a yi ba. An kasa saukewa masanan",
|
||||
"error_text_template": "Sunan na tushe da adireshin ba zai iya ɗaukar ` , ' \" haruffa\nkuma ya zama tsakanin 1 zuwa 106 haruffa",
|
||||
|
||||
|
||||
"auth_store_ban_timeout": "ban_timeout",
|
||||
"auth_store_banned_for": "An haramta don",
|
||||
"auth_store_banned_minutes": "da minti",
|
||||
"auth_store_incorrect_password": "PIN na gaskiya",
|
||||
"wallet_store_monero_wallet": "Monero walat",
|
||||
"wallet_restoration_store_incorrect_seed_length": "kalmar sirrin iri ba daidai ba",
|
||||
|
||||
|
||||
"full_balance": "DUKAN KUDI",
|
||||
"available_balance": "KUDI",
|
||||
"hidden_balance": "BOYE KUDI",
|
||||
|
||||
|
||||
"sync_status_syncronizing": "KWAFI",
|
||||
"sync_status_syncronized": "KYAU",
|
||||
"sync_status_not_connected": "BABU INTERNET",
|
||||
|
@ -357,21 +298,15 @@
|
|||
"sync_status_connecting": "HADA",
|
||||
"sync_status_connected": "HANNU",
|
||||
"sync_status_attempting_sync": "KWAFI",
|
||||
|
||||
|
||||
"transaction_priority_slow": "SAURI DA SAURI",
|
||||
"transaction_priority_regular": "SAURI NORMAL",
|
||||
"transaction_priority_medium": "SAURI DA DADI",
|
||||
"transaction_priority_fast": "sauri",
|
||||
"transaction_priority_fastest": "mafi sauri",
|
||||
|
||||
|
||||
"trade_for_not_created": "Ba a ƙirƙira ciniki don ${title} ba.",
|
||||
"trade_not_created": "Ba a ƙirƙira ciniki ba",
|
||||
"trade_id_not_found": "Ba a samo cinikin ${tradeId} na ${title} ba.",
|
||||
"trade_not_found": "Ba a sami ciniki ba.",
|
||||
|
||||
|
||||
"trade_state_pending": "Jira",
|
||||
"trade_state_confirming": "Tabbatar",
|
||||
"trade_state_trading": "Ciniki",
|
||||
|
@ -386,59 +321,48 @@
|
|||
"trade_state_timeout": "lokacin da ya ƙare",
|
||||
"trade_state_created": "an halicci",
|
||||
"trade_state_finished": "an kammala",
|
||||
|
||||
"invalid_password" : "Mot de passe incorrect",
|
||||
"unlock" : "Ouvrir",
|
||||
"enter_wallet_password" : "Entrez le mot de passe du portefeuille",
|
||||
"repeate_wallet_password" : "Répétez le mot de passe du portefeuille",
|
||||
"wallet_password_is_empty" : "Le mot de passe du portefeuille est vide. Le mot de passe du portefeuille ne doit pas être vide",
|
||||
"repeated_password_is_incorrect" : "Le mot de passe répété est incorrect. Veuillez répéter le mot de passe du portefeuille.",
|
||||
"change_language": "canja harshen",
|
||||
"change_language_to": "canja harshen zuwa ${language}?",
|
||||
|
||||
"paste": "Manna",
|
||||
"restore_from_seed_placeholder": "Da fatan za a shigar da ko manna maɓallin ku a nan",
|
||||
"add_new_word": "Ƙara kalma sabuwa",
|
||||
"incorrect_seed": "rubutun da aka shigar ba shi da inganci.",
|
||||
|
||||
"biometric_auth_reason": "Duba hoton yatsa don tantancewa",
|
||||
"version": "Sigar ${currentVersion}",
|
||||
|
||||
"openalias_alert_title": "An gano adireshin",
|
||||
"openalias_alert_content": "Zaka aika kuɗi zuwa \n${recipient_name}",
|
||||
|
||||
"card_address": "Adireshin:",
|
||||
"buy": "Sayi",
|
||||
"sell": "sayar",
|
||||
|
||||
"placeholder_transactions": "Za a nuna ma'amalolin ku anan",
|
||||
"placeholder_contacts": "Za a nuna lambobin sadarwar ku anan",
|
||||
|
||||
"template": "Samfura",
|
||||
"confirm_delete_template": "Wannan aikin zai share wannan samfuri. Kuna so ku ci gaba?",
|
||||
"confirm_delete_wallet": "Wannan aikin zai share wannan walat. Kuna so ku ci gaba?",
|
||||
|
||||
"picker_description": "Don zaɓar ChangeNOW ko MorphToken, da farko canja kasuwancin pair din ku",
|
||||
|
||||
"change_wallet_alert_title": "Canja walat yanzu",
|
||||
"change_wallet_alert_content": "Kana so ka canja walat yanzu zuwa ${wallet_name}?",
|
||||
|
||||
"creating_new_wallet": "Haliccin walat sabuwa",
|
||||
"creating_new_wallet_error": "Kuskure: ${description}",
|
||||
|
||||
"seed_alert_title": "Hankali",
|
||||
"seed_alert_content": "Irin ita ce kawai hanya don dawo da walat ɗin ku. Kun rubuta shi?",
|
||||
"seed_alert_back": "juya baya",
|
||||
"seed_alert_yes": "E, Na yi",
|
||||
|
||||
"exchange_sync_alert_content": "Da fatan za a jira har sai an daidaita walat ɗin ku",
|
||||
|
||||
"pre_seed_title": "MUHIMMANCI",
|
||||
"pre_seed_description": "A kan shafin nan za ku ga wata ƙungiya na ${words} kalmomi. Wannan shine tsarin daban-daban ku kuma na sirri kuma shine hanya ɗaya kadai don mai da purse dinku a cikin yanayin rasa ko rashin aiki. Yana da damar da kuke a cikin tabbatar da kuyi rubuta shi kuma kuyi ajiye shi a wuri na aminci wanda ya wuce wurin app na Cake Wallet.",
|
||||
"pre_seed_button_text": "Ina fahimta. Nuna mini seed din nawa",
|
||||
|
||||
"xmr_to_error": "XMR.TO kuskure",
|
||||
"xmr_to_error_description": "Adadin ba shi da inganci. Maksimum ɗaura 8 digiri bayan decimal point",
|
||||
|
||||
"provider_error": "${provider} kuskure",
|
||||
|
||||
"use_ssl": "Yi amfani da SSL",
|
||||
"trusted": "Amintacce",
|
||||
|
||||
"color_theme": "Jigon launi",
|
||||
"light_theme": "Haske",
|
||||
"bright_theme": "Mai haske",
|
||||
|
@ -451,11 +375,9 @@
|
|||
"transaction_key": "Aikace-aikacen key",
|
||||
"confirmations": "Tabbatar",
|
||||
"recipient_address": "Adireshin mai karɓa",
|
||||
|
||||
"extra_id": "Karin ID:",
|
||||
"destination_tag": "Tambarin makoma:",
|
||||
"memo": "Memo:",
|
||||
|
||||
"backup": "Ajiyayyen",
|
||||
"change_password": "Canza kalmar shiga",
|
||||
"backup_password": "Ajiyayyen kalmar sirri",
|
||||
|
@ -463,55 +385,40 @@
|
|||
"export_backup": "Ajiyayyen fitarwa",
|
||||
"save_backup_password": "Da fatan za a tabbatar cewa kun adana kalmar sirrin ajiyar ku. Ba za ku iya shigo da fayilolin ajiyar ku ba tare da shi ba.",
|
||||
"backup_file": "Ajiyayyen fayil",
|
||||
|
||||
"edit_backup_password": "Shirya Kalmar wucewa ta Ajiyayyen",
|
||||
"save_backup_password_alert": "Ajiye kalmar sirri ta ajiya",
|
||||
"change_backup_password_alert": "Fayilolin madadin ku na baya ba za su kasance don shigo da sabon kalmar sirri ta madadin ba. Sabuwar kalmar sirri ta ajiya za a yi amfani da ita kawai don sabbin fayilolin madadin. Shin kun tabbata cewa kuna son canza kalmar wucewa?",
|
||||
|
||||
"enter_backup_password": "Shigar da kalmar wucewa ta madadin nan",
|
||||
"select_backup_file": "Zaɓi fayil ɗin madadin",
|
||||
"import": "Shigo da",
|
||||
"please_select_backup_file": "Da fatan za a zaɓi fayil ɗin madadin kuma shigar da kalmar wucewa ta madadin.",
|
||||
|
||||
"fixed_rate": "Kafaffen ƙima",
|
||||
"fixed_rate_alert": "Za ku iya shigar da adadin karɓa lokacin da aka duba ƙayyadadden zaɓin ƙimar kuɗi. Kuna so ku canza zuwa ƙayyadadden yanayin ƙimar kuɗi?",
|
||||
|
||||
"xlm_extra_info": "Don Allah kar a manta da saka Memo ID yayin aika ma'amalar XLM don musayar",
|
||||
"xrp_extra_info": "Don Allah kar a manta da saka alamar Ƙaddamarwa yayin aika ma'amalar XRP don musayar",
|
||||
|
||||
"exchange_incorrect_current_wallet_for_xmr": "Idan kana son musanya XMR daga ma'aunin Cake Wallet Monero, da fatan za a fara canza wallet ɗin Monero ɗin ku.",
|
||||
"confirmed": "An tabbatar",
|
||||
"unconfirmed": "Ba a tabbatar ba",
|
||||
"displayable": "Ana iya nunawa",
|
||||
|
||||
"submit_request": "gabatar da bukata",
|
||||
|
||||
"buy_alert_content": "A halin yanzu muna tallafawa kawai siyan Bitcoin da Litecoin. Don siyan Bitcoin ko Litecoin, da fatan za a ƙirƙira ko canza zuwa walat ɗin ku na Bitcoin ko Litecoin.",
|
||||
"sell_alert_content": "A halin yanzu muna tallafawa siyar da Bitcoin da Litecoin kawai. Da fatan za a ƙirƙira ko canza zuwa walat ɗin ku na Bitcoin ko Litecoin.",
|
||||
|
||||
"outdated_electrum_wallet_description": "Sabbin walat ɗin Bitcoin da aka kirkira a cikin Cake yanzu suna da nau'in kalma 24. Ya zama dole ka ƙirƙiri sabon walat ɗin Bitcoin kuma canza duk kuɗin ku zuwa sabon walat ɗin kalmomi 24, kuma ku daina amfani da walat tare da iri mai kalma 12. Da fatan za a yi haka nan take don samun kuɗin ku.",
|
||||
"understand": "na gane",
|
||||
|
||||
"apk_update": "apk sabunta",
|
||||
|
||||
"buy_bitcoin": "Sayi Bitcoin",
|
||||
"buy_with": "Saya da",
|
||||
"moonpay_alert_text": "Darajar adadin dole ne ya zama fiye ko daidai da ${minAmount} ${fiatCurrency}",
|
||||
|
||||
"outdated_electrum_wallet_receive_warning": "Idan wannan walat ɗin yana da nau'in kalma 12 kuma an ƙirƙira shi a cikin Cake, KAR KA saka Bitcoin cikin wannan jakar. Duk wani BTC da aka canjawa wuri zuwa wannan walat na iya ɓacewa. Ƙirƙiri sabon walat mai kalmomi 24 (matsa menu a saman dama, zaɓi Wallets, zaɓi Ƙirƙiri Sabon Wallet, sannan zaɓi Bitcoin) kuma NAN nan take matsar da BTC ɗin ku a can. Sabbin (kalmomi 24) BTC wallets daga Cake suna da tsaro",
|
||||
"do_not_show_me": "Kar ka sake nuna min wannan",
|
||||
|
||||
"unspent_coins_title": "Tsabar da ba a kashe ba",
|
||||
"unspent_coins_details_title": "Bayanan tsabar kudi da ba a kashe ba",
|
||||
"freeze": "Daskare",
|
||||
"frozen": "Daskararre",
|
||||
"coin_control": "Sarrafa tsabar kuɗi (na zaɓi)",
|
||||
|
||||
"address_detected": "An gano adireshin",
|
||||
"address_from_domain": "Wannan adireshin ya fito daga ${domain} akan Unstoppable Domain",
|
||||
|
||||
"add_receiver": "Ƙara wani mai karɓa (na zaɓi)",
|
||||
|
||||
"manage_yats": "Sarrafa Yats",
|
||||
"yat_alert_title": "Aika da karɓar crypto cikin sauƙi tare da Yat",
|
||||
"yat_alert_content": "Masu amfani da Wallet ɗin Cake yanzu za su iya aikawa da karɓar duk kuɗin da suka fi so tare da sunan mai amfani na tushen emoji iri ɗaya.",
|
||||
|
@ -681,11 +588,10 @@
|
|||
"contact_list_contacts": "Lambobin sadarwa",
|
||||
"contact_list_wallets": "Wallets dina",
|
||||
"bitcoin_payments_require_1_confirmation": "Akwatin Bitcoin na buɗe 1 sambumbu, da yake za ta samu mintuna 20 ko yawa. Ina kira ga sabuwar lafiya! Zaka sanarwa ta email lokacin da aka samu akwatin samun lambar waya.",
|
||||
"send_to_this_address" : "Aiko ${currency} ${tag} zuwa adireshin wannan",
|
||||
"arrive_in_this_address" : "${currency} ${tag} zai je wurin wannan adireshi",
|
||||
"send_to_this_address": "Aiko ${currency} ${tag} zuwa adireshin wannan",
|
||||
"arrive_in_this_address": "${currency} ${tag} zai je wurin wannan adireshi",
|
||||
"do_not_send": "Kada ka aika",
|
||||
"error_dialog_content": "Ai, yanzu muka ga alamar kuskure. \n\nDa fatan, aika rahoton kuskuren da muka kira zuwa gasar tsarinmu don gaskiyar shirya.",
|
||||
"scan_qr_code": "Gani QR kodin",
|
||||
"cold_or_recover_wallet": "Samun kashi na baya ko samun kashi na kasa",
|
||||
"please_wait": "Don Allah a rufe",
|
||||
"sweeping_wallet": "Kashi na kasa",
|
||||
|
@ -705,10 +611,17 @@
|
|||
"frozen_balance": "Falin kuma maɓallin",
|
||||
"settings": "Saiti",
|
||||
"sell_monero_com_alert_content": "Selling Monero bai sami ƙarshen mai bukatar samun ba",
|
||||
"error_text_input_below_minimum_limit" : "Kudin ba a kamai",
|
||||
"error_text_input_above_maximum_limit" : "Kudin da ya kamata",
|
||||
"show_market_place" :"Nuna dan kasuwa",
|
||||
"error_text_input_below_minimum_limit": "Kudin ba a kamai",
|
||||
"error_text_input_above_maximum_limit": "Kudin da ya kamata",
|
||||
"show_market_place": "Nuna dan kasuwa",
|
||||
"prevent_screenshots": "Fada lambobi da jarrabobi na kayan lambobi",
|
||||
"disable_buy": "Kashe alama",
|
||||
"disable_sell": "Kashe karbuwa"
|
||||
}
|
||||
"disable_sell": "Kashe karbuwa",
|
||||
"available_balance_description": "Ma'auni mai samuwa” ko ”,Tabbataccen Ma'auni”, kudade ne da za a iya kashewa nan da nan. Idan kudade sun bayyana a cikin ƙananan ma'auni amma ba babban ma'auni ba, to dole ne ku jira 'yan mintoci kaɗan don kudaden shiga don samun ƙarin tabbaci na hanyar sadarwa. Bayan sun sami ƙarin tabbaci, za a kashe su.",
|
||||
"syncing_wallet_alert_title": "Walat ɗin ku yana aiki tare",
|
||||
"syncing_wallet_alert_content": "Ma'aunin ku da lissafin ma'amala bazai cika ba har sai an ce \"SYNCHRONIZED\" a saman. Danna/matsa don ƙarin koyo.",
|
||||
"generate_name": "Ƙirƙirar Suna",
|
||||
"balance_page": "Ma'auni Page",
|
||||
"share": "Raba",
|
||||
"slidable": "Mai iya zamewa"
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue