Files
hash-wallet/cw_evm/lib/utils/evm_chain_utils.dart
T
046e57c598 Add Robinhood Chain (#3398)
* fix android CI

* feat: Add Robinhood Chain, all major flows done. minor issue now is our providers don't support it yet as its still pretty early, two weeks from launch

* feat: Add Robinhood Chain, all major flows done. minor issue now is our providers don't support it yet as its still pretty early, two weeks from launch

* Cleanup

* auto-reformat

* fix ui issue and contact listing for tokens

* fix: missing icons and crash for fee priority in settings

* chore: cleanup

* fixes from feedbacks

* fix: review issues and sync to latest dev
feat: switch history api to etherscan, add history toggle to privacy settings, exclude robETH from exchange pickers, skip tokens discovery for chains that moralis hasn't indexed, add tests

* fix: address Robinhood review comments

* fix: show Solana token icons in history

* fix: address review comments and default Robinhood to PublicNode

* fix:  revert filter and refuse unmapped networks in provider

---------

Co-authored-by: Robert Malikowski <malikowskirobert@gmail.com>
2026-10-04 13:22:05 +02:00

126 lines
4.5 KiB
Dart

import "package:cw_evm/evm_chain_transaction_priority.dart";
import "package:web3dart/web3dart.dart" show EtherAmount, EtherUnit;
/// Utility class for chain-specific EVM chain operations
class EVMChainUtils {
static int getTotalPriorityFee(EVMChainTransactionPriority priority, int chainId) =>
switch (chainId) {
1 => _ethereumPriorityFee(priority),
137 => _polygonPriorityFee(priority),
8453 => _basePriorityFee(priority),
56 => _ethereumPriorityFee(priority),
42161 => 0, // Arbitrum doesn't use priority fees
4663 => 0, // Robinhood Chain (Arbitrum Orbit) doesn't use priority fees
_ => _ethereumPriorityFee(priority),
};
static bool hasPriorityFee(int chainId) => switch (chainId) {
42161 => false, // Arbitrum doesn't use priority fees
4663 => false, // Robinhood Chain (Arbitrum Orbit) doesn't use priority fees
_ => true,
};
static int computeBufferedMaxFeePerGasWei({
required int? gasBaseFee,
required int gasPrice,
required int priorityFeeWei,
required bool chainHasPriorityFee,
}) {
if (gasBaseFee != null && gasBaseFee > 0) {
final baseFeeWithPriority = gasBaseFee + priorityFeeWei;
final bufferMultiplier = chainHasPriorityFee ? 115 : 105;
final bufferPercent = (baseFeeWithPriority * bufferMultiplier) ~/ 100;
final bufferMin = baseFeeWithPriority + (baseFeeWithPriority ~/ 100);
return bufferPercent > bufferMin ? bufferPercent : bufferMin;
}
return gasPrice + priorityFeeWei;
}
static String getTransactionHistoryFileName(int chainId) => switch (chainId) {
1 => "transactions.json", // Ethereum
137 => "polygon_transactions.json",
8453 => "base_transactions.json",
42161 => "arbitrum_transactions.json",
56 => "bsc_transactions.json",
4663 => "robinhood_transactions.json",
_ => "transactions_$chainId.json", // Generic format for other chains
};
/// Get scan provider preference key for a wallet type
static String getScanProviderPreferenceKey(int chainId) => switch (chainId) {
1 => "use_etherscan",
137 => "use_polygonscan",
8453 => "use_base_scan",
42161 => "use_arbitrum_scan",
56 => "use_bscscan",
4663 => "use_robinhood_scan",
_ => "use_etherscan",
};
static String getDefaultTokenTag(int chainId) => switch (chainId) {
1 => "ETH",
137 => "POL",
8453 => "BASE",
42161 => "ARB",
56 => "BSC",
4663 => "ROB",
_ => "ETH",
};
static String getFeeCurrency(int chainId) => switch (chainId) {
1 => "ETH",
137 => "POL",
8453 => "ETH",
42161 => "ETH",
56 => "BNB",
4663 => "ETH",
_ => "ETH",
};
static String getDefaultTokenSymbol(int chainId) => switch (chainId) {
1 => "ETH",
137 => "POL",
8453 => "BASE",
42161 => "ARBITRUM",
56 => "BSC",
4663 => "ETH",
_ => "ETH",
};
static String? getMoralisChainName(int chainId) => switch (chainId) {
1 => "eth",
137 => "polygon",
8453 => "base",
42161 => "arbitrum",
56 => "bsc",
_ => null,
};
static int _ethereumPriorityFee(EVMChainTransactionPriority priority) =>
EtherAmount.fromInt(EtherUnit.gwei, priority.tip).getInWei.toInt();
// Polygon priority fee calculation (minimum 25 gwei + additional based on priority)
static int _polygonPriorityFee(EVMChainTransactionPriority priority) {
const int minPriorityFee = 25;
final minPriorityFeeWei = EtherAmount.fromInt(EtherUnit.gwei, minPriorityFee).getInWei.toInt();
final int additionalPriorityFee = switch (priority) {
EVMChainTransactionPriority.slow => 0,
EVMChainTransactionPriority.medium =>
EtherAmount.fromInt(EtherUnit.gwei, 15).getInWei.toInt(),
EVMChainTransactionPriority.fast => EtherAmount.fromInt(EtherUnit.gwei, 35).getInWei.toInt(),
_ => 0,
};
return minPriorityFeeWei + additionalPriorityFee;
}
static int _basePriorityFee(EVMChainTransactionPriority priority) => switch (priority) {
EVMChainTransactionPriority.fast => EtherAmount.fromInt(EtherUnit.mwei, 5).getInWei.toInt(),
EVMChainTransactionPriority.medium =>
EtherAmount.fromInt(EtherUnit.mwei, 3).getInWei.toInt(),
EVMChainTransactionPriority.slow => EtherAmount.fromInt(EtherUnit.mwei, 1).getInWei.toInt(),
_ => EtherAmount.fromInt(EtherUnit.mwei, 1).getInWei.toInt(),
};
}