Merge branch 'main' into CW-432-Add-Bitcoin-Cash-BCH

This commit is contained in:
Serhii 2023-08-25 15:27:30 +03:00
commit f7470addfe
322 changed files with 6381 additions and 4217 deletions

View file

@ -18,7 +18,7 @@ jobs:
- name: Flutter action - name: Flutter action
uses: subosito/flutter-action@v1 uses: subosito/flutter-action@v1
with: with:
flutter-version: '3.3.x' flutter-version: '3.10.x'
channel: stable channel: stable
- name: Install package dependencies - name: Install package dependencies

View file

@ -28,7 +28,7 @@ jobs:
- name: Flutter action - name: Flutter action
uses: subosito/flutter-action@v1 uses: subosito/flutter-action@v1
with: with:
flutter-version: '3.7.x' flutter-version: '3.10.x'
channel: stable channel: stable
- name: Install package dependencies - name: Install package dependencies
@ -55,7 +55,7 @@ jobs:
/opt/android/cake_wallet/cw_monero/android/.cxx /opt/android/cake_wallet/cw_monero/android/.cxx
/opt/android/cake_wallet/cw_monero/ios/External /opt/android/cake_wallet/cw_monero/ios/External
/opt/android/cake_wallet/cw_shared_external/ios/External /opt/android/cake_wallet/cw_shared_external/ios/External
key: ${{ hashFiles('**/build_monero.sh', '**/build_haven.sh') }} key: ${{ hashFiles('**/build_monero.sh', '**/build_haven.sh', '**/monero_api.cpp') }}
- if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }} - if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
name: Generate Externals name: Generate Externals

2
.gitignore vendored
View file

@ -144,4 +144,4 @@ assets/images/app_logo.png
macos/Runner/Info.plist macos/Runner/Info.plist
macos/Runner/DebugProfile.entitlements macos/Runner/DebugProfile.entitlements
macos/Runner/Release.entitlements macos/Runner/Release.entitlements

View file

@ -27,6 +27,6 @@ subprojects {
project.evaluationDependsOn(':app') project.evaluationDependsOn(':app')
} }
task clean(type: Delete) { tasks.register("clean", Delete) {
delete rootProject.buildDir delete rootProject.buildDir
} }

View file

@ -1,8 +1,2 @@
Monero background syncing! See https://guides.cakewallet.com/docs/monero/#background-syncing Bug fixes
Cake 2FA access control settings! See https://guides.cakewallet.com/docs/advanced-features/authentication/#cake-2fa-presets-and-access-control-settings Fiat Onramp improvements
Support Monero node proxy
UI improvements when sending to Address Book entry
Allow renaming Monero account names
Send templates now support multiple recipients (try using to make Monero change)
Onramper improvements
Scan node QR codes (for Umbrel)

View file

@ -1,9 +1,2 @@
Ethereum! Store ETH and ERC-20 tokens Bug fixes
Monero background syncing! See https://guides.cakewallet.com/docs/monero/#background-syncing Fiat Onramp improvements
Cake 2FA access control settings! See https://guides.cakewallet.com/docs/advanced-features/authentication/#cake-2fa-presets-and-access-control-settings
Support Monero node proxy
UI improvements when sending to Address Book entry
Allow renaming Monero/Haven account names
Send templates now support multiple recipients (try using to make Monero change)
Onramper improvements
Scan node QR codes (for Umbrel)

View file

@ -1,4 +1,4 @@
class BitcoinTransactionNoInputsException implements Exception { class BitcoinTransactionNoInputsException implements Exception {
@override @override
String toString() => 'Not enough inputs available'; String toString() => 'Not enough inputs available. Please select more under Coin Control';
} }

View file

@ -755,5 +755,5 @@ packages:
source: hosted source: hosted
version: "3.1.1" version: "3.1.1"
sdks: sdks:
dart: ">=2.19.0 <4.0.0" dart: ">=2.19.0 <3.0.0"
flutter: ">=3.0.0" flutter: ">=3.0.0"

View file

@ -13,16 +13,16 @@ dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
path_provider: ^2.0.11 path_provider: ^2.0.11
http: ^0.13.4 http: ^1.1.0
mobx: ^2.0.7+4 mobx: ^2.0.7+4
flutter_mobx: ^2.0.6+1 flutter_mobx: ^2.0.6+1
intl: ^0.17.0 intl: ^0.18.0
cw_core: cw_core:
path: ../cw_core path: ../cw_core
bitcoin_flutter: bitcoin_flutter:
git: git:
url: https://github.com/cake-tech/bitcoin_flutter.git url: https://github.com/cake-tech/bitcoin_flutter.git
ref: cake-update-v2 ref: cake-update-v3
bitbox: bitbox:
git: git:
url: https://github.com/Serhii-Borodenko/cw_bitbox.git url: https://github.com/Serhii-Borodenko/cw_bitbox.git

View file

@ -2,24 +2,31 @@ import 'package:cw_core/balance.dart';
import 'package:cw_core/monero_amount_format.dart'; import 'package:cw_core/monero_amount_format.dart';
class MoneroBalance extends Balance { class MoneroBalance extends Balance {
MoneroBalance({required this.fullBalance, required this.unlockedBalance}) MoneroBalance({required this.fullBalance, required this.unlockedBalance, this.frozenBalance = 0})
: formattedFullBalance = moneroAmountToString(amount: fullBalance), : formattedFullBalance = moneroAmountToString(amount: fullBalance),
formattedUnlockedBalance = formattedUnlockedBalance = moneroAmountToString(amount: unlockedBalance),
moneroAmountToString(amount: unlockedBalance), frozenFormatted = moneroAmountToString(amount: frozenBalance),
super(unlockedBalance, fullBalance); super(unlockedBalance, fullBalance);
MoneroBalance.fromString( MoneroBalance.fromString(
{required this.formattedFullBalance, {required this.formattedFullBalance,
required this.formattedUnlockedBalance}) required this.formattedUnlockedBalance,
this.frozenFormatted = '0.0'})
: fullBalance = moneroParseAmount(amount: formattedFullBalance), : fullBalance = moneroParseAmount(amount: formattedFullBalance),
unlockedBalance = moneroParseAmount(amount: formattedUnlockedBalance), unlockedBalance = moneroParseAmount(amount: formattedUnlockedBalance),
frozenBalance = moneroParseAmount(amount: frozenFormatted),
super(moneroParseAmount(amount: formattedUnlockedBalance), super(moneroParseAmount(amount: formattedUnlockedBalance),
moneroParseAmount(amount: formattedFullBalance)); moneroParseAmount(amount: formattedFullBalance));
final int fullBalance; final int fullBalance;
final int unlockedBalance; final int unlockedBalance;
final int frozenBalance;
final String formattedFullBalance; final String formattedFullBalance;
final String formattedUnlockedBalance; final String formattedUnlockedBalance;
final String frozenFormatted;
@override
String get formattedFrozenBalance => frozenFormatted == '0.0' ? '' : frozenFormatted;
@override @override
String get formattedAvailableBalance => formattedUnlockedBalance; String get formattedAvailableBalance => formattedUnlockedBalance;

View file

@ -13,7 +13,9 @@ class UnspentCoinsInfo extends HiveObject {
required this.noteRaw, required this.noteRaw,
required this.address, required this.address,
required this.vout, required this.vout,
required this.value}); required this.value,
this.keyImage = null
});
static const typeId = UNSPENT_COINS_INFO_TYPE_ID; static const typeId = UNSPENT_COINS_INFO_TYPE_ID;
static const boxName = 'Unspent'; static const boxName = 'Unspent';
@ -43,6 +45,9 @@ class UnspentCoinsInfo extends HiveObject {
@HiveField(7, defaultValue: 0) @HiveField(7, defaultValue: 0)
int vout; int vout;
@HiveField(8, defaultValue: null)
String? keyImage;
String get note => noteRaw ?? ''; String get note => noteRaw ?? '';
set note(String value) => noteRaw = value; set note(String value) => noteRaw = value;

View file

@ -42,7 +42,9 @@ abstract class WalletBase<
set syncStatus(SyncStatus status); set syncStatus(SyncStatus status);
String get seed; String? get seed;
String? get privateKey => null;
Object get keys; Object get keys;

View file

@ -665,5 +665,5 @@ packages:
source: hosted source: hosted
version: "3.1.1" version: "3.1.1"
sdks: sdks:
dart: ">=2.19.0 <4.0.0" dart: ">=2.19.0 <3.0.0"
flutter: ">=3.0.0" flutter: ">=3.0.0"

View file

@ -12,12 +12,12 @@ environment:
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
http: ^0.13.4 http: ^1.1.0
file: ^6.1.4 file: ^6.1.4
path_provider: ^2.0.11 path_provider: ^2.0.11
mobx: ^2.0.7+4 mobx: ^2.0.7+4
flutter_mobx: ^2.0.6+1 flutter_mobx: ^2.0.6+1
intl: ^0.17.0 intl: ^0.18.0
encrypt: ^5.0.1 encrypt: ^5.0.1
dev_dependencies: dev_dependencies:

View file

@ -9,7 +9,7 @@ import 'package:cw_ethereum/pending_ethereum_transaction.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:web3dart/web3dart.dart'; import 'package:web3dart/web3dart.dart';
import 'package:web3dart/contracts/erc20.dart'; import 'package:erc20/erc20.dart';
import 'package:cw_core/node.dart'; import 'package:cw_core/node.dart';
import 'package:cw_ethereum/ethereum_transaction_priority.dart'; import 'package:cw_ethereum/ethereum_transaction_priority.dart';
import 'package:cw_ethereum/.secrets.g.dart' as secrets; import 'package:cw_ethereum/.secrets.g.dart' as secrets;
@ -72,7 +72,7 @@ class EthereumClient {
to: EthereumAddress.fromHex(toAddress), to: EthereumAddress.fromHex(toAddress),
maxGas: gas, maxGas: gas,
gasPrice: price, gasPrice: price,
maxPriorityFeePerGas: EtherAmount.fromUnitAndValue(EtherUnit.gwei, priority.tip), maxPriorityFeePerGas: EtherAmount.fromInt(EtherUnit.gwei, priority.tip),
value: _isEthereum ? EtherAmount.inWei(BigInt.parse(amount)) : EtherAmount.zero(), value: _isEthereum ? EtherAmount.inWei(BigInt.parse(amount)) : EtherAmount.zero(),
); );
@ -83,7 +83,7 @@ class EthereumClient {
if (_isEthereum) { if (_isEthereum) {
_sendTransaction = () async => await sendTransaction(signedTransaction); _sendTransaction = () async => await sendTransaction(signedTransaction);
} else { } else {
final erc20 = Erc20( final erc20 = ERC20(
client: _client!, client: _client!,
address: EthereumAddress.fromHex(contractAddress!), address: EthereumAddress.fromHex(contractAddress!),
); );
@ -153,7 +153,7 @@ I/flutter ( 4474): Gas Used: 53000
Future<ERC20Balance> fetchERC20Balances( Future<ERC20Balance> fetchERC20Balances(
EthereumAddress userAddress, String contractAddress) async { EthereumAddress userAddress, String contractAddress) async {
final erc20 = Erc20(address: EthereumAddress.fromHex(contractAddress), client: _client!); final erc20 = ERC20(address: EthereumAddress.fromHex(contractAddress), client: _client!);
final balance = await erc20.balanceOf(userAddress); final balance = await erc20.balanceOf(userAddress);
int exponent = (await erc20.decimals()).toInt(); int exponent = (await erc20.decimals()).toInt();
@ -163,7 +163,7 @@ I/flutter ( 4474): Gas Used: 53000
Future<Erc20Token?> getErc20Token(String contractAddress) async { Future<Erc20Token?> getErc20Token(String contractAddress) async {
try { try {
final erc20 = Erc20(address: EthereumAddress.fromHex(contractAddress), client: _client!); final erc20 = ERC20(address: EthereumAddress.fromHex(contractAddress), client: _client!);
final name = await erc20.name(); final name = await erc20.name();
final symbol = await erc20.symbol(); final symbol = await erc20.symbol();
final decimal = await erc20.decimals(); final decimal = await erc20.decimals();

View file

@ -44,12 +44,14 @@ abstract class EthereumWalletBase
with Store { with Store {
EthereumWalletBase({ EthereumWalletBase({
required WalletInfo walletInfo, required WalletInfo walletInfo,
required String mnemonic, String? mnemonic,
String? privateKey,
required String password, required String password,
ERC20Balance? initialBalance, ERC20Balance? initialBalance,
}) : syncStatus = NotConnectedSyncStatus(), }) : syncStatus = NotConnectedSyncStatus(),
_password = password, _password = password,
_mnemonic = mnemonic, _mnemonic = mnemonic,
_hexPrivateKey = privateKey,
_isTransactionUpdating = false, _isTransactionUpdating = false,
_client = EthereumClient(), _client = EthereumClient(),
walletAddresses = EthereumWalletAddresses(walletInfo), walletAddresses = EthereumWalletAddresses(walletInfo),
@ -66,12 +68,13 @@ abstract class EthereumWalletBase
_sharedPrefs.complete(SharedPreferences.getInstance()); _sharedPrefs.complete(SharedPreferences.getInstance());
} }
final String _mnemonic; final String? _mnemonic;
final String? _hexPrivateKey;
final String _password; final String _password;
late final Box<Erc20Token> erc20TokensBox; late final Box<Erc20Token> erc20TokensBox;
late final EthPrivateKey _privateKey; late final EthPrivateKey _ethPrivateKey;
late EthereumClient _client; late EthereumClient _client;
@ -99,8 +102,12 @@ abstract class EthereumWalletBase
erc20TokensBox = await CakeHive.openBox<Erc20Token>(Erc20Token.boxName); erc20TokensBox = await CakeHive.openBox<Erc20Token>(Erc20Token.boxName);
await walletAddresses.init(); await walletAddresses.init();
await transactionHistory.init(); await transactionHistory.init();
_privateKey = await getPrivateKey(_mnemonic, _password); _ethPrivateKey = await getPrivateKey(
walletAddresses.address = _privateKey.address.toString(); mnemonic: _mnemonic,
privateKey: _hexPrivateKey,
password: _password,
);
walletAddresses.address = _ethPrivateKey.address.toString();
await save(); await save();
} }
@ -108,8 +115,7 @@ abstract class EthereumWalletBase
int calculateEstimatedFee(TransactionPriority priority, int? amount) { int calculateEstimatedFee(TransactionPriority priority, int? amount) {
try { try {
if (priority is EthereumTransactionPriority) { if (priority is EthereumTransactionPriority) {
final priorityFee = final priorityFee = EtherAmount.fromInt(EtherUnit.gwei, priority.tip).getInWei.toInt();
EtherAmount.fromUnitAndValue(EtherUnit.gwei, priority.tip).getInWei.toInt();
return (_gasPrice! + priorityFee) * (_estimatedGas ?? 0); return (_gasPrice! + priorityFee) * (_estimatedGas ?? 0);
} }
@ -142,7 +148,7 @@ abstract class EthereumWalletBase
throw Exception("Ethereum Node connection failed"); throw Exception("Ethereum Node connection failed");
} }
_client.setListeners(_privateKey.address, _onNewTransaction); _client.setListeners(_ethPrivateKey.address, _onNewTransaction);
_setTransactionUpdateTimer(); _setTransactionUpdateTimer();
@ -202,7 +208,7 @@ abstract class EthereumWalletBase
} }
final pendingEthereumTransaction = await _client.signTransaction( final pendingEthereumTransaction = await _client.signTransaction(
privateKey: _privateKey, privateKey: _ethPrivateKey,
toAddress: _credentials.outputs.first.isParsedAddress toAddress: _credentials.outputs.first.isParsedAddress
? _credentials.outputs.first.extractedAddress! ? _credentials.outputs.first.extractedAddress!
: _credentials.outputs.first.address, : _credentials.outputs.first.address,
@ -240,7 +246,7 @@ abstract class EthereumWalletBase
@override @override
Future<Map<String, EthereumTransactionInfo>> fetchTransactions() async { Future<Map<String, EthereumTransactionInfo>> fetchTransactions() async {
final address = _privateKey.address.hex; final address = _ethPrivateKey.address.hex;
final transactions = await _client.fetchTransactions(address); final transactions = await _client.fetchTransactions(address);
final List<Future<List<EthereumTransactionModel>>> erc20TokensTransactions = []; final List<Future<List<EthereumTransactionModel>>> erc20TokensTransactions = [];
@ -300,7 +306,10 @@ abstract class EthereumWalletBase
} }
@override @override
String get seed => _mnemonic; String? get seed => _mnemonic;
@override
String get privateKey => HEX.encode(_ethPrivateKey.privateKey);
@action @action
@override @override
@ -327,6 +336,7 @@ abstract class EthereumWalletBase
String toJSON() => json.encode({ String toJSON() => json.encode({
'mnemonic': _mnemonic, 'mnemonic': _mnemonic,
'private_key': privateKey,
'balance': balance[currency]!.toJSON(), 'balance': balance[currency]!.toJSON(),
}); });
@ -338,13 +348,15 @@ abstract class EthereumWalletBase
final path = await pathForWallet(name: name, type: walletInfo.type); final path = await pathForWallet(name: name, type: walletInfo.type);
final jsonSource = await read(path: path, password: password); final jsonSource = await read(path: path, password: password);
final data = json.decode(jsonSource) as Map; final data = json.decode(jsonSource) as Map;
final mnemonic = data['mnemonic'] as String; final mnemonic = data['mnemonic'] as String?;
final privateKey = data['private_key'] as String?;
final balance = ERC20Balance.fromJSON(data['balance'] as String) ?? ERC20Balance(BigInt.zero); final balance = ERC20Balance.fromJSON(data['balance'] as String) ?? ERC20Balance(BigInt.zero);
return EthereumWallet( return EthereumWallet(
walletInfo: walletInfo, walletInfo: walletInfo,
password: password, password: password,
mnemonic: mnemonic, mnemonic: mnemonic,
privateKey: privateKey,
initialBalance: balance, initialBalance: balance,
); );
} }
@ -357,7 +369,7 @@ abstract class EthereumWalletBase
} }
Future<ERC20Balance> _fetchEthBalance() async { Future<ERC20Balance> _fetchEthBalance() async {
final balance = await _client.getBalance(_privateKey.address); final balance = await _client.getBalance(_ethPrivateKey.address);
return ERC20Balance(balance.getInWei); return ERC20Balance(balance.getInWei);
} }
@ -366,7 +378,7 @@ abstract class EthereumWalletBase
try { try {
if (token.enabled) { if (token.enabled) {
balance[token] = await _client.fetchERC20Balances( balance[token] = await _client.fetchERC20Balances(
_privateKey.address, _ethPrivateKey.address,
token.contractAddress, token.contractAddress,
); );
} else { } else {
@ -376,8 +388,15 @@ abstract class EthereumWalletBase
} }
} }
Future<EthPrivateKey> getPrivateKey(String mnemonic, String password) async { Future<EthPrivateKey> getPrivateKey(
final seed = bip39.mnemonicToSeed(mnemonic); {String? mnemonic, String? privateKey, required String password}) async {
assert(mnemonic != null || privateKey != null);
if (privateKey != null) {
return EthPrivateKey.fromHex(privateKey);
}
final seed = bip39.mnemonicToSeed(mnemonic!);
final root = bip32.BIP32.fromSeed(seed); final root = bip32.BIP32.fromSeed(seed);
@ -413,7 +432,7 @@ abstract class EthereumWalletBase
if (_token.enabled) { if (_token.enabled) {
balance[_token] = await _client.fetchERC20Balances( balance[_token] = await _client.fetchERC20Balances(
_privateKey.address, _ethPrivateKey.address,
_token.contractAddress, _token.contractAddress,
); );
} else { } else {

View file

@ -8,16 +8,22 @@ class EthereumNewWalletCredentials extends WalletCredentials {
class EthereumRestoreWalletFromSeedCredentials extends WalletCredentials { class EthereumRestoreWalletFromSeedCredentials extends WalletCredentials {
EthereumRestoreWalletFromSeedCredentials( EthereumRestoreWalletFromSeedCredentials(
{required String name, required String password, required this.mnemonic, WalletInfo? walletInfo}) {required String name,
required String password,
required this.mnemonic,
WalletInfo? walletInfo})
: super(name: name, password: password, walletInfo: walletInfo); : super(name: name, password: password, walletInfo: walletInfo);
final String mnemonic; final String mnemonic;
} }
class EthereumRestoreWalletFromWIFCredentials extends WalletCredentials { class EthereumRestoreWalletFromPrivateKey extends WalletCredentials {
EthereumRestoreWalletFromWIFCredentials( EthereumRestoreWalletFromPrivateKey(
{required String name, required String password, required this.wif, WalletInfo? walletInfo}) {required String name,
required String password,
required this.privateKey,
WalletInfo? walletInfo})
: super(name: name, password: password, walletInfo: walletInfo); : super(name: name, password: password, walletInfo: walletInfo);
final String wif; final String privateKey;
} }

View file

@ -13,7 +13,7 @@ import 'package:bip39/bip39.dart' as bip39;
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
class EthereumWalletService extends WalletService<EthereumNewWalletCredentials, class EthereumWalletService extends WalletService<EthereumNewWalletCredentials,
EthereumRestoreWalletFromSeedCredentials, EthereumRestoreWalletFromWIFCredentials> { EthereumRestoreWalletFromSeedCredentials, EthereumRestoreWalletFromPrivateKey> {
EthereumWalletService(this.walletInfoSource); EthereumWalletService(this.walletInfoSource);
final Box<WalletInfo> walletInfoSource; final Box<WalletInfo> walletInfoSource;
@ -66,8 +66,18 @@ class EthereumWalletService extends WalletService<EthereumNewWalletCredentials,
} }
@override @override
Future<EthereumWallet> restoreFromKeys(credentials) { Future<EthereumWallet> restoreFromKeys(EthereumRestoreWalletFromPrivateKey credentials) async {
throw UnimplementedError(); final wallet = EthereumWallet(
password: credentials.password!,
privateKey: credentials.privateKey,
walletInfo: credentials.walletInfo!,
);
await wallet.init();
wallet.addInitialTokens();
await wallet.save();
return wallet;
} }
@override @override

View file

@ -12,13 +12,14 @@ environment:
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
web3dart: 2.3.5 web3dart: ^2.7.1
erc20: ^1.0.1
mobx: ^2.0.7+4 mobx: ^2.0.7+4
bip39: ^1.0.6 bip39: ^1.0.6
bip32: ^2.0.0 bip32: ^2.0.0
ed25519_hd_key: ^2.2.0 ed25519_hd_key: ^2.2.0
hex: ^0.2.0 hex: ^0.2.0
http: ^0.13.4 http: ^1.1.0
shared_preferences: ^2.0.15 shared_preferences: ^2.0.15
cw_core: cw_core:
path: ../cw_core path: ../cw_core

View file

@ -13,11 +13,11 @@ dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
ffi: ^2.0.1 ffi: ^2.0.1
http: ^0.13.4 http: ^1.1.0
path_provider: ^2.0.11 path_provider: ^2.0.11
mobx: ^2.0.7+4 mobx: ^2.0.7+4
flutter_mobx: ^2.0.6+1 flutter_mobx: ^2.0.6+1
intl: ^0.17.0 intl: ^0.18.0
cw_core: cw_core:
path: ../cw_core path: ../cw_core

View file

@ -399,5 +399,5 @@ packages:
source: hosted source: hosted
version: "0.2.0+3" version: "0.2.0+3"
sdks: sdks:
dart: ">=2.18.1 <4.0.0" dart: ">=2.18.1 <3.0.0"
flutter: ">=3.0.0" flutter: ">=3.0.0"

View file

@ -6,6 +6,7 @@
#include <fstream> #include <fstream>
#include <unistd.h> #include <unistd.h>
#include <mutex> #include <mutex>
#include <list>
#include "thread" #include "thread"
#include "CwWalletListener.h" #include "CwWalletListener.h"
#if __APPLE__ #if __APPLE__
@ -182,6 +183,62 @@ extern "C"
} }
}; };
struct CoinsInfoRow
{
uint64_t blockHeight;
char *hash;
uint64_t internalOutputIndex;
uint64_t globalOutputIndex;
bool spent;
bool frozen;
uint64_t spentHeight;
uint64_t amount;
bool rct;
bool keyImageKnown;
uint64_t pkIndex;
uint32_t subaddrIndex;
uint32_t subaddrAccount;
char *address;
char *addressLabel;
char *keyImage;
uint64_t unlockTime;
bool unlocked;
char *pubKey;
bool coinbase;
char *description;
CoinsInfoRow(Monero::CoinsInfo *coinsInfo)
{
blockHeight = coinsInfo->blockHeight();
std::string *hash_str = new std::string(coinsInfo->hash());
hash = strdup(hash_str->c_str());
internalOutputIndex = coinsInfo->internalOutputIndex();
globalOutputIndex = coinsInfo->globalOutputIndex();
spent = coinsInfo->spent();
frozen = coinsInfo->frozen();
spentHeight = coinsInfo->spentHeight();
amount = coinsInfo->amount();
rct = coinsInfo->rct();
keyImageKnown = coinsInfo->keyImageKnown();
pkIndex = coinsInfo->pkIndex();
subaddrIndex = coinsInfo->subaddrIndex();
subaddrAccount = coinsInfo->subaddrAccount();
address = strdup(coinsInfo->address().c_str()) ;
addressLabel = strdup(coinsInfo->addressLabel().c_str());
keyImage = strdup(coinsInfo->keyImage().c_str());
unlockTime = coinsInfo->unlockTime();
unlocked = coinsInfo->unlocked();
pubKey = strdup(coinsInfo->pubKey().c_str());
coinbase = coinsInfo->coinbase();
description = strdup(coinsInfo->description().c_str());
}
void setUnlocked(bool unlocked);
};
Monero::Coins *m_coins;
Monero::Wallet *m_wallet; Monero::Wallet *m_wallet;
Monero::TransactionHistory *m_transaction_history; Monero::TransactionHistory *m_transaction_history;
MoneroWalletListener *m_listener; MoneroWalletListener *m_listener;
@ -189,6 +246,7 @@ extern "C"
Monero::SubaddressAccount *m_account; Monero::SubaddressAccount *m_account;
uint64_t m_last_known_wallet_height; uint64_t m_last_known_wallet_height;
uint64_t m_cached_syncing_blockchain_height = 0; uint64_t m_cached_syncing_blockchain_height = 0;
std::list<Monero::CoinsInfo*> m_coins_info;
std::mutex store_lock; std::mutex store_lock;
bool is_storing = false; bool is_storing = false;
@ -224,6 +282,17 @@ extern "C"
{ {
m_subaddress = nullptr; m_subaddress = nullptr;
} }
m_coins_info = std::list<Monero::CoinsInfo*>();
if (wallet != nullptr)
{
m_coins = wallet->coins();
}
else
{
m_coins = nullptr;
}
} }
Monero::Wallet *get_current_wallet() Monero::Wallet *get_current_wallet()
@ -487,9 +556,18 @@ extern "C"
} }
bool transaction_create(char *address, char *payment_id, char *amount, bool transaction_create(char *address, char *payment_id, char *amount,
uint8_t priority_raw, uint32_t subaddr_account, Utf8Box &error, PendingTransactionRaw &pendingTransaction) uint8_t priority_raw, uint32_t subaddr_account,
char **preferred_inputs, uint32_t preferred_inputs_size,
Utf8Box &error, PendingTransactionRaw &pendingTransaction)
{ {
nice(19); nice(19);
std::set<std::string> _preferred_inputs;
for (int i = 0; i < preferred_inputs_size; i++) {
_preferred_inputs.insert(std::string(*preferred_inputs));
preferred_inputs++;
}
auto priority = static_cast<Monero::PendingTransaction::Priority>(priority_raw); auto priority = static_cast<Monero::PendingTransaction::Priority>(priority_raw);
std::string _payment_id; std::string _payment_id;
@ -503,11 +581,11 @@ extern "C"
if (amount != nullptr) if (amount != nullptr)
{ {
uint64_t _amount = Monero::Wallet::amountFromString(std::string(amount)); uint64_t _amount = Monero::Wallet::amountFromString(std::string(amount));
transaction = m_wallet->createTransaction(std::string(address), _payment_id, _amount, m_wallet->defaultMixin(), priority, subaddr_account); transaction = m_wallet->createTransaction(std::string(address), _payment_id, _amount, m_wallet->defaultMixin(), priority, subaddr_account, {}, _preferred_inputs);
} }
else else
{ {
transaction = m_wallet->createTransaction(std::string(address), _payment_id, Monero::optional<uint64_t>(), m_wallet->defaultMixin(), priority, subaddr_account); transaction = m_wallet->createTransaction(std::string(address), _payment_id, Monero::optional<uint64_t>(), m_wallet->defaultMixin(), priority, subaddr_account, {}, _preferred_inputs);
} }
int status = transaction->status(); int status = transaction->status();
@ -527,7 +605,9 @@ extern "C"
} }
bool transaction_create_mult_dest(char **addresses, char *payment_id, char **amounts, uint32_t size, bool transaction_create_mult_dest(char **addresses, char *payment_id, char **amounts, uint32_t size,
uint8_t priority_raw, uint32_t subaddr_account, Utf8Box &error, PendingTransactionRaw &pendingTransaction) uint8_t priority_raw, uint32_t subaddr_account,
char **preferred_inputs, uint32_t preferred_inputs_size,
Utf8Box &error, PendingTransactionRaw &pendingTransaction)
{ {
nice(19); nice(19);
@ -541,6 +621,13 @@ extern "C"
amounts++; amounts++;
} }
std::set<std::string> _preferred_inputs;
for (int i = 0; i < preferred_inputs_size; i++) {
_preferred_inputs.insert(std::string(*preferred_inputs));
preferred_inputs++;
}
auto priority = static_cast<Monero::PendingTransaction::Priority>(priority_raw); auto priority = static_cast<Monero::PendingTransaction::Priority>(priority_raw);
std::string _payment_id; std::string _payment_id;
Monero::PendingTransaction *transaction; Monero::PendingTransaction *transaction;
@ -800,6 +887,91 @@ extern "C"
return m_wallet->trustedDaemon(); return m_wallet->trustedDaemon();
} }
CoinsInfoRow* coin(int index)
{
if (index >= 0 && index < m_coins_info.size()) {
std::list<Monero::CoinsInfo*>::iterator it = m_coins_info.begin();
std::advance(it, index);
Monero::CoinsInfo* element = *it;
std::cout << "Element at index " << index << ": " << element << std::endl;
return new CoinsInfoRow(element);
} else {
std::cout << "Invalid index." << std::endl;
return nullptr; // Return a default value (nullptr) for invalid index
}
}
void refresh_coins(uint32_t accountIndex)
{
m_coins_info.clear();
m_coins->refresh();
for (const auto i : m_coins->getAll()) {
if (i->subaddrAccount() == accountIndex && !(i->spent())) {
m_coins_info.push_back(i);
}
}
}
uint64_t coins_count()
{
return m_coins_info.size();
}
CoinsInfoRow** coins_from_account(uint32_t accountIndex)
{
std::vector<CoinsInfoRow*> matchingCoins;
for (int i = 0; i < coins_count(); i++) {
CoinsInfoRow* coinInfo = coin(i);
if (coinInfo->subaddrAccount == accountIndex) {
matchingCoins.push_back(coinInfo);
}
}
CoinsInfoRow** result = new CoinsInfoRow*[matchingCoins.size()];
std::copy(matchingCoins.begin(), matchingCoins.end(), result);
return result;
}
CoinsInfoRow** coins_from_txid(const char* txid, size_t* count)
{
std::vector<CoinsInfoRow*> matchingCoins;
for (int i = 0; i < coins_count(); i++) {
CoinsInfoRow* coinInfo = coin(i);
if (std::string(coinInfo->hash) == txid) {
matchingCoins.push_back(coinInfo);
}
}
*count = matchingCoins.size();
CoinsInfoRow** result = new CoinsInfoRow*[*count];
std::copy(matchingCoins.begin(), matchingCoins.end(), result);
return result;
}
CoinsInfoRow** coins_from_key_image(const char** keyimages, size_t keyimageCount, size_t* count)
{
std::vector<CoinsInfoRow*> matchingCoins;
for (int i = 0; i < coins_count(); i++) {
CoinsInfoRow* coinsInfoRow = coin(i);
for (size_t j = 0; j < keyimageCount; j++) {
if (coinsInfoRow->keyImageKnown && std::string(coinsInfoRow->keyImage) == keyimages[j]) {
matchingCoins.push_back(coinsInfoRow);
break;
}
}
}
*count = matchingCoins.size();
CoinsInfoRow** result = new CoinsInfoRow*[*count];
std::copy(matchingCoins.begin(), matchingCoins.end(), result);
return result;
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -0,0 +1,23 @@
import 'dart:ffi';
import 'package:cw_monero/api/signatures.dart';
import 'package:cw_monero/api/structs/coins_info_row.dart';
import 'package:cw_monero/api/types.dart';
import 'package:cw_monero/api/monero_api.dart';
final refreshCoinsNative = moneroApi
.lookup<NativeFunction<refresh_coins>>('refresh_coins')
.asFunction<RefreshCoins>();
final coinsCountNative = moneroApi
.lookup<NativeFunction<coins_count>>('coins_count')
.asFunction<CoinsCount>();
final coinNative = moneroApi
.lookup<NativeFunction<coin>>('coin')
.asFunction<GetCoin>();
void refreshCoins(int accountIndex) => refreshCoinsNative(accountIndex);
int countOfCoins() => coinsCountNative();
CoinsInfoRow getCoin(int index) => coinNative(index).ref;

View file

@ -1,4 +1,5 @@
import 'dart:ffi'; import 'dart:ffi';
import 'package:cw_monero/api/structs/coins_info_row.dart';
import 'package:cw_monero/api/structs/pending_transaction.dart'; import 'package:cw_monero/api/structs/pending_transaction.dart';
import 'package:cw_monero/api/structs/ut8_box.dart'; import 'package:cw_monero/api/structs/ut8_box.dart';
import 'package:ffi/ffi.dart'; import 'package:ffi/ffi.dart';
@ -9,8 +10,8 @@ typedef create_wallet = Int8 Function(
typedef restore_wallet_from_seed = Int8 Function( typedef restore_wallet_from_seed = Int8 Function(
Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Int32, Int64, Pointer<Utf8>); Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Int32, Int64, Pointer<Utf8>);
typedef restore_wallet_from_keys = Int8 Function(Pointer<Utf8>, Pointer<Utf8>, typedef restore_wallet_from_keys = Int8 Function(Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>,
Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Int32, Int64, Pointer<Utf8>); Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Int32, Int64, Pointer<Utf8>);
typedef is_wallet_exist = Int8 Function(Pointer<Utf8>); typedef is_wallet_exist = Int8 Function(Pointer<Utf8>);
@ -63,8 +64,7 @@ typedef subaddrress_refresh = Void Function(Int32);
typedef subaddress_get_all = Pointer<Int64> Function(); typedef subaddress_get_all = Pointer<Int64> Function();
typedef subaddress_add_new = Void Function( typedef subaddress_add_new = Void Function(Int32 accountIndex, Pointer<Utf8> label);
Int32 accountIndex, Pointer<Utf8> label);
typedef subaddress_set_label = Void Function( typedef subaddress_set_label = Void Function(
Int32 accountIndex, Int32 addressIndex, Pointer<Utf8> label); Int32 accountIndex, Int32 addressIndex, Pointer<Utf8> label);
@ -77,8 +77,7 @@ typedef account_get_all = Pointer<Int64> Function();
typedef account_add_new = Void Function(Pointer<Utf8> label); typedef account_add_new = Void Function(Pointer<Utf8> label);
typedef account_set_label = Void Function( typedef account_set_label = Void Function(Int32 accountIndex, Pointer<Utf8> label);
Int32 accountIndex, Pointer<Utf8> label);
typedef transactions_refresh = Void Function(); typedef transactions_refresh = Void Function();
@ -94,6 +93,8 @@ typedef transaction_create = Int8 Function(
Pointer<Utf8> amount, Pointer<Utf8> amount,
Int8 priorityRaw, Int8 priorityRaw,
Int32 subaddrAccount, Int32 subaddrAccount,
Pointer<Pointer<Utf8>> preferredInputs,
Int32 preferredInputsSize,
Pointer<Utf8Box> error, Pointer<Utf8Box> error,
Pointer<PendingTransactionRaw> pendingTransaction); Pointer<PendingTransactionRaw> pendingTransaction);
@ -104,6 +105,8 @@ typedef transaction_create_mult_dest = Int8 Function(
Int32 size, Int32 size,
Int8 priorityRaw, Int8 priorityRaw,
Int32 subaddrAccount, Int32 subaddrAccount,
Pointer<Pointer<Utf8>> preferredInputs,
Int32 preferredInputsSize,
Pointer<Utf8Box> error, Pointer<Utf8Box> error,
Pointer<PendingTransactionRaw> pendingTransaction); Pointer<PendingTransactionRaw> pendingTransaction);
@ -123,10 +126,16 @@ typedef on_startup = Void Function();
typedef rescan_blockchain = Void Function(); typedef rescan_blockchain = Void Function();
typedef get_subaddress_label = Pointer<Utf8> Function( typedef get_subaddress_label = Pointer<Utf8> Function(Int32 accountIndex, Int32 addressIndex);
Int32 accountIndex,
Int32 addressIndex);
typedef set_trusted_daemon = Void Function(Int8 trusted); typedef set_trusted_daemon = Void Function(Int8 trusted);
typedef trusted_daemon = Int8 Function(); typedef trusted_daemon = Int8 Function();
typedef refresh_coins = Void Function(Int32 accountIndex);
typedef coins_count = Int64 Function();
// typedef coins_from_txid = Pointer<CoinsInfoRow> Function(Pointer<Utf8> txid);
typedef coin = Pointer<CoinsInfoRow> Function(Int32 index);

