Skip to content
Draft

charts #3162

Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
12aab78
charts (wip)
malik1004x Mar 27, 2026
6f26e86
Merge branch 'dev' into charts
malik1004x Apr 1, 2026
da10776
charts (wip)
malik1004x Apr 1, 2026
afad271
wip
malik1004x Apr 2, 2026
92d419b
Merge branch 'dev' into charts
malik1004x Apr 2, 2026
8b3cac8
add asset grid
malik1004x Apr 2, 2026
474271b
split files
malik1004x Apr 2, 2026
65aa1c6
logic wip
malik1004x Apr 3, 2026
ce036a2
proper getPrices logic
malik1004x Apr 3, 2026
86094b3
viewmodel (wip)
malik1004x Apr 3, 2026
1a39bed
Merge branch 'dev' into charts
malik1004x Apr 8, 2026
7c3bd24
charts
malik1004x Apr 9, 2026
4f1e216
remove unused import
malik1004x Apr 9, 2026
9327a9e
remove restricted import...?
malik1004x Apr 9, 2026
a7b3311
fix background gradient when scrolling
malik1004x Apr 9, 2026
bf26ddd
add safeguards for broken db
malik1004x Apr 9, 2026
71bff7e
save new pin on removal
malik1004x Apr 9, 2026
e993efc
add safeguards for concurrency
malik1004x Apr 9, 2026
b1d6a77
add haptic feedback
malik1004x Apr 9, 2026
2e88ccf
fix haptic feedback
malik1004x Apr 9, 2026
0ae4e9a
fix fiat ticker
malik1004x Apr 10, 2026
c81f95a
reduce chart padding
malik1004x Apr 10, 2026
e8f8c3d
add line touch indicator
malik1004x Apr 10, 2026
5386f47
improve touch target size on range selector
malik1004x Apr 10, 2026
10c1774
add date/time display when viewing past amount
malik1004x May 21, 2026
4b872da
Merge branch 'dev' into charts
malik1004x May 21, 2026
6efeace
merge
malik1004x May 21, 2026
6d3cc66
remove iconSvgPath reference
malik1004x May 21, 2026
5794b0d
merge
malik1004x May 21, 2026
2d63949
fix state for date display
malik1004x May 21, 2026
7fdcc2b
Merge branch 'dev' into charts
malik1004x Jul 6, 2026
e624694
merge
malik1004x Jul 6, 2026
aab0d55
Merge branch 'dev' into charts
malik1004x Jul 14, 2026
7abb38f
auto-reformat
malik1004x Jul 14, 2026
268964e
only load charts when page is opened
malik1004x Jul 17, 2026
a1587ae
Merge branch 'dev' into charts
malik1004x Jul 20, 2026
811b269
merge
malik1004x Jul 20, 2026
28b8a71
Merge branch 'dev' into charts
malik1004x Aug 5, 2026
0bfed99
reformat and apply lints
malik1004x Aug 5, 2026
045661a
refactor to use `Money` instead of storing amount in `String`
malik1004x Aug 14, 2026
e898285
Merge branch 'dev' into charts
malik1004x Aug 14, 2026
9514e1e
add slop comment
malik1004x Aug 14, 2026
c1b1118
fix exception on division by zero
malik1004x Aug 14, 2026
5f340ed
ci
malik1004x Aug 14, 2026
6078598
Merge branch 'dev' into charts
malik1004x Aug 20, 2026
464428d
workaround toDouble being removed
malik1004x Aug 20, 2026
5195ea9
Merge branch 'dev' into charts
malik1004x Aug 24, 2026
8cf7cfd
disable strict parsing and rounding
malik1004x Aug 24, 2026
ef613ab
fix abs()
malik1004x Aug 24, 2026
7f987aa
use new currency picker sheet
malik1004x Aug 26, 2026
74dd375
Merge branch 'dev' into charts
malik1004x Sep 10, 2026
2ffc763
safeguard for max flutter-supported decimals
malik1004x Sep 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cw_core/lib/crypto_currency.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen

@override
String get symbol => title;
@override
String get apiString => "crypto.$title";

set enabled(bool value) => this.enabled = value;

