← Code knowledge base
Reviewed Flutter implementation · 2026-10-28

exchange_transfer_routes.dart

mobile_flutter/lib/features/wallets/domain/exchange_transfer_routes.dart

Immutable source snapshot based on revision ce45c9c3bbde. Original line numbers are retained. This is implementation evidence; check the public API catalogue before adapting it.

The mobile /api/v1/mobile routes belong to the example backend. Company credentials stay on that backend. Some sections outside the documented product scope may be omitted.

Lines 1–130

import '../../../core/models/platform_models.dart';import 'wallet_models.dart'; const exchangeDefaultChainId = 137; int exchangeChainId(String network) {  final n = network.trim().toLowerCase();  // A merged display label is not an exact transfer route.  if (n.contains('/') || n.contains(',')) return 0;  if (n.contains('tron') || n == 'trx' || n == 'trc20') return -200;  if (n.contains('polygon') || n == 'matic') return 137;  if (n.contains('arbitrum') || n == 'arb') return 42161;  if (n.contains('optimism') || n == 'op') return 10;  if (n.contains('avalanche') || n == 'avax') return 43114;  if (n.contains('ethereum') || n == 'eth' || n == 'erc20') return 1;  return 0;} List<HoppaWalletAsset> exchangeTransferRoutes(  List<HoppaWalletAsset> addresses,  List<HoppaWalletAsset> balances,) {  final routes = <String, HoppaWalletAsset>{};  for (final address in addresses) {    final symbol = address.symbol.trim().toUpperCase();    final chain = exchangeChainId(address.network);    if (!['USDC', 'USDT'].contains(symbol) ||        chain == 0 ||        address.address.trim().isEmpty) {      continue;    }    // Interlace balances are shared across chains. Deposit-address rows only    // identify a route; their amounts must never replace or multiply a balance.    final balance = balances        .where((b) => b.symbol.trim().toUpperCase() == symbol)        .firstOrNull;    routes.putIfAbsent(        '$symbol:$chain:${address.address}',        () => HoppaWalletAsset(              symbol: symbol,              name: address.name,              network: address.network,              amount: balance?.amount ?? 0,              fiatValue: balance?.fiatValue ?? 0,              address: address.address,              tint: address.tint,              walletId: address.walletId,            ));  }  return [    ...routes.values        .where((w) => exchangeChainId(w.network) == exchangeDefaultChainId),    ...routes.values        .where((w) => exchangeChainId(w.network) != exchangeDefaultChainId),  ];} // Present one choice per currency while retaining the exact route for requests.// Callers pass only routes supported by both the card wallet and BoomFi.List<HoppaWalletAsset> exchangeTransferCurrencyRoutes(  List<HoppaWalletAsset> routes, {  required bool Function(String) canTrade,}) {  final choices = <HoppaWalletAsset>[];  for (final symbol in ['USDC', 'USDT']) {    if (!canTrade(symbol)) continue;    final matching = routes.where((w) => w.symbol.toUpperCase() == symbol);    final selected = matching            .where((w) => exchangeChainId(w.network) == exchangeDefaultChainId)            .firstOrNull ??        matching.firstOrNull;    if (selected != null) choices.add(selected);  }  return choices;} String exchangeRouteKey(HoppaWalletAsset wallet) =>    '${wallet.symbol}:${exchangeChainId(wallet.network)}:${wallet.address}'; Object? _field(Map map, String name) =>    map[name] ?? map['${name[0].toUpperCase()}${name.substring(1)}']; Set<String> exchangeBudgetCurrencies(PlatformResource budget) {  final supported = _field(budget.metadata, 'supportedCurrencies');  return {    if (supported is List)      ...supported.map((c) => c.toString().trim().toUpperCase()),    ...exchangeBudgetBalances(budget).keys,    (_field(budget.metadata, 'currency') ?? 'EUR')        .toString()        .trim()        .toUpperCase(),  };} Map<String, double> exchangeBudgetBalances(PlatformResource budget) {  final result = <String, double>{};  void add(Map row) {    final currency =        (_field(row, 'currency') ?? _field(row, 'currencyCode') ?? '')            .toString()            .trim()            .toUpperCase();    final amount = double.tryParse((_field(row, 'availableBalance') ??            _field(row, 'available') ??            _field(row, 'amount') ??            _field(row, 'balance') ??            '')        .toString());    if (currency.isNotEmpty && amount != null && amount.isFinite) {      result.putIfAbsent(currency, () => amount);    }  }   for (final key in [    'balances',    'currencyBalances',    'supportedCurrencyBalances',    'availableBalances'  ]) {    final rows = _field(budget.metadata, key);    if (rows is List) {      for (final row in rows.whereType<Map>()) {        add(row);      }    }  }  add(budget.metadata);  return result;}
HOPPA DEVELOPER ASSISTANT

What are you building?

From a question to an implementation.

Get a step-by-step flow, example code and the docs behind it. Choose a starting point or describe your feature.

Answers use the public API guide and example app code. Check the linked reference before shipping. Explore code sources ↗

Your question and recent conversation are sent to our AI provider. Don’t include API keys, personal data or card details.