View file

@ -0,0 +1,73 @@
import 'dart:ffi';
import 'package:ffi/ffi.dart';
class CoinsInfoRow extends Struct {
@Int64()
external int blockHeight;
external Pointer<Utf8> hash;
@Uint64()
external int internalOutputIndex;
@Uint64()
external int globalOutputIndex;
@Int8()
external int spent;
@Int8()
external int frozen;
@Uint64()
external int spentHeight;
@Uint64()
external int amount;
@Int8()
external int rct;
@Int8()
external int keyImageKnown;
@Uint64()
external int pkIndex;
@Uint32()
external int subaddrIndex;
@Uint32()
external int subaddrAccount;
external Pointer<Utf8> address;
external Pointer<Utf8> addressLabel;
external Pointer<Utf8> keyImage;
@Uint64()
external int unlockTime;
@Int8()
external int unlocked;
external Pointer<Utf8> pubKey;
@Int8()
external int coinbase;
external Pointer<Utf8> description;
String getHash() => hash.toDartString();
String getAddress() => address.toDartString();
String getAddressLabel() => addressLabel.toDartString();
String getKeyImage() => keyImage.toDartString();
String getPubKey() => pubKey.toDartString();
String getDescription() => description.toDartString();
}

View file

@ -35,9 +35,8 @@ final transactionCommitNative = moneroApi
.lookup<NativeFunction<transaction_commit>>('transaction_commit') .lookup<NativeFunction<transaction_commit>>('transaction_commit')
.asFunction<TransactionCommit>(); .asFunction<TransactionCommit>();
final getTxKeyNative = moneroApi final getTxKeyNative =
.lookup<NativeFunction<get_tx_key>>('get_tx_key') moneroApi.lookup<NativeFunction<get_tx_key>>('get_tx_key').asFunction<GetTxKey>();
.asFunction<GetTxKey>();
String getTxKey(String txId) { String getTxKey(String txId) {
final txIdPointer = txId.toNativeUtf8(); final txIdPointer = txId.toNativeUtf8();
@ -71,10 +70,21 @@ PendingTransactionDescription createTransactionSync(
required String paymentId, required String paymentId,
required int priorityRaw, required int priorityRaw,
String? amount, String? amount,
int accountIndex = 0}) { int accountIndex = 0,
List<String> preferredInputs = const []}) {
final addressPointer = address.toNativeUtf8(); final addressPointer = address.toNativeUtf8();
final paymentIdPointer = paymentId.toNativeUtf8(); final paymentIdPointer = paymentId.toNativeUtf8();
final amountPointer = amount != null ? amount.toNativeUtf8() : nullptr; final amountPointer = amount != null ? amount.toNativeUtf8() : nullptr;
final int preferredInputsSize = preferredInputs.length;
final List<Pointer<Utf8>> preferredInputsPointers =
preferredInputs.map((output) => output.toNativeUtf8()).toList();
final Pointer<Pointer<Utf8>> preferredInputsPointerPointer = calloc(preferredInputsSize);
for (int i = 0; i < preferredInputsSize; i++) {
preferredInputsPointerPointer[i] = preferredInputsPointers[i];
}
final errorMessagePointer = calloc<Utf8Box>(); final errorMessagePointer = calloc<Utf8Box>();
final pendingTransactionRawPointer = calloc<PendingTransactionRaw>(); final pendingTransactionRawPointer = calloc<PendingTransactionRaw>();
final created = transactionCreateNative( final created = transactionCreateNative(
@ -83,10 +93,16 @@ PendingTransactionDescription createTransactionSync(
amountPointer, amountPointer,
priorityRaw, priorityRaw,
accountIndex, accountIndex,
preferredInputsPointerPointer,
preferredInputsSize,
errorMessagePointer, errorMessagePointer,
pendingTransactionRawPointer) != pendingTransactionRawPointer) !=
0; 0;
calloc.free(preferredInputsPointerPointer);
preferredInputsPointers.forEach((element) => calloc.free(element));
calloc.free(addressPointer); calloc.free(addressPointer);
calloc.free(paymentIdPointer); calloc.free(paymentIdPointer);
@ -111,15 +127,16 @@ PendingTransactionDescription createTransactionSync(
PendingTransactionDescription createTransactionMultDestSync( PendingTransactionDescription createTransactionMultDestSync(
{required List<MoneroOutput> outputs, {required List<MoneroOutput> outputs,
required String paymentId, required String paymentId,
required int priorityRaw, required int priorityRaw,
int accountIndex = 0}) { int accountIndex = 0,
List<String> preferredInputs = const []}) {
final int size = outputs.length; final int size = outputs.length;
final List<Pointer<Utf8>> addressesPointers = outputs.map((output) => final List<Pointer<Utf8>> addressesPointers =
output.address.toNativeUtf8()).toList(); outputs.map((output) => output.address.toNativeUtf8()).toList();
final Pointer<Pointer<Utf8>> addressesPointerPointer = calloc(size); final Pointer<Pointer<Utf8>> addressesPointerPointer = calloc(size);
final List<Pointer<Utf8>> amountsPointers = outputs.map((output) => final List<Pointer<Utf8>> amountsPointers =
output.amount.toNativeUtf8()).toList(); outputs.map((output) => output.amount.toNativeUtf8()).toList();
final Pointer<Pointer<Utf8>> amountsPointerPointer = calloc(size); final Pointer<Pointer<Utf8>> amountsPointerPointer = calloc(size);
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
@ -127,25 +144,38 @@ PendingTransactionDescription createTransactionMultDestSync(
amountsPointerPointer[i] = amountsPointers[i]; amountsPointerPointer[i] = amountsPointers[i];
} }
final int preferredInputsSize = preferredInputs.length;
final List<Pointer<Utf8>> preferredInputsPointers =
preferredInputs.map((output) => output.toNativeUtf8()).toList();
final Pointer<Pointer<Utf8>> preferredInputsPointerPointer = calloc(preferredInputsSize);
for (int i = 0; i < preferredInputsSize; i++) {
preferredInputsPointerPointer[i] = preferredInputsPointers[i];
}
final paymentIdPointer = paymentId.toNativeUtf8(); final paymentIdPointer = paymentId.toNativeUtf8();
final errorMessagePointer = calloc<Utf8Box>(); final errorMessagePointer = calloc<Utf8Box>();
final pendingTransactionRawPointer = calloc<PendingTransactionRaw>(); final pendingTransactionRawPointer = calloc<PendingTransactionRaw>();
final created = transactionCreateMultDestNative( final created = transactionCreateMultDestNative(
addressesPointerPointer, addressesPointerPointer,
paymentIdPointer, paymentIdPointer,
amountsPointerPointer, amountsPointerPointer,
size, size,
priorityRaw, priorityRaw,
accountIndex, accountIndex,
errorMessagePointer, preferredInputsPointerPointer,
pendingTransactionRawPointer) != preferredInputsSize,
errorMessagePointer,
pendingTransactionRawPointer) !=
0; 0;
calloc.free(addressesPointerPointer); calloc.free(addressesPointerPointer);
calloc.free(amountsPointerPointer); calloc.free(amountsPointerPointer);
calloc.free(preferredInputsPointerPointer);
addressesPointers.forEach((element) => calloc.free(element)); addressesPointers.forEach((element) => calloc.free(element));
amountsPointers.forEach((element) => calloc.free(element)); amountsPointers.forEach((element) => calloc.free(element));
preferredInputsPointers.forEach((element) => calloc.free(element));
calloc.free(paymentIdPointer); calloc.free(paymentIdPointer);
@ -164,13 +194,12 @@ PendingTransactionDescription createTransactionMultDestSync(
pointerAddress: pendingTransactionRawPointer.address); pointerAddress: pendingTransactionRawPointer.address);
} }
void commitTransactionFromPointerAddress({required int address}) => commitTransaction( void commitTransactionFromPointerAddress({required int address}) =>
transactionPointer: Pointer<PendingTransactionRaw>.fromAddress(address)); commitTransaction(transactionPointer: Pointer<PendingTransactionRaw>.fromAddress(address));
void commitTransaction({required Pointer<PendingTransactionRaw> transactionPointer}) { void commitTransaction({required Pointer<PendingTransactionRaw> transactionPointer}) {
final errorMessagePointer = calloc<Utf8Box>(); final errorMessagePointer = calloc<Utf8Box>();
final isCommited = final isCommited = transactionCommitNative(transactionPointer, errorMessagePointer) != 0;
transactionCommitNative(transactionPointer, errorMessagePointer) != 0;
if (!isCommited) { if (!isCommited) {
final message = errorMessagePointer.ref.getValue(); final message = errorMessagePointer.ref.getValue();
@ -185,13 +214,15 @@ PendingTransactionDescription _createTransactionSync(Map args) {
final amount = args['amount'] as String?; final amount = args['amount'] as String?;
final priorityRaw = args['priorityRaw'] as int; final priorityRaw = args['priorityRaw'] as int;
final accountIndex = args['accountIndex'] as int; final accountIndex = args['accountIndex'] as int;
final preferredInputs = args['preferredInputs'] as List<String>;
return createTransactionSync( return createTransactionSync(
address: address, address: address,
paymentId: paymentId, paymentId: paymentId,
amount: amount, amount: amount,
priorityRaw: priorityRaw, priorityRaw: priorityRaw,
accountIndex: accountIndex); accountIndex: accountIndex,
preferredInputs: preferredInputs);
} }
PendingTransactionDescription _createTransactionMultDestSync(Map args) { PendingTransactionDescription _createTransactionMultDestSync(Map args) {
@ -199,12 +230,14 @@ PendingTransactionDescription _createTransactionMultDestSync(Map args) {
final paymentId = args['paymentId'] as String; final paymentId = args['paymentId'] as String;
final priorityRaw = args['priorityRaw'] as int; final priorityRaw = args['priorityRaw'] as int;
final accountIndex = args['accountIndex'] as int; final accountIndex = args['accountIndex'] as int;
final preferredInputs = args['preferredInputs'] as List<String>;
return createTransactionMultDestSync( return createTransactionMultDestSync(
outputs: outputs, outputs: outputs,
paymentId: paymentId, paymentId: paymentId,
priorityRaw: priorityRaw, priorityRaw: priorityRaw,
accountIndex: accountIndex); accountIndex: accountIndex,
preferredInputs: preferredInputs);
} }
Future<PendingTransactionDescription> createTransaction( Future<PendingTransactionDescription> createTransaction(
@ -212,23 +245,27 @@ Future<PendingTransactionDescription> createTransaction(
required int priorityRaw, required int priorityRaw,
String? amount, String? amount,
String paymentId = '', String paymentId = '',
int accountIndex = 0}) => int accountIndex = 0,
List<String> preferredInputs = const []}) =>
compute(_createTransactionSync, { compute(_createTransactionSync, {
'address': address, 'address': address,
'paymentId': paymentId, 'paymentId': paymentId,
'amount': amount, 'amount': amount,
'priorityRaw': priorityRaw, 'priorityRaw': priorityRaw,
'accountIndex': accountIndex 'accountIndex': accountIndex,
'preferredInputs': preferredInputs
}); });
Future<PendingTransactionDescription> createTransactionMultDest( Future<PendingTransactionDescription> createTransactionMultDest(
{required List<MoneroOutput> outputs, {required List<MoneroOutput> outputs,
required int priorityRaw, required int priorityRaw,
String paymentId = '', String paymentId = '',
int accountIndex = 0}) => int accountIndex = 0,
List<String> preferredInputs = const []}) =>
compute(_createTransactionMultDestSync, { compute(_createTransactionMultDestSync, {
'outputs': outputs, 'outputs': outputs,
'paymentId': paymentId, 'paymentId': paymentId,
'priorityRaw': priorityRaw, 'priorityRaw': priorityRaw,
'accountIndex': accountIndex 'accountIndex': accountIndex,
'preferredInputs': preferredInputs
}); });

View file

@ -1,4 +1,5 @@
import 'dart:ffi'; import 'dart:ffi';
import 'package:cw_monero/api/structs/coins_info_row.dart';
import 'package:cw_monero/api/structs/pending_transaction.dart'; import 'package:cw_monero/api/structs/pending_transaction.dart';
import 'package:cw_monero/api/structs/ut8_box.dart'; import 'package:cw_monero/api/structs/ut8_box.dart';
import 'package:ffi/ffi.dart'; import 'package:ffi/ffi.dart';
@ -92,6 +93,8 @@ typedef TransactionCreate = int Function(
Pointer<Utf8> amount, Pointer<Utf8> amount,
int priorityRaw, int priorityRaw,
int subaddrAccount, int subaddrAccount,
Pointer<Pointer<Utf8>> preferredInputs,
int preferredInputsSize,
Pointer<Utf8Box> error, Pointer<Utf8Box> error,
Pointer<PendingTransactionRaw> pendingTransaction); Pointer<PendingTransactionRaw> pendingTransaction);
@ -102,6 +105,8 @@ typedef TransactionCreateMultDest = int Function(
int size, int size,
int priorityRaw, int priorityRaw,
int subaddrAccount, int subaddrAccount,
Pointer<Pointer<Utf8>> preferredInputs,
int preferredInputsSize,
Pointer<Utf8Box> error, Pointer<Utf8Box> error,
Pointer<PendingTransactionRaw> pendingTransaction); Pointer<PendingTransactionRaw> pendingTransaction);
@ -127,4 +132,10 @@ typedef GetSubaddressLabel = Pointer<Utf8> Function(
typedef SetTrustedDaemon = void Function(int); typedef SetTrustedDaemon = void Function(int);
typedef TrustedDaemon = int Function(); typedef TrustedDaemon = int Function();
typedef RefreshCoins = void Function(int);
typedef CoinsCount = int Function();
typedef GetCoin = Pointer<CoinsInfoRow> Function(int);

View file

@ -0,0 +1,4 @@
class MoneroTransactionNoInputsException implements Exception {
@override
String toString() => 'Not enough inputs available. Please select more under Coin Control';
}

View file

@ -1,6 +1,6 @@
import 'package:cw_monero/api/structs/subaddress_row.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:cw_monero/api/coins_info.dart';
import 'package:cw_monero/api/subaddress_list.dart' as subaddress_list; import 'package:cw_monero/api/subaddress_list.dart' as subaddress_list;
import 'package:cw_core/subaddress.dart'; import 'package:cw_core/subaddress.dart';
@ -22,6 +22,8 @@ abstract class MoneroSubaddressListBase with Store {
bool _isUpdating; bool _isUpdating;
void update({required int accountIndex}) { void update({required int accountIndex}) {
refreshCoins(accountIndex);
if (_isUpdating) { if (_isUpdating) {
return; return;
} }

View file

@ -0,0 +1,28 @@
import 'package:cw_monero/api/structs/coins_info_row.dart';
class MoneroUnspent {
MoneroUnspent(this.address, this.hash, this.keyImage, this.value, this.isFrozen, this.isUnlocked)
: isSending = true,
note = '';
MoneroUnspent.fromCoinsInfoRow(CoinsInfoRow coinsInfoRow)
: address = coinsInfoRow.getAddress(),
hash = coinsInfoRow.getHash(),
keyImage = coinsInfoRow.getKeyImage(),
value = coinsInfoRow.amount,
isFrozen = coinsInfoRow.frozen == 1,
isUnlocked = coinsInfoRow.unlocked == 1,
isSending = true,
note = '';
final String address;
final String hash;
final String keyImage;
final int value;
final bool isUnlocked;
bool isFrozen;
bool isSending;
String note;
}

View file

@ -1,33 +1,35 @@
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:cw_core/pathForWallet.dart';
import 'package:cw_core/transaction_priority.dart';
import 'package:cw_core/monero_amount_format.dart';
import 'package:cw_monero/monero_transaction_creation_exception.dart';
import 'package:cw_monero/monero_transaction_info.dart';
import 'package:cw_monero/monero_wallet_addresses.dart';
import 'package:cw_core/monero_wallet_utils.dart';
import 'package:cw_monero/api/structs/pending_transaction.dart';
import 'package:mobx/mobx.dart';
import 'package:cw_monero/api/transaction_history.dart'
as monero_transaction_history;
import 'package:cw_monero/api/wallet.dart';
import 'package:cw_monero/api/wallet.dart' as monero_wallet;
import 'package:cw_monero/api/transaction_history.dart' as transaction_history;
import 'package:cw_monero/api/monero_output.dart';
import 'package:cw_monero/monero_transaction_creation_credentials.dart';
import 'package:cw_monero/pending_monero_transaction.dart';
import 'package:cw_core/monero_wallet_keys.dart';
import 'package:cw_core/monero_balance.dart';
import 'package:cw_monero/monero_transaction_history.dart';
import 'package:cw_core/account.dart'; import 'package:cw_core/account.dart';
import 'package:cw_core/pending_transaction.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/sync_status.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/node.dart';
import 'package:cw_core/monero_transaction_priority.dart';
import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/monero_amount_format.dart';
import 'package:cw_core/monero_balance.dart';
import 'package:cw_core/monero_transaction_priority.dart';
import 'package:cw_core/monero_wallet_keys.dart';
import 'package:cw_core/monero_wallet_utils.dart';
import 'package:cw_core/node.dart';
import 'package:cw_core/pathForWallet.dart';
import 'package:cw_core/pending_transaction.dart';
import 'package:cw_core/sync_status.dart';
import 'package:cw_core/transaction_priority.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_monero/api/coins_info.dart';
import 'package:cw_monero/api/monero_output.dart';
import 'package:cw_monero/api/structs/pending_transaction.dart';
import 'package:cw_monero/api/transaction_history.dart' as transaction_history;
import 'package:cw_monero/api/wallet.dart' as monero_wallet;
import 'package:cw_monero/exceptions/monero_transaction_creation_exception.dart';
import 'package:cw_monero/exceptions/monero_transaction_no_inputs_exception.dart';
import 'package:cw_monero/pending_monero_transaction.dart';
import 'package:cw_monero/monero_transaction_creation_credentials.dart';
import 'package:cw_monero/monero_transaction_history.dart';
import 'package:cw_monero/monero_transaction_info.dart';
import 'package:cw_monero/monero_unspent.dart';
import 'package:cw_monero/monero_wallet_addresses.dart';
import 'package:mobx/mobx.dart';
import 'package:hive/hive.dart';
part 'monero_wallet.g.dart'; part 'monero_wallet.g.dart';
@ -37,37 +39,39 @@ class MoneroWallet = MoneroWalletBase with _$MoneroWallet;
abstract class MoneroWalletBase extends WalletBase<MoneroBalance, abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
MoneroTransactionHistory, MoneroTransactionInfo> with Store { MoneroTransactionHistory, MoneroTransactionInfo> with Store {
MoneroWalletBase({required WalletInfo walletInfo}) MoneroWalletBase({required WalletInfo walletInfo,
required Box<UnspentCoinsInfo> unspentCoinsInfo})
: balance = ObservableMap<CryptoCurrency, MoneroBalance>.of({ : balance = ObservableMap<CryptoCurrency, MoneroBalance>.of({
CryptoCurrency.xmr: MoneroBalance( CryptoCurrency.xmr: MoneroBalance(
fullBalance: monero_wallet.getFullBalance(accountIndex: 0), fullBalance: monero_wallet.getFullBalance(accountIndex: 0),
unlockedBalance: monero_wallet.getFullBalance(accountIndex: 0)) unlockedBalance: monero_wallet.getFullBalance(accountIndex: 0))
}), }),
_isTransactionUpdating = false, _isTransactionUpdating = false,
_hasSyncAfterStartup = false, _hasSyncAfterStartup = false,
walletAddresses = MoneroWalletAddresses(walletInfo), walletAddresses = MoneroWalletAddresses(walletInfo),
syncStatus = NotConnectedSyncStatus(), syncStatus = NotConnectedSyncStatus(),
unspentCoins = [],
this.unspentCoinsInfo = unspentCoinsInfo,
super(walletInfo) { super(walletInfo) {
transactionHistory = MoneroTransactionHistory(); transactionHistory = MoneroTransactionHistory();
_onAccountChangeReaction = reaction((_) => walletAddresses.account, _onAccountChangeReaction = reaction((_) => walletAddresses.account, (Account? account) {
(Account? account) {
if (account == null) { if (account == null) {
return; return;
} }
balance = ObservableMap<CryptoCurrency, MoneroBalance>.of( balance = ObservableMap<CryptoCurrency, MoneroBalance>.of(<CryptoCurrency, MoneroBalance>{
<CryptoCurrency, MoneroBalance>{ currency: MoneroBalance(
currency: MoneroBalance(
fullBalance: monero_wallet.getFullBalance(accountIndex: account.id), fullBalance: monero_wallet.getFullBalance(accountIndex: account.id),
unlockedBalance: unlockedBalance: monero_wallet.getUnlockedBalance(accountIndex: account.id))
monero_wallet.getUnlockedBalance(accountIndex: account.id)) });
});
walletAddresses.updateSubaddressList(accountIndex: account.id); walletAddresses.updateSubaddressList(accountIndex: account.id);
}); });
} }
static const int _autoSaveInterval = 30; static const int _autoSaveInterval = 30;
Box<UnspentCoinsInfo> unspentCoinsInfo;
@override @override
MoneroWalletAddresses walletAddresses; MoneroWalletAddresses walletAddresses;
@ -89,11 +93,12 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
publicSpendKey: monero_wallet.getPublicSpendKey(), publicSpendKey: monero_wallet.getPublicSpendKey(),
publicViewKey: monero_wallet.getPublicViewKey()); publicViewKey: monero_wallet.getPublicViewKey());
SyncListener? _listener; monero_wallet.SyncListener? _listener;
ReactionDisposer? _onAccountChangeReaction; ReactionDisposer? _onAccountChangeReaction;
bool _isTransactionUpdating; bool _isTransactionUpdating;
bool _hasSyncAfterStartup; bool _hasSyncAfterStartup;
Timer? _autoSaveTimer; Timer? _autoSaveTimer;
List<MoneroUnspent> unspentCoins;
Future<void> init() async { Future<void> init() async {
await walletAddresses.init(); await walletAddresses.init();
@ -170,10 +175,12 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
@override @override
Future<PendingTransaction> createTransaction(Object credentials) async { Future<PendingTransaction> createTransaction(Object credentials) async {
final _credentials = credentials as MoneroTransactionCreationCredentials; final _credentials = credentials as MoneroTransactionCreationCredentials;
final inputs = <String>[];
final outputs = _credentials.outputs; final outputs = _credentials.outputs;
final hasMultiDestination = outputs.length > 1; final hasMultiDestination = outputs.length > 1;
final unlockedBalance = final unlockedBalance =
monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account!.id); monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account!.id);
var allInputsAmount = 0;
PendingTransactionDescription pendingTransactionDescription; PendingTransactionDescription pendingTransactionDescription;
@ -181,6 +188,21 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
throw MoneroTransactionCreationException('The wallet is not synced.'); throw MoneroTransactionCreationException('The wallet is not synced.');
} }
if (unspentCoins.isEmpty) {
await updateUnspent();
}
for (final utx in unspentCoins) {
if (utx.isSending) {
allInputsAmount += utx.value;
inputs.add(utx.keyImage);
}
}
if (inputs.isEmpty) {
throw MoneroTransactionNoInputsException();
}
if (hasMultiDestination) { if (hasMultiDestination) {
if (outputs.any((item) => item.sendAll if (outputs.any((item) => item.sendAll
|| (item.formattedCryptoAmount ?? 0) <= 0)) { || (item.formattedCryptoAmount ?? 0) <= 0)) {
@ -208,7 +230,8 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
await transaction_history.createTransactionMultDest( await transaction_history.createTransactionMultDest(
outputs: moneroOutputs, outputs: moneroOutputs,
priorityRaw: _credentials.priority.serialize(), priorityRaw: _credentials.priority.serialize(),
accountIndex: walletAddresses.account!.id); accountIndex: walletAddresses.account!.id,
preferredInputs: inputs);
} else { } else {
final output = outputs.first; final output = outputs.first;
final address = output.isParsedAddress final address = output.isParsedAddress
@ -229,12 +252,12 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
'You do not have enough unlocked balance. Unlocked: $formattedBalance. Transaction amount: ${output.cryptoAmount}.'); 'You do not have enough unlocked balance. Unlocked: $formattedBalance. Transaction amount: ${output.cryptoAmount}.');
} }
pendingTransactionDescription = pendingTransactionDescription = await transaction_history.createTransaction(
await transaction_history.createTransaction(
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);
} }
return PendingMoneroTransaction(pendingTransactionDescription); return PendingMoneroTransaction(pendingTransactionDescription);
@ -354,6 +377,85 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
await walletInfo.save(); await walletInfo.save();
} }
Future<void> updateUnspent() async {
refreshCoins(walletAddresses.account!.id);
unspentCoins.clear();
final coinCount = countOfCoins();
for (var i = 0; i < coinCount; i++) {
final coin = getCoin(i);
if (coin.spent == 0) {
unspentCoins.add(MoneroUnspent.fromCoinsInfoRow(coin));
}
}
if (unspentCoinsInfo.isEmpty) {
unspentCoins.forEach((coin) => _addCoinInfo(coin));
return;
}
if (unspentCoins.isNotEmpty) {
unspentCoins.forEach((coin) {
final coinInfoList = unspentCoinsInfo.values.where((element) =>
element.walletId.contains(id) && element.hash.contains(coin.hash));
if (coinInfoList.isNotEmpty) {
final coinInfo = coinInfoList.first;
coin.isFrozen = coinInfo.isFrozen;
coin.isSending = coinInfo.isSending;
coin.note = coinInfo.note;
} else {
_addCoinInfo(coin);
}
});
}
await _refreshUnspentCoinsInfo();
_askForUpdateBalance();
}
Future<void> _addCoinInfo(MoneroUnspent coin) async {
final newInfo = UnspentCoinsInfo(
walletId: id,
hash: coin.hash,
isFrozen: coin.isFrozen,
isSending: coin.isSending,
noteRaw: coin.note,
address: coin.address,
value: coin.value,
vout: 0,
keyImage: coin.keyImage
);
await unspentCoinsInfo.add(newInfo);
}
Future<void> _refreshUnspentCoinsInfo() async {
try {
final List<dynamic> keys = <dynamic>[];
final currentWalletUnspentCoins = unspentCoinsInfo.values
.where((element) => element.walletId.contains(id));
if (currentWalletUnspentCoins.isNotEmpty) {
currentWalletUnspentCoins.forEach((element) {
final existUnspentCoins = unspentCoins.where((coin) => element.hash.contains(coin.hash));
if (existUnspentCoins.isEmpty) {
keys.add(element.key);
}
});
}
if (keys.isNotEmpty) {
await unspentCoinsInfo.deleteAll(keys);
}
} catch (e) {
print(e.toString());
}
}
String getTransactionAddress(int accountIndex, int addressIndex) => String getTransactionAddress(int accountIndex, int addressIndex) =>
monero_wallet.getAddress( monero_wallet.getAddress(
accountIndex: accountIndex, accountIndex: accountIndex,
@ -361,7 +463,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
@override @override
Future<Map<String, MoneroTransactionInfo>> fetchTransactions() async { Future<Map<String, MoneroTransactionInfo>> fetchTransactions() async {
monero_transaction_history.refreshTransactions(); transaction_history.refreshTransactions();
return _getAllTransactions(null).fold<Map<String, MoneroTransactionInfo>>( return _getAllTransactions(null).fold<Map<String, MoneroTransactionInfo>>(
<String, MoneroTransactionInfo>{}, <String, MoneroTransactionInfo>{},
(Map<String, MoneroTransactionInfo> acc, MoneroTransactionInfo tx) { (Map<String, MoneroTransactionInfo> acc, MoneroTransactionInfo tx) {
@ -392,7 +494,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
} }
List<MoneroTransactionInfo> _getAllTransactions(dynamic _) => List<MoneroTransactionInfo> _getAllTransactions(dynamic _) =>
monero_transaction_history transaction_history
.getAllTransations() .getAllTransations()
.map((row) => MoneroTransactionInfo.fromRow(row)) .map((row) => MoneroTransactionInfo.fromRow(row))
.toList(); .toList();
@ -407,7 +509,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
return; return;
} }
final currentHeight = getCurrentHeight(); final currentHeight = monero_wallet.getCurrentHeight();
if (currentHeight <= 1) { if (currentHeight <= 1) {
final height = _getHeightByDate(walletInfo.date); final height = _getHeightByDate(walletInfo.date);
@ -439,11 +541,13 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
void _askForUpdateBalance() { void _askForUpdateBalance() {
final unlockedBalance = _getUnlockedBalance(); final unlockedBalance = _getUnlockedBalance();
final fullBalance = _getFullBalance(); final fullBalance = _getFullBalance();
final frozenBalance = _getFrozenBalance();
if (balance[currency]!.fullBalance != fullBalance || if (balance[currency]!.fullBalance != fullBalance ||
balance[currency]!.unlockedBalance != unlockedBalance) { balance[currency]!.unlockedBalance != unlockedBalance ||
balance[currency]!.frozenBalance != frozenBalance) {
balance[currency] = MoneroBalance( balance[currency] = MoneroBalance(
fullBalance: fullBalance, unlockedBalance: unlockedBalance); fullBalance: fullBalance, unlockedBalance: unlockedBalance, frozenBalance: frozenBalance);
} }
} }
@ -456,6 +560,17 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
int _getUnlockedBalance() => int _getUnlockedBalance() =>
monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account!.id); monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account!.id);
int _getFrozenBalance() {
var frozenBalance = 0;
for (var coin in unspentCoinsInfo.values) {
if (coin.isFrozen)
frozenBalance += coin.value;
}
return frozenBalance;
}
void _onNewBlock(int height, int blocksLeft, double ptc) async { void _onNewBlock(int height, int blocksLeft, double ptc) async {
try { try {
if (walletInfo.isRecovery) { if (walletInfo.isRecovery) {

View file

@ -1,16 +1,16 @@
import 'dart:io'; import 'dart:io';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/monero_wallet_utils.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';
import 'package:cw_core/wallet_service.dart';
import 'package:cw_core/pathForWallet.dart'; import 'package:cw_core/pathForWallet.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_service.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
import 'package:cw_monero/api/exceptions/wallet_opening_exception.dart';
import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager;
import 'package:cw_monero/monero_wallet.dart';
import 'package:hive/hive.dart';
class MoneroNewWalletCredentials extends WalletCredentials { class MoneroNewWalletCredentials extends WalletCredentials {
MoneroNewWalletCredentials({required String name, required this.language, String? password}) MoneroNewWalletCredentials({required String name, required this.language, String? password})
@ -53,9 +53,10 @@ class MoneroWalletService extends WalletService<
MoneroNewWalletCredentials, MoneroNewWalletCredentials,
MoneroRestoreWalletFromSeedCredentials, MoneroRestoreWalletFromSeedCredentials,
MoneroRestoreWalletFromKeysCredentials> { MoneroRestoreWalletFromKeysCredentials> {
MoneroWalletService(this.walletInfoSource); MoneroWalletService(this.walletInfoSource, this.unspentCoinsInfoSource);
final Box<WalletInfo> walletInfoSource; final Box<WalletInfo> walletInfoSource;
final Box<UnspentCoinsInfo> unspentCoinsInfoSource;
static bool walletFilesExist(String path) => static bool walletFilesExist(String path) =>
!File(path).existsSync() && !File('$path.keys').existsSync(); !File(path).existsSync() && !File('$path.keys').existsSync();
@ -71,7 +72,8 @@ class MoneroWalletService extends WalletService<
path: path, path: path,
password: credentials.password!, password: credentials.password!,
language: credentials.language); language: credentials.language);
final wallet = MoneroWallet(walletInfo: credentials.walletInfo!); final wallet = MoneroWallet(
walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource);
await wallet.init(); await wallet.init();
return wallet; return wallet;
@ -107,7 +109,7 @@ class MoneroWalletService extends WalletService<
.openWalletAsync({'path': path, 'password': password}); .openWalletAsync({'path': path, 'password': password});
final walletInfo = walletInfoSource.values.firstWhere( final walletInfo = walletInfoSource.values.firstWhere(
(info) => info.id == WalletBase.idFor(name, getType())); (info) => info.id == WalletBase.idFor(name, getType()));
final wallet = MoneroWallet(walletInfo: walletInfo); final wallet = MoneroWallet(walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfoSource);
final isValid = wallet.walletAddresses.validate(); final isValid = wallet.walletAddresses.validate();
if (!isValid) { if (!isValid) {
@ -157,7 +159,8 @@ class MoneroWalletService extends WalletService<
String currentName, String password, String newName) async { String currentName, String password, String newName) async {
final currentWalletInfo = walletInfoSource.values.firstWhere( final currentWalletInfo = walletInfoSource.values.firstWhere(
(info) => info.id == WalletBase.idFor(currentName, getType())); (info) => info.id == WalletBase.idFor(currentName, getType()));
final currentWallet = MoneroWallet(walletInfo: currentWalletInfo); final currentWallet =
MoneroWallet(walletInfo: currentWalletInfo, unspentCoinsInfo: unspentCoinsInfoSource);
await currentWallet.renameWalletFiles(newName); await currentWallet.renameWalletFiles(newName);
@ -181,7 +184,8 @@ class MoneroWalletService extends WalletService<
address: credentials.address, address: credentials.address,
viewKey: credentials.viewKey, viewKey: credentials.viewKey,
spendKey: credentials.spendKey); spendKey: credentials.spendKey);
final wallet = MoneroWallet(walletInfo: credentials.walletInfo!); final wallet = MoneroWallet(
walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource);
await wallet.init(); await wallet.init();
return wallet; return wallet;
@ -202,7 +206,8 @@ class MoneroWalletService extends WalletService<
password: credentials.password!, password: credentials.password!,
seed: credentials.mnemonic, seed: credentials.mnemonic,
restoreHeight: credentials.height!); restoreHeight: credentials.height!);
final wallet = MoneroWallet(walletInfo: credentials.walletInfo!); final wallet = MoneroWallet(
walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource);
await wallet.init(); await wallet.init();
return wallet; return wallet;

View file

@ -672,5 +672,5 @@ packages:
source: hosted source: hosted
version: "3.1.1" version: "3.1.1"
sdks: sdks:
dart: ">=2.19.0 <4.0.0" dart: ">=2.19.0 <3.0.0"
flutter: ">=3.0.0" flutter: ">=3.0.0"

View file

@ -13,11 +13,11 @@ dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
ffi: ^2.0.1 ffi: ^2.0.1
http: ^0.13.4 http: ^1.1.0
path_provider: ^2.0.11 path_provider: ^2.0.11
mobx: ^2.0.7+4 mobx: ^2.0.7+4
flutter_mobx: ^2.0.6+1 flutter_mobx: ^2.0.6+1
intl: ^0.17.0 intl: ^0.18.0
encrypt: ^5.0.1 encrypt: ^5.0.1
cw_core: cw_core:
path: ../cw_core path: ../cw_core

View file

@ -5,7 +5,7 @@ author: Cake Walelt
homepage: https://cakewallet.com homepage: https://cakewallet.com
environment: environment:
sdk: ">=2.7.0 <3.0.0" sdk: ">=2.12.0 <3.0.0"
flutter: ">=1.20.0" flutter: ">=1.20.0"
dependencies: dependencies:

View file

@ -5,10 +5,10 @@
The following are the system requirements to build CakeWallet for your Android device. The following are the system requirements to build CakeWallet for your Android device.
``` ```
Ubuntu >= 16.04 Ubuntu >= 20.04
Android SDK 29 or higher (better to have the latest one 33) Android SDK 29 or higher (better to have the latest one 33)
Android NDK 17c Android NDK 17c
Flutter 3.7.x Flutter 3.10.x or earlier
``` ```
## Building CakeWallet on Android ## Building CakeWallet on Android
@ -66,7 +66,7 @@ Verify that the Android toolchain, Flutter, and Android Studio have been correct
The output of this command will appear like this, indicating successful installations. If there are problems with your installation, they **must** be corrected before proceeding. The output of this command will appear like this, indicating successful installations. If there are problems with your installation, they **must** be corrected before proceeding.
``` ```
Doctor summary (to see all details, run flutter doctor -v): Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.7.x, on Linux, locale en_US.UTF-8) [✓] Flutter (Channel stable, 3.10.x, on Linux, locale en_US.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 29 or higher) [✓] Android toolchain - develop for Android devices (Android SDK version 29 or higher)
[✓] Android Studio (version 4.0 or higher) [✓] Android Studio (version 4.0 or higher)
``` ```

View file

@ -174,12 +174,12 @@ DEPENDENCIES:
- in_app_review (from `.symlinks/plugins/in_app_review/ios`) - in_app_review (from `.symlinks/plugins/in_app_review/ios`)
- local_auth_ios (from `.symlinks/plugins/local_auth_ios/ios`) - local_auth_ios (from `.symlinks/plugins/local_auth_ios/ios`)
- package_info (from `.symlinks/plugins/package_info/ios`) - package_info (from `.symlinks/plugins/package_info/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- platform_device_id (from `.symlinks/plugins/platform_device_id/ios`) - platform_device_id (from `.symlinks/plugins/platform_device_id/ios`)
- sensitive_clipboard (from `.symlinks/plugins/sensitive_clipboard/ios`) - sensitive_clipboard (from `.symlinks/plugins/sensitive_clipboard/ios`)
- share_plus (from `.symlinks/plugins/share_plus/ios`) - share_plus (from `.symlinks/plugins/share_plus/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- uni_links (from `.symlinks/plugins/uni_links/ios`) - uni_links (from `.symlinks/plugins/uni_links/ios`)
- UnstoppableDomainsResolution (~> 4.0.0) - UnstoppableDomainsResolution (~> 4.0.0)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
@ -236,7 +236,7 @@ EXTERNAL SOURCES:
package_info: package_info:
:path: ".symlinks/plugins/package_info/ios" :path: ".symlinks/plugins/package_info/ios"
path_provider_foundation: path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/ios" :path: ".symlinks/plugins/path_provider_foundation/darwin"
permission_handler_apple: permission_handler_apple:
:path: ".symlinks/plugins/permission_handler_apple/ios" :path: ".symlinks/plugins/permission_handler_apple/ios"
platform_device_id: platform_device_id:
@ -246,7 +246,7 @@ EXTERNAL SOURCES:
share_plus: share_plus:
:path: ".symlinks/plugins/share_plus/ios" :path: ".symlinks/plugins/share_plus/ios"
shared_preferences_foundation: shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/ios" :path: ".symlinks/plugins/shared_preferences_foundation/darwin"
uni_links: uni_links:
:path: ".symlinks/plugins/uni_links/ios" :path: ".symlinks/plugins/uni_links/ios"
url_launcher_ios: url_launcher_ios:

View file

@ -182,6 +182,8 @@ class AnonPayApi {
switch (currency) { switch (currency) {
case CryptoCurrency.usdt: case CryptoCurrency.usdt:
return CryptoCurrency.btc.title.toLowerCase(); return CryptoCurrency.btc.title.toLowerCase();
case CryptoCurrency.eth:
return 'ERC20';
default: default:
return currency.tag != null ? _normalizeTag(currency.tag!) : 'Mainnet'; return currency.tag != null ? _normalizeTag(currency.tag!) : 'Mainnet';
} }

View file

@ -137,7 +137,8 @@ class CWBitcoin extends Bitcoin {
bitcoinUnspent.address, bitcoinUnspent.address,
bitcoinUnspent.hash, bitcoinUnspent.hash,
bitcoinUnspent.value, bitcoinUnspent.value,
bitcoinUnspent.vout)) bitcoinUnspent.vout,
null))
.toList(); .toList();
} }
@ -169,4 +170,4 @@ class CWBitcoin extends Bitcoin {
@override @override
TransactionPriority getLitecoinTransactionPrioritySlow() TransactionPriority getLitecoinTransactionPrioritySlow()
=> LitecoinTransactionPriority.slow; => LitecoinTransactionPriority.slow;
} }

View file

@ -1,8 +1,10 @@
import 'package:cake_wallet/.secrets.g.dart' as secrets; import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/themes/theme_base.dart'; import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
import 'package:flutter/material.dart';
class OnRamperBuyProvider { class OnRamperBuyProvider {
OnRamperBuyProvider({required SettingsStore settingsStore, required WalletBase wallet}) OnRamperBuyProvider({required SettingsStore settingsStore, required WalletBase wallet})
@ -27,7 +29,11 @@ class OnRamperBuyProvider {
} }
} }
Uri requestUrl() { String getColorStr(Color color) {
return color.value.toRadixString(16).replaceAll(RegExp(r'^ff'), "");
}
Uri requestUrl(BuildContext context) {
String primaryColor, String primaryColor,
secondaryColor, secondaryColor,
primaryTextColor, primaryTextColor,
@ -35,31 +41,16 @@ class OnRamperBuyProvider {
containerColor, containerColor,
cardColor; cardColor;
switch (_settingsStore.currentTheme.type) { primaryColor = getColorStr(Theme.of(context).primaryColor);
case ThemeType.bright: secondaryColor = getColorStr(Theme.of(context).colorScheme.background);
primaryColor = '815dfbff'; primaryTextColor = getColorStr(Theme.of(context).extension<CakeTextTheme>()!.titleColor);
secondaryColor = 'ffffff'; secondaryTextColor =
primaryTextColor = '141519'; getColorStr(Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor);
secondaryTextColor = '6b6f80'; containerColor = getColorStr(Theme.of(context).colorScheme.background);
containerColor = 'ffffff'; cardColor = getColorStr(Theme.of(context).cardColor);
cardColor = 'f2f0faff';
break; if (_settingsStore.currentTheme.title == S.current.high_contrast_theme) {
case ThemeType.light: cardColor = getColorStr(Colors.white);
primaryColor = '2194ffff';
secondaryColor = 'ffffff';
primaryTextColor = '141519';
secondaryTextColor = '6b6f80';
containerColor = 'ffffff';
cardColor = 'e5f7ff';
break;
case ThemeType.dark:
primaryColor = '456effff';
secondaryColor = '1b2747ff';
primaryTextColor = 'ffffff';
secondaryTextColor = 'ffffff';
containerColor = '19233C';
cardColor = '232f4fff';
break;
} }
final networkName = _wallet.currency.fullName?.toUpperCase().replaceAll(" ", ""); final networkName = _wallet.currency.fullName?.toUpperCase().replaceAll(" ", "");

View file

@ -1,4 +1,3 @@
import 'package:uuid/uuid.dart';
import 'package:cw_core/key.dart'; import 'package:cw_core/key.dart';
String generateWalletPassword() { String generateWalletPassword() {

View file

@ -178,8 +178,6 @@ import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:cake_wallet/view_model/wallet_restoration_from_seed_vm.dart';
import 'package:cake_wallet/view_model/wallet_restoration_from_keys_vm.dart';
import 'package:cake_wallet/core/wallet_creation_service.dart'; import 'package:cake_wallet/core/wallet_creation_service.dart';
import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/store/app_store.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
@ -219,10 +217,10 @@ late Box<Template> _templates;
late Box<ExchangeTemplate> _exchangeTemplates; late Box<ExchangeTemplate> _exchangeTemplates;
late Box<TransactionDescription> _transactionDescriptionBox; late Box<TransactionDescription> _transactionDescriptionBox;
late Box<Order> _ordersSource; late Box<Order> _ordersSource;
late Box<UnspentCoinsInfo>? _unspentCoinsInfoSource; late Box<UnspentCoinsInfo> _unspentCoinsInfoSource;
late Box<AnonpayInvoiceInfo> _anonpayInvoiceInfoSource; late Box<AnonpayInvoiceInfo> _anonpayInvoiceInfoSource;
Future setup({ Future<void> setup({
required Box<WalletInfo> walletInfoSource, required Box<WalletInfo> walletInfoSource,
required Box<Node> nodeSource, required Box<Node> nodeSource,
required Box<Contact> contactSource, required Box<Contact> contactSource,
@ -231,7 +229,7 @@ Future setup({
required Box<ExchangeTemplate> exchangeTemplates, required Box<ExchangeTemplate> exchangeTemplates,
required Box<TransactionDescription> transactionDescriptionBox, required Box<TransactionDescription> transactionDescriptionBox,
required Box<Order> ordersSource, required Box<Order> ordersSource,
Box<UnspentCoinsInfo>? unspentCoinsInfoSource, required Box<UnspentCoinsInfo> unspentCoinsInfoSource,
required Box<AnonpayInvoiceInfo> anonpayInvoiceInfoSource, required Box<AnonpayInvoiceInfo> anonpayInvoiceInfoSource,
}) async { }) async {
_walletInfoSource = walletInfoSource; _walletInfoSource = walletInfoSource;
@ -321,25 +319,6 @@ Future setup({
getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type), _walletInfoSource, getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
type: type)); type: type));
getIt.registerFactoryParam<WalletRestorationFromSeedVM, List, void>((args, _) {
final type = args.first as WalletType;
final language = args[1] as String;
final mnemonic = args[2] as String;
return WalletRestorationFromSeedVM(
getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
type: type, language: language, seed: mnemonic);
});
getIt.registerFactoryParam<WalletRestorationFromKeysVM, List, void>((args, _) {
final type = args.first as WalletType;
final language = args[1] as String;
return WalletRestorationFromKeysVM(
getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
type: type, language: language);
});
getIt.registerFactoryParam<WalletRestorationFromQRVM, WalletType, void>((WalletType type, _) { getIt.registerFactoryParam<WalletRestorationFromQRVM, WalletType, void>((WalletType type, _) {
return WalletRestorationFromQRVM(getIt.get<AppStore>(), return WalletRestorationFromQRVM(getIt.get<AppStore>(),
getIt.get<WalletCreationService>(param1: type), _walletInfoSource, type); getIt.get<WalletCreationService>(param1: type), _walletInfoSource, type);
@ -753,11 +732,11 @@ Future setup({
case WalletType.haven: case WalletType.haven:
return haven!.createHavenWalletService(_walletInfoSource); return haven!.createHavenWalletService(_walletInfoSource);
case WalletType.monero: case WalletType.monero:
return monero!.createMoneroWalletService(_walletInfoSource); return monero!.createMoneroWalletService(_walletInfoSource, _unspentCoinsInfoSource);
case WalletType.bitcoin: case WalletType.bitcoin:
return bitcoin!.createBitcoinWalletService(_walletInfoSource, _unspentCoinsInfoSource!); return bitcoin!.createBitcoinWalletService(_walletInfoSource, _unspentCoinsInfoSource);
case WalletType.litecoin: case WalletType.litecoin:
return bitcoin!.createLitecoinWalletService(_walletInfoSource, _unspentCoinsInfoSource!); return bitcoin!.createLitecoinWalletService(_walletInfoSource, _unspentCoinsInfoSource);
case WalletType.ethereum: case WalletType.ethereum:
return ethereum!.createEthereumWalletService(_walletInfoSource); return ethereum!.createEthereumWalletService(_walletInfoSource);
case WalletType.bitcoinCash: case WalletType.bitcoinCash:

View file

@ -50,7 +50,7 @@ class MainActions {
case WalletType.monero: case WalletType.monero:
case WalletType.bitcoinCash: case WalletType.bitcoinCash:
if (viewModel.isEnabledBuyAction) { if (viewModel.isEnabledBuyAction) {
final uri = getIt.get<OnRamperBuyProvider>().requestUrl(); final uri = getIt.get<OnRamperBuyProvider>().requestUrl(context);
if (DeviceInfo.instance.isMobile) { if (DeviceInfo.instance.isMobile) {
Navigator.of(context) Navigator.of(context)
.pushNamed(Routes.webViewPage, arguments: [S.of(context).buy, uri]); .pushNamed(Routes.webViewPage, arguments: [S.of(context).buy, uri]);

View file

@ -0,0 +1,18 @@
class Unspent {
Unspent(this.address, this.hash, this.value, this.vout, this.keyImage)
: isSending = true,
isFrozen = false,
note = '';
final String address;
final String hash;
final int value;
final int vout;
final String? keyImage;
bool isSending;
bool isFrozen;
String note;
bool get isP2wpkh => address.startsWith('bc') || address.startsWith('ltc');
}

View file

@ -22,6 +22,14 @@ class CWEthereum extends Ethereum {
}) => }) =>
EthereumRestoreWalletFromSeedCredentials(name: name, password: password, mnemonic: mnemonic); EthereumRestoreWalletFromSeedCredentials(name: name, password: password, mnemonic: mnemonic);
@override
WalletCredentials createEthereumRestoreWalletFromPrivateKey({
required String name,
required String privateKey,
required String password,
}) =>
EthereumRestoreWalletFromPrivateKey(name: name, password: password, privateKey: privateKey);
@override @override
String getAddress(WalletBase wallet) => (wallet as EthereumWallet).walletAddresses.address; String getAddress(WalletBase wallet) => (wallet as EthereumWallet).walletAddresses.address;

View file

@ -68,14 +68,12 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
required CryptoCurrency to, required CryptoCurrency to,
required bool isFixedRateMode}) async { required bool isFixedRateMode}) async {
final headers = {apiHeaderKey: apiKey}; final headers = {apiHeaderKey: apiKey};
final normalizedFrom = normalizeCryptoCurrency(from);
final normalizedTo = normalizeCryptoCurrency(to);
final flow = getFlow(isFixedRateMode); final flow = getFlow(isFixedRateMode);
final params = <String, String>{ final params = <String, String>{
'fromCurrency': normalizedFrom, 'fromCurrency': _normalizeCurrency(from),
'toCurrency': normalizedTo, 'toCurrency': _normalizeCurrency(to),
'fromNetwork': networkFor(from), 'fromNetwork': _networkFor(from),
'toNetwork': networkFor(to), 'toNetwork': _networkFor(to),
'flow': flow 'flow': flow
}; };
final uri = Uri.https(apiAuthority, rangePath, params); final uri = Uri.https(apiAuthority, rangePath, params);
@ -112,10 +110,10 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
final flow = getFlow(isFixedRateMode); final flow = getFlow(isFixedRateMode);
final type = isFixedRateMode ? 'reverse' : 'direct'; final type = isFixedRateMode ? 'reverse' : 'direct';
final body = <String, dynamic>{ final body = <String, dynamic>{
'fromCurrency': normalizeCryptoCurrency(_request.from), 'fromCurrency': _normalizeCurrency(_request.from),
'toCurrency': normalizeCryptoCurrency(_request.to), 'toCurrency': _normalizeCurrency(_request.to),
'fromNetwork': networkFor(_request.from), 'fromNetwork': _networkFor(_request.from),
'toNetwork': networkFor(_request.to), 'toNetwork': _networkFor(_request.to),
if (!isFixedRateMode) 'fromAmount': _request.fromAmount, if (!isFixedRateMode) 'fromAmount': _request.fromAmount,
if (isFixedRateMode) 'toAmount': _request.toAmount, if (isFixedRateMode) 'toAmount': _request.toAmount,
'address': _request.address, 'address': _request.address,
@ -241,10 +239,10 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
final type = isReverse ? 'reverse' : 'direct'; final type = isReverse ? 'reverse' : 'direct';
final flow = getFlow(isFixedRateMode); final flow = getFlow(isFixedRateMode);
final params = <String, String>{ final params = <String, String>{
'fromCurrency': normalizeCryptoCurrency(from), 'fromCurrency': _normalizeCurrency(from),
'toCurrency': normalizeCryptoCurrency(to), 'toCurrency': _normalizeCurrency(to),
'fromNetwork': networkFor(from), 'fromNetwork': _networkFor(from),
'toNetwork': networkFor(to), 'toNetwork': _networkFor(to),
'type': type, 'type': type,
'flow': flow 'flow': flow
}; };
@ -273,25 +271,34 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
} }
} }
String networkFor(CryptoCurrency currency) { String _networkFor(CryptoCurrency currency) {
switch (currency) { switch (currency) {
case CryptoCurrency.usdt: case CryptoCurrency.usdt:
return CryptoCurrency.btc.title.toLowerCase(); return 'btc';
default: default:
return currency.tag != null ? currency.tag!.toLowerCase() : currency.title.toLowerCase(); return currency.tag != null ? _normalizeTag(currency.tag!) : currency.title.toLowerCase();
} }
} }
}
String normalizeCryptoCurrency(CryptoCurrency currency) { String _normalizeCurrency(CryptoCurrency currency) {
switch (currency) { switch (currency) {
case CryptoCurrency.zec: case CryptoCurrency.zec:
return 'zec'; return 'zec';
case CryptoCurrency.usdcpoly: default:
return 'usdcmatic'; return currency.title.toLowerCase();
case CryptoCurrency.maticpoly: }
return 'maticmainnet';
default:
return currency.title.toLowerCase();
} }
}
String _normalizeTag(String tag) {
switch (tag) {
case 'POLY':
return 'matic';
case 'LN':
return 'lightning';
case 'AVAXC':
return 'cchain';
default:
return tag.toLowerCase();
}
}
}

View file

@ -28,7 +28,6 @@ class SideShiftExchangeProvider extends ExchangeProvider {
CryptoCurrency.xhv, CryptoCurrency.xhv,
CryptoCurrency.dcr, CryptoCurrency.dcr,
CryptoCurrency.kmd, CryptoCurrency.kmd,
CryptoCurrency.mkr,
CryptoCurrency.oxt, CryptoCurrency.oxt,
CryptoCurrency.pivx, CryptoCurrency.pivx,
CryptoCurrency.rune, CryptoCurrency.rune,

View file

@ -20,7 +20,6 @@ class TrocadorExchangeProvider extends ExchangeProvider {
bool useTorOnly; bool useTorOnly;
static const List<CryptoCurrency> _notSupported = [ static const List<CryptoCurrency> _notSupported = [
CryptoCurrency.scrt,
CryptoCurrency.stx, CryptoCurrency.stx,
CryptoCurrency.zaddr, CryptoCurrency.zaddr,
]; ];
@ -60,8 +59,8 @@ class TrocadorExchangeProvider extends ExchangeProvider {
}) async { }) async {
final params = <String, String>{ final params = <String, String>{
'api_key': apiKey, 'api_key': apiKey,
'ticker_from': request.from.title.toLowerCase(), 'ticker_from': _normalizeCurrency(request.from),
'ticker_to': request.to.title.toLowerCase(), 'ticker_to': _normalizeCurrency(request.to),
'network_from': _networkFor(request.from), 'network_from': _networkFor(request.from),
'network_to': _networkFor(request.to), 'network_to': _networkFor(request.to),
'payment': isFixedRateMode ? 'True' : 'False', 'payment': isFixedRateMode ? 'True' : 'False',
@ -137,7 +136,7 @@ class TrocadorExchangeProvider extends ExchangeProvider {
required bool isFixedRateMode}) async { required bool isFixedRateMode}) async {
final params = <String, String>{ final params = <String, String>{
'api_key': apiKey, 'api_key': apiKey,
'ticker': from.title.toLowerCase(), 'ticker': _normalizeCurrency(from),
'name': from.name, 'name': from.name,
}; };
@ -177,8 +176,8 @@ class TrocadorExchangeProvider extends ExchangeProvider {
final params = <String, String>{ final params = <String, String>{
'api_key': apiKey, 'api_key': apiKey,
'ticker_from': from.title.toLowerCase(), 'ticker_from': _normalizeCurrency(from),
'ticker_to': to.title.toLowerCase(), 'ticker_to': _normalizeCurrency(to),
'network_from': _networkFor(from), 'network_from': _networkFor(from),
'network_to': _networkFor(to), 'network_to': _networkFor(to),
if (!isFixedRateMode) 'amount_from': amount.toString(), if (!isFixedRateMode) 'amount_from': amount.toString(),
@ -279,6 +278,15 @@ class TrocadorExchangeProvider extends ExchangeProvider {
} }
} }
String _normalizeCurrency(CryptoCurrency currency) {
switch (currency) {
case CryptoCurrency.zec:
return 'zec';
default:
return currency.title.toLowerCase();
}
}
String _normalizeTag(String tag) { String _normalizeTag(String tag) {
switch (tag) { switch (tag) {
case 'ETH': case 'ETH':

View file

@ -736,6 +736,21 @@ class HaMaterialLocalizations extends GlobalMaterialLocalizations {
@override @override
String get keyboardKeySpace => 'Space'; String get keyboardKeySpace => 'Space';
@override
String get bottomSheetLabel => "Bottom Sheet";
@override
String get currentDateLabel => "Current Date";
@override
String get keyboardKeyShift => "Shift";
@override
String get scrimLabel => "Scrim";
@override
String get scrimOnTapHintRaw => "Scrip on Tap";
} }
/// Cupertino Support /// Cupertino Support
@ -937,4 +952,7 @@ class HaCupertinoLocalizations extends GlobalCupertinoLocalizations {
static const LocalizationsDelegate<CupertinoLocalizations> delegate = static const LocalizationsDelegate<CupertinoLocalizations> delegate =
_HaCupertinoLocalizationsDelegate(); _HaCupertinoLocalizationsDelegate();
@override
String get noSpellCheckReplacementsLabel => "";
} }

View file

@ -736,6 +736,21 @@ String get keyboardKeyMetaWindows => 'Windows';
@override @override
String get keyboardKeySpace => 'Space'; String get keyboardKeySpace => 'Space';
@override
String get bottomSheetLabel => "Bottom Sheet";
@override
String get currentDateLabel => "Current Date";
@override
String get keyboardKeyShift => "Shift";
@override
String get scrimLabel => "Scrim";
@override
String get scrimOnTapHintRaw => "Scrip on Tap";
} }
/// Cupertino Support /// Cupertino Support
@ -937,4 +952,7 @@ String get todayLabel => 'Oyọ';
static const LocalizationsDelegate<CupertinoLocalizations> delegate = static const LocalizationsDelegate<CupertinoLocalizations> delegate =
_YoCupertinoLocalizationsDelegate(); _YoCupertinoLocalizationsDelegate();
@override
String get noSpellCheckReplacementsLabel => "";
} }

View file

@ -133,11 +133,7 @@ Future<void> initializeAppConfigs() async {
final templates = await CakeHive.openBox<Template>(Template.boxName); final templates = await CakeHive.openBox<Template>(Template.boxName);
final exchangeTemplates = await CakeHive.openBox<ExchangeTemplate>(ExchangeTemplate.boxName); final exchangeTemplates = await CakeHive.openBox<ExchangeTemplate>(ExchangeTemplate.boxName);
final anonpayInvoiceInfo = await CakeHive.openBox<AnonpayInvoiceInfo>(AnonpayInvoiceInfo.boxName); final anonpayInvoiceInfo = await CakeHive.openBox<AnonpayInvoiceInfo>(AnonpayInvoiceInfo.boxName);
Box<UnspentCoinsInfo>? unspentCoinsInfoSource; final unspentCoinsInfoSource = await CakeHive.openBox<UnspentCoinsInfo>(UnspentCoinsInfo.boxName);
if (!isMoneroOnly) {
unspentCoinsInfoSource = await CakeHive.openBox<UnspentCoinsInfo>(UnspentCoinsInfo.boxName);
}
await initialSetup( await initialSetup(
sharedPreferences: await SharedPreferences.getInstance(), sharedPreferences: await SharedPreferences.getInstance(),
@ -169,7 +165,7 @@ Future<void> initialSetup(
required Box<TransactionDescription> transactionDescriptions, required Box<TransactionDescription> transactionDescriptions,
required FlutterSecureStorage secureStorage, required FlutterSecureStorage secureStorage,
required Box<AnonpayInvoiceInfo> anonpayInvoiceInfo, required Box<AnonpayInvoiceInfo> anonpayInvoiceInfo,
Box<UnspentCoinsInfo>? unspentCoinsInfoSource, required Box<UnspentCoinsInfo> unspentCoinsInfoSource,
int initialMigrationVersion = 15}) async { int initialMigrationVersion = 15}) async {
LanguageService.loadLocaleList(); LanguageService.loadLocaleList();
await defaultSettingsMigration( await defaultSettingsMigration(

View file

@ -1,361 +1,363 @@
part of 'monero.dart'; part of 'monero.dart';
class CWMoneroAccountList extends MoneroAccountList { class CWMoneroAccountList extends MoneroAccountList {
CWMoneroAccountList(this._wallet); CWMoneroAccountList(this._wallet);
final Object _wallet;
@override final Object _wallet;
@computed
@override
@computed
ObservableList<Account> get accounts { ObservableList<Account> get accounts {
final moneroWallet = _wallet as MoneroWallet; final moneroWallet = _wallet as MoneroWallet;
final accounts = moneroWallet.walletAddresses.accountList final accounts = moneroWallet.walletAddresses.accountList.accounts
.accounts .map((acc) => Account(id: acc.id, label: acc.label, balance: acc.balance))
.map((acc) => Account(id: acc.id, label: acc.label, balance: acc.balance)) .toList();
.toList(); return ObservableList<Account>.of(accounts);
return ObservableList<Account>.of(accounts);
} }
@override @override
void update(Object wallet) { void update(Object wallet) {
final moneroWallet = wallet as MoneroWallet; final moneroWallet = wallet as MoneroWallet;
moneroWallet.walletAddresses.accountList.update(); moneroWallet.walletAddresses.accountList.update();
} }
@override @override
void refresh(Object wallet) { void refresh(Object wallet) {
final moneroWallet = wallet as MoneroWallet; final moneroWallet = wallet as MoneroWallet;
moneroWallet.walletAddresses.accountList.refresh(); moneroWallet.walletAddresses.accountList.refresh();
} }
@override @override
List<Account> getAll(Object wallet) { List<Account> getAll(Object wallet) {
final moneroWallet = wallet as MoneroWallet; final moneroWallet = wallet as MoneroWallet;
return moneroWallet.walletAddresses.accountList return moneroWallet.walletAddresses.accountList
.getAll() .getAll()
.map((acc) => Account(id: acc.id, label: acc.label, balance: acc.balance)) .map((acc) => Account(id: acc.id, label: acc.label, balance: acc.balance))
.toList(); .toList();
} }
@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); await moneroWallet.walletAddresses.accountList.addAccount(label: label);
} }
@override @override
Future<void> setLabelAccount(Object wallet, {required int accountIndex, required String label}) async { Future<void> setLabelAccount(Object wallet,
final moneroWallet = wallet as MoneroWallet; {required int accountIndex, required String label}) async {
await moneroWallet.walletAddresses.accountList final moneroWallet = wallet as MoneroWallet;
.setLabelAccount( await moneroWallet.walletAddresses.accountList
accountIndex: accountIndex, .setLabelAccount(accountIndex: accountIndex, label: label);
label: label);
} }
} }
class CWMoneroSubaddressList extends MoneroSubaddressList { class CWMoneroSubaddressList extends MoneroSubaddressList {
CWMoneroSubaddressList(this._wallet); CWMoneroSubaddressList(this._wallet);
final Object _wallet;
@override final Object _wallet;
@computed
@override
@computed
ObservableList<Subaddress> get subaddresses { ObservableList<Subaddress> get subaddresses {
final moneroWallet = _wallet as MoneroWallet; final moneroWallet = _wallet as MoneroWallet;
final subAddresses = moneroWallet.walletAddresses.subaddressList final subAddresses = moneroWallet.walletAddresses.subaddressList.subaddresses
.subaddresses .map((sub) => Subaddress(id: sub.id, address: sub.address, label: sub.label))
.map((sub) => Subaddress( .toList();
id: sub.id, return ObservableList<Subaddress>.of(subAddresses);
address: sub.address,
label: sub.label))
.toList();
return ObservableList<Subaddress>.of(subAddresses);
} }
@override @override
void update(Object wallet, {required int accountIndex}) { void update(Object wallet, {required int accountIndex}) {
final moneroWallet = wallet as MoneroWallet; final moneroWallet = wallet as MoneroWallet;
moneroWallet.walletAddresses.subaddressList.update(accountIndex: accountIndex); moneroWallet.walletAddresses.subaddressList.update(accountIndex: accountIndex);
} }
@override @override
void refresh(Object wallet, {required int accountIndex}) { void refresh(Object wallet, {required int accountIndex}) {
final moneroWallet = wallet as MoneroWallet; final moneroWallet = wallet as MoneroWallet;
moneroWallet.walletAddresses.subaddressList.refresh(accountIndex: accountIndex); moneroWallet.walletAddresses.subaddressList.refresh(accountIndex: accountIndex);
} }
@override @override
List<Subaddress> getAll(Object wallet) { List<Subaddress> getAll(Object wallet) {
final moneroWallet = wallet as MoneroWallet; final moneroWallet = wallet as MoneroWallet;
return moneroWallet.walletAddresses return moneroWallet.walletAddresses.subaddressList
.subaddressList .getAll()
.getAll() .map((sub) => Subaddress(id: sub.id, label: sub.label, address: sub.address))
.map((sub) => Subaddress(id: sub.id, label: sub.label, address: sub.address)) .toList();
.toList();
} }
@override @override
Future<void> addSubaddress(Object wallet, {required int accountIndex, required String label}) async { Future<void> addSubaddress(Object wallet,
final moneroWallet = wallet as MoneroWallet; {required int accountIndex, required String label}) async {
await moneroWallet.walletAddresses.subaddressList final moneroWallet = wallet as MoneroWallet;
.addSubaddress( await moneroWallet.walletAddresses.subaddressList
accountIndex: accountIndex, .addSubaddress(accountIndex: accountIndex, label: label);
label: label);
} }
@override @override
Future<void> setLabelSubaddress(Object wallet, Future<void> setLabelSubaddress(Object wallet,
{required int accountIndex, required int addressIndex, required String label}) async { {required int accountIndex, required int addressIndex, required String label}) async {
final moneroWallet = wallet as MoneroWallet; final moneroWallet = wallet as MoneroWallet;
await moneroWallet.walletAddresses.subaddressList await moneroWallet.walletAddresses.subaddressList
.setLabelSubaddress( .setLabelSubaddress(accountIndex: accountIndex, addressIndex: addressIndex, label: label);
accountIndex: accountIndex,
addressIndex: addressIndex,
label: label);
} }
} }
class CWMoneroWalletDetails extends MoneroWalletDetails { class CWMoneroWalletDetails extends MoneroWalletDetails {
CWMoneroWalletDetails(this._wallet); CWMoneroWalletDetails(this._wallet);
final Object _wallet;
@computed final Object _wallet;
@computed
@override @override
Account get account { Account get account {
final moneroWallet = _wallet as MoneroWallet; final moneroWallet = _wallet as MoneroWallet;
final acc = moneroWallet.walletAddresses.account; final acc = moneroWallet.walletAddresses.account;
return Account(id: acc!.id, label: acc.label, balance: acc.balance); return Account(id: acc!.id, label: acc.label, balance: acc.balance);
} }
@computed @computed
@override @override
MoneroBalance get balance { MoneroBalance get balance {
final moneroWallet = _wallet as MoneroWallet; final moneroWallet = _wallet as MoneroWallet;
final balance = moneroWallet.balance; final balance = moneroWallet.balance;
throw Exception('Unimplemented'); throw Exception('Unimplemented');
// return MoneroBalance(); // return MoneroBalance();
//return MoneroBalance( //return MoneroBalance(
// fullBalance: balance.fullBalance, // fullBalance: balance.fullBalance,
// unlockedBalance: balance.unlockedBalance); // unlockedBalance: balance.unlockedBalance);
} }
} }
class CWMonero extends Monero { class CWMonero extends Monero {
@override @override
MoneroAccountList getAccountList(Object wallet) { MoneroAccountList getAccountList(Object wallet) {
return CWMoneroAccountList(wallet); return CWMoneroAccountList(wallet);
} }
@override
MoneroSubaddressList getSubaddressList(Object wallet) {
return CWMoneroSubaddressList(wallet);
}
@override
TransactionHistoryBase getTransactionHistory(Object wallet) {
final moneroWallet = wallet as MoneroWallet;
return moneroWallet.transactionHistory;
}
@override
MoneroWalletDetails getMoneroWalletDetails(Object wallet) {
return CWMoneroWalletDetails(wallet);
}
@override
int getHeigthByDate({required DateTime date}) {
return getMoneroHeigthByDate(date: date);
}
@override
TransactionPriority getDefaultTransactionPriority() {
return MoneroTransactionPriority.automatic;
}
@override @override
TransactionPriority getMoneroTransactionPrioritySlow() MoneroSubaddressList getSubaddressList(Object wallet) {
=> MoneroTransactionPriority.slow; return CWMoneroSubaddressList(wallet);
}
@override @override
TransactionPriority getMoneroTransactionPriorityAutomatic() TransactionHistoryBase getTransactionHistory(Object wallet) {
=> MoneroTransactionPriority.automatic; final moneroWallet = wallet as MoneroWallet;
return moneroWallet.transactionHistory;
}
@override @override
TransactionPriority deserializeMoneroTransactionPriority({required int raw}) { MoneroWalletDetails getMoneroWalletDetails(Object wallet) {
return MoneroTransactionPriority.deserialize(raw: raw); return CWMoneroWalletDetails(wallet);
} }
@override @override
List<TransactionPriority> getTransactionPriorities() { int getHeigthByDate({required DateTime date}) {
return MoneroTransactionPriority.all; return getMoneroHeigthByDate(date: date);
} }
@override @override
List<String> getMoneroWordList(String language) { TransactionPriority getDefaultTransactionPriority() {
switch (language.toLowerCase()) { return MoneroTransactionPriority.automatic;
case 'english': }
return EnglishMnemonics.words;
case 'chinese (simplified)':
return ChineseSimplifiedMnemonics.words;
case 'dutch':
return DutchMnemonics.words;
case 'german':
return GermanMnemonics.words;
case 'japanese':
return JapaneseMnemonics.words;
case 'portuguese':
return PortugueseMnemonics.words;
case 'russian':
return RussianMnemonics.words;
case 'spanish':
return SpanishMnemonics.words;
case 'french':
return FrenchMnemonics.words;
case 'italian':
return ItalianMnemonics.words;
default:
return EnglishMnemonics.words;
}
}
@override @override
WalletCredentials createMoneroRestoreWalletFromKeysCredentials({ TransactionPriority getMoneroTransactionPrioritySlow() => MoneroTransactionPriority.slow;
required String name,
required String spendKey,
required String viewKey,
required String address,
required String password,
required String language,
required int height}) {
return MoneroRestoreWalletFromKeysCredentials(
name: name,
spendKey: spendKey,
viewKey: viewKey,
address: address,
password: password,
language: language,
height: height);
}
@override
WalletCredentials createMoneroRestoreWalletFromSeedCredentials({
required String name,
required String password,
required int height,
required String mnemonic}) {
return MoneroRestoreWalletFromSeedCredentials(
name: name,
password: password,
height: height,
mnemonic: mnemonic);
}
@override @override
WalletCredentials createMoneroNewWalletCredentials({ TransactionPriority getMoneroTransactionPriorityAutomatic() =>
MoneroTransactionPriority.automatic;
@override
TransactionPriority deserializeMoneroTransactionPriority({required int raw}) {
return MoneroTransactionPriority.deserialize(raw: raw);
}
@override
List<TransactionPriority> getTransactionPriorities() {
return MoneroTransactionPriority.all;
}
@override
List<String> getMoneroWordList(String language) {
switch (language.toLowerCase()) {
case 'english':
return EnglishMnemonics.words;
case 'chinese (simplified)':
return ChineseSimplifiedMnemonics.words;
case 'dutch':
return DutchMnemonics.words;
case 'german':
return GermanMnemonics.words;
case 'japanese':
return JapaneseMnemonics.words;
case 'portuguese':
return PortugueseMnemonics.words;
case 'russian':
return RussianMnemonics.words;
case 'spanish':
return SpanishMnemonics.words;
case 'french':
return FrenchMnemonics.words;
case 'italian':
return ItalianMnemonics.words;
default:
return EnglishMnemonics.words;
}
}
@override
WalletCredentials createMoneroRestoreWalletFromKeysCredentials(
{required String name,
required String spendKey,
required String viewKey,
required String address,
required String password,
required String language,
required int height}) {
return MoneroRestoreWalletFromKeysCredentials(
name: name,
spendKey: spendKey,
viewKey: viewKey,
address: address,
password: password,
language: language,
height: height);
}
@override
WalletCredentials createMoneroRestoreWalletFromSeedCredentials(
{required String name,
required String password,
required int height,
required String mnemonic}) {
return MoneroRestoreWalletFromSeedCredentials(
name: name, password: password, height: height, mnemonic: mnemonic);
}
@override
WalletCredentials createMoneroNewWalletCredentials({
required String name, required String name,
required String language, required String language,
String? password,}) { String? password,
return MoneroNewWalletCredentials( }) {
name: name, return MoneroNewWalletCredentials(name: name, password: password, language: language);
password: password, }
language: language);
}
@override @override
Map<String, String> getKeys(Object wallet) { Map<String, String> getKeys(Object wallet) {
final moneroWallet = wallet as MoneroWallet; final moneroWallet = wallet as MoneroWallet;
final keys = moneroWallet.keys; final keys = moneroWallet.keys;
return <String, String>{ return <String, String>{
'privateSpendKey': keys.privateSpendKey, 'privateSpendKey': keys.privateSpendKey,
'privateViewKey': keys.privateViewKey, 'privateViewKey': keys.privateViewKey,
'publicSpendKey': keys.publicSpendKey, 'publicSpendKey': keys.publicSpendKey,
'publicViewKey': keys.publicViewKey}; 'publicViewKey': keys.publicViewKey
} };
}
@override @override
Object createMoneroTransactionCreationCredentials({ Object createMoneroTransactionCreationCredentials(
required List<Output> outputs, {required List<Output> outputs, required TransactionPriority priority}) {
required TransactionPriority priority}) { return MoneroTransactionCreationCredentials(
return MoneroTransactionCreationCredentials( outputs: outputs
outputs: outputs.map((out) => OutputInfo( .map((out) => OutputInfo(
fiatAmount: out.fiatAmount, fiatAmount: out.fiatAmount,
cryptoAmount: out.cryptoAmount, cryptoAmount: out.cryptoAmount,
address: out.address, address: out.address,
note: out.note, note: out.note,
sendAll: out.sendAll, sendAll: out.sendAll,
extractedAddress: out.extractedAddress, extractedAddress: out.extractedAddress,
isParsedAddress: out.isParsedAddress, isParsedAddress: out.isParsedAddress,
formattedCryptoAmount: out.formattedCryptoAmount)) formattedCryptoAmount: out.formattedCryptoAmount))
.toList(), .toList(),
priority: priority as MoneroTransactionPriority); priority: priority as MoneroTransactionPriority);
} }
@override @override
Object createMoneroTransactionCreationCredentialsRaw({ Object createMoneroTransactionCreationCredentialsRaw(
required List<OutputInfo> outputs, {required List<OutputInfo> outputs, required TransactionPriority priority}) {
required TransactionPriority priority}) { return MoneroTransactionCreationCredentials(
return MoneroTransactionCreationCredentials( outputs: outputs, priority: priority as MoneroTransactionPriority);
outputs: outputs, }
priority: priority as MoneroTransactionPriority);
}
@override @override
String formatterMoneroAmountToString({required int amount}) { String formatterMoneroAmountToString({required int amount}) {
return moneroAmountToString(amount: amount); return moneroAmountToString(amount: amount);
} }
@override @override
double formatterMoneroAmountToDouble({required int amount}) { double formatterMoneroAmountToDouble({required int amount}) {
return moneroAmountToDouble(amount: amount); return moneroAmountToDouble(amount: amount);
} }
@override @override
int formatterMoneroParseAmount({required String amount}) { int formatterMoneroParseAmount({required String amount}) {
return moneroParseAmount(amount: amount); return moneroParseAmount(amount: amount);
} }
@override @override
Account getCurrentAccount(Object wallet) { Account getCurrentAccount(Object wallet) {
final moneroWallet = wallet as MoneroWallet; final moneroWallet = wallet as MoneroWallet;
final acc = moneroWallet.walletAddresses.account; final acc = moneroWallet.walletAddresses.account;
return Account(id: acc!.id, label: acc.label, balance: acc.balance); return Account(id: acc!.id, label: acc.label, balance: acc.balance);
} }
@override @override
void setCurrentAccount(Object wallet, int id, String label, String? balance) { void setCurrentAccount(Object wallet, int id, String label, String? balance) {
final moneroWallet = wallet as MoneroWallet; final moneroWallet = wallet as MoneroWallet;
moneroWallet.walletAddresses.account = monero_account.Account(id: id, label: label, balance: balance); moneroWallet.walletAddresses.account =
} monero_account.Account(id: id, label: label, balance: balance);
}
@override @override
void onStartup() { void onStartup() {
monero_wallet_api.onStartup(); monero_wallet_api.onStartup();
} }
@override @override
int getTransactionInfoAccountId(TransactionInfo tx) { int getTransactionInfoAccountId(TransactionInfo tx) {
final moneroTransactionInfo = tx as MoneroTransactionInfo; final moneroTransactionInfo = tx as MoneroTransactionInfo;
return moneroTransactionInfo.accountIndex; return moneroTransactionInfo.accountIndex;
} }
@override @override
WalletService createMoneroWalletService(Box<WalletInfo> walletInfoSource) { WalletService createMoneroWalletService(
return MoneroWalletService(walletInfoSource); Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource) {
} return MoneroWalletService(walletInfoSource, unspentCoinSource);
}
@override @override
String getTransactionAddress(Object wallet, int accountIndex, int addressIndex) { String getTransactionAddress(Object wallet, int accountIndex, int addressIndex) {
final moneroWallet = wallet as MoneroWallet; final moneroWallet = wallet as MoneroWallet;
return moneroWallet.getTransactionAddress(accountIndex, addressIndex); return moneroWallet.getTransactionAddress(accountIndex, addressIndex);
} }
@override @override
String getSubaddressLabel(Object wallet, int accountIndex, int addressIndex) { String getSubaddressLabel(Object wallet, int accountIndex, int addressIndex) {
final moneroWallet = wallet as MoneroWallet; final moneroWallet = wallet as MoneroWallet;
return moneroWallet.getSubaddressLabel(accountIndex, addressIndex); return moneroWallet.getSubaddressLabel(accountIndex, addressIndex);
} }
@override @override
Map<String, String> pendingTransactionInfo(Object transaction) { Map<String, String> pendingTransactionInfo(Object transaction) {
final ptx = transaction as PendingMoneroTransaction; final ptx = transaction as PendingMoneroTransaction;
return {'id': ptx.id, 'hex': ptx.hex, 'key': ptx.txKey}; return {'id': ptx.id, 'hex': ptx.hex, 'key': ptx.txKey};
} }
@override
List<Unspent> getUnspents(Object wallet) {
final moneroWallet = wallet as MoneroWallet;
return moneroWallet.unspentCoins
.map((MoneroUnspent moneroUnspent) => Unspent(moneroUnspent.address, moneroUnspent.hash,
moneroUnspent.value, 0, moneroUnspent.keyImage))
.toList();
}
@override
void updateUnspents(Object wallet) async {
final moneroWallet = wallet as MoneroWallet;
await moneroWallet.updateUnspent();
}
} }

View file

@ -15,6 +15,9 @@ class Palette {
static const Color nightBlue = Color.fromRGBO(46, 57, 96, 1.0); static const Color nightBlue = Color.fromRGBO(46, 57, 96, 1.0);
static const Color moderateOrangeYellow = Color.fromRGBO(245, 134, 82, 1.0); static const Color moderateOrangeYellow = Color.fromRGBO(245, 134, 82, 1.0);
static const Color moderateOrange = Color.fromRGBO(235, 117, 63, 1.0); static const Color moderateOrange = Color.fromRGBO(235, 117, 63, 1.0);
static const Color moneroOrange = Color.fromRGBO(255, 102, 0, 1.0);
static const Color moneroLightOrange = Color.fromRGBO(250, 240, 246, 1.0);
static const Color bitcoinOrange = Color.fromRGBO(242, 169, 0, 1.0);
static const Color shineGreen = Color.fromRGBO(76, 189, 87, 1.0); static const Color shineGreen = Color.fromRGBO(76, 189, 87, 1.0);
static const Color moderateGreen = Color.fromRGBO(45, 158, 56, 1.0); static const Color moderateGreen = Color.fromRGBO(45, 158, 56, 1.0);
static const Color cornflower = Color.fromRGBO(85, 147, 240, 1.0); static const Color cornflower = Color.fromRGBO(85, 147, 240, 1.0);
@ -48,6 +51,7 @@ class Palette {
static const Color paleCornflowerBlue = Color.fromRGBO(185, 196, 237, 1.0); static const Color paleCornflowerBlue = Color.fromRGBO(185, 196, 237, 1.0);
static const Color manatee = Color.fromRGBO(153, 161, 176, 1.0); static const Color manatee = Color.fromRGBO(153, 161, 176, 1.0);
static const Color stateGray = Color.fromRGBO(68, 74, 89, 1.0); static const Color stateGray = Color.fromRGBO(68, 74, 89, 1.0);
static const Color highContrastGray = Color.fromRGBO(76, 76, 76, 1.0);
static const Color frostySky = Color.fromRGBO(0, 184, 250, 1.0); static const Color frostySky = Color.fromRGBO(0, 184, 250, 1.0);
} }
@ -90,4 +94,7 @@ class PaletteDark {
static const Color lightPurpleBlue = Color.fromRGBO(120, 133, 170, 1.0); static const Color lightPurpleBlue = Color.fromRGBO(120, 133, 170, 1.0);
static const Color indicatorVioletBlue = Color.fromRGBO(59, 72, 119, 1.0); static const Color indicatorVioletBlue = Color.fromRGBO(59, 72, 119, 1.0);
static const Color granite = Color.fromRGBO(48, 51, 60, 1.0); static const Color granite = Color.fromRGBO(48, 51, 60, 1.0);
} static const Color matrixGreen = Color.fromRGBO(18, 229, 90, 1.0);
static const Color moneroOrange = Color.fromRGBO(255, 102, 0, 1.0);
static const Color moneroCard = Color.fromRGBO(20, 21, 24, 1.0);
}

View file

@ -57,7 +57,6 @@ import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/view_model/wallet_new_vm.dart'; import 'package:cake_wallet/view_model/wallet_new_vm.dart';
import 'package:cake_wallet/view_model/wallet_restoration_from_seed_vm.dart';
import 'package:cake_wallet/exchange/trade.dart'; import 'package:cake_wallet/exchange/trade.dart';
import 'package:cw_core/transaction_info.dart'; import 'package:cw_core/transaction_info.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
@ -80,7 +79,6 @@ import 'package:cake_wallet/src/screens/monero_accounts/monero_account_edit_or_c
import 'package:cake_wallet/src/screens/contact/contact_list_page.dart'; import 'package:cake_wallet/src/screens/contact/contact_list_page.dart';
import 'package:cake_wallet/src/screens/contact/contact_page.dart'; import 'package:cake_wallet/src/screens/contact/contact_page.dart';
import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart'; import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
import 'package:cake_wallet/src/screens/restore/restore_wallet_from_seed_details.dart';
import 'package:cake_wallet/src/screens/exchange/exchange_page.dart'; import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
import 'package:cake_wallet/src/screens/rescan/rescan_page.dart'; import 'package:cake_wallet/src/screens/rescan/rescan_page.dart';
import 'package:cake_wallet/src/screens/faq/faq_page.dart'; import 'package:cake_wallet/src/screens/faq/faq_page.dart';
@ -398,16 +396,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
builder: (_) => builder: (_) =>
getIt.get<BuyWebViewPage>(param1: args)); getIt.get<BuyWebViewPage>(param1: args));
case Routes.restoreWalletFromSeedDetails:
final args = settings.arguments as List;
final walletRestorationFromSeedVM =
getIt.get<WalletRestorationFromSeedVM>(param1: args);
return CupertinoPageRoute<void>(
fullscreenDialog: true,
builder: (_) => RestoreWalletFromSeedDetailsPage(
walletRestorationFromSeedVM: walletRestorationFromSeedVM));
case Routes.exchange: case Routes.exchange:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
fullscreenDialog: true, fullscreenDialog: true,

View file

@ -30,7 +30,6 @@ class Routes {
static const tradeDetails = '/trade_details'; static const tradeDetails = '/trade_details';
static const exchangeFunds = '/exchange_funds'; static const exchangeFunds = '/exchange_funds';
static const exchangeTrade = '/exchange_trade'; static const exchangeTrade = '/exchange_trade';
static const restoreWalletFromSeedDetails = '/restore_from_seed_details';
static const exchange = '/exchange'; static const exchange = '/exchange';
static const settings = '/settings'; static const settings = '/settings';
static const desktop_settings_page = '/desktop_settings_page'; static const desktop_settings_page = '/desktop_settings_page';

View file

@ -42,10 +42,9 @@ class _AnonpayDetailsPageBodyState extends State<AnonpayDetailsPageBody> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SectionStandardList( return SectionStandardList(
context: context,
sectionCount: 1, sectionCount: 1,
itemCounter: (int _) => widget.anonpayDetailsViewModel.items.length, itemCounter: (int _) => widget.anonpayDetailsViewModel.items.length,
itemBuilder: (_, __, index) { itemBuilder: (__, index) {
final item = widget.anonpayDetailsViewModel.items[index]; final item = widget.anonpayDetailsViewModel.items[index];
if (item is DetailsListStatusItem) { if (item is DetailsListStatusItem) {

View file

@ -80,7 +80,7 @@ class BackupPage extends BasePage {
isLoading: backupViewModelBase.state is IsExecutingState, isLoading: backupViewModelBase.state is IsExecutingState,
onPressed: () => onExportBackup(context), onPressed: () => onExportBackup(context),
text: S.of(context).export_backup, text: S.of(context).export_backup,
color: Theme.of(context).accentTextTheme.bodyLarge!.color!, color: Theme.of(context).primaryColor,
textColor: Colors.white, textColor: Colors.white,
), ),
), ),
@ -127,9 +127,9 @@ class BackupPage extends BasePage {
builder: (dialogContext) { builder: (dialogContext) {
return AlertWithTwoActions( return AlertWithTwoActions(
alertTitle: S.of(context).export_backup, alertTitle: S.of(context).export_backup,
alertContent: 'Please select destination for the backup file.', alertContent: S.of(context).select_destination,
rightButtonText: 'Save to Downloads', rightButtonText: S.of(context).save_to_downloads,
leftButtonText: 'Share', leftButtonText:S.of(context).share,
actionRightButton: () async { actionRightButton: () async {
final permission = await Permission.storage.request(); final permission = await Permission.storage.request();

View file

@ -7,6 +7,7 @@ import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart'; import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/view_model/edit_backup_password_view_model.dart'; import 'package:cake_wallet/view_model/edit_backup_password_view_model.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
class EditBackupPasswordPage extends BasePage { class EditBackupPasswordPage extends BasePage {
EditBackupPasswordPage(this.editBackupPasswordViewModel) EditBackupPasswordPage(this.editBackupPasswordViewModel)
@ -39,19 +40,13 @@ class EditBackupPasswordPage extends BasePage {
controller: textEditingController, controller: textEditingController,
style: TextStyle( style: TextStyle(
fontSize: 26, fontSize: 26,
color: Theme.of(context) color: Theme.of(context).extension<CakeTextTheme>()!.titleColor)))),
.primaryTextTheme!
.titleLarge!
.color!)))),
Positioned( Positioned(
child: Observer( child: Observer(
builder: (_) => PrimaryButton( builder: (_) => PrimaryButton(
onPressed: () => onSave(context), onPressed: () => onSave(context),
text: S.of(context).save, text: S.of(context).save,
color: Theme.of(context) color: Theme.of(context).primaryColor,
.accentTextTheme!
.bodyLarge!
.color!,
textColor: Colors.white, textColor: Colors.white,
isDisabled: !editBackupPasswordViewModel.canSave)), isDisabled: !editBackupPasswordViewModel.canSave)),
bottom: 24, bottom: 24,

View file

@ -1,7 +1,6 @@
import 'package:cake_wallet/themes/theme_base.dart'; import 'package:cake_wallet/themes/theme_base.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/src/widgets/nav_bar.dart'; import 'package:cake_wallet/src/widgets/nav_bar.dart';
@ -10,22 +9,22 @@ import 'package:cake_wallet/generated/i18n.dart';
enum AppBarStyle { regular, withShadow, transparent } enum AppBarStyle { regular, withShadow, transparent }
abstract class BasePage extends StatelessWidget { abstract class BasePage extends StatelessWidget {
BasePage() BasePage() : _scaffoldKey = GlobalKey<ScaffoldState>();
: _scaffoldKey = GlobalKey<ScaffoldState>();
final GlobalKey<ScaffoldState> _scaffoldKey; final GlobalKey<ScaffoldState> _scaffoldKey;
final Image closeButtonImage = final Image closeButtonImage = Image.asset('assets/images/close_button.png');
Image.asset('assets/images/close_button.png');
final Image closeButtonImageDarkTheme = final Image closeButtonImageDarkTheme =
Image.asset('assets/images/close_button_dark_theme.png'); Image.asset('assets/images/close_button_dark_theme.png');
String? get title => null; String? get title => null;
Color get backgroundLightColor => Colors.white; Color? get backgroundLightColor => null;
Color get backgroundDarkColor => PaletteDark.backgroundColor; Color? get backgroundDarkColor => null;
Color? get titleColor => null; bool get gradientBackground => false;
bool get gradientAll => false;
bool get resizeToAvoidBottomInset => true; bool get resizeToAvoidBottomInset => true;
@ -43,15 +42,41 @@ abstract class BasePage extends StatelessWidget {
void onClose(BuildContext context) => Navigator.of(context).pop(); void onClose(BuildContext context) => Navigator.of(context).pop();
Color pageBackgroundColor(BuildContext context) =>
(currentTheme.type == ThemeType.dark
? backgroundDarkColor
: backgroundLightColor) ??
(gradientBackground && currentTheme.type == ThemeType.bright
? Colors.transparent
: Theme.of(context).colorScheme.background);
Color titleColor(BuildContext context) =>
(gradientBackground && currentTheme.type == ThemeType.bright) ||
(gradientAll && currentTheme.brightness == Brightness.light)
? Colors.white
: Theme.of(context).appBarTheme.titleTextStyle!.color!;
Color? pageIconColor(BuildContext context) => titleColor(context);
Widget closeButton(BuildContext context) => Image.asset(
currentTheme.type == ThemeType.dark
? 'assets/images/close_button_dark_theme.png'
: 'assets/images/close_button.png',
color: pageIconColor(context),
height: 16,
);
Widget backButton(BuildContext context) => Icon(
Icons.arrow_back_ios,
color: pageIconColor(context),
size: 16,
);
Widget? leading(BuildContext context) { Widget? leading(BuildContext context) {
if (ModalRoute.of(context)?.isFirst ?? true) { if (ModalRoute.of(context)?.isFirst ?? true) {
return null; return null;
} }
final _backButton = Icon(Icons.arrow_back_ios,
color: titleColor ?? Theme.of(context).primaryTextTheme!.titleLarge!.color!,
size: 16,);
return MergeSemantics( return MergeSemantics(
child: SizedBox( child: SizedBox(
height: 37, height: 37,
@ -66,7 +91,7 @@ abstract class BasePage extends StatelessWidget {
(states) => Colors.transparent), (states) => Colors.transparent),
), ),
onPressed: () => onClose(context), onPressed: () => onClose(context),
child: _backButton, child: backButton(context),
), ),
), ),
), ),
@ -83,8 +108,7 @@ abstract class BasePage extends StatelessWidget {
fontSize: 18.0, fontSize: 18.0,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontFamily: 'Lato', fontFamily: 'Lato',
color: titleColor ?? color: titleColor(context)),
Theme.of(context).primaryTextTheme!.titleLarge!.color!),
); );
} }
@ -93,9 +117,8 @@ abstract class BasePage extends StatelessWidget {
Widget? floatingActionButton(BuildContext context) => null; Widget? floatingActionButton(BuildContext context) => null;
ObstructingPreferredSizeWidget appBar(BuildContext context) { ObstructingPreferredSizeWidget appBar(BuildContext context) {
final appBarColor = currentTheme.type == ThemeType.dark final appBarColor = pageBackgroundColor(context);
? backgroundDarkColor : backgroundLightColor;
switch (appBarStyle) { switch (appBarStyle) {
case AppBarStyle.regular: case AppBarStyle.regular:
// FIX-ME: NavBar no context // FIX-ME: NavBar no context
@ -139,12 +162,9 @@ abstract class BasePage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final _backgroundColor = currentTheme.type == ThemeType.dark
? backgroundDarkColor : backgroundLightColor;
final root = Scaffold( final root = Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
backgroundColor: _backgroundColor, backgroundColor: pageBackgroundColor(context),
resizeToAvoidBottomInset: resizeToAvoidBottomInset, resizeToAvoidBottomInset: resizeToAvoidBottomInset,
extendBodyBehindAppBar: extendBodyBehindAppBar, extendBodyBehindAppBar: extendBodyBehindAppBar,
endDrawer: endDrawer, endDrawer: endDrawer,

View file

@ -24,9 +24,6 @@ class BuyWebViewPage extends BasePage {
@override @override
Color get backgroundDarkColor => Colors.white; Color get backgroundDarkColor => Colors.white;
@override
Color get titleColor => Palette.darkBlueCraiola;
@override @override
Widget body(BuildContext context) => Widget body(BuildContext context) =>
BuyWebViewPageBody(buyViewModel, ordersStore: ordersStore, url: url); BuyWebViewPageBody(buyViewModel, ordersStore: ordersStore, url: url);

View file

@ -3,6 +3,10 @@ import 'package:cake_wallet/buy/buy_provider.dart';
import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart'; import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart';
import 'package:cake_wallet/entities/fiat_currency.dart'; import 'package:cake_wallet/entities/fiat_currency.dart';
import 'package:cake_wallet/src/widgets/picker.dart'; import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
import 'package:cake_wallet/src/screens/buy/widgets/buy_list_item.dart'; import 'package:cake_wallet/src/screens/buy/widgets/buy_list_item.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
@ -58,9 +62,6 @@ class PreOrderPage extends BasePage {
@override @override
String get title => S.current.buy + ' ' + walletTypeToString(buyViewModel.wallet.type); String get title => S.current.buy + ' ' + walletTypeToString(buyViewModel.wallet.type);
@override
Color get titleColor => Colors.white;
@override @override
bool get resizeToAvoidBottomInset => false; bool get resizeToAvoidBottomInset => false;
@ -80,10 +81,7 @@ class PreOrderPage extends BasePage {
return KeyboardActions( return KeyboardActions(
config: KeyboardActionsConfig( config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS, keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor: Theme.of(context) keyboardBarColor: Theme.of(context).extension<KeyboardTheme>()!.keyboardBarColor,
.accentTextTheme!
.bodyLarge!
.backgroundColor!,
nextFocus: false, nextFocus: false,
actions: [ actions: [
KeyboardActionsItem( KeyboardActionsItem(
@ -104,10 +102,8 @@ class PreOrderPage extends BasePage {
bottomLeft: Radius.circular(24), bottomLeft: Radius.circular(24),
bottomRight: Radius.circular(24)), bottomRight: Radius.circular(24)),
gradient: LinearGradient(colors: [ gradient: LinearGradient(colors: [
Theme.of(context).primaryTextTheme!.titleMedium!.color!, Theme.of(context).extension<SendPageTheme>()!.firstGradientColor,
Theme.of(context) Theme.of(context).extension<SendPageTheme>()!.secondGradientColor,
.primaryTextTheme!.titleMedium!
.decorationColor!,
], begin: Alignment.topLeft, end: Alignment.bottomRight), ], begin: Alignment.topLeft, end: Alignment.bottomRight),
), ),
child: Padding( child: Padding(
@ -162,11 +158,11 @@ class PreOrderPage extends BasePage {
), ),
), ),
hintText: '0.00', hintText: '0.00',
borderColor: Theme.of(context).primaryTextTheme!.bodyLarge!.decorationColor!, borderColor: Theme.of(context).extension<ExchangePageTheme>()!.textFieldBorderBottomPanelColor,
borderWidth: 0.5, borderWidth: 0.5,
textStyle: TextStyle(fontSize: 36, fontWeight: FontWeight.w500, color: Colors.white), textStyle: TextStyle(fontSize: 36, fontWeight: FontWeight.w500, color: Colors.white),
placeholderTextStyle: TextStyle( placeholderTextStyle: TextStyle(
color: Theme.of(context).primaryTextTheme!.headlineSmall!.decorationColor!, color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
fontSize: 36, fontSize: 36,
), ),
@ -181,7 +177,7 @@ class PreOrderPage extends BasePage {
S.of(context).buy_with + ':', S.of(context).buy_with + ':',
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
color: Theme.of(context).primaryTextTheme.titleLarge!.color!, color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
fontSize: 18, fontSize: 18,
fontWeight: FontWeight.bold fontWeight: FontWeight.bold
), ),
@ -248,7 +244,7 @@ class PreOrderPage extends BasePage {
? S.of(context).buy ? S.of(context).buy
: S.of(context).buy_with + : S.of(context).buy_with +
' ${buyViewModel.selectedProvider!.description.title}', ' ${buyViewModel.selectedProvider!.description.title}',
color: Theme.of(context).accentTextTheme!.bodyLarge!.color!, color: Theme.of(context).primaryColor,
textColor: Colors.white, textColor: Colors.white,
isLoading: buyViewModel.isRunning, isLoading: buyViewModel.isRunning,
isDisabled: (buyViewModel.selectedProvider == null) || isDisabled: (buyViewModel.selectedProvider == null) ||

View file

@ -1,6 +1,8 @@
import 'package:cake_wallet/core/auth_service.dart'; import 'package:cake_wallet/core/auth_service.dart';
import 'package:cake_wallet/entities/contact_base.dart'; import 'package:cake_wallet/entities/contact_base.dart';
import 'package:cake_wallet/entities/contact_record.dart'; import 'package:cake_wallet/entities/contact_record.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
import 'package:cake_wallet/utils/show_bar.dart'; import 'package:cake_wallet/utils/show_bar.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -32,13 +34,13 @@ class ContactListPage extends BasePage {
height: 32.0, height: 32.0,
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
color: Theme.of(context).accentTextTheme!.bodySmall!.color!), color: Theme.of(context).extension<ExchangePageTheme>()!.buttonBackgroundColor),
child: Stack( child: Stack(
alignment: Alignment.center, alignment: Alignment.center,
children: <Widget>[ children: <Widget>[
Icon( Icon(
Icons.add, Icons.add,
color: Theme.of(context).primaryTextTheme.titleLarge!.color!, color: Theme.of(context).appBarTheme.titleTextStyle!.color,
size: 22.0, size: 22.0,
), ),
ButtonTheme( ButtonTheme(
@ -48,17 +50,15 @@ class ContactListPage extends BasePage {
// FIX-ME: Style // FIX-ME: Style
//shape: CircleBorder(), //shape: CircleBorder(),
onPressed: () async { onPressed: () async {
if (contactListViewModel if (contactListViewModel.shouldRequireTOTP2FAForAddingContacts) {
.shouldRequireTOTP2FAForAddingContacts) {
authService.authenticateAction( authService.authenticateAction(
context, context,
route: Routes.addressBookAddContact, route: Routes.addressBookAddContact,
conditionToDetermineIfToUse2FA: contactListViewModel conditionToDetermineIfToUse2FA:
.shouldRequireTOTP2FAForAddingContacts, contactListViewModel.shouldRequireTOTP2FAForAddingContacts,
); );
} else { } else {
await Navigator.of(context) await Navigator.of(context).pushNamed(Routes.addressBookAddContact);
.pushNamed(Routes.addressBookAddContact);
} }
}, },
child: Offstage()), child: Offstage()),
@ -72,17 +72,13 @@ class ContactListPage extends BasePage {
@override @override
Widget body(BuildContext context) { Widget body(BuildContext context) {
return Container( return Container(
padding: EdgeInsets.only(top: 20.0, bottom: 20.0), padding: EdgeInsets.all(20.0),
child: Observer(builder: (_) { child: Observer(builder: (_) {
final contacts = contactListViewModel.contactsToShow; final contacts = contactListViewModel.contactsToShow;
final walletContacts = contactListViewModel.walletContactsToShow; final walletContacts = contactListViewModel.walletContactsToShow;
return CollapsibleSectionList( return CollapsibleSectionList(
context: context,
sectionCount: 2, sectionCount: 2,
themeColor: Theme.of(context).primaryTextTheme.titleLarge!.color!, sectionTitleBuilder: (int sectionIndex) {
dividerThemeColor:
Theme.of(context).primaryTextTheme.bodySmall!.decorationColor!,
sectionTitleBuilder: (_, int sectionIndex) {
var title = S.current.contact_list_contacts; var title = S.current.contact_list_contacts;
if (sectionIndex == 0) { if (sectionIndex == 0) {
@ -95,7 +91,7 @@ class ContactListPage extends BasePage {
}, },
itemCounter: (int sectionIndex) => itemCounter: (int sectionIndex) =>
sectionIndex == 0 ? walletContacts.length : contacts.length, sectionIndex == 0 ? walletContacts.length : contacts.length,
itemBuilder: (_, sectionIndex, index) { itemBuilder: (int sectionIndex, index) {
if (sectionIndex == 0) { if (sectionIndex == 0) {
final walletInfo = walletContacts[index]; final walletInfo = walletContacts[index];
return generateRaw(context, walletInfo); return generateRaw(context, walletInfo);
@ -128,8 +124,7 @@ class ContactListPage extends BasePage {
return; return;
} }
final isCopied = await showNameAndAddressDialog( final isCopied = await showNameAndAddressDialog(context, contact.name, contact.address);
context, contact.name, contact.address);
if (isCopied) { if (isCopied) {
await Clipboard.setData(ClipboardData(text: contact.address)); await Clipboard.setData(ClipboardData(text: contact.address));
@ -137,7 +132,6 @@ class ContactListPage extends BasePage {
} }
}, },
child: Container( child: Container(
color: Colors.transparent,
padding: const EdgeInsets.only(top: 16, bottom: 16, right: 24), padding: const EdgeInsets.only(top: 16, bottom: 16, right: 24),
child: Row( child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@ -152,7 +146,7 @@ class ContactListPage extends BasePage {
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
color: Theme.of(context).primaryTextTheme.titleLarge!.color!, color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
), ),
), ),
)) ))
@ -177,8 +171,7 @@ class ContactListPage extends BasePage {
false; false;
} }
Future<bool> showNameAndAddressDialog( Future<bool> showNameAndAddressDialog(BuildContext context, String name, String address) async {
BuildContext context, String name, String address) async {
return await showPopUp<bool>( return await showPopUp<bool>(
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
@ -193,8 +186,7 @@ class ContactListPage extends BasePage {
false; false;
} }
ActionPane _actionPane(BuildContext context, ContactRecord contact) => ActionPane _actionPane(BuildContext context, ContactRecord contact) => ActionPane(
ActionPane(
motion: const ScrollMotion(), motion: const ScrollMotion(),
extentRatio: 0.4, extentRatio: 0.4,
children: [ children: [

View file

@ -1,5 +1,6 @@
import 'package:cake_wallet/core/address_validator.dart'; import 'package:cake_wallet/core/address_validator.dart';
import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cw_core/currency.dart'; import 'package:cw_core/currency.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -17,6 +18,8 @@ import 'package:cake_wallet/src/widgets/address_text_field.dart';
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart'; import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart'; import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart';
import 'package:cake_wallet/themes/extensions/address_theme.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
class ContactPage extends BasePage { class ContactPage extends BasePage {
ContactPage(this.contactViewModel) ContactPage(this.contactViewModel)
@ -47,7 +50,7 @@ class ContactPage extends BasePage {
@override @override
Widget body(BuildContext context) { Widget body(BuildContext context) {
final downArrow = Image.asset('assets/images/arrow_bottom_purple_icon.png', final downArrow = Image.asset('assets/images/arrow_bottom_purple_icon.png',
color: Theme.of(context).primaryTextTheme!.labelSmall!.color!, color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor,
height: 8); height: 8);
reaction((_) => contactViewModel.state, (ExecutionState state) { reaction((_) => contactViewModel.state, (ExecutionState state) {
@ -99,15 +102,9 @@ class ContactPage extends BasePage {
AddressTextFieldOption.paste, AddressTextFieldOption.paste,
AddressTextFieldOption.qrCode, AddressTextFieldOption.qrCode,
], ],
buttonColor: Theme.of(context) buttonColor: Theme.of(context).extension<AddressTheme>()!.actionButtonColor,
.accentTextTheme!
.displaySmall!
.color!,
iconColor: PaletteDark.gray, iconColor: PaletteDark.gray,
borderColor: Theme.of(context) borderColor: Theme.of(context).extension<CakeTextTheme>()!.textfieldUnderlineColor,
.primaryTextTheme!
.titleLarge!
.backgroundColor!,
validator: validator:
AddressValidator(type: contactViewModel.currency!), AddressValidator(type: contactViewModel.currency!),
), ),
@ -143,10 +140,7 @@ class ContactPage extends BasePage {
await contactViewModel.save(); await contactViewModel.save();
}, },
text: S.of(context).save, text: S.of(context).save,
color: Theme.of(context) color: Theme.of(context).primaryColor,
.accentTextTheme!
.bodyLarge!
.color!,
textColor: Colors.white, textColor: Colors.white,
isDisabled: !contactViewModel.isReady))) isDisabled: !contactViewModel.isReady)))
], ],

View file

@ -4,6 +4,8 @@ import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/entities/main_actions.dart'; import 'package:cake_wallet/entities/main_actions.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/market_place_page.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/market_place_page.dart';
import 'package:cake_wallet/src/widgets/gradient_background.dart';
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
import 'package:cake_wallet/utils/device_info.dart'; import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/version_comparator.dart'; import 'package:cake_wallet/utils/version_comparator.dart';
import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart';
@ -11,7 +13,6 @@ import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/yat_emoji_id.dart'; import 'package:cake_wallet/src/screens/yat_emoji_id.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/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:flutter/material.dart'; import 'package:flutter/material.dart';
@ -29,6 +30,8 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart'; import 'package:smooth_page_indicator/smooth_page_indicator.dart';
import 'package:cake_wallet/main.dart'; import 'package:cake_wallet/main.dart';
import 'package:cake_wallet/src/screens/release_notes/release_notes_screen.dart'; import 'package:cake_wallet/src/screens/release_notes/release_notes_screen.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
class DashboardPage extends StatelessWidget { class DashboardPage extends StatelessWidget {
DashboardPage({ DashboardPage({
@ -81,28 +84,11 @@ class _DashboardPageView extends BasePage {
final BalancePage balancePage; final BalancePage balancePage;
@override @override
Color get backgroundLightColor => bool get gradientBackground => true;
currentTheme.type == ThemeType.bright ? Colors.transparent : Colors.white;
@override
Color get backgroundDarkColor => Colors.transparent;
@override @override
Widget Function(BuildContext, Widget) get rootWrapper => Widget Function(BuildContext, Widget) get rootWrapper =>
(BuildContext context, Widget scaffold) => Container( (BuildContext context, Widget scaffold) => GradientBackground(scaffold: scaffold);
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Theme.of(context).colorScheme.secondary,
Theme.of(context).scaffoldBackgroundColor,
Theme.of(context).primaryColor,
],
begin: Alignment.topRight,
end: Alignment.bottomLeft,
),
),
child: scaffold,
);
@override @override
bool get resizeToAvoidBottomInset => false; bool get resizeToAvoidBottomInset => false;
@ -122,7 +108,7 @@ class _DashboardPageView extends BasePage {
Widget trailing(BuildContext context) { Widget trailing(BuildContext context) {
final menuButton = Image.asset( final menuButton = Image.asset(
'assets/images/menu.png', 'assets/images/menu.png',
color: Theme.of(context).accentTextTheme.displayMedium!.backgroundColor, color: Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
); );
return Container( return Container(
@ -141,6 +127,7 @@ class _DashboardPageView extends BasePage {
final DashboardViewModel dashboardViewModel; final DashboardViewModel dashboardViewModel;
final WalletAddressListViewModel addressListViewModel; final WalletAddressListViewModel addressListViewModel;
int get initialPage => dashboardViewModel.shouldShowMarketPlaceInDashboard ? 1 : 0; int get initialPage => dashboardViewModel.shouldShowMarketPlaceInDashboard ? 1 : 0;
ObservableList<Widget> pages = ObservableList<Widget>(); ObservableList<Widget> pages = ObservableList<Widget>();
bool _isEffectsInstalled = false; bool _isEffectsInstalled = false;
@ -199,8 +186,10 @@ class _DashboardPageView extends BasePage {
dotWidth: 6.0, dotWidth: 6.0,
dotHeight: 6.0, dotHeight: 6.0,
dotColor: Theme.of(context).indicatorColor, dotColor: Theme.of(context).indicatorColor,
activeDotColor: activeDotColor: Theme.of(context)
Theme.of(context).accentTextTheme.headlineMedium!.backgroundColor!, .extension<DashboardPageTheme>()!
.indicatorDotTheme
.activeIndicatorColor,
), ),
), ),
); );
@ -216,12 +205,11 @@ class _DashboardPageView extends BasePage {
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.0), borderRadius: BorderRadius.circular(50.0),
border: Border.all( border: Border.all(
color: currentTheme.type == ThemeType.bright color: Theme.of(context).extension<BalancePageTheme>()!.cardBorderColor,
? Color.fromRGBO(255, 255, 255, 0.2)
: Colors.transparent,
width: 1, width: 1,
), ),
color: Theme.of(context).textTheme.titleLarge!.backgroundColor!, color:
Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
), ),
child: Container( child: Container(
padding: EdgeInsets.only(left: 32, right: 32), padding: EdgeInsets.only(left: 32, right: 32),
@ -240,13 +228,11 @@ class _DashboardPageView extends BasePage {
width: 24, width: 24,
color: action.isEnabled?.call(dashboardViewModel) ?? true color: action.isEnabled?.call(dashboardViewModel) ?? true
? Theme.of(context) ? Theme.of(context)
.accentTextTheme .extension<DashboardPageTheme>()!
.displayMedium! .mainActionsIconColor
.backgroundColor!
: Theme.of(context) : Theme.of(context)
.accentTextTheme .extension<BalancePageTheme>()!
.displaySmall! .labelTextColor,
.backgroundColor!,
), ),
title: action.name(context), title: action.name(context),
onClick: () async => onClick: () async =>
@ -254,9 +240,8 @@ class _DashboardPageView extends BasePage {
textColor: action.isEnabled?.call(dashboardViewModel) ?? true textColor: action.isEnabled?.call(dashboardViewModel) ?? true
? null ? null
: Theme.of(context) : Theme.of(context)
.accentTextTheme .extension<BalancePageTheme>()!
.displaySmall! .labelTextColor,
.backgroundColor!,
), ),
), ),
) )

View file

@ -1,4 +1,7 @@
import 'package:auto_size_text/auto_size_text.dart'; import 'package:auto_size_text/auto_size_text.dart';
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class DesktopActionButton extends StatelessWidget { class DesktopActionButton extends StatelessWidget {
@ -30,7 +33,7 @@ class DesktopActionButton extends StatelessWidget {
width: double.infinity, width: double.infinity,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0), borderRadius: BorderRadius.circular(15.0),
color: Theme.of(context).textTheme!.titleLarge!.backgroundColor!, color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
), ),
child: Center( child: Center(
child: Row( child: Row(
@ -41,14 +44,8 @@ class DesktopActionButton extends StatelessWidget {
height: 30, height: 30,
width: 30, width: 30,
color: isEnabled color: isEnabled
? Theme.of(context) ? Theme.of(context).extension<DashboardPageTheme>()!.textColor
.accentTextTheme! : Theme.of(context).extension<BalancePageTheme>()!.labelTextColor,
.displayMedium!
.backgroundColor!
: Theme.of(context)
.accentTextTheme!
.displaySmall!
.backgroundColor!,
), ),
const SizedBox(width: 10), const SizedBox(width: 10),
AutoSizeText( AutoSizeText(
@ -58,10 +55,7 @@ class DesktopActionButton extends StatelessWidget {
fontFamily: 'Lato', fontFamily: 'Lato',
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: isEnabled color: isEnabled
? Theme.of(context) ? Theme.of(context).extension<DashboardPageTheme>()!.textColor
.accentTextTheme!
.displayMedium!
.backgroundColor!
: null, : null,
height: 1, height: 1,
), ),

View file

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
class SideMenuItem extends StatelessWidget { class SideMenuItem extends StatelessWidget {
const SideMenuItem({ const SideMenuItem({
@ -16,7 +17,7 @@ class SideMenuItem extends StatelessWidget {
Color _setColor(BuildContext context) { Color _setColor(BuildContext context) {
if (isSelected) { if (isSelected) {
return Theme.of(context).primaryTextTheme!.titleLarge!.color!; return Theme.of(context).extension<CakeTextTheme>()!.titleColor;
} else { } else {
return Theme.of(context).highlightColor; return Theme.of(context).highlightColor;
} }

View file

@ -1,10 +1,12 @@
import 'package:another_flushbar/flushbar.dart'; import 'package:another_flushbar/flushbar.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/core/auth_service.dart'; import 'package:cake_wallet/core/auth_service.dart';
import 'package:cake_wallet/entities/desktop_dropdown_item.dart'; import 'package:cake_wallet/entities/desktop_dropdown_item.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/dropdown_item_widget.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/dropdown_item_widget.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/themes/extensions/menu_theme.dart';
import 'package:cake_wallet/utils/show_bar.dart'; import 'package:cake_wallet/utils/show_bar.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/wallet_list/wallet_list_item.dart'; import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
@ -38,14 +40,14 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
'assets/images/new_wallet.png', 'assets/images/new_wallet.png',
height: 12, height: 12,
width: 12, width: 12,
color: Theme.of(context).primaryTextTheme!.titleLarge!.color!, color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
); );
Image _restoreWalletImage(BuildContext context) => Image.asset( Image _restoreWalletImage(BuildContext context) => Image.asset(
'assets/images/restore_wallet.png', 'assets/images/restore_wallet.png',
height: 12, height: 12,
width: 12, width: 12,
color: Theme.of(context).primaryTextTheme!.titleLarge!.color!, color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
); );
Flushbar<void>? _progressBar; Flushbar<void>? _progressBar;
@ -95,8 +97,8 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
onChanged: (item) { onChanged: (item) {
item?.onSelected(); item?.onSelected();
}, },
dropdownColor: themeData.textTheme!.bodyLarge?.decorationColor, dropdownColor: themeData.extension<CakeMenuTheme>()!.backgroundColor,
style: TextStyle(color: themeData.primaryTextTheme!.titleLarge?.color), style: TextStyle(color: themeData.extension<CakeTextTheme>()!.titleColor),
selectedItemBuilder: (context) => dropDownItems.map((item) => item.child).toList(), selectedItemBuilder: (context) => dropDownItems.map((item) => item.child).toList(),
value: dropDownItems.firstWhere((element) => element.isSelected), value: dropDownItems.firstWhere((element) => element.isSelected),
underline: const SizedBox(), underline: const SizedBox(),

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class DropDownItemWidget extends StatelessWidget { class DropDownItemWidget extends StatelessWidget {
@ -23,7 +24,7 @@ class DropDownItemWidget extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontSize: 22, fontSize: 22,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Theme.of(context).primaryTextTheme!.titleLarge!.color!, color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
), ),
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
maxLines: 1, maxLines: 1,

View file

@ -6,6 +6,7 @@ import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/src/widgets/checkbox_widget.dart'; import 'package:cake_wallet/src/widgets/checkbox_widget.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/scollable_with_bottom_section.dart'; import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
import 'package:cake_wallet/view_model/dashboard/home_settings_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/home_settings_view_model.dart';
import 'package:cw_core/erc20_token.dart'; import 'package:cw_core/erc20_token.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -111,7 +112,7 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
Container( Container(
padding: EdgeInsets.symmetric(vertical: 16, horizontal: 28), padding: EdgeInsets.symmetric(vertical: 16, horizontal: 28),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Theme.of(context).accentTextTheme.bodySmall!.color!, color: Theme.of(context).cardColor,
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
), ),
child: Row( child: Row(
@ -128,7 +129,7 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Theme.of(context).primaryTextTheme.titleLarge!.color!, color: Theme.of(context).dialogTheme.backgroundColor,
), ),
), ),
Padding( Padding(
@ -138,7 +139,7 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
color: Theme.of(context).primaryTextTheme.labelSmall!.color!, color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor,
), ),
), ),
), ),
@ -197,7 +198,7 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
} }
}, },
text: S.of(context).save, text: S.of(context).save,
color: Theme.of(context).accentTextTheme.bodyLarge!.color!, color: Theme.of(context).primaryColor,
textColor: Colors.white, textColor: Colors.white,
), ),
), ),

View file

@ -7,6 +7,8 @@ import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart'; import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart'; import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
import 'package:cake_wallet/themes/extensions/address_theme.dart';
import 'package:cake_wallet/themes/extensions/menu_theme.dart';
import 'package:cake_wallet/view_model/dashboard/home_settings_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/home_settings_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_mobx/flutter_mobx.dart';
@ -34,7 +36,7 @@ class HomeSettingsPage extends BasePage {
onItemSelected: _homeSettingsViewModel.setSortBalanceBy, onItemSelected: _homeSettingsViewModel.setSortBalanceBy,
), ),
), ),
Divider(color: Theme.of(context).primaryTextTheme.bodySmall!.decorationColor!), Divider(color: Theme.of(context).extension<CakeMenuTheme>()!.dividerColor),
Observer( Observer(
builder: (_) => SettingsSwitcherCell( builder: (_) => SettingsSwitcherCell(
title: S.of(context).pin_at_top(_homeSettingsViewModel.nativeToken.title), title: S.of(context).pin_at_top(_homeSettingsViewModel.nativeToken.title),
@ -44,7 +46,7 @@ class HomeSettingsPage extends BasePage {
}, },
), ),
), ),
Divider(color: Theme.of(context).primaryTextTheme.bodySmall!.decorationColor!), Divider(color: Theme.of(context).extension<CakeMenuTheme>()!.dividerColor),
const SizedBox(height: 20), const SizedBox(height: 20),
Row( Row(
children: [ children: [
@ -53,12 +55,12 @@ class HomeSettingsPage extends BasePage {
padding: const EdgeInsetsDirectional.only(start: 16), padding: const EdgeInsetsDirectional.only(start: 16),
child: TextFormField( child: TextFormField(
controller: _searchController, controller: _searchController,
style: TextStyle(color: Theme.of(context).primaryTextTheme.titleLarge!.color!), style: TextStyle(color: Theme.of(context).dialogTheme.backgroundColor),
decoration: InputDecoration( decoration: InputDecoration(
hintText: S.of(context).search_add_token, hintText: S.of(context).search_add_token,
prefixIcon: Image.asset("assets/images/search_icon.png"), prefixIcon: Image.asset("assets/images/search_icon.png"),
filled: true, filled: true,
fillColor: Theme.of(context).accentTextTheme.displaySmall!.color!, fillColor: Theme.of(context).extension<AddressTheme>()!.actionButtonColor,
alignLabelWithHint: false, alignLabelWithHint: false,
contentPadding: const EdgeInsets.symmetric(vertical: 4, horizontal: 16), contentPadding: const EdgeInsets.symmetric(vertical: 4, horizontal: 16),
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
@ -84,15 +86,15 @@ class HomeSettingsPage extends BasePage {
}); });
}, },
elevation: 0, elevation: 0,
fillColor: Theme.of(context).accentTextTheme.bodySmall!.color!, fillColor: Theme.of(context).cardColor,
child: Icon( child: Icon(
Icons.add, Icons.add,
color: Theme.of(context).primaryTextTheme.titleLarge!.color!, color: Theme.of(context).dialogTheme.backgroundColor,
size: 22.0, size: 22.0,
), ),
padding: EdgeInsets.all(12), padding: EdgeInsets.all(12),
shape: CircleBorder(), shape: CircleBorder(),
splashColor: Theme.of(context).accentTextTheme.bodySmall!.color!, splashColor: Theme.of(context).cardColor,
), ),
], ],
), ),
@ -146,7 +148,7 @@ class HomeSettingsPage extends BasePage {
), ),
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Theme.of(context).accentTextTheme.bodySmall!.color!, color: Theme.of(context).cardColor,
borderRadius: BorderRadius.circular(30), borderRadius: BorderRadius.circular(30),
), ),
); );

View file

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
class ActionButton extends StatelessWidget { class ActionButton extends StatelessWidget {
ActionButton( ActionButton(
@ -46,14 +47,11 @@ class ActionButton extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontSize: 10, fontSize: 10,
color: textColor ?? color: textColor ??
Theme.of(context) Theme.of(context).extension<DashboardPageTheme>()!.cardTextColor),
.accentTextTheme!
.displayMedium!
.backgroundColor!),
) )
], ],
), ),
), ),
); );
} }
} }

View file

@ -1,10 +1,14 @@
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
import 'package:cake_wallet/anonpay/anonpay_donation_link_info.dart'; import 'package:cake_wallet/anonpay/anonpay_donation_link_info.dart';
import 'package:cake_wallet/entities/preferences_key.dart'; import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cake_wallet/entities/receive_page_option.dart'; import 'package:cake_wallet/entities/receive_page_option.dart';
import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/present_receive_option_picker.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/present_receive_option_picker.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/src/widgets/gradient_background.dart';
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart'; import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
import 'package:cake_wallet/themes/theme_base.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/share_util.dart'; import 'package:cake_wallet/utils/share_util.dart';
@ -21,6 +25,8 @@ import 'package:keyboard_actions/keyboard_actions.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
class AddressPage extends BasePage { class AddressPage extends BasePage {
AddressPage({ AddressPage({
@ -48,11 +54,7 @@ class AddressPage extends BasePage {
final FocusNode _cryptoAmountFocus; final FocusNode _cryptoAmountFocus;
@override @override
Color get backgroundLightColor => bool get gradientBackground => true;
currentTheme.type == ThemeType.bright ? Colors.transparent : Colors.white;
@override
Color get backgroundDarkColor => Colors.transparent;
@override @override
bool get resizeToAvoidBottomInset => false; bool get resizeToAvoidBottomInset => false;
@ -61,14 +63,6 @@ class AddressPage extends BasePage {
@override @override
Widget? leading(BuildContext context) { Widget? leading(BuildContext context) {
final _backButton = Icon(
Icons.arrow_back_ios,
color: Theme.of(context).accentTextTheme.displayMedium!.backgroundColor!,
size: 16,
);
final _closeButton =
currentTheme.type == ThemeType.dark ? closeButtonImageDarkTheme : closeButtonImage;
bool isMobileView = ResponsiveLayoutUtil.instance.isMobile; bool isMobileView = ResponsiveLayoutUtil.instance.isMobile;
return MergeSemantics( return MergeSemantics(
@ -84,7 +78,7 @@ class AddressPage extends BasePage {
overlayColor: MaterialStateColor.resolveWith((states) => Colors.transparent), overlayColor: MaterialStateColor.resolveWith((states) => Colors.transparent),
), ),
onPressed: () => onClose(context), onPressed: () => onClose(context),
child: !isMobileView ? _closeButton : _backButton, child: !isMobileView ? closeButton(context) : backButton(context),
), ),
), ),
), ),
@ -94,20 +88,11 @@ class AddressPage extends BasePage {
@override @override
Widget middle(BuildContext context) => PresentReceiveOptionPicker( Widget middle(BuildContext context) => PresentReceiveOptionPicker(
receiveOptionViewModel: receiveOptionViewModel, color: titleColor(context), receiveOptionViewModel: receiveOptionViewModel);
hasWhiteBackground: currentTheme.type == ThemeType.light,
);
@override @override
Widget Function(BuildContext, Widget) get rootWrapper => Widget Function(BuildContext, Widget) get rootWrapper =>
(BuildContext context, Widget scaffold) => Container( (BuildContext context, Widget scaffold) => GradientBackground(scaffold: scaffold);
decoration: BoxDecoration(
gradient: LinearGradient(colors: [
Theme.of(context).colorScheme.secondary,
Theme.of(context).scaffoldBackgroundColor,
Theme.of(context).primaryColor,
], begin: Alignment.topRight, end: Alignment.bottomLeft)),
child: scaffold);
@override @override
Widget? trailing(BuildContext context) { Widget? trailing(BuildContext context) {
@ -125,11 +110,7 @@ class AddressPage extends BasePage {
context: context, context: context,
); );
}, },
icon: Icon( icon: Icon(Icons.share, size: 20, color: pageIconColor(context)),
Icons.share,
size: 20,
color: Theme.of(context).accentTextTheme.displayMedium!.backgroundColor!,
),
), ),
); );
} }
@ -166,10 +147,10 @@ class AddressPage extends BasePage {
return KeyboardActions( return KeyboardActions(
autoScroll: false, autoScroll: false,
disableScroll: true, disableScroll: true,
tapOutsideToDismiss: true, tapOutsideBehavior: TapOutsideBehavior.translucentDismiss,
config: KeyboardActionsConfig( config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS, keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor: Theme.of(context).accentTextTheme.bodyLarge!.backgroundColor!, keyboardBarColor: Theme.of(context).extension<KeyboardTheme>()!.keyboardBarColor,
nextFocus: false, nextFocus: false,
actions: [ actions: [
KeyboardActionsItem( KeyboardActionsItem(
@ -201,8 +182,12 @@ class AddressPage extends BasePage {
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(25)), borderRadius: BorderRadius.all(Radius.circular(25)),
border: Border.all( border: Border.all(
color: Theme.of(context).textTheme.titleMedium!.color!, width: 1), color:
color: Theme.of(context).textTheme.titleLarge!.backgroundColor!), Theme.of(context).extension<BalancePageTheme>()!.cardBorderColor,
width: 1),
color: Theme.of(context)
.extension<SyncIndicatorTheme>()!
.syncedBackgroundColor),
child: Row( child: Row(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -216,14 +201,13 @@ class AddressPage extends BasePage {
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Theme.of(context) color: Theme.of(context)
.accentTextTheme.displayMedium! .extension<SyncIndicatorTheme>()!
.backgroundColor!), .textColor),
)), )),
Icon( Icon(
Icons.arrow_forward_ios, Icons.arrow_forward_ios,
size: 14, size: 14,
color: color: Theme.of(context).extension<SyncIndicatorTheme>()!.textColor,
Theme.of(context).accentTextTheme.displayMedium!.backgroundColor!,
) )
], ],
), ),
@ -234,8 +218,7 @@ class AddressPage extends BasePage {
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
fontSize: 15, fontSize: 15,
color: color: Theme.of(context).extension<BalancePageTheme>()!.labelTextColor));
Theme.of(context).accentTextTheme.displaySmall!.backgroundColor!));
} else { } else {
return const SizedBox(); return const SizedBox();
} }

View file

@ -1,4 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
class AnonpayTransactionRow extends StatelessWidget { class AnonpayTransactionRow extends StatelessWidget {
AnonpayTransactionRow({ AnonpayTransactionRow({
@ -37,19 +39,19 @@ class AnonpayTransactionRow extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!)), color: Theme.of(context).extension<DashboardPageTheme>()!.textColor)),
Text(amount + ' ' + currency, Text(amount + ' ' + currency,
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!)) color: Theme.of(context).extension<DashboardPageTheme>()!.textColor))
]), ]),
SizedBox(height: 5), SizedBox(height: 5),
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[
Text(createdAt, Text(createdAt,
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 14,
color: Theme.of(context).textTheme!.labelSmall!.backgroundColor!)) color: Theme.of(context).extension<CakeTextTheme>()!.dateSectionRowColor))
]) ])
], ],
)) ))

