Skip to content

feat: migrate Trade data to SQLite with TradeLegacy for backward compatibility#3106

Open
Blazebrain wants to merge 6 commits intodevfrom
CW-1423-Migrate-Trade-Object-To-SQLite
Open

feat: migrate Trade data to SQLite with TradeLegacy for backward compatibility#3106
Blazebrain wants to merge 6 commits intodevfrom
CW-1423-Migrate-Trade-Object-To-SQLite

Conversation

@Blazebrain
Copy link
Copy Markdown
Contributor

Issue Number (if Applicable): Fixes #

Description

Please include a summary of the changes and which issue is fixed / feature is added.

Pull Request - Checklist

  • Initial Manual Tests Passed
  • Double check modified code and verify it with the feature/task requirements
  • Format code
  • Look for code duplication
  • Clear naming for variables and methods
  • Manual tests in accessibility mode (TalkBack on Android) passed

@Blazebrain Blazebrain self-assigned this Mar 18, 2026
@Blazebrain Blazebrain requested a review from OmarHatem28 March 18, 2026 19:01
Comment thread lib/exchange/trade_legacy.dart Outdated
Box<TradeLegacy> box,
) async {
printV('Migrating Trades to SQLite: start');
final sw = Stopwatch()..start();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

debugging and forgotten?

Comment thread lib/exchange/trade.dart Outdated
Comment on lines 79 to 85
int fromRaw = -1;

CryptoCurrency? get from => CryptoCurrency.safeDeserialize(raw: fromRaw);

@HiveField(3, defaultValue: -1)
int toRaw = -1;

CryptoCurrency? get to => CryptoCurrency.safeDeserialize(raw: toRaw);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we want to get rid of this, and save the currency itself, not the Raw number.
this was the main issue why we want the migration, is because tokens don't have raw value, so when you try and parse the raw value to currency it will not find it and fail.

so get rid of raw, and safe the currency itself so we don't need to parse anything and just show the saved currency for this trade

Comment thread lib/exchange/trade.dart Outdated
Comment on lines +126 to +139
CryptoCurrency? get userCurrencyFrom {
if (userCurrencyFromRaw == null || userCurrencyFromRaw!.isEmpty) {
return null;
}
final underscoreIndex = userCurrencyFromRaw!.indexOf('_');
if (underscoreIndex < 0) {
return CryptoCurrency(
title: userCurrencyFromRaw!,
tag: null,
name: '',
raw: -1,
decimals: 1,
);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check with @serhii-bor what was the reason for those getters and variables as well, and remove them as well if it fits

Comment on lines +19 to +21
CryptoCurrency? get _from => trade.fromRaw >= 0 ? trade.from : trade.userCurrencyFrom;

String get tradeFormattedReceiveAmount => displayMode == BalanceDisplayMode.hiddenBalance
? "---"
: appStore.amountParsingProxy
.getDisplayCryptoAmount(trade.receiveAmountFormatted(), trade.to!);
CryptoCurrency? get _to => trade.toRaw >= 0 ? trade.to : trade.userCurrencyTo;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

things like this would be removed as well, since we would have the currency directly

Comment thread cw_core/lib/db/sqlite.dart Outdated
Comment on lines +193 to +194
fromRaw INTEGER NOT NULL DEFAULT -1,
toRaw INTEGER NOT NULL DEFAULT -1,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

those 2 and also userCurrencyFromRaw userCurrencyToRaw should be removed in this migration and replaced with the currency it self, we can do it as a TEXT with the value being the stringified version of the json map of the currency, but then you need to find a way to distinguish between tokens and currencies, and different tokens (erc, spl, trx, etc...)

@Blazebrain Blazebrain marked this pull request as ready for review April 1, 2026 09:00
@OmarHatem28 OmarHatem28 requested a review from MrCyjaneK April 15, 2026 12:32
Comment thread lib/exchange/trade.dart
String? fromCurrencyJson;

CryptoCurrency? get from => CryptoCurrency.safeDeserialize(raw: fromRaw);
String? toCurrencyJson;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{
  "version": 1,
  "title": "XMR",
  "name": "xmr",
  "decimals": 12,
  "raw": 0,
  "fullName": "Monero",
  "iconPath": "assets/images/crypto/monero.webp",
  "flatIconPath": "assets/new-ui/balance_card_icons/monero.svg"
}

Some of the data we store here is very fragile (iconPath / flatIconPath).

Comment thread lib/exchange/trade.dart

static bool _hasValidString(String? value) => value != null && value.trim().isNotEmpty;

void mergeFindTradeByIdResult(Trade updated) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: since sqlite fields accept NULL and things like createdAt / expiredAt are still nullable this function can be heavily simplified to just contain raw x = updated.x or x = updated.x?.trim() instead of the if conditions.

Comment thread lib/exchange/trade.dart
sourceTokenAmountRaw = updated.sourceTokenAmountRaw;
}

internalId = keepInternalId;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are not touching internalId anywhere so internalId = keepInternalId; and final keepInternalId = internalId; is unnecessary


import 'package:cw_core/crypto_currency.dart';

class TradeCurrencySnapshot {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm really allergic to constant-schema JSON in SQL databases :p

In addition to that a few things:

flatIconPath and chainIconPath are not guaranteed to be constant as we may move assets in future.

Also I've noticed that in case when the currency is not explicitly supported by us the JSON looks like this:

{
  "version": 1,
  "title": "SUN",
  "name": "SUN",
  "decimals": 18,
  "raw": -1,
  "tag": "TRX",
  "fullName": "SUN"
}

nit: I'd prefer if we store these fields as raw values in the SQL table (currencyFromName, currencyFromDecimals etc...) to make our future life easier, assuming that in future we will want to lookup all TRX trades we can use SQL instead of manually parsing through every trade JSON object, or doing complex migrations.
Same with updating the fields, chainIconPath update, for example during a migration, can be done much easier without querying the entire table and doing json.parse on every row.

CakeImageWidget(imageUrl: _getIconPath(from),
width: currencyIconSize, height: currencyIconSize),
CakeImageWidget(
imageUrl: _getIconPath(from), width: currencyIconSize, height: currencyIconSize),
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: here we may use asset icon that doesn't exist.


@override
DateTime get date => trade.createdAt!;
DateTime get date => trade.createdAt ?? DateTime.now();
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'd probably default to DateTime.fromMillisecondsSinceEpoch(0, isUtc: true);

try { // temporarily until we migrate from hive to sqlite and store the full currency object
try {
if (currency.iconPath != null) {
return currency.iconPath!;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here we may use iconPath that is stale from the serialization

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants