Skip to content
16 changes: 16 additions & 0 deletions cw_bitcoin/lib/electrum_wallet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,19 @@ abstract class ElectrumWalletBase
reaction((_) => syncStatus, _syncStatusReaction);

sharedPrefs.complete(SharedPreferences.getInstance());

_onBalanceChangeReaction = reaction(
(_) => balance.entries.map((e) => e.value).toList(),
(_) {
for (final bal in balance.keys) {
if (balance[bal]?.formattedAvailableBalance != null) {
BalanceCache(bal.title, bal.tag ?? "", walletInfo.internalId,
balance[bal]!.formattedAvailableBalance)
.save();
}
}
},
);
}

static Bip32Slip10Secp256k1 getAccountHDWallet(
Expand Down Expand Up @@ -184,6 +197,8 @@ abstract class ElectrumWalletBase

final EncryptionFileUtils encryptionFileUtils;

late final ReactionDisposer _onBalanceChangeReaction;

@override
final String? passphrase;

Expand Down Expand Up @@ -1583,6 +1598,7 @@ abstract class ElectrumWalletBase
} catch (_) {}
_autoSaveTimer?.cancel();
_updateFeeRateTimer?.cancel();
_onBalanceChangeReaction.reaction.dispose();
}

@action
Expand Down
54 changes: 46 additions & 8 deletions cw_core/lib/wallet_info.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class WalletInfoAddressInfo {
String address;
String label;

static String get tableName => 'walletInfoAddressInfo';
static String get tableName => 'walletInfoAddressInfo';
static String get selfIdColumn => "${tableName}Id";

static Future<List<WalletInfoAddressInfo>> selectList(int walletInfoId) async {
Expand Down Expand Up @@ -134,8 +134,8 @@ class WalletInfoAddressMap {
String addressKey;
String addressValue;

static String get tableName => 'walletInfoAddressMap';
static String get selfIdColumn => "${tableName}Id";
static String get tableName => 'walletInfoAddressMap';
static String get selfIdColumn => "${tableName}Id";

static Future<List<WalletInfoAddressMap>> selectList(int walletInfoId) async {
final query = await db.query(tableName, where: 'walletInfoId = ?', whereArgs: [walletInfoId]);
Expand Down Expand Up @@ -184,7 +184,7 @@ class WalletInfoAddress {
WalletInfoAddressType type;
String address;

static String get tableName => 'walletInfoAddress';
static String get tableName => 'walletInfoAddress';
static String get selfIdColumn => "${tableName}Id";

static Future<List<WalletInfoAddress>> selectList(int walletInfoId, WalletInfoAddressType type) async {
Expand Down Expand Up @@ -245,7 +245,7 @@ class DerivationInfo {

int id;

static String get tableName => 'walletInfoDerivationInfo';
static String get tableName => 'walletInfoDerivationInfo';
static String get selfIdColumn => "${tableName}Id";

String address;
Expand All @@ -262,7 +262,7 @@ class DerivationInfo {
columns: [
selfIdColumn,
'address',
'balance',
'balance',
'transactionsCount',
'derivationType',
'derivationPath',
Expand Down Expand Up @@ -377,7 +377,7 @@ class WalletInfo {
);
}

static String get tableName => 'walletInfo';
static String get tableName => 'walletInfo';
static String get selfIdColumn => "${tableName}Id";

int internalId;
Expand Down Expand Up @@ -495,7 +495,7 @@ class WalletInfo {
String? parentAddress;
String? hashedWalletIdentifier;
bool isNonSeedWallet;

int sortOrder;

String get yatLastUsedAddress => yatLastUsedAddressRaw ?? '';
Expand Down Expand Up @@ -615,3 +615,41 @@ class WalletInfo {
await save();
}
}

class BalanceCache {
final String title;
final String tag;
final int walletInfoId;
final String cachedBalance;

static String get tableName => "BalanceCache";

const BalanceCache(this.title, this.tag, this.walletInfoId, this.cachedBalance);

BalanceCache.fromJson(Map<String, dynamic> json)
: title = json['title'] as String,
tag = json['tag'] as String,
walletInfoId = json['walletInfoId'] as int,
cachedBalance = json['cachedBalance'] as String;

Map<String, dynamic> toJson() => {
'title': title,
'tag': tag,
'walletInfoId': walletInfoId,
'cachedBalance': cachedBalance,
};

static Future<List<BalanceCache>> fromWalletId(int walletInfoId) async {
final list = await db.query(
tableName,
where: 'walletInfoId = ?',
whereArgs: [walletInfoId],
);
return List.generate(list.length, (index) => BalanceCache.fromJson(list[index]));
}

Future<void> save() async {
final json = toJson();
await db.insert(tableName, json, conflictAlgorithm: ConflictAlgorithm.replace);
}
}
24 changes: 21 additions & 3 deletions cw_evm/lib/evm_chain_wallet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,28 @@ abstract class EVMChainWalletBase
}

sharedPrefs.complete(SharedPreferences.getInstance());

_onBalanceChangeReaction = reaction(
(_) => balance.entries.map((e) => e.value).toList(),
(_) {
for (final bal in balance.keys) {
if (balance[bal]?.formattedAvailableBalance != null) {
BalanceCache(bal.title, bal.tag ?? "", walletInfo.internalId,
balance[bal]!.formattedAvailableBalance)
.save();
}
}
},
);
}

final String? _mnemonic;
final String? _hexPrivateKey;
final String _password;
final EncryptionFileUtils encryptionFileUtils;

late final ReactionDisposer _onBalanceChangeReaction;

late final Box<Erc20Token> erc20TokensBox;

late final Box<Erc20Token> evmChainErc20TokensBox;
Expand Down Expand Up @@ -334,7 +349,8 @@ abstract class EVMChainWalletBase
final gasUnits = await _client.getEstimatedGasUnitsForTransaction(
senderAddress: evmChainPrivateKey.address,
toAddress: evmChainPrivateKey.address,
contractAddress: _getUSDCContractAddress(), // Using USDC for default estimation
contractAddress: _getUSDCContractAddress(),
// Using USDC for default estimation
gasPrice: EtherAmount.fromInt(EtherUnit.wei, gasPrice),
value: EtherAmount.fromBigInt(EtherUnit.wei, BigInt.from(0.0000000001)),
);
Expand Down Expand Up @@ -413,6 +429,7 @@ abstract class EVMChainWalletBase
Future<void> close({bool shouldCleanup = false}) async {
_client.stop();
_transactionsUpdateTimer?.cancel();
_onBalanceChangeReaction.reaction.dispose();
}

@action
Expand Down Expand Up @@ -609,7 +626,8 @@ abstract class EVMChainWalletBase
) async {
// Estimate gas with the SAME call (sender, to, value, data)
final gas = await calculateActualEstimatedFeeForCreateTransaction(
amount: valueWei, // native value (usually 0 for ERC20 transfer)
amount: valueWei,
// native value (usually 0 for ERC20 transfer)
receivingAddressHex: to,
priority: priority,
contractAddress: null,
Expand Down Expand Up @@ -806,7 +824,6 @@ abstract class EVMChainWalletBase

Future<void> _updateBalance() async {
balance[currency] = await _fetchEVMChainBalance();

await _fetchErc20Balances();
await save();
}
Expand Down Expand Up @@ -882,6 +899,7 @@ abstract class EVMChainWalletBase

@override
Future<void>? updateBalance() async => await _updateBalance();

@override
Future<void> updateTransactionsHistory() async => await _updateTransactions();

Expand Down
16 changes: 16 additions & 0 deletions cw_monero/lib/monero_wallet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,19 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
_onTxHistoryChangeReaction = reaction((_) => transactionHistory, (__) {
_updateSubAddress(isEnabledAutoGenerateSubaddress, account: walletAddresses.account);
});

_onBalanceChangeReaction = reaction(
(_) => balance.entries.map((e) => e.value).toList(),
(_) {
for (final bal in balance.keys) {
if (balance[bal]?.formattedAvailableBalance != null) {
BalanceCache(bal.title, bal.tag ?? "", walletInfo.internalId,
balance[bal]!.formattedAvailableBalance)
.save();
}
}
},
);
}

static const int _autoSaveInterval = 30;
Expand Down Expand Up @@ -147,6 +160,8 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
monero_wallet.SyncListener? _listener;
ReactionDisposer? _onAccountChangeReaction;
ReactionDisposer? _onTxHistoryChangeReaction;
late final ReactionDisposer _onBalanceChangeReaction;

bool _isTransactionUpdating;
bool _hasSyncAfterStartup;
Timer? _autoSaveTimer;
Expand Down Expand Up @@ -224,6 +239,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
_listener?.stop();
_onAccountChangeReaction?.reaction.dispose();
_onTxHistoryChangeReaction?.reaction.dispose();
_onBalanceChangeReaction.reaction.dispose();
_autoSaveTimer?.cancel();
}

Expand Down
16 changes: 16 additions & 0 deletions cw_nano/lib/nano_wallet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,19 @@ abstract class NanoWalletBase
if (!CakeHive.isAdapterRegistered(NanoAccount.typeId)) {
CakeHive.registerAdapter(NanoAccountAdapter());
}

_onBalanceChangeReaction = reaction(
(_) => balance.entries.map((e) => e.value).toList(),
(_) {
for (final bal in balance.keys) {
if (balance[bal]?.formattedAvailableBalance != null) {
BalanceCache(bal.title, bal.tag ?? "", walletInfo.internalId,
balance[bal]!.formattedAvailableBalance)
.save();
}
}
},
);
}

String _mnemonic;
Expand All @@ -75,6 +88,8 @@ abstract class NanoWalletBase

final EncryptionFileUtils _encryptionFileUtils;

late final ReactionDisposer _onBalanceChangeReaction;

String? _privateKey;
String? _publicAddress;
String? _hexSeed;
Expand Down Expand Up @@ -154,6 +169,7 @@ abstract class NanoWalletBase
Future<void> close({bool shouldCleanup = false}) async {
_client.stop();
_receiveTimer?.cancel();
_onBalanceChangeReaction.reaction.dispose();
}

@action
Expand Down
16 changes: 16 additions & 0 deletions cw_solana/lib/solana_wallet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,19 @@ abstract class SolanaWalletBase
CakeHive.registerAdapter(SPLTokenAdapter());
}

_onBalanceChangeReaction = reaction(
(_) => balance.entries.map((e) => e.value).toList(),
(_) {
for (final bal in balance.keys) {
if (balance[bal]?.formattedAvailableBalance != null) {
BalanceCache(bal.title, bal.tag ?? "", walletInfo.internalId,
balance[bal]!.formattedAvailableBalance)
.save();
}
}
},
);

_sharedPrefs.complete(SharedPreferences.getInstance());
}

Expand All @@ -78,6 +91,8 @@ abstract class SolanaWalletBase
final String? _hexPrivateKey;
final EncryptionFileUtils encryptionFileUtils;

late final ReactionDisposer _onBalanceChangeReaction;

late final SolanaWalletClient _client;

@observable
Expand Down Expand Up @@ -185,6 +200,7 @@ abstract class SolanaWalletBase
Future<void> close({bool shouldCleanup = false}) async {
_client.stop();
_transactionsUpdateTimer?.cancel();
_onBalanceChangeReaction.reaction.dispose();
}

@action
Expand Down
20 changes: 19 additions & 1 deletion cw_tron/lib/tron_wallet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,28 @@ abstract class TronWalletBase
if (!CakeHive.isAdapterRegistered(TronToken.typeId)) {
CakeHive.registerAdapter(TronTokenAdapter());
}

_onBalanceChangeReaction = reaction(
(_) => balance.entries.map((e) => e.value).toList(),
(_) {
for (final bal in balance.keys) {
if (balance[bal]?.formattedAvailableBalance != null) {
BalanceCache(bal.title, bal.tag ?? "", walletInfo.internalId,
balance[bal]!.formattedAvailableBalance)
.save();
}
}
},
);
}

final String? _mnemonic;
final String? _hexPrivateKey;
final String _password;
final EncryptionFileUtils encryptionFileUtils;

late final ReactionDisposer _onBalanceChangeReaction;

late final Box<TronToken> tronTokensBox;

late final TronPrivateKey _tronPrivateKey;
Expand Down Expand Up @@ -228,7 +243,10 @@ abstract class TronWalletBase
Future<void> changePassword(String password) => throw UnimplementedError("changePassword");

@override
Future<void> close({bool shouldCleanup = false}) async => _transactionsUpdateTimer?.cancel();
Future<void> close({bool shouldCleanup = false}) async {
_transactionsUpdateTimer?.cancel();
_onBalanceChangeReaction.reaction.dispose();
}

@action
@override
Expand Down
Loading