View file

@ -1,7 +1,7 @@
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/exchange_trade/information_page.dart'; import 'package:cake_wallet/src/screens/exchange_trade/information_page.dart';
import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/themes/theme_base.dart'; import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
import 'package:cake_wallet/utils/feature_flag.dart'; import 'package:cake_wallet/utils/feature_flag.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -10,6 +10,8 @@ import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:auto_size_text/auto_size_text.dart'; import 'package:auto_size_text/auto_size_text.dart';
import 'package:cake_wallet/src/widgets/introducing_card.dart'; import 'package:cake_wallet/src/widgets/introducing_card.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
class BalancePage extends StatelessWidget { class BalancePage extends StatelessWidget {
BalancePage({required this.dashboardViewModel, required this.settingsStore}); BalancePage({required this.dashboardViewModel, required this.settingsStore});
@ -41,7 +43,8 @@ class BalancePage extends StatelessWidget {
fontSize: 24, fontSize: 24,
fontFamily: 'Lato', fontFamily: 'Lato',
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Theme.of(context).accentTextTheme.displayMedium!.backgroundColor!, color:
Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
height: 1, height: 1,
), ),
maxLines: 1, maxLines: 1,
@ -55,8 +58,9 @@ class BalancePage extends StatelessWidget {
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Image.asset( child: Image.asset(
'assets/images/home_screen_settings_icon.png', 'assets/images/home_screen_settings_icon.png',
color: color: Theme.of(context)
Theme.of(context).accentTextTheme.displayMedium!.backgroundColor!, .extension<DashboardPageTheme>()!
.pageTitleTextColor,
), ),
), ),
), ),
@ -72,9 +76,7 @@ class BalancePage extends StatelessWidget {
return IntroducingCard( return IntroducingCard(
title: S.of(context).introducing_cake_pay, title: S.of(context).introducing_cake_pay,
subTitle: S.of(context).cake_pay_learn_more, subTitle: S.of(context).cake_pay_learn_more,
borderColor: settingsStore.currentTheme.type == ThemeType.bright borderColor: Theme.of(context).extension<BalancePageTheme>()!.cardBorderColor,
? Color.fromRGBO(255, 255, 255, 0.2)
: Colors.transparent,
closeCard: dashboardViewModel.balanceViewModel.disableIntroCakePayCard); closeCard: dashboardViewModel.balanceViewModel.disableIntroCakePayCard);
} }
return Container(); return Container();
@ -134,12 +136,10 @@ class BalancePage extends StatelessWidget {
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0), borderRadius: BorderRadius.circular(30.0),
border: Border.all( border: Border.all(
color: settingsStore.currentTheme.type == ThemeType.bright color: Theme.of(context).extension<BalancePageTheme>()!.cardBorderColor,
? Color.fromRGBO(255, 255, 255, 0.2)
: Colors.transparent,
width: 1, width: 1,
), ),
color: Theme.of(context).textTheme.titleLarge!.backgroundColor!, color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
), ),
child: Container( child: Container(
margin: const EdgeInsets.only(top: 16, left: 24, right: 24, bottom: 24), margin: const EdgeInsets.only(top: 16, left: 24, right: 24, bottom: 24),
@ -164,9 +164,8 @@ class BalancePage extends StatelessWidget {
fontFamily: 'Lato', fontFamily: 'Lato',
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: Theme.of(context) color: Theme.of(context)
.accentTextTheme! .extension<BalancePageTheme>()!
.displaySmall! .labelTextColor,
.backgroundColor!,
height: 1)), height: 1)),
if (hasAdditionalBalance) if (hasAdditionalBalance)
Padding( Padding(
@ -174,9 +173,8 @@ class BalancePage extends StatelessWidget {
child: Icon(Icons.help_outline, child: Icon(Icons.help_outline,
size: 16, size: 16,
color: Theme.of(context) color: Theme.of(context)
.accentTextTheme! .extension<BalancePageTheme>()!
.displaySmall! .labelTextColor),
.backgroundColor!),
), ),
], ],
), ),
@ -187,9 +185,8 @@ class BalancePage extends StatelessWidget {
fontFamily: 'Lato', fontFamily: 'Lato',
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
color: Theme.of(context) color: Theme.of(context)
.accentTextTheme! .extension<BalancePageTheme>()!
.displayMedium! .balanceAmountColor,
.backgroundColor!,
height: 1), height: 1),
maxLines: 1, maxLines: 1,
textAlign: TextAlign.start), textAlign: TextAlign.start),
@ -200,10 +197,7 @@ class BalancePage extends StatelessWidget {
fontSize: 16, fontSize: 16,
fontFamily: 'Lato', fontFamily: 'Lato',
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Theme.of(context) color: Theme.of(context).extension<BalancePageTheme>()!.textColor,
.accentTextTheme!
.displayMedium!
.backgroundColor!,
height: 1)), height: 1)),
], ],
), ),
@ -213,7 +207,7 @@ class BalancePage extends StatelessWidget {
fontSize: 28, fontSize: 28,
fontFamily: 'Lato', fontFamily: 'Lato',
fontWeight: FontWeight.w800, fontWeight: FontWeight.w800,
color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!, color: Theme.of(context).extension<BalancePageTheme>()!.assetTitleColor,
height: 1)), height: 1)),
], ],
), ),
@ -229,7 +223,7 @@ class BalancePage extends StatelessWidget {
fontSize: 12, fontSize: 12,
fontFamily: 'Lato', fontFamily: 'Lato',
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: Theme.of(context).accentTextTheme.displaySmall!.backgroundColor!, color: Theme.of(context).extension<BalancePageTheme>()!.labelTextColor,
height: 1, height: 1,
), ),
), ),
@ -240,7 +234,7 @@ class BalancePage extends StatelessWidget {
fontSize: 20, fontSize: 20,
fontFamily: 'Lato', fontFamily: 'Lato',
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: Theme.of(context).accentTextTheme.displayMedium!.backgroundColor!, color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
height: 1, height: 1,
), ),
maxLines: 1, maxLines: 1,
@ -254,7 +248,7 @@ class BalancePage extends StatelessWidget {
fontSize: 12, fontSize: 12,
fontFamily: 'Lato', fontFamily: 'Lato',
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: Theme.of(context).accentTextTheme.displayMedium!.backgroundColor!, color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
height: 1, height: 1,
), ),
), ),
@ -272,7 +266,7 @@ class BalancePage extends StatelessWidget {
fontSize: 12, fontSize: 12,
fontFamily: 'Lato', fontFamily: 'Lato',
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: Theme.of(context).accentTextTheme.displaySmall!.backgroundColor!, color: Theme.of(context).extension<BalancePageTheme>()!.labelTextColor,
height: 1, height: 1,
), ),
), ),
@ -283,7 +277,7 @@ class BalancePage extends StatelessWidget {
fontSize: 20, fontSize: 20,
fontFamily: 'Lato', fontFamily: 'Lato',
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: Theme.of(context).accentTextTheme.displayMedium!.backgroundColor!, color: Theme.of(context).extension<BalancePageTheme>()!.assetTitleColor,
height: 1, height: 1,
), ),
maxLines: 1, maxLines: 1,
@ -297,7 +291,7 @@ class BalancePage extends StatelessWidget {
fontSize: 12, fontSize: 12,
fontFamily: 'Lato', fontFamily: 'Lato',
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: Theme.of(context).accentTextTheme.displayMedium!.backgroundColor!, color: Theme.of(context).extension<BalancePageTheme>()!.textColor,
height: 1, height: 1,
), ),
), ),