Expand Down
1 change: 1 addition & 0 deletions cw_core/lib/currency.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ abstract class Currency {

@override
int get hashCode => decimals.hashCode ^ symbol.hashCode ^ tag.hashCode;
String get apiString;
}
228 changes: 130 additions & 98 deletions cw_core/lib/db/sqlite.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import 'dart:io';
import "dart:io";

import 'package:cw_core/db/sqlite_debug.dart';
import 'package:cw_core/root_dir.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:flutter/foundation.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
import 'package:path/path.dart' as p;
import "package:cw_core/db/sqlite_debug.dart";
import "package:cw_core/root_dir.dart";
import "package:cw_core/utils/print_verbose.dart";
import "package:flutter/foundation.dart";
import "package:path/path.dart" as p;
import "package:sqflite_common_ffi/sqflite_ffi.dart";

Database? db;

Expand All @@ -16,11 +16,11 @@ Future<void> _addColumnIfNotExists(
required String definition,
}) async {
final result = await db.rawQuery("PRAGMA table_info($table)");
final columnExists = result.any((row) => row['name'] == column);
final columnExists = result.any((row) => row["name"] == column);

if (!columnExists) {
await db.execute(
'ALTER TABLE $table ADD COLUMN $column $definition;',
"ALTER TABLE $table ADD COLUMN $column $definition;",
);
}
}
Expand Down Expand Up @@ -63,11 +63,13 @@ Future<void> _initDb({String? pathOverride}) async {
}
}
await db?.close();
db = await openDatabase(dbFile.path, version: 9,
onUpgrade: (Database db, int oldVersion, int newVersion) async {
printV("migrating: $oldVersion, $newVersion");
if (oldVersion <= 1) {
await db.execute('''
db = await openDatabase(
dbFile.path,
version: 10,
onUpgrade: (db, oldVersion, newVersion) async {
printV("migrating: $oldVersion, $newVersion");
if (oldVersion <= 1) {
await db.execute("""
DELETE FROM WalletInfo
WHERE walletInfoId NOT IN (
SELECT MIN(walletInfoId)
Expand All @@ -77,10 +79,10 @@ WHERE walletInfoId NOT IN (

CREATE UNIQUE INDEX IF NOT EXISTS idx_walletinfo_id_unique
ON WalletInfo (id);
''');
}
if (oldVersion <= 2) {
await db.execute('''
""");
}
if (oldVersion <= 2) {
await db.execute('''
CREATE TABLE IF NOT EXISTS BalanceCardStyleSettings (
walletInfoId INTEGER,
accountIndex INTEGER DEFAULT -1,
Expand All @@ -91,64 +93,74 @@ CREATE TABLE IF NOT EXISTS BalanceCardStyleSettings (
FOREIGN KEY (walletInfoId) REFERENCES WalletInfo(walletInfoId)
);
''');
await _addColumnIfNotExists(
db,
table: 'WalletInfo',
column: 'receiveInfoboxDismissed',
definition: 'BOOLEAN DEFAULT FALSE',
);
await _addColumnIfNotExists(
db,
table: "WalletInfo",
column: "receiveInfoboxDismissed",
definition: "BOOLEAN DEFAULT FALSE",
);

await _addColumnIfNotExists(
db,
table: 'BalanceCardStyleSettings',
column: 'cardOrder',
definition: 'INTEGER DEFAULT 0',
);
}
if (oldVersion <= 3) {
await _addColumnIfNotExists(db,
table: "WalletInfo", column: "showCombinedBalance", definition: "BOOLEAN DEFAULT TRUE");
// null - primary token (eth, sol etc)
// not null - address of fav token
// if address doesn't correspond to a valid token, fallback to primary token
await _addColumnIfNotExists(db,
table: "WalletInfo", column: "favoriteTokenAddress", definition: "TEXT DEFAULT NULL");
}

if (oldVersion <= 4) {
await _createBridgeTransferTable(db);
}

if (oldVersion <= 5) {
await _createTradeTable(db);
}
if (oldVersion <= 6) {
await _addColumnIfNotExists(
db,
table: 'Trade',
column: 'toAddressExtraId',
definition: 'TEXT',
);
}
if (oldVersion <= 7) {
await _createNodeTable(db);
}
if (oldVersion <= 8) {
await _addColumnIfNotExists(
db,
table: 'BalanceCardStyleSettings',
column: 'iconStyleIndex',
definition: 'INTEGER DEFAULT 0',
);
await _addColumnIfNotExists(
db,
table: 'BalanceCardStyleSettings',
column: 'isGradientOnly',
definition: 'BOOLEAN DEFAULT FALSE',
);
}
}, onCreate: (Database db, int version) async {
await db.execute('''
await _addColumnIfNotExists(
db,
table: "BalanceCardStyleSettings",
column: "cardOrder",
definition: "INTEGER DEFAULT 0",
);
}
if (oldVersion <= 3) {
await _addColumnIfNotExists(
db,
table: "WalletInfo",
column: "showCombinedBalance",
definition: "BOOLEAN DEFAULT TRUE",
);
// null - primary token (eth, sol etc)
// not null - address of fav token
// if address doesn't correspond to a valid token, fallback to primary token
await _addColumnIfNotExists(
db,
table: "WalletInfo",
column: "favoriteTokenAddress",
definition: "TEXT DEFAULT NULL",
);
}
if (oldVersion <= 4) {
await _createBridgeTransferTable(db);
}
if (oldVersion <= 5) {
await _createTradeTable(db);
}
if (oldVersion <= 6) {
await _addColumnIfNotExists(
db,
table: "Trade",
column: "toAddressExtraId",
definition: "TEXT",
);
}
if (oldVersion <= 7) {
await _createNodeTable(db);
}
if (oldVersion <= 8) {
await _addColumnIfNotExists(
db,
table: "BalanceCardStyleSettings",
column: "iconStyleIndex",
definition: "INTEGER DEFAULT 0",
);
await _addColumnIfNotExists(
db,
table: "BalanceCardStyleSettings",
column: "isGradientOnly",
definition: "BOOLEAN DEFAULT FALSE",
);
}
if (oldVersion <= 9) {
await _createChartsTables(db);
}
},
onCreate: (db, version) async {
await db.execute('''
CREATE TABLE WalletInfo (
walletInfoId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
id TEXT NOT NULL,
Expand Down Expand Up @@ -177,7 +189,7 @@ CREATE TABLE WalletInfo (
);
''');

await db.execute('''
await db.execute("""
CREATE TABLE WalletInfoDerivationInfo (
walletInfoDerivationInfoId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
address TEXT NOT NULL,
Expand All @@ -188,9 +200,9 @@ CREATE TABLE WalletInfoDerivationInfo (
scriptType TEXT,
description TEXT
);
''');
""");

await db.execute('''
await db.execute('''
CREATE TABLE WalletInfoAddress (
walletInfoAddressId INTEGER PRIMARY KEY AUTOINCREMENT,
walletInfoId INTEGER,
Expand All @@ -200,7 +212,7 @@ CREATE TABLE WalletInfoAddress (
);
''');

await db.execute('''
await db.execute("""
CREATE TABLE WalletInfoAddressInfo (
walletInfoAddressInfoId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
walletInfoId INTEGER NOT NULL,
Expand All @@ -210,9 +222,9 @@ CREATE TABLE WalletInfoAddressInfo (
mapValueLabel TEXT NOT NULL,
CONSTRAINT WalletInfoAddressInfo_WalletInfo_FK FOREIGN KEY (walletInfoId) REFERENCES WalletInfo(walletInfoId)
);
''');
""");

await db.execute('''
await db.execute('''
CREATE TABLE "WalletInfoAddressMap" (
walletInfoAddressMapId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
walletInfoId INTEGER NOT NULL,
Expand All @@ -221,11 +233,11 @@ CREATE TABLE "WalletInfoAddressMap" (
CONSTRAINT WalletInfoAddress_WalletInfo_FK FOREIGN KEY (walletInfoId) REFERENCES WalletInfo(walletInfoId)
);
''');
await db.execute('''
await db.execute("""
CREATE UNIQUE INDEX IF NOT EXISTS idx_walletinfo_id_unique
ON WalletInfo (id);
''');
await db.execute('''
""");
await db.execute('''
CREATE TABLE BalanceCardStyleSettings (
walletInfoId INTEGER,
accountIndex INTEGER DEFAULT -1,
Expand All @@ -239,14 +251,34 @@ CREATE TABLE BalanceCardStyleSettings (
FOREIGN KEY (walletInfoId) REFERENCES WalletInfo(walletInfoId)
);
''');
await _createBridgeTransferTable(db);
await _createNodeTable(db);
await _createTradeTable(db);
});
await _createBridgeTransferTable(db);
await _createNodeTable(db);
await _createTradeTable(db);
await _createChartsTables(db);
},
);
}

Future<void> _createChartsTables(Database db) async {
await db.execute("""
CREATE TABLE PriceData (
fromCurrency TEXT NOT NULL,
toCurrency TEXT NOT NULL,
timestamp INTEGER NOT NULL,
price TEXT NOT NULL,
PRIMARY KEY (fromCurrency, toCurrency, timestamp)
);
""");
await db.execute("""
CREATE TABLE ChartsAssets (
asset TEXT PRIMARY KEY,
isFavorite BOOLEAN DEFAULT FALSE
);
""");
}

Future<void> _createTradeTable(Database db) async {
await db.execute('''
await db.execute("""
CREATE TABLE IF NOT EXISTS Trade (
tradeId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
id TEXT NOT NULL,
Expand Down Expand Up @@ -301,11 +333,11 @@ CREATE TABLE IF NOT EXISTS Trade (
chainId INTEGER,
fee REAL
);
''');
await db.execute('''
""");
await db.execute("""
CREATE UNIQUE INDEX IF NOT EXISTS idx_trade_id_unique
ON Trade (id);
''');
""");
}

Future<Map<String, dynamic>> dumpDb() async {
Expand All @@ -321,7 +353,7 @@ Future<Map<String, dynamic>> dumpDb() async {

Future<List<String>> _getTableNames(Database db) async {
final tableNames = await db.rawQuery('SELECT name FROM sqlite_master WHERE type = "table"');
return tableNames.map((e) => (e["name"]).toString()).toList();
return tableNames.map((e) => e["name"].toString()).toList();
}

Future<Map<String, dynamic>> _dumpDb() async {
Expand All @@ -344,7 +376,7 @@ Future<Map<String, dynamic>> dumpCustomDb(String path) async {
}

Future<void> _createBridgeTransferTable(Database db) async {
await db.execute('''
await db.execute("""
CREATE TABLE IF NOT EXISTS BridgeTransfer (
id TEXT NOT NULL PRIMARY KEY,
wallet_id TEXT NOT NULL,
Expand All @@ -363,15 +395,15 @@ CREATE TABLE IF NOT EXISTS BridgeTransfer (
error_message TEXT,
status_message TEXT
);
''');
await db.execute('''
""");
await db.execute("""
CREATE INDEX IF NOT EXISTS idx_bridgetransfer_wallet_id
ON BridgeTransfer(wallet_id);
''');
""");
}

Future<void> _createNodeTable(Database db) async {
db.execute("""
await db.execute("""
CREATE TABLE Node (
NodeId INTEGER PRIMARY KEY,
uri TEXT NOT NULL,
Expand Down
3 changes: 3 additions & 0 deletions cw_core/lib/erc20_token.dart
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,7 @@ class Erc20Token extends CryptoCurrency with HiveObjectMixin {

@override
int get hashCode => contractAddress.hashCode;

@override
String get apiString => "evm.$contractAddress";
}
3 changes: 3 additions & 0 deletions cw_core/lib/spl_token.dart
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,7 @@ class SPLToken extends CryptoCurrency with HiveObjectMixin {

@override
int get hashCode => mintAddress.hashCode;

@override
String get apiString => "sol.$mintAddress";
}
3 changes: 3 additions & 0 deletions cw_core/lib/tron_token.dart
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,7 @@ class TronToken extends CryptoCurrency with HiveObjectMixin {

@override
int get hashCode => contractAddress.hashCode;

@override
String get apiString => "trx.$contractAddress";
}
Loading
Loading