prevent trade.from saving as null + fallback when it does (#3346)

malik1004x committed Jun 25, 2026 at 12:05 UTC eaa8338a52f693e438dc46a7541c2b205c634c28
5 files changed +28 -16
lib/exchange/provider/near_Intents_exchange_provider.dart
+2 -2
@@ -280,8 +280,8 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
280 final trade = Trade(
281 id: depositAddress,
282 // Using deposit address as trade ID
283 - from: from,
284 - to: to,
283 + from: request.fromCurrency,
284 + to: request.toCurrency,
285 provider: description,
286 providerName: title,
287 state: TradeState.created,
lib/new-ui/widgets/coins_page/assets_history/history_section.dart
-3
@@ -101,9 +101,6 @@ class HistorySection extends StatelessWidget {
101 final trade = item.trade;
102 final tradeFrom = trade.from;
103 final tradeTo = trade.to;
104 - if (tradeFrom == null || tradeTo == null) {
105 - return const SizedBox.shrink();
106 - }
104
105 return GestureDetector(
106 onTap: () => Navigator.of(context)
lib/new-ui/widgets/coins_page/assets_history/history_trade_tile.dart
+18 -11
@@ -15,13 +15,13 @@ class HistoryTradeTile extends StatelessWidget {
15 required this.roundedTop,
16 required this.roundedBottom,
17 required this.bottomSeparator,
18 - required this.from,
19 - required this.to,
18 + this.from,
19 + this.to,
20 required this.swapState,
21 required this.provider});
22
23 - final CryptoCurrency from;
24 - final CryptoCurrency to;
23 + final CryptoCurrency? from;
24 + final CryptoCurrency? to;
25 final ExchangeProviderDescription provider;
26 final String date;
27 final String amount;
@@ -32,6 +32,11 @@ class HistoryTradeTile extends StatelessWidget {
32 final TradeState swapState;
33
34 Widget _getLeadingStack(BuildContext context) {
35 + if (from == null || to == null) {
36 + return SizedBox(width: 50, height: 50);
37 + }
38 +
39 +
40 double currencyIconSize = 22.0;
41
42 return SizedBox(
@@ -40,7 +45,7 @@ class HistoryTradeTile extends StatelessWidget {
45 child: Stack(
46 children: [
47 CakeImageWidget(
43 - imageUrl: _getIconPath(from), width: currencyIconSize, height: currencyIconSize),
48 + imageUrl: _getIconPath(from!), width: currencyIconSize, height: currencyIconSize),
49 Positioned(
50 top: currencyIconSize / 2,
51 left: currencyIconSize / 2,
@@ -50,7 +55,7 @@ class HistoryTradeTile extends StatelessWidget {
55 Border.all(width: 2, color: Theme.of(context).colorScheme.surfaceContainer),
56 shape: BoxShape.circle),
57 child: CakeImageWidget(
53 - imageUrl: _getIconPath(to),
58 + imageUrl: _getIconPath(to!),
59 width: currencyIconSize,
60 height: currencyIconSize,
61 ),
@@ -85,8 +90,8 @@ class HistoryTradeTile extends StatelessWidget {
90 style: TextStyle(
91 color: Theme.of(context).colorScheme.onSurfaceVariant,
92 fontWeight: FontWeight.w500)),
88 - Text(from.title, style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant)),
89 - if (fromChainIcon.isNotEmpty)
93 + if(from?.title != null) Text(from!.title, style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant)),
94 + if (fromChainIcon?.isNotEmpty ?? false)
95 CakeImageWidget(
96 imageUrl: fromChainIcon,
97 width: 12,
@@ -106,10 +111,11 @@ class HistoryTradeTile extends StatelessWidget {
111 receiveAmount.withMaxDecimals(8),
112 style: TextStyle(fontWeight: FontWeight.w500),
113 ),
114 + if(to!=null)
115 Text(
110 - to.title,
116 + to!.title,
117 ),
112 - if (toChainIcon.isNotEmpty) CakeImageWidget(imageUrl: toChainIcon, width: 12, height: 12)
118 + if (toChainIcon?.isNotEmpty ?? false) CakeImageWidget(imageUrl: toChainIcon, width: 12, height: 12)
119 ],
120 ),
121 leadingIcon: _getLeadingStack(context),
@@ -137,7 +143,8 @@ class HistoryTradeTile extends StatelessWidget {
143 return "";
144 }
145
140 - String _getChainIcon(CryptoCurrency currency) {
146 + String? _getChainIcon(CryptoCurrency? currency) {
147 + if(currency == null) return null;
148 try {
149 if (currency.title.isNotEmpty) {
150 final parsedCurrency = CryptoCurrency.safeParseCurrencyFromString(currency.title, tag: currency.tag);
lib/src/screens/dev/moneroc_cache_debug.dart
+2
@@ -9,6 +9,7 @@ import 'package:cw_core/root_dir.dart';
9 import 'package:cw_core/wallet_type.dart';
10 import 'package:flutter/material.dart';
11 import 'package:flutter/services.dart';
12 +import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
13 import 'package:path/path.dart' as path;
14
15 class DevMoneroWalletCacheDebugPage extends StatelessWidget {
@@ -263,6 +264,7 @@ class _JsonExplorerState extends State<JsonExplorer> {
264 ),
265 )
266 : ListView.builder(
267 + controller: ModalScrollController.of(context),
268 itemCount: _filteredItems.length,
269 itemBuilder: (context, index) {
270 final item = _filteredItems[index];
lib/view_model/exchange/exchange_view_model.dart
+6
@@ -1242,6 +1242,12 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
1242 trade.walletId = wallet.id;
1243 trade.chainId = wallet.chainId;
1244 trade.fromWalletAddress = wallet.walletAddresses.address;
1245 + if(trade.from == null) {
1246 + trade.from = depositCurrency;
1247 + }
1248 + if(trade.to == null) {
1249 + trade.to = receiveCurrency;
1250 + }
1251
1252 final canCreateTrade = await isCanCreateTrade(trade);
1253 if (!canCreateTrade.result) {