View file

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/utils/date_formatter.dart'; import 'package:cake_wallet/utils/date_formatter.dart';
@ -36,9 +37,6 @@ class DateSectionRaw extends StatelessWidget {
child: Text(title, child: Text(title,
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
color: Theme.of(context) color: Theme.of(context).extension<CakeTextTheme>()!.dateSectionRowColor)));
.textTheme!
.labelSmall!
.backgroundColor!)));
} }
} }

View file

@ -1,12 +1,15 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/filter_tile.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/filter_tile.dart';
import 'package:cake_wallet/src/widgets/section_divider.dart'; import 'package:cake_wallet/src/widgets/section_divider.dart';
import 'package:cake_wallet/src/widgets/standard_checkbox.dart'; import 'package:cake_wallet/src/widgets/standard_checkbox.dart';
import 'package:cake_wallet/themes/extensions/menu_theme.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/src/widgets/picker_wrapper_widget.dart'; import 'package:cake_wallet/src/widgets/picker_wrapper_widget.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_mobx/flutter_mobx.dart';
//import 'package:date_range_picker/date_range_picker.dart' as date_rage_picker; //import 'package:date_range_picker/date_range_picker.dart' as date_rage_picker;
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
class FilterWidget extends StatelessWidget { class FilterWidget extends StatelessWidget {
FilterWidget({required this.dashboardViewModel}); FilterWidget({required this.dashboardViewModel});
@ -15,7 +18,7 @@ class FilterWidget extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
const sectionDivider = const SectionDivider(); const sectionDivider = const HorizontalSectionDivider();
return PickerWrapperWidget( return PickerWrapperWidget(
children: [ children: [
Padding( Padding(
@ -23,7 +26,7 @@ class FilterWidget extends StatelessWidget {
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(24)), borderRadius: BorderRadius.all(Radius.circular(24)),
child: Container( child: Container(
color: Theme.of(context).textTheme!.bodyLarge!.decorationColor!, color: Theme.of(context).extension<CakeMenuTheme>()!.backgroundColor,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -32,10 +35,7 @@ class FilterWidget extends StatelessWidget {
child: Text( child: Text(
S.of(context).filter_by, S.of(context).filter_by,
style: TextStyle( style: TextStyle(
color: Theme.of(context) color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor,
.primaryTextTheme!
.labelSmall!
.color!,
fontSize: 16, fontSize: 16,
fontFamily: 'Lato', fontFamily: 'Lato',
decoration: TextDecoration.none, decoration: TextDecoration.none,
@ -63,10 +63,7 @@ class FilterWidget extends StatelessWidget {
child: Text( child: Text(
title, title,
style: TextStyle( style: TextStyle(
color: Theme.of(context) color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
.primaryTextTheme!
.titleLarge!
.color!,
fontSize: 16, fontSize: 16,
fontFamily: 'Lato', fontFamily: 'Lato',
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,

View file

@ -1,8 +1,10 @@
import 'package:cake_wallet/src/screens/dashboard/widgets/filter_widget.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/filter_widget.dart';
import 'package:cake_wallet/themes/extensions/filter_theme.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
class HeaderRow extends StatelessWidget { class HeaderRow extends StatelessWidget {
HeaderRow({required this.dashboardViewModel}); HeaderRow({required this.dashboardViewModel});
@ -12,7 +14,7 @@ class HeaderRow extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final filterIcon = Image.asset('assets/images/filter_icon.png', final filterIcon = Image.asset('assets/images/filter_icon.png',
color: Theme.of(context).textTheme!.bodySmall!.decorationColor!); color: Theme.of(context).extension<FilterTheme>()!.iconColor);
return Container( return Container(
height: 52, height: 52,
@ -27,10 +29,7 @@ class HeaderRow extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Theme.of(context) color: Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor),
.accentTextTheme!
.displayMedium!
.backgroundColor!),
), ),
GestureDetector( GestureDetector(
onTap: () { onTap: () {
@ -45,7 +44,7 @@ class HeaderRow extends StatelessWidget {
width: 36, width: 36,
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
color: Theme.of(context).textTheme!.labelSmall!.color!), color: Theme.of(context).extension<FilterTheme>()!.buttonColor),
child: filterIcon, child: filterIcon,
), ),
) )

View file

@ -8,6 +8,7 @@ import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
class MarketPlacePage extends StatelessWidget { class MarketPlacePage extends StatelessWidget {
MarketPlacePage({ MarketPlacePage({
@ -40,10 +41,7 @@ class MarketPlacePage extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontSize: 24, fontSize: 24,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Theme.of(context) color: Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
.accentTextTheme!
.displayMedium!
.backgroundColor!,
), ),
), ),
Expanded( Expanded(

View file

@ -1,13 +1,12 @@
import 'package:cake_wallet/src/widgets/setting_action_button.dart'; import 'package:cake_wallet/src/widgets/setting_action_button.dart';
import 'package:cake_wallet/src/widgets/setting_actions.dart'; import 'package:cake_wallet/src/widgets/setting_actions.dart';
import 'package:cake_wallet/themes/extensions/menu_theme.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_mobx/flutter_mobx.dart';
// FIXME: terrible design.
class MenuWidget extends StatefulWidget { class MenuWidget extends StatefulWidget {
MenuWidget(this.dashboardViewModel); MenuWidget(this.dashboardViewModel);
@ -19,19 +18,19 @@ class MenuWidget extends StatefulWidget {
class MenuWidgetState extends State<MenuWidget> { class MenuWidgetState extends State<MenuWidget> {
MenuWidgetState() MenuWidgetState()
: this.menuWidth = 0, : this.menuWidth = 0,
this.screenWidth = 0, this.screenWidth = 0,
this.screenHeight = 0, this.screenHeight = 0,
this.headerHeight = 120, this.headerHeight = 120,
this.tileHeight = 60, this.tileHeight = 60,
this.fromTopEdge = 50, this.fromTopEdge = 50,
this.fromBottomEdge = 25, this.fromBottomEdge = 25,
this.moneroIcon = Image.asset('assets/images/monero_menu.png'), this.moneroIcon = Image.asset('assets/images/monero_menu.png'),
this.bitcoinIcon = Image.asset('assets/images/bitcoin_menu.png'), this.bitcoinIcon = Image.asset('assets/images/bitcoin_menu.png'),
this.litecoinIcon = Image.asset('assets/images/litecoin_menu.png'), this.litecoinIcon = Image.asset('assets/images/litecoin_menu.png'),
this.havenIcon = Image.asset('assets/images/haven_menu.png'), this.havenIcon = Image.asset('assets/images/haven_menu.png'),
this.ethereumIcon = Image.asset('assets/images/eth_icon.png'), this.ethereumIcon = Image.asset('assets/images/eth_icon.png'),
this.bitcoinCashIcon = Image.asset('assets/images/bch_icon.png'); this.bitcoinCashIcon = Image.asset('assets/images/bch_icon.png');
final largeScreen = 731; final largeScreen = 731;
@ -88,121 +87,111 @@ class MenuWidgetState extends State<MenuWidget> {
final itemCount = SettingActions.all.length; final itemCount = SettingActions.all.length;
moneroIcon = Image.asset('assets/images/monero_menu.png', moneroIcon = Image.asset('assets/images/monero_menu.png',
color: Theme.of(context) color: Theme.of(context).extension<CakeMenuTheme>()!.iconColor);
.accentTextTheme
.labelSmall!
.decorationColor!);
bitcoinIcon = Image.asset('assets/images/bitcoin_menu.png', bitcoinIcon = Image.asset('assets/images/bitcoin_menu.png',
color: Theme.of(context) color: Theme.of(context).extension<CakeMenuTheme>()!.iconColor);
.accentTextTheme
.labelSmall!
.decorationColor!);
return Row( return Row(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[ children: <Widget>[
Padding( Padding(
padding: EdgeInsets.only(left: 24), padding: EdgeInsets.only(left: 24),
child: Container( child: Container(
height: 60, height: 60,
width: 4, width: 4,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(2)), color: PaletteDark.gray), borderRadius: BorderRadius.all(Radius.circular(2)), color: PaletteDark.gray),
)), ),
),
SizedBox(width: 12), SizedBox(width: 12),
Expanded( Expanded(
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.only( borderRadius:
topLeft: Radius.circular(24), bottomLeft: Radius.circular(24)), BorderRadius.only(topLeft: Radius.circular(24), bottomLeft: Radius.circular(24)),
child: Container( child: Container(
color: color: Theme.of(context).extension<CakeMenuTheme>()!.backgroundColor,
Theme.of(context).textTheme!.bodyLarge!.decorationColor!, child: ListView.separated(
child: ListView.separated( padding: EdgeInsets.only(top: 0),
padding: EdgeInsets.only(top: 0), itemBuilder: (_, index) {
itemBuilder: (_, index) { if (index == 0) {
if (index == 0) { return Container(
return Container( height: headerHeight,
height: headerHeight, decoration: BoxDecoration(
decoration: BoxDecoration( gradient: LinearGradient(colors: [
gradient: LinearGradient(colors: [ Theme.of(context).extension<CakeMenuTheme>()!.headerFirstGradientColor,
Theme.of(context) Theme.of(context).extension<CakeMenuTheme>()!.headerSecondGradientColor,
.accentTextTheme! ], begin: Alignment.topLeft, end: Alignment.bottomRight),
.headlineMedium! ),
.color!, padding: EdgeInsets.only(
Theme.of(context) left: 24, top: fromTopEdge, right: 24, bottom: fromBottomEdge),
.accentTextTheme! child: Row(
.headlineMedium! mainAxisAlignment: MainAxisAlignment.start,
.decorationColor!, ], begin: Alignment.topLeft, end: Alignment.bottomRight), children: <Widget>[
), _iconFor(type: widget.dashboardViewModel.type),
padding: EdgeInsets.only( SizedBox(width: 12),
left: 24, top: fromTopEdge, right: 24, bottom: fromBottomEdge), SingleChildScrollView(
child: Row( child: Container(
mainAxisAlignment: MainAxisAlignment.start, child: Column(
children: <Widget>[ crossAxisAlignment: CrossAxisAlignment.start,
_iconFor(type: widget.dashboardViewModel.type), mainAxisAlignment: widget.dashboardViewModel.subname.isNotEmpty
SizedBox(width: 12), ? MainAxisAlignment.spaceBetween
SingleChildScrollView( : MainAxisAlignment.center,
child: Container( children: <Widget>[
child: Column( Text(
crossAxisAlignment: CrossAxisAlignment.start, widget.dashboardViewModel.name,
mainAxisAlignment: widget.dashboardViewModel.subname.isNotEmpty style: TextStyle(
? MainAxisAlignment.spaceBetween color: Colors.white,
: MainAxisAlignment.center, fontSize: 16,
children: <Widget>[ fontWeight: FontWeight.bold),
Text(
widget.dashboardViewModel.name,
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold),
),
if (widget.dashboardViewModel.subname.isNotEmpty)
Observer(
builder: (_) => Text(
widget.dashboardViewModel.subname,
style: TextStyle(
color: Theme.of(context)
.accentTextTheme!
.labelSmall!
.decorationColor!,
fontWeight: FontWeight.w500,
fontSize: 12),
))
],
), ),
)) if (widget.dashboardViewModel.subname.isNotEmpty)
], Observer(
builder: (_) => Text(
widget.dashboardViewModel.subname,
style: TextStyle(
color: Theme.of(context)
.extension<CakeMenuTheme>()!
.subnameTextColor,
fontWeight: FontWeight.w500,
fontSize: 12),
),
),
],
),
), ),
);
}
index--;
final item = SettingActions.all[index];
final isLastTile = index == itemCount - 1;
return SettingActionButton(
isLastTile: isLastTile,
tileHeight: tileHeight,
selectionActive: false,
fromBottomEdge: fromBottomEdge,
fromTopEdge: fromTopEdge,
onTap: () => item.onTap.call(context),
image: item.image,
title: item.name.call(context),
);
},
separatorBuilder: (_, index) => Container(
height: 1,
color: Theme.of(context)
.primaryTextTheme!
.bodySmall!
.decorationColor!,
), ),
itemCount: itemCount + 1), ],
))) ),
);
}
index--;
final item = SettingActions.all[index];
final isLastTile = index == itemCount - 1;
return SettingActionButton(
isLastTile: isLastTile,
tileHeight: tileHeight,
selectionActive: false,
fromBottomEdge: fromBottomEdge,
fromTopEdge: fromTopEdge,
onTap: () => item.onTap.call(context),
image: item.image,
title: item.name.call(context),
);
},
separatorBuilder: (_, index) => Container(
height: 1,
color: Theme.of(context).extension<CakeMenuTheme>()!.dividerColor,
),
itemCount: itemCount + 1,
),
),
),
),
], ],
); );
} }

View file

@ -1,6 +1,9 @@
import 'package:cake_wallet/buy/buy_provider_description.dart'; import 'package:cake_wallet/buy/buy_provider_description.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/buy/get_buy_provider_icon.dart'; import 'package:cake_wallet/buy/get_buy_provider_icon.dart';
import 'package:cake_wallet/themes/extensions/order_theme.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
class OrderRow extends StatelessWidget { class OrderRow extends StatelessWidget {
OrderRow({ OrderRow({
@ -20,7 +23,7 @@ class OrderRow extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final iconColor = final iconColor =
Theme.of(context).primaryTextTheme!.displayLarge!.backgroundColor!; Theme.of(context).extension<OrderTheme>()!.iconColor;
final providerIcon = getBuyProviderIcon(provider, iconColor: iconColor); final providerIcon = getBuyProviderIcon(provider, iconColor: iconColor);
@ -48,14 +51,14 @@ class OrderRow extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor! color: Theme.of(context).extension<DashboardPageTheme>()!.textColor
)), )),
formattedAmount != null formattedAmount != null
? Text(formattedAmount! + ' ' + to, ? Text(formattedAmount! + ' ' + to,
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor! color: Theme.of(context).extension<DashboardPageTheme>()!.textColor
)) ))
: Container() : Container()
]), ]),
@ -66,10 +69,7 @@ class OrderRow extends StatelessWidget {
Text(createdAtFormattedDate, Text(createdAtFormattedDate,
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 14,
color: Theme.of(context) color: Theme.of(context).extension<CakeTextTheme>()!.dateSectionRowColor))
.textTheme!
.labelSmall!
.backgroundColor!))
]) ])
], ],
) )

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/rounded_checkbox.dart'; import 'package:cake_wallet/src/screens/ionia/widgets/rounded_checkbox.dart';
import 'package:cake_wallet/src/widgets/alert_background.dart'; import 'package:cake_wallet/src/widgets/alert_background.dart';
@ -10,22 +11,16 @@ import 'package:cake_wallet/generated/i18n.dart';
class PresentReceiveOptionPicker extends StatelessWidget { class PresentReceiveOptionPicker extends StatelessWidget {
PresentReceiveOptionPicker( PresentReceiveOptionPicker(
{required this.receiveOptionViewModel, this.hasWhiteBackground = false}); {required this.receiveOptionViewModel, required this.color});
final ReceiveOptionViewModel receiveOptionViewModel; final ReceiveOptionViewModel receiveOptionViewModel;
final bool hasWhiteBackground; final Color color;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final textIconTheme = hasWhiteBackground
? Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!
: Colors.white;
final arrowBottom = Image.asset( final arrowBottom = Image.asset(
'assets/images/arrow_bottom_purple_icon.png', 'assets/images/arrow_bottom_purple_icon.png',
color: textIconTheme, color: color,
height: 6, height: 6,
); );
@ -51,14 +46,14 @@ class PresentReceiveOptionPicker extends StatelessWidget {
fontSize: 18.0, fontSize: 18.0,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontFamily: 'Lato', fontFamily: 'Lato',
color: textIconTheme), color: color),
), ),
Observer( Observer(
builder: (_) => Text(receiveOptionViewModel.selectedReceiveOption.toString(), builder: (_) => Text(receiveOptionViewModel.selectedReceiveOption.toString(),
style: TextStyle( style: TextStyle(
fontSize: 10.0, fontSize: 10.0,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: textIconTheme))) color: color)))
], ],
), ),
SizedBox(width: 5), SizedBox(width: 5),
@ -113,10 +108,7 @@ class PresentReceiveOptionPicker extends StatelessWidget {
Text(option.toString(), Text(option.toString(),
textAlign: TextAlign.left, textAlign: TextAlign.left,
style: textSmall( style: textSmall(
color: Theme.of(context) color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
.primaryTextTheme!
.titleLarge!
.color!,
).copyWith( ).copyWith(
fontWeight: fontWeight:
value == option ? FontWeight.w800 : FontWeight.w500, value == option ? FontWeight.w800 : FontWeight.w500,

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/core/sync_status_title.dart'; import 'package:cake_wallet/core/sync_status_title.dart';
@ -32,7 +33,7 @@ class SyncIndicator extends StatelessWidget {
child: Container( child: Container(
height: 30, height: 30,
width: syncIndicatorWidth, width: syncIndicatorWidth,
color: Theme.of(context).textTheme!.titleLarge!.decorationColor!, color: Theme.of(context).extension<SyncIndicatorTheme>()!.notSyncedBackgroundColor,
child: Stack( child: Stack(
alignment: Alignment.center, alignment: Alignment.center,
children: <Widget>[ children: <Widget>[
@ -44,7 +45,7 @@ class SyncIndicator extends StatelessWidget {
child: Container( child: Container(
width: indicatorWidth, width: indicatorWidth,
height: 30, height: 30,
color: Theme.of(context).textTheme!.titleLarge!.backgroundColor!, color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
) )
) )
: Offstage(), : Offstage(),
@ -66,7 +67,7 @@ class SyncIndicator extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Theme.of(context).textTheme!.titleLarge!.color! color: Theme.of(context).extension<SyncIndicatorTheme>()!.textColor
), ),
), ),
) )

View file

@ -1,3 +1,5 @@
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/palette.dart';
@ -26,7 +28,7 @@ class SyncIndicatorIcon extends StatelessWidget {
if (boolMode) { if (boolMode) {
indicatorColor = isSynced indicatorColor = isSynced
? PaletteDark.brightGreen ? PaletteDark.brightGreen
: Theme.of(context).textTheme!.bodySmall!.color!; : Theme.of(context).extension<SyncIndicatorTheme>()!.notSyncedIconColor;
} else { } else {
switch (value.toLowerCase()) { switch (value.toLowerCase()) {
case waiting: case waiting:
@ -34,7 +36,7 @@ class SyncIndicatorIcon extends StatelessWidget {
break; break;
case actionRequired: case actionRequired:
indicatorColor = indicatorColor =
Theme.of(context).textTheme!.displayMedium!.decorationColor!; Theme.of(context).extension<ReceivePageTheme>()!.currentTileBackgroundColor;
break; break;
case created: case created:
indicatorColor = PaletteDark.brightGreen; indicatorColor = PaletteDark.brightGreen;

View file

@ -1,6 +1,8 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/crypto_currency.dart';
import 'package:cake_wallet/exchange/exchange_provider_description.dart'; import 'package:cake_wallet/exchange/exchange_provider_description.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
class TradeRow extends StatelessWidget { class TradeRow extends StatelessWidget {
TradeRow({ TradeRow({
@ -43,14 +45,14 @@ class TradeRow extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!)), color: Theme.of(context).extension<DashboardPageTheme>()!.textColor)),
formattedAmount != null formattedAmount != null
? Text(formattedAmount! + ' ' + amountCrypto, ? Text(formattedAmount! + ' ' + amountCrypto,
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: color:
Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!)) Theme.of(context).extension<DashboardPageTheme>()!.textColor))
: Container() : Container()
]), ]),
SizedBox(height: 5), SizedBox(height: 5),
@ -59,7 +61,7 @@ class TradeRow extends StatelessWidget {
Text(createdAtFormattedDate!, Text(createdAtFormattedDate!,
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 14,
color: Theme.of(context).textTheme!.labelSmall!.backgroundColor!)) color: Theme.of(context).extension<CakeTextTheme>()!.dateSectionRowColor))
]) ])
], ],
)) ))

View file

@ -1,5 +1,8 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cw_core/transaction_direction.dart'; import 'package:cw_core/transaction_direction.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
class TransactionRow extends StatelessWidget { class TransactionRow extends StatelessWidget {
TransactionRow( TransactionRow(
@ -35,7 +38,7 @@ class TransactionRow extends StatelessWidget {
width: 36, width: 36,
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
color: Theme.of(context).textTheme!.labelSmall!.decorationColor! color: Theme.of(context).extension<TransactionTradeTheme>()!.rowsColor
), ),
child: Image.asset( child: Image.asset(
direction == TransactionDirection.incoming direction == TransactionDirection.incoming
@ -54,14 +57,12 @@ class TransactionRow extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme! color: Theme.of(context).extension<DashboardPageTheme>()!.textColor)),
.displayMedium!.backgroundColor!)),
Text(formattedAmount, Text(formattedAmount,
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme! color: Theme.of(context).extension<DashboardPageTheme>()!.textColor))
.displayMedium!.backgroundColor!))
]), ]),
SizedBox(height: 5), SizedBox(height: 5),
Row( Row(
@ -70,17 +71,11 @@ class TransactionRow extends StatelessWidget {
Text(formattedDate, Text(formattedDate,
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 14,
color: Theme.of(context) color: Theme.of(context).extension<CakeTextTheme>()!.dateSectionRowColor)),
.textTheme!
.labelSmall!
.backgroundColor!)),
Text(formattedFiatAmount, Text(formattedFiatAmount,
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 14,
color: Theme.of(context) color: Theme.of(context).extension<CakeTextTheme>()!.dateSectionRowColor))
.textTheme!
.labelSmall!
.backgroundColor!))
]) ])
], ],
) )

View file

@ -1,5 +1,6 @@
import 'package:cake_wallet/src/screens/dashboard/widgets/anonpay_transaction_row.dart'; 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/screens/dashboard/widgets/order_row.dart';
import 'package:cake_wallet/themes/extensions/placeholder_theme.dart';
import 'package:cake_wallet/src/widgets/dashboard_card_widget.dart'; import 'package:cake_wallet/src/widgets/dashboard_card_widget.dart';
import 'package:cake_wallet/utils/responsive_layout_util.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/anonpay_transaction_list_item.dart';
@ -155,10 +156,7 @@ class TransactionsPage extends StatelessWidget {
S.of(context).placeholder_transactions, S.of(context).placeholder_transactions,
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 14,
color: Theme.of(context) color: Theme.of(context).extension<PlaceholderTheme>()!.color),
.primaryTextTheme
.labelSmall!
.decorationColor!),
), ),
); );
})) }))

View file

@ -1,6 +1,8 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'dart:ui'; import 'dart:ui';
import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
@ -87,10 +89,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
style: TextStyle( style: TextStyle(
fontSize: 20.0, fontSize: 20.0,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Theme.of(context) color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
.primaryTextTheme!
.titleLarge!
.color!),
), ),
) )
], ],
@ -107,10 +106,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
style: TextStyle( style: TextStyle(
fontSize: 12.0, fontSize: 12.0,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Theme.of(context) color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
.primaryTextTheme!
.titleLarge!
.color!),
), ),
) )
], ],
@ -126,10 +122,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
style: TextStyle( style: TextStyle(
fontSize: 12.0, fontSize: 12.0,
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
color: Theme.of(context) color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
.primaryTextTheme!
.titleLarge!
.color!),
)) ))
], ],
), ),
@ -146,10 +139,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
style: TextStyle( style: TextStyle(
fontSize: 14.0, fontSize: 14.0,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Theme.of(context) color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
.primaryTextTheme!
.titleLarge!
.color!),
), ),
) )
], ],
@ -167,7 +157,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
changenowUrl, changenowUrl,
textAlign: TextAlign.left, textAlign: TextAlign.left,
style: TextStyle( style: TextStyle(
color: Palette.blueCraiola, color: Theme.of(context).primaryColor,
fontSize: 14.0, fontSize: 14.0,
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
decoration: TextDecoration.underline), decoration: TextDecoration.underline),
@ -193,7 +183,8 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
gradient: LinearGradient( gradient: LinearGradient(
colors: [ colors: [
Theme.of(context) Theme.of(context)
.backgroundColor .colorScheme
.background
.withOpacity(0.0), .withOpacity(0.0),
Theme.of(context).colorScheme.background, Theme.of(context).colorScheme.background,
], ],
@ -232,10 +223,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all( border: Border.all(
color: Theme.of(context) color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor,
.primaryTextTheme!
.bodySmall!
.color!,
width: 1.0), width: 1.0),
borderRadius: BorderRadius.all( borderRadius: BorderRadius.all(
Radius.circular(8.0)), Radius.circular(8.0)),
@ -253,10 +241,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 14.0, fontSize: 14.0,
color: Theme.of(context) color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
.primaryTextTheme!
.titleLarge!
.color!),
) )
], ],
), ),
@ -273,14 +258,8 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
.popAndPushNamed(Routes.welcome) .popAndPushNamed(Routes.welcome)
: null, : null,
text: 'Accept', text: 'Accept',
color: Theme.of(context) color: Theme.of(context).extension<WalletListTheme>()!.createNewWalletButtonBackgroundColor,
.accentTextTheme! textColor: Theme.of(context).extension<WalletListTheme>()!.restoreWalletButtonTextColor),
.titleSmall!
.decorationColor!,
textColor: Theme.of(context)
.accentTextTheme!
.headlineSmall!
.decorationColor!),
), ),
], ],
], ],

View file

@ -1,8 +1,11 @@
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
import 'package:cake_wallet/core/auth_service.dart'; import 'package:cake_wallet/core/auth_service.dart';
import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/src/screens/exchange/widgets/desktop_exchange_cards_section.dart'; import 'package:cake_wallet/src/screens/exchange/widgets/desktop_exchange_cards_section.dart';
import 'package:cake_wallet/src/screens/exchange/widgets/mobile_exchange_cards_section.dart'; import 'package:cake_wallet/src/screens/exchange/widgets/mobile_exchange_cards_section.dart';
import 'package:cake_wallet/src/widgets/add_template_button.dart'; import 'package:cake_wallet/src/widgets/add_template_button.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
import 'package:cake_wallet/themes/theme_base.dart'; import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/utils/debounce.dart'; import 'package:cake_wallet/utils/debounce.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart'; import 'package:cake_wallet/utils/responsive_layout_util.dart';
@ -78,7 +81,10 @@ class ExchangePage extends BasePage {
String get title => S.current.exchange; String get title => S.current.exchange;
@override @override
Color get titleColor => Colors.white; bool get gradientBackground => true;
@override
bool get gradientAll => true;
@override @override
bool get resizeToAvoidBottomInset => false; bool get resizeToAvoidBottomInset => false;
@ -115,7 +121,7 @@ class ExchangePage extends BasePage {
Widget? leading(BuildContext context) { Widget? leading(BuildContext context) {
final _backButton = Icon( final _backButton = Icon(
Icons.arrow_back_ios, Icons.arrow_back_ios,
color: titleColor, color: titleColor(context),
size: 16, size: 16,
); );
final _closeButton = final _closeButton =
@ -152,7 +158,7 @@ class ExchangePage extends BasePage {
disableScroll: true, disableScroll: true,
config: KeyboardActionsConfig( config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS, keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor: Theme.of(context).accentTextTheme.bodyLarge!.backgroundColor!, keyboardBarColor: Theme.of(context).extension<KeyboardTheme>()!.keyboardBarColor,
nextFocus: false, nextFocus: false,
actions: [ actions: [
KeyboardActionsItem( KeyboardActionsItem(
@ -205,8 +211,8 @@ class ExchangePage extends BasePage {
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
color: Theme.of(context) color: Theme.of(context)
.primaryTextTheme.displayLarge! .extension<ExchangePageTheme>()!
.decorationColor!, .receiveAmountColor,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
fontSize: 12), fontSize: 12),
), ),
@ -244,7 +250,7 @@ class ExchangePage extends BasePage {
} }
} }
}, },
color: Theme.of(context).accentTextTheme.bodyLarge!.color!, color: Theme.of(context).primaryColor,
textColor: Colors.white, textColor: Colors.white,
isDisabled: exchangeViewModel.selectedProviders.isEmpty, isDisabled: exchangeViewModel.selectedProviders.isEmpty,
isLoading: exchangeViewModel.tradeState is TradeIsCreating)), isLoading: exchangeViewModel.tradeState is TradeIsCreating)),
@ -624,8 +630,8 @@ class ExchangePage extends BasePage {
}, },
imageArrow: arrowBottomPurple, imageArrow: arrowBottomPurple,
currencyButtonColor: Colors.transparent, currencyButtonColor: Colors.transparent,
addressButtonsColor: Theme.of(context).focusColor, addressButtonsColor: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
borderColor: Theme.of(context).primaryTextTheme.bodyLarge!.color!, borderColor: Theme.of(context).extension<ExchangePageTheme>()!.textFieldBorderTopPanelColor,
currencyValueValidator: (value) { currencyValueValidator: (value) {
return !exchangeViewModel.isFixedRateMode return !exchangeViewModel.isFixedRateMode
? AmountValidator( ? AmountValidator(
@ -672,8 +678,8 @@ class ExchangePage extends BasePage {
exchangeViewModel.changeReceiveCurrency(currency: currency), exchangeViewModel.changeReceiveCurrency(currency: currency),
imageArrow: arrowBottomCakeGreen, imageArrow: arrowBottomCakeGreen,
currencyButtonColor: Colors.transparent, currencyButtonColor: Colors.transparent,
addressButtonsColor: Theme.of(context).focusColor, addressButtonsColor: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
borderColor: Theme.of(context).primaryTextTheme.bodyLarge!.decorationColor!, borderColor: Theme.of(context).extension<ExchangePageTheme>()!.textFieldBorderBottomPanelColor,
currencyValueValidator: (value) { currencyValueValidator: (value) {
return exchangeViewModel.isFixedRateMode return exchangeViewModel.isFixedRateMode
? AmountValidator( ? AmountValidator(

View file

@ -1,3 +1,5 @@
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
import 'package:cake_wallet/exchange/exchange_provider.dart'; import 'package:cake_wallet/exchange/exchange_provider.dart';
import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart'; import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
@ -29,10 +31,10 @@ class ExchangeTemplatePage extends BasePage {
var _isReactionsSet = false; var _isReactionsSet = false;
@override @override
String get title => S.current.exchange_new_template; bool get gradientAll => true;
@override @override
Color get titleColor => Colors.white; String get title => S.current.exchange_new_template;
@override @override
bool get extendBodyBehindAppBar => true; bool get extendBodyBehindAppBar => true;
@ -73,10 +75,7 @@ class ExchangeTemplatePage extends BasePage {
disableScroll: true, disableScroll: true,
config: KeyboardActionsConfig( config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS, keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor: Theme.of(context) keyboardBarColor: Theme.of(context).extension<KeyboardTheme>()!.keyboardBarColor,
.accentTextTheme!
.bodyLarge!
.backgroundColor!,
nextFocus: false, nextFocus: false,
actions: [ actions: [
KeyboardActionsItem( KeyboardActionsItem(
@ -101,8 +100,8 @@ class ExchangeTemplatePage extends BasePage {
), ),
gradient: LinearGradient( gradient: LinearGradient(
colors: [ colors: [
Theme.of(context).primaryTextTheme!.bodyMedium!.color!, Theme.of(context).extension<ExchangePageTheme>()!.firstGradientBottomPanelColor,
Theme.of(context).primaryTextTheme!.bodyMedium!.decorationColor!, Theme.of(context).extension<ExchangePageTheme>()!.secondGradientBottomPanelColor,
], ],
stops: [0.35, 1.0], stops: [0.35, 1.0],
begin: Alignment.topLeft, begin: Alignment.topLeft,
@ -120,12 +119,8 @@ class ExchangeTemplatePage extends BasePage {
), ),
gradient: LinearGradient( gradient: LinearGradient(
colors: [ colors: [
Theme.of(context) Theme.of(context).extension<ExchangePageTheme>()!.firstGradientTopPanelColor,
.primaryTextTheme!.titleSmall! Theme.of(context).extension<ExchangePageTheme>()!.secondGradientTopPanelColor,
.color!,
Theme.of(context)
.primaryTextTheme!.titleSmall!
.decorationColor!,
], ],
begin: Alignment.topLeft, begin: Alignment.topLeft,
end: Alignment.bottomRight), end: Alignment.bottomRight),
@ -157,10 +152,8 @@ class ExchangeTemplatePage extends BasePage {
imageArrow: arrowBottomPurple, imageArrow: arrowBottomPurple,
currencyButtonColor: Colors.transparent, currencyButtonColor: Colors.transparent,
addressButtonsColor: addressButtonsColor:
Theme.of(context).focusColor, Theme.of(context).extension<ExchangePageTheme>()!.textFieldButtonColor,
borderColor: Theme.of(context) borderColor: Theme.of(context).extension<ExchangePageTheme>()!.textFieldBorderBottomPanelColor,
.primaryTextTheme!.bodyLarge!
.color!,
currencyValueValidator: AmountValidator( currencyValueValidator: AmountValidator(
currency: exchangeViewModel.depositCurrency), currency: exchangeViewModel.depositCurrency),
//addressTextFieldValidator: AddressValidator( //addressTextFieldValidator: AddressValidator(
@ -197,10 +190,8 @@ class ExchangeTemplatePage extends BasePage {
imageArrow: arrowBottomCakeGreen, imageArrow: arrowBottomCakeGreen,
currencyButtonColor: Colors.transparent, currencyButtonColor: Colors.transparent,
addressButtonsColor: addressButtonsColor:
Theme.of(context).focusColor, Theme.of(context).extension<ExchangePageTheme>()!.textFieldButtonColor,
borderColor: Theme.of(context) borderColor: Theme.of(context).extension<ExchangePageTheme>()!.textFieldBorderBottomPanelColor,
.primaryTextTheme!.bodyLarge!
.decorationColor!,
currencyValueValidator: AmountValidator( currencyValueValidator: AmountValidator(
currency: exchangeViewModel.receiveCurrency), currency: exchangeViewModel.receiveCurrency),
//addressTextFieldValidator: AddressValidator( //addressTextFieldValidator: AddressValidator(
@ -226,9 +217,7 @@ class ExchangeTemplatePage extends BasePage {
description, description,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
color: Theme.of(context) color: Theme.of(context).extension<ExchangePageTheme>()!.receiveAmountColor,
.primaryTextTheme!.displayLarge!
.decorationColor!,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
fontSize: 12), fontSize: 12),
), ),
@ -256,7 +245,7 @@ class ExchangeTemplatePage extends BasePage {
} }
}, },
text: S.of(context).save, text: S.of(context).save,
color: Colors.green, color: Theme.of(context).primaryColor,
textColor: Colors.white), textColor: Colors.white),
]), ]),
)) ))
@ -444,4 +433,4 @@ class ExchangeTemplatePage extends BasePage {
key.currentState!.addressController.text = ''; key.currentState!.addressController.text = '';
} }
} }
} }

View file

@ -1,3 +1,5 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/extensions/cake_scrollbar_theme.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/palette.dart';
@ -20,10 +22,7 @@ class PickerItemWidget extends StatelessWidget {
return GestureDetector( return GestureDetector(
onTap: onTap, onTap: onTap,
child: Container( child: Container(
color: Theme.of(context) color: Theme.of(context).dialogTheme.backgroundColor,
.accentTextTheme!
.titleLarge!
.color!,
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 24), padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 24),
child: Row( child: Row(
@ -44,10 +43,7 @@ class PickerItemWidget extends StatelessWidget {
style: TextStyle( style: TextStyle(
color: isSelected color: isSelected
? Palette.blueCraiola ? Palette.blueCraiola
: Theme.of(context) : Theme.of(context).extension<CakeTextTheme>()!.titleColor,
.primaryTextTheme!
.titleLarge!
.color!,
fontSize: isSelected ? 16 : 14.0, fontSize: isSelected ? 16 : 14.0,
fontFamily: 'Lato', fontFamily: 'Lato',
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
@ -65,19 +61,13 @@ class PickerItemWidget extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontSize: 7.0, fontSize: 7.0,
fontFamily: 'Lato', fontFamily: 'Lato',
color: Theme.of(context) color: Theme.of(context).extension<CakeScrollbarTheme>()!.thumbColor),
.textTheme!
.bodyMedium!
.color!),
), ),
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6.0), borderRadius: BorderRadius.circular(6.0),
//border: Border.all(color: ), //border: Border.all(color: ),
color: Theme.of(context) color: Theme.of(context).extension<CakeScrollbarTheme>()!.trackColor,
.textTheme!
.bodyMedium!
.decorationColor!,
), ),
), ),
), ),
@ -86,10 +76,7 @@ class PickerItemWidget extends StatelessWidget {
), ),
if (isSelected) if (isSelected)
Icon(Icons.check_circle, Icon(Icons.check_circle,
color: Theme.of(context) color: Theme.of(context).primaryColor)
.accentTextTheme!
.bodyLarge!
.color!)
], ],
), ),
), ),

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/themes/extensions/picker_theme.dart';
import 'package:cw_core/currency.dart'; import 'package:cw_core/currency.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'currency_picker_item_widget.dart'; import 'currency_picker_item_widget.dart';
@ -20,10 +21,7 @@ class CurrencyPickerWidget extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
color: Theme.of(context) color: Theme.of(context).extension<PickerTheme>()!.dividerColor,
.accentTextTheme!
.titleLarge!
.backgroundColor!,
child: Scrollbar( child: Scrollbar(
controller: _scrollController, controller: _scrollController,
child: GridView.builder( child: GridView.builder(

View file

@ -1,6 +1,8 @@
import 'package:cake_wallet/entities/contact_base.dart'; import 'package:cake_wallet/entities/contact_base.dart';
import 'package:cake_wallet/themes/extensions/qr_code_theme.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
import 'package:cake_wallet/utils/show_bar.dart'; import 'package:cake_wallet/utils/show_bar.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/utils/payment_request.dart'; import 'package:cake_wallet/utils/payment_request.dart';
@ -12,6 +14,7 @@ import 'package:cw_core/crypto_currency.dart';
import 'package:cake_wallet/src/widgets/address_text_field.dart'; import 'package:cake_wallet/src/widgets/address_text_field.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart'; import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
class ExchangeCard extends StatefulWidget { class ExchangeCard extends StatefulWidget {
ExchangeCard( ExchangeCard(
@ -160,7 +163,7 @@ class ExchangeCardState extends State<ExchangeCard> {
final copyImage = Image.asset('assets/images/copy_content.png', final copyImage = Image.asset('assets/images/copy_content.png',
height: 16, height: 16,
width: 16, width: 16,
color: Theme.of(context).primaryTextTheme!.displaySmall!.color!); color: Theme.of(context).extension<SendPageTheme>()!.estimatedFeeColor);
return Container( return Container(
width: double.infinity, width: double.infinity,
@ -175,7 +178,7 @@ class ExchangeCardState extends State<ExchangeCard> {
style: TextStyle( style: TextStyle(
fontSize: 18, fontSize: 18,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Theme.of(context).textTheme!.headlineSmall!.color!), color: Theme.of(context).extension<QRCodeTheme>()!.qrCodeColor),
) )
], ],
), ),
@ -211,10 +214,7 @@ class ExchangeCardState extends State<ExchangeCard> {
height: 32, height: 32,
decoration: BoxDecoration( decoration: BoxDecoration(
color: widget.addressButtonsColor ?? color: widget.addressButtonsColor ??
Theme.of(context) Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
.primaryTextTheme!
.headlineMedium!
.color!,
borderRadius: borderRadius:
BorderRadius.all(Radius.circular(6))), BorderRadius.all(Radius.circular(6))),
child: Center( child: Center(
@ -224,10 +224,7 @@ class ExchangeCardState extends State<ExchangeCard> {
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Theme.of(context) color: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonIconColor)),
.primaryTextTheme!
.headlineMedium!
.decorationColor!)),
), ),
), ),
), ),
@ -268,10 +265,7 @@ class ExchangeCardState extends State<ExchangeCard> {
placeholderTextStyle: TextStyle( placeholderTextStyle: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Theme.of(context) color: Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor),
.accentTextTheme!
.displayLarge!
.decorationColor!),
validator: _isAmountEditable validator: _isAmountEditable
? widget.currencyValueValidator ? widget.currencyValueValidator
: null), : null),
@ -282,10 +276,7 @@ class ExchangeCardState extends State<ExchangeCard> {
height: 32, height: 32,
width: 32, width: 32,
decoration: BoxDecoration( decoration: BoxDecoration(
color: Theme.of(context) color: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
.primaryTextTheme!
.headlineMedium!
.color!,
borderRadius: borderRadius:
BorderRadius.all(Radius.circular(6))), BorderRadius.all(Radius.circular(6))),
child: InkWell( child: InkWell(
@ -296,10 +287,7 @@ class ExchangeCardState extends State<ExchangeCard> {
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Theme.of(context) color: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonIconColor)),
.primaryTextTheme!
.headlineMedium!
.decorationColor!)),
), ),
), ),
) )
@ -310,10 +298,7 @@ class ExchangeCardState extends State<ExchangeCard> {
)), )),
Divider( Divider(
height: 1, height: 1,
color: Theme.of(context) color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor),
.primaryTextTheme!
.headlineSmall!
.decorationColor!),
Padding( Padding(
padding: EdgeInsets.only(top: 5), padding: EdgeInsets.only(top: 5),
child: Container( child: Container(
@ -329,10 +314,7 @@ class ExchangeCardState extends State<ExchangeCard> {
style: TextStyle( style: TextStyle(
fontSize: 10, fontSize: 10,
height: 1.2, height: 1.2,
color: Theme.of(context) color: Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor),
.accentTextTheme!
.displayLarge!
.decorationColor!),
) )
: Offstage(), : Offstage(),
_min != null ? SizedBox(width: 10) : Offstage(), _min != null ? SizedBox(width: 10) : Offstage(),
@ -344,10 +326,7 @@ class ExchangeCardState extends State<ExchangeCard> {
style: TextStyle( style: TextStyle(
fontSize: 10, fontSize: 10,
height: 1.2, height: 1.2,
color: Theme.of(context) color: Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor))
.accentTextTheme!
.displayLarge!
.decorationColor!))
: Offstage(), : Offstage(),
])), ])),
), ),
@ -359,10 +338,7 @@ class ExchangeCardState extends State<ExchangeCard> {
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Theme.of(context) color: Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor),
.accentTextTheme!
.displayLarge!
.decorationColor!),
)) ))
: Offstage(), : Offstage(),
_isAddressEditable _isAddressEditable
@ -400,10 +376,7 @@ class ExchangeCardState extends State<ExchangeCard> {
hintStyle: TextStyle( hintStyle: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Theme.of(context) color: Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor),
.accentTextTheme!
.displayLarge!
.decorationColor!),
buttonColor: widget.addressButtonsColor, buttonColor: widget.addressButtonsColor,
validator: widget.addressTextFieldValidator, validator: widget.addressTextFieldValidator,
onPushPasteButton: widget.onPushPasteButton, onPushPasteButton: widget.onPushPasteButton,
@ -472,10 +445,7 @@ class ExchangeCardState extends State<ExchangeCard> {
6))), 6))),
child: Image.asset( child: Image.asset(
'assets/images/open_book.png', 'assets/images/open_book.png',
color: Theme.of(context) color: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonIconColor,
.primaryTextTheme!
.headlineMedium!
.decorationColor!,
)), )),
)), )),
), ),

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class MobileExchangeCardsSection extends StatelessWidget { class MobileExchangeCardsSection extends StatelessWidget {
@ -21,8 +22,8 @@ class MobileExchangeCardsSection extends StatelessWidget {
), ),
gradient: LinearGradient( gradient: LinearGradient(
colors: [ colors: [
Theme.of(context).primaryTextTheme!.bodyMedium!.color!, Theme.of(context).extension<ExchangePageTheme>()!.firstGradientBottomPanelColor,
Theme.of(context).primaryTextTheme!.bodyMedium!.decorationColor!, Theme.of(context).extension<ExchangePageTheme>()!.secondGradientBottomPanelColor,
], ],
stops: [0.35, 1.0], stops: [0.35, 1.0],
begin: Alignment.topLeft, begin: Alignment.topLeft,
@ -37,11 +38,8 @@ class MobileExchangeCardsSection extends StatelessWidget {
bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)), bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
gradient: LinearGradient( gradient: LinearGradient(
colors: [ colors: [
Theme.of(context).primaryTextTheme!.titleSmall!.color!, Theme.of(context).extension<ExchangePageTheme>()!.firstGradientTopPanelColor,
Theme.of(context) Theme.of(context).extension<ExchangePageTheme>()!.secondGradientTopPanelColor,
.primaryTextTheme!
.titleSmall!
.decorationColor!,
], ],
begin: Alignment.topLeft, begin: Alignment.topLeft,
end: Alignment.bottomRight, end: Alignment.bottomRight,

View file

@ -1,4 +1,5 @@
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/themes/extensions/qr_code_theme.dart';
import 'package:cake_wallet/src/widgets/check_box_picker.dart'; import 'package:cake_wallet/src/widgets/check_box_picker.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -49,10 +50,7 @@ class PresentProviderPicker extends StatelessWidget {
style: TextStyle( style: TextStyle(
fontSize: 10.0, fontSize: 10.0,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Theme.of(context) color: Theme.of(context).extension<QRCodeTheme>()!.qrCodeColor)))
.textTheme!
.headlineSmall!
.color!)))
], ],
), ),
SizedBox(width: 5), SizedBox(width: 5),

View file

@ -1,5 +1,7 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/exchange/exchange_provider_description.dart'; import 'package:cake_wallet/exchange/exchange_provider_description.dart';
import 'package:cake_wallet/store/dashboard/trades_store.dart'; import 'package:cake_wallet/store/dashboard/trades_store.dart';
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
import 'package:cake_wallet/utils/show_bar.dart'; import 'package:cake_wallet/utils/show_bar.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
@ -9,6 +11,7 @@ import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart'; import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/exchange/trade.dart'; import 'package:cake_wallet/exchange/trade.dart';
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
class ExchangeConfirmPage extends BasePage { class ExchangeConfirmPage extends BasePage {
ExchangeConfirmPage({required this.tradesStore}) : trade = tradesStore.trade!; ExchangeConfirmPage({required this.tradesStore}) : trade = tradesStore.trade!;
@ -36,10 +39,7 @@ class ExchangeConfirmPage extends BasePage {
style: TextStyle( style: TextStyle(
fontSize: 18.0, fontSize: 18.0,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Theme.of(context) color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
.primaryTextTheme!
.titleLarge!
.color!),
), ),
)), )),
Container( Container(
@ -48,14 +48,8 @@ class ExchangeConfirmPage extends BasePage {
borderRadius: BorderRadius.all(Radius.circular(30)), borderRadius: BorderRadius.all(Radius.circular(30)),
border: Border.all( border: Border.all(
width: 1, width: 1,
color: Theme.of(context) color: Theme.of(context).cardColor),
.accentTextTheme! color: Theme.of(context).dialogTheme.backgroundColor),
.bodySmall!
.color!),
color: Theme.of(context)
.accentTextTheme!
.titleLarge!
.color!),
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
Expanded( Expanded(
@ -70,10 +64,7 @@ class ExchangeConfirmPage extends BasePage {
style: TextStyle( style: TextStyle(
fontSize: 12.0, fontSize: 12.0,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Theme.of(context) color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor),
.primaryTextTheme!
.labelSmall!
.color!),
), ),
Text( Text(
trade.id, trade.id,
@ -82,10 +73,7 @@ class ExchangeConfirmPage extends BasePage {
style: TextStyle( style: TextStyle(
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Theme.of(context) color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
.primaryTextTheme!
.titleLarge!
.color!),
), ),
], ],
), ),
@ -100,14 +88,8 @@ class ExchangeConfirmPage extends BasePage {
context, S.of(context).copied_to_clipboard); context, S.of(context).copied_to_clipboard);
}, },
text: S.of(context).copy_id, text: S.of(context).copy_id,
color: Theme.of(context) color: Theme.of(context).extension<ExchangePageTheme>()!.buttonBackgroundColor,
.accentTextTheme! textColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
.bodySmall!
.backgroundColor!,
textColor: Theme.of(context)
.primaryTextTheme!
.titleLarge!
.color!),
), ),
) )
], ],
@ -136,10 +118,7 @@ class ExchangeConfirmPage extends BasePage {
onPressed: () => Navigator.of(context) onPressed: () => Navigator.of(context)
.pushReplacementNamed(Routes.exchangeTrade), .pushReplacementNamed(Routes.exchangeTrade),
text: S.of(context).saved_the_trade_id, text: S.of(context).saved_the_trade_id,
color: Theme.of(context) color: Theme.of(context).primaryColor,
.accentTextTheme!
.bodyLarge!
.color!,
textColor: Colors.white) textColor: Colors.white)
], ],
), ),

View file

@ -1,4 +1,6 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'dart:ui'; import 'dart:ui';
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
import 'package:cake_wallet/utils/request_review_handler.dart'; import 'package:cake_wallet/utils/request_review_handler.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_mobx/flutter_mobx.dart';
@ -20,6 +22,7 @@ import 'package:cake_wallet/src/screens/exchange_trade/widgets/timer_widget.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/scollable_with_bottom_section.dart'; import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.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/themes/extensions/transaction_trade_theme.dart';
void showInformation( void showInformation(
ExchangeTradeViewModel exchangeTradeViewModel, BuildContext context) { ExchangeTradeViewModel exchangeTradeViewModel, BuildContext context) {
@ -51,7 +54,7 @@ class ExchangeTradePage extends BasePage {
@override @override
Widget trailing(BuildContext context) { Widget trailing(BuildContext context) {
final questionImage = Image.asset('assets/images/question_mark.png', final questionImage = Image.asset('assets/images/question_mark.png',
color: Theme.of(context).primaryTextTheme!.titleLarge!.color!); color: Theme.of(context).extension<CakeTextTheme>()!.titleColor);
return SizedBox( return SizedBox(
height: 20.0, height: 20.0,
@ -111,7 +114,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
final copyImage = Image.asset('assets/images/copy_content.png', final copyImage = Image.asset('assets/images/copy_content.png',
height: 16, height: 16,
width: 16, width: 16,
color: Theme.of(context).primaryTextTheme!.labelSmall!.color!); color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor);
_setEffects(); _setEffects();
@ -133,17 +136,11 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
style: TextStyle( style: TextStyle(
fontSize: 14.0, fontSize: 14.0,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Theme.of(context) color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor),
.primaryTextTheme!
.labelSmall!
.color!),
), ),
if (trade.expiredAt != null) if (trade.expiredAt != null)
TimerWidget(trade.expiredAt!, TimerWidget(trade.expiredAt!,
color: Theme.of(context) color: Theme.of(context).extension<CakeTextTheme>()!.titleColor)
.primaryTextTheme!
.titleLarge!
.color!)
]) ])
: Offstage(), : Offstage(),
Padding( Padding(
@ -160,10 +157,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all( border: Border.all(
width: 3, width: 3,
color: Theme.of(context) color: Theme.of(context).extension<ExchangePageTheme>()!.qrCodeColor
.accentTextTheme!
.titleSmall!
.color!
) )
), ),
child: QrImage(data: trade.inputAddress ?? fetchingLabel), child: QrImage(data: trade.inputAddress ?? fetchingLabel),
@ -179,10 +173,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
itemCount: widget.exchangeTradeViewModel.items.length, itemCount: widget.exchangeTradeViewModel.items.length,
separatorBuilder: (context, index) => Container( separatorBuilder: (context, index) => Container(
height: 1, height: 1,
color: Theme.of(context) color: Theme.of(context).extension<ExchangePageTheme>()!.dividerCodeColor,
.accentTextTheme!
.titleSmall!
.backgroundColor!,
), ),
itemBuilder: (context, index) { itemBuilder: (context, index) {
final item = widget.exchangeTradeViewModel.items[index]; final item = widget.exchangeTradeViewModel.items[index];
@ -228,10 +219,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
onPressed: () => onPressed: () =>
widget.exchangeTradeViewModel.confirmSending(), widget.exchangeTradeViewModel.confirmSending(),
text: S.of(context).confirm, text: S.of(context).confirm,
color: Theme.of(context) color: Theme.of(context).primaryColor,
.accentTextTheme!
.bodyLarge!
.color!,
textColor: Colors.white) textColor: Colors.white)
: Offstage(); : Offstage();
})), })),
@ -321,7 +309,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
return Stack( return Stack(
children: <Widget>[ children: <Widget>[
Container( Container(
color: Theme.of(popupContext).backgroundColor, color: Theme.of(popupContext).colorScheme.background,
child: Center( child: Center(
child: Image.asset( child: Image.asset(
'assets/images/birthday_cake.png'), 'assets/images/birthday_cake.png'),
@ -341,10 +329,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
style: TextStyle( style: TextStyle(
fontSize: 22, fontSize: 22,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Theme.of(popupContext) color: Theme.of(popupContext).extension<CakeTextTheme>()!.titleColor,
.primaryTextTheme!
.titleLarge!
.color,
decoration: TextDecoration.none, decoration: TextDecoration.none,
), ),
), ),
@ -360,10 +345,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
RequestReviewHandler.requestReview(); RequestReviewHandler.requestReview();
}, },
text: S.of(popupContext).got_it, text: S.of(popupContext).got_it,
color: Theme.of(popupContext) color: Theme.of(popupContext).primaryColor,
.accentTextTheme!
.bodyLarge!
.color!,
textColor: Colors.white)) textColor: Colors.white))
], ],
); );
@ -372,7 +354,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
return Stack( return Stack(
children: <Widget>[ children: <Widget>[
Container( Container(
color: Theme.of(popupContext).backgroundColor, color: Theme.of(popupContext).colorScheme.background,
child: Center( child: Center(
child: Image.asset( child: Image.asset(
'assets/images/birthday_cake.png'), 'assets/images/birthday_cake.png'),
@ -384,7 +366,8 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: Theme.of(popupContext) color: Theme.of(popupContext)
.backgroundColor .colorScheme
.background
.withOpacity(0.25)), .withOpacity(0.25)),
child: Center( child: Center(
child: Padding( child: Padding(
@ -395,10 +378,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
style: TextStyle( style: TextStyle(
fontSize: 22, fontSize: 22,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Theme.of(popupContext) color: Theme.of(popupContext).extension<CakeTextTheme>()!.titleColor,
.primaryTextTheme!
.titleLarge!
.color!,
decoration: TextDecoration.none, decoration: TextDecoration.none,
), ),
), ),

View file

@ -1,9 +1,13 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'dart:ui'; import 'dart:ui';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart'; import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
import 'package:cake_wallet/themes/extensions/info_theme.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/src/widgets/alert_background.dart'; import 'package:cake_wallet/src/widgets/alert_background.dart';
import 'package:cake_wallet/themes/extensions/menu_theme.dart';
class InformationPage extends StatelessWidget { class InformationPage extends StatelessWidget {
InformationPage({required this.information}); InformationPage({required this.information});
@ -21,7 +25,7 @@ class InformationPage extends StatelessWidget {
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(30)), borderRadius: BorderRadius.all(Radius.circular(30)),
color: Theme.of(context).textTheme!.bodyLarge!.decorationColor! color: Theme.of(context).extension<CakeMenuTheme>()!.backgroundColor
), ),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@ -36,7 +40,7 @@ class InformationPage extends StatelessWidget {
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
fontFamily: 'Lato', fontFamily: 'Lato',
decoration: TextDecoration.none, decoration: TextDecoration.none,
color: Theme.of(context).accentTextTheme!.bodySmall!.decorationColor! color: Theme.of(context).extension<InfoTheme>()!.textColor
), ),
), ),
), ),
@ -45,8 +49,8 @@ class InformationPage extends StatelessWidget {
child: PrimaryButton( child: PrimaryButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
text: S.of(context).got_it, text: S.of(context).got_it,
color: Theme.of(context).accentTextTheme!.bodySmall!.backgroundColor!, color: Theme.of(context).extension<ExchangePageTheme>()!.buttonBackgroundColor,
textColor: Theme.of(context).primaryTextTheme!.titleLarge!.color! textColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor
), ),
) )
], ],

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/palette.dart';
@ -26,12 +27,12 @@ class FAQItemState extends State<FAQItem> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final addIcon = Icon(Icons.add, final addIcon = Icon(Icons.add,
color: Theme.of(context).primaryTextTheme!.titleLarge!.color!); color: Theme.of(context).extension<CakeTextTheme>()!.titleColor);
final removeIcon = Icon(Icons.remove, color: Palette.blueCraiola); final removeIcon = Icon(Icons.remove, color: Palette.blueCraiola);
final icon = isActive ? removeIcon : addIcon; final icon = isActive ? removeIcon : addIcon;
final color = isActive final color = isActive
? Palette.blueCraiola ? Palette.blueCraiola
: Theme.of(context).primaryTextTheme!.titleLarge!.color!; : Theme.of(context).extension<CakeTextTheme>()!.titleColor;
return ListTileTheme( return ListTileTheme(
contentPadding: EdgeInsets.fromLTRB(0, 6, 24, 6), contentPadding: EdgeInsets.fromLTRB(0, 6, 24, 6),
@ -54,7 +55,7 @@ class FAQItemState extends State<FAQItem> {
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
color: color:
Theme.of(context).primaryTextTheme!.titleLarge!.color!), Theme.of(context).extension<CakeTextTheme>()!.titleColor),
), ),
)) ))
]) ])

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/core/email_validator.dart'; import 'package:cake_wallet/core/email_validator.dart';
import 'package:cake_wallet/ionia/ionia_create_state.dart'; import 'package:cake_wallet/ionia/ionia_create_state.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
@ -40,10 +41,7 @@ class IoniaCreateAccountPage extends BasePage {
return Text( return Text(
S.current.sign_up, S.current.sign_up,
style: textMediumSemiBold( style: textMediumSemiBold(
color: Theme.of(context) color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
.accentTextTheme!
.displayLarge!
.backgroundColor!,
), ),
); );
} }
@ -84,10 +82,7 @@ class IoniaCreateAccountPage extends BasePage {
onPressed: _createAccount, onPressed: _createAccount,
isLoading: isLoading:
_authViewModel.createUserState is IoniaCreateStateLoading, _authViewModel.createUserState is IoniaCreateStateLoading,
color: Theme.of(context) color: Theme.of(context).primaryColor,
.accentTextTheme!
.bodyLarge!
.color!,
textColor: Colors.white, textColor: Colors.white,
), ),
), ),
@ -107,10 +102,7 @@ class IoniaCreateAccountPage extends BasePage {
TextSpan( TextSpan(
text: S.of(context).settings_terms_and_conditions, text: S.of(context).settings_terms_and_conditions,
style: TextStyle( style: TextStyle(
color: Theme.of(context) color: Theme.of(context).primaryColor,
.accentTextTheme!
.bodyLarge!
.color!,
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
), ),
recognizer: TapGestureRecognizer() recognizer: TapGestureRecognizer()
@ -122,10 +114,7 @@ class IoniaCreateAccountPage extends BasePage {
TextSpan( TextSpan(
text: S.of(context).privacy_policy, text: S.of(context).privacy_policy,
style: TextStyle( style: TextStyle(
color: Theme.of(context) color: Theme.of(context).primaryColor,
.accentTextTheme!
.bodyLarge!
.color!,
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
), ),
recognizer: TapGestureRecognizer() recognizer: TapGestureRecognizer()

Some files were not shown because too many files have changed in this diff Show more