CW-1368: Add Binance Smart Chain (#2836)

* feat: Add Binance Smart Chain support to wallet types and EVM chain registry * feat: Add BSC node list and support in wallet type and chain ID mappings * feat: Add BSC default tokens and update evm utility functions * feat: Integrate BSC support in node settings and management * feat: Add BSC support to config scripts and wallet type generation * feat: Add BSC support to EVM chain ID and switcher * feat: Extend BSC support in wallet utilities and chain type checks * feat: Add BSC support to different wallet functions * feat: Add BSCURI class and implement for uri handling * feat: Update Android and iOS configurations to support BSC URL schemes * feat: Add BSC support to different functionalities and settings * refactor: Update wallet type name from'Binance Smart Chain' to BNB Smart Chain * feat: Add switcher icon and updates token utils * Review fixes * More changes to BSC name, wallet listing and images * Add more default tokens

David Adegoke committed Feb 5, 2026 at 13:48 UTC 308de0389d226690aa5e553b0c396dd0143d2bb3
103 files changed +609 -157
android/app/src/main/AndroidManifestBase.xml
+3
@@ -112,6 +112,9 @@
112 <data android:scheme="arbitrum" />
113 <data android:scheme="arbitrum-wallet" />
114 <data android:scheme="arbitrum_wallet" />
115 + <data android:scheme="bsc" />
116 + <data android:scheme="bsc-wallet" />
117 + <data android:scheme="bsc_wallet" />
118 <data android:scheme="zcash" />
119 <data android:scheme="zcash-wallet" />
120 </intent-filter>
assets/bsc_node_list.yml new
+28
@@ -0,0 +1,28 @@
1 +-
2 + uri: bsc-dataseed.bnbchain.org
3 + useSSL: true
4 + isDefault: true
5 + isEnabledForAutoSwitching: true
6 +-
7 + uri: bsc-dataseed2.bnbchain.org
8 + useSSL: true
9 + isEnabledForAutoSwitching: true
10 +-
11 + uri: bsc-dataseed.nariox.org
12 + useSSL: true
13 + isEnabledForAutoSwitching: true
14 +-
15 + uri: bsc-dataseed.defibit.io
16 + useSSL: true
17 + isEnabledForAutoSwitching: true
18 +-
19 + uri: bsc-dataseed.ninicoin.io
20 + useSSL: true
21 + isEnabledForAutoSwitching: true
22 +-
23 + uri: bsc.nodereal.io
24 + useSSL: true
25 + isEnabledForAutoSwitching: true
26 +-
27 + uri: bsc-dataseed-public.bnbchain.org
28 + useSSL: true
assets/images/bnb_chain_QR.svg new
+5
@@ -0,0 +1,5 @@
1 +<svg width="45" height="45" viewBox="0 0 45 45" fill="none" xmlns="http://www.w3.org/2000/svg">
2 +<rect x="1" y="1" width="43" height="43" rx="6" fill="white"/>
3 +<rect x="1" y="1" width="43" height="43" rx="6" stroke="black" stroke-width="2"/>
4 +<path d="M13.5524 10.7945L22.5085 5.625L31.4646 10.7945L28.1719 12.7043L22.5085 9.44452L16.8451 12.7043L13.5524 10.7945ZM31.4646 17.314L28.1719 15.4043L22.5085 18.664L16.8451 15.4043L13.5524 17.314V21.1335L19.2158 24.3932V30.9128L22.5085 32.8226L25.8012 30.9128V24.3932L31.4646 21.1335V17.314ZM31.4646 27.6531V23.8335L28.1719 25.7432V29.5628L31.4646 27.6531ZM33.8024 29.0031L28.139 32.2628V36.0823L37.0951 30.9128V20.5737L33.8024 22.4835V29.0031ZM30.5098 14.0543L33.8024 15.964V19.7835L37.0951 17.8738V14.0543L33.8024 12.1445L30.5098 14.0543ZM19.2158 33.6458V37.4653L22.5085 39.375L25.8012 37.4653V33.6458L22.5085 35.5555L19.2158 33.6458ZM13.5524 27.6531L16.8451 29.5628V25.7432L13.5524 23.8335V27.6531ZM19.2158 14.0543L22.5085 15.964L25.8012 14.0543L22.5085 12.1445L19.2158 14.0543ZM11.2146 15.964L14.5072 14.0543L11.2146 12.1445L7.92188 14.0543V17.8738L11.2146 19.7835V15.964ZM11.2146 22.4835L7.92188 20.5737V30.9128L16.878 36.0823V32.2628L11.2146 29.0031V22.4835Z" fill="black"/>
5 +</svg>
assets/images/bnb_chain_mono.svg new
+3
@@ -0,0 +1,3 @@
1 +<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
2 +<path d="M7.51434 4.90147L16.006 0L24.4978 4.90147L21.3758 6.7122L16.006 3.62147L10.6363 6.7122L7.51434 4.90147ZM24.4978 11.0829L21.3758 9.2722L16.006 12.3629L10.6363 9.2722L7.51434 11.0829V14.7044L12.8841 17.7951V23.9765L16.006 25.7873L19.128 23.9765V17.7951L24.4978 14.7044V11.0829ZM24.4978 20.8859V17.2644L21.3758 19.0751V22.6965L24.4978 20.8859ZM26.7143 22.1659L21.3446 25.2565V28.878L29.8363 23.9765V14.1736L26.7143 15.9844V22.1659ZM23.5924 7.9922L26.7143 9.80292V13.4244L29.8363 11.6137V7.9922L26.7143 6.18147L23.5924 7.9922ZM12.8841 26.5679V30.1893L16.006 32L19.128 30.1893V26.5679L16.006 28.3785L12.8841 26.5679ZM7.51434 20.8859L10.6363 22.6965V19.0751L7.51434 17.2644V20.8859ZM12.8841 7.9922L16.006 9.80292L19.128 7.9922L16.006 6.18147L12.8841 7.9922ZM5.29773 9.80292L8.41969 7.9922L5.29773 6.18147L2.17578 7.9922V11.6137L5.29773 13.4244V9.80292ZM5.29773 15.9844L2.17578 14.1736V23.9765L10.6675 28.878V25.2565L5.29773 22.1659V15.9844Z" fill="white"/>
3 +</svg>
assets/images/crypto/BNB.webp
Binary files /dev/null and b/assets/images/crypto/BNB.webp differ
assets/images/evm_switcher_icons/bnb_icon.svg new
+3
@@ -0,0 +1,3 @@
1 +<svg width="96" height="96" viewBox="0 0 96 96" fill="none" xmlns="http://www.w3.org/2000/svg">
2 +<path d="M22.8814 14.7044L48.1429 0L73.4043 14.7044L64.117 20.1366L48.1429 10.8644L32.1687 20.1366L22.8814 14.7044ZM73.4043 33.2488L64.117 27.8166L48.1429 37.0888L32.1687 27.8166L22.8814 33.2488V44.1132L38.8555 53.3854V71.9297L48.1429 77.362L57.4302 71.9297V53.3854L73.4043 44.1132V33.2488ZM73.4043 62.6576V51.7932L64.117 57.2254V68.0898L73.4043 62.6576ZM79.9984 66.4976L64.0243 75.7698V86.6341L89.2857 71.9297V42.521L79.9984 47.9532V66.4976ZM70.7111 23.9766L79.9984 29.4088V40.2732L89.2857 34.841V23.9766L79.9984 18.5444L70.7111 23.9766ZM38.8555 79.7034V90.5678L48.1429 96L57.4302 90.5678V79.7034L48.1429 85.1356L38.8555 79.7034ZM22.8814 62.6576L32.1687 68.0898V57.2254L22.8814 51.7932V62.6576ZM38.8555 23.9766L48.1429 29.4088L57.4302 23.9766L48.1429 18.5444L38.8555 23.9766ZM16.2873 29.4088L25.5746 23.9766L16.2873 18.5444L7 23.9766V34.841L16.2873 40.2732V29.4088ZM16.2873 47.9532L7 42.521V71.9297L32.2615 86.6341V75.7698L16.2873 66.4976V47.9532Z" fill="#F0B90B"/>
3 +</svg>
cw_core/lib/crypto_currency.dart
+1 -1
@@ -147,7 +147,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
147 static const xmr = CryptoCurrency(title: 'XMR', fullName: 'Monero', raw: 0, name: 'xmr', iconPath: 'assets/images/crypto/monero.webp', decimals: 12);
148 static const ada = CryptoCurrency(title: 'ADA', fullName: 'Cardano', raw: 1, name: 'ada', iconPath: 'assets/images/ada_icon.png', decimals: 6);
149 static const bch = CryptoCurrency(title: 'BCH', fullName: 'Bitcoin Cash', raw: 2, name: 'bch', iconPath: 'assets/images/crypto/bitcoin-cash.webp', decimals: 8);
150 - static const bnb = CryptoCurrency(title: 'BNB', tag: 'BSC', fullName: 'Binance Coin', raw: 3, name: 'bnb', iconPath: 'assets/images/bnb_icon.png', decimals: 8);
150 + static const bnb = CryptoCurrency(title: 'BNB', tag: 'BSC', fullName: 'Binance Coin', raw: 3, name: 'bnb', iconPath: 'assets/images/crypto/BNB.webp', decimals: 8);
151 static const btc = CryptoCurrency(title: 'BTC', fullName: 'Bitcoin', raw: 4, name: 'btc', iconPath: 'assets/images/crypto/bitcoin.webp', decimals: 8);
152 static const dai = CryptoCurrency(title: 'DAI', tag: 'ETH', fullName: 'Dai', raw: 5, name: 'dai', iconPath: 'assets/images/crypto/dai.webp', decimals: 18);
153 static const dash = CryptoCurrency(title: 'DASH', fullName: 'Dash', raw: 6, name: 'dash', iconPath: 'assets/images/dash_icon.png', decimals: 8);
cw_core/lib/currency_for_wallet_type.dart
+6
@@ -24,6 +24,8 @@ CryptoCurrency walletTypeToCryptoCurrency(WalletType type, {bool isTestnet = fal
24 return CryptoCurrency.baseEth;
25 case WalletType.arbitrum:
26 return CryptoCurrency.arbEth;
27 + case WalletType.bsc:
28 + return CryptoCurrency.bnb;
29 case WalletType.bitcoinCash:
30 return CryptoCurrency.bch;
31 case WalletType.nano:
@@ -62,6 +64,8 @@ CryptoCurrency getCryptoCurrencyByChainId(int chainId) {
64 return CryptoCurrency.baseEth;
65 case 42161:
66 return CryptoCurrency.arbEth;
67 + case 56:
68 + return CryptoCurrency.bnb;
69 default:
70 return CryptoCurrency.eth;
71 }
@@ -79,6 +83,8 @@ int? getChainIdByCryptoCurrency(CryptoCurrency currency) {
83 return 8453;
84 case CryptoCurrency.arbEth:
85 return 42161;
86 + case CryptoCurrency.bnb:
87 + return 56;
88 default:
89 return null;
90 }
cw_core/lib/erc20_token.dart
+1
@@ -72,6 +72,7 @@ class Erc20Token extends CryptoCurrency with HiveObjectMixin {
72 static const polygonBoxName = 'PolygonErc20Tokens';
73 static const baseBoxName = 'BaseErc20Tokens';
74 static const arbitrumBoxName = 'ArbitrumErc20Tokens';
75 + static const bscBoxName = 'BscErc20Tokens';
76
77 @override
78 bool operator ==(Object other) => other is Erc20Token && other.contractAddress == contractAddress;
cw_core/lib/node.dart
+2
@@ -122,6 +122,7 @@ class Node extends HiveObject with Keyable {
122 case WalletType.ethereum:
123 case WalletType.polygon:
124 case WalletType.base:
125 + case WalletType.bsc:
126 case WalletType.arbitrum:
127 case WalletType.solana:
128 case WalletType.tron:
@@ -188,6 +189,7 @@ class Node extends HiveObject with Keyable {
189 case WalletType.polygon:
190 case WalletType.base:
191 case WalletType.arbitrum:
192 + case WalletType.bsc:
193 case WalletType.solana:
194 case WalletType.tron:
195 case WalletType.dogecoin:
cw_core/lib/wallet_type.dart
+14
@@ -22,6 +22,7 @@ const walletTypes = [
22 WalletType.base,
23 WalletType.arbitrum,
24 WalletType.zcash,
25 + WalletType.bsc,
26 ];
27
28 @HiveType(typeId: WALLET_TYPE_TYPE_ID)
@@ -82,6 +83,9 @@ enum WalletType {
83
84 @HiveField(18)
85 zcash,
86 +
87 + @HiveField(19)
88 + bsc,
89 }
90
91 int serializeToInt(WalletType type) {
@@ -122,6 +126,8 @@ int serializeToInt(WalletType type) {
126 return 16;
127 case WalletType.zcash:
128 return 17;
129 + case WalletType.bsc:
130 + return 18;
131 case WalletType.none:
132 return -1;
133 }
@@ -165,6 +171,8 @@ WalletType deserializeFromInt(int raw) {
171 return WalletType.arbitrum;
172 case 17:
173 return WalletType.zcash;
174 + case 18:
175 + return WalletType.bsc;
176 default:
177 throw Exception('Unexpected token: $raw for WalletType deserializeFromInt');
178 }
@@ -208,6 +216,8 @@ String walletTypeToString(WalletType type) {
216 return 'Arbitrum';
217 case WalletType.zcash:
218 return 'Zcash';
219 + case WalletType.bsc:
220 + return 'BNB Smart Chain';
221 case WalletType.none:
222 return '';
223 }
@@ -251,6 +261,8 @@ String walletTypeToDisplayName(WalletType type) {
261 return 'Arbitrum (ARB)';
262 case WalletType.zcash:
263 return 'Zcash (ZEC)';
264 + case WalletType.bsc:
265 + return 'BNB Smart Chain (BNB)';
266 case WalletType.none:
267 return '';
268 }
@@ -275,6 +287,8 @@ WalletType? cryptoCurrencyToWalletType(CryptoCurrency type) {
287 return WalletType.base;
288 case CryptoCurrency.arbEth:
289 return WalletType.arbitrum;
290 + case CryptoCurrency.bnb:
291 + return WalletType.bsc;
292 case CryptoCurrency.bch:
293 return WalletType.bitcoinCash;
294 case CryptoCurrency.nano:
cw_evm/lib/clients/bsc_client.dart new
+47
@@ -0,0 +1,47 @@
1 +import 'package:cw_evm/clients/evm_chain_client.dart';
2 +import 'package:flutter/foundation.dart';
3 +import 'package:web3dart/web3dart.dart';
4 +
5 +class BSCClient extends EVMChainClient {
6 + BSCClient() : super(chainId: 56);
7 +
8 + @override
9 + Transaction createTransaction({
10 + required EthereumAddress from,
11 + required EthereumAddress to,
12 + required EtherAmount amount,
13 + EtherAmount? maxPriorityFeePerGas,
14 + Uint8List? data,
15 + int? maxGas,
16 + EtherAmount? gasPrice,
17 + EtherAmount? maxFeePerGas,
18 + int? nonce,
19 + }) {
20 + EtherAmount? finalGasPrice = gasPrice;
21 +
22 + if (gasPrice == null && maxFeePerGas != null) {
23 + // If we have EIP-1559 parameters but no legacy gasPrice, then use maxFeePerGas as gasPrice
24 + // BSC RPC nodes may have issues with EIP-1559 transaction encoding
25 + finalGasPrice = maxFeePerGas;
26 + }
27 +
28 + return Transaction(
29 + from: from,
30 + to: to,
31 + value: amount,
32 + data: data,
33 + maxGas: maxGas,
34 + gasPrice: finalGasPrice,
35 + nonce: nonce,
36 + // maxFeePerGas: maxFeePerGas,
37 + // maxPriorityFeePerGas: maxPriorityFeePerGas,
38 + );
39 + }
40 +
41 + @override
42 + Uint8List prepareSignedTransactionForSending(Uint8List signedTransaction) => signedTransaction;
43 +
44 + @override
45 + int get chainId => 56;
46 +}
47 +
cw_evm/lib/clients/evm_chain_client.dart
+3 -1
@@ -277,12 +277,14 @@ class EVMChainClient {
277 currency == CryptoCurrency.maticpoly ||
278 currency == CryptoCurrency.baseEth ||
279 currency == CryptoCurrency.arbEth ||
280 + currency == CryptoCurrency.bnb ||
281 contractAddress != null);
282
283 bool isNativeToken = currency == CryptoCurrency.eth ||
284 currency == CryptoCurrency.maticpoly ||
285 currency == CryptoCurrency.baseEth ||
285 - currency == CryptoCurrency.arbEth;
286 + currency == CryptoCurrency.arbEth ||
287 + currency == CryptoCurrency.bnb;
288
289 // Get nonce with "pending" block tag to include pending transactions
290 // This prevents "Nonce too low" errors when sending multiple transactions quickly
cw_evm/lib/evm_chain_client_factory.dart
+3
@@ -1,5 +1,6 @@
1 import 'package:cw_evm/clients/arbitrum_client.dart';
2 import 'package:cw_evm/clients/base_client.dart';
3 +import 'package:cw_evm/clients/bsc_client.dart';
4 import 'package:cw_evm/clients/ethereum_client.dart';
5 import 'package:cw_evm/clients/polygon_client.dart';
6 import 'package:cw_evm/clients/evm_chain_client.dart';
@@ -29,6 +30,8 @@ class EVMChainClientFactory {
30 return BaseClient();
31 case 42161:
32 return ArbitrumClient();
33 + case 56:
34 + return BSCClient();
35 default:
36 return EVMChainClient(chainId: chainId);
37 }
cw_evm/lib/evm_chain_default_tokens.dart
+2
@@ -1,6 +1,7 @@
1 import 'package:cw_core/erc20_token.dart';
2 import 'package:cw_evm/tokens/arbitrum_tokens.dart';
3 import 'package:cw_evm/tokens/base_tokens.dart';
4 +import 'package:cw_evm/tokens/bsc_tokens.dart';
5 import 'package:cw_evm/tokens/ethereum_tokens.dart';
6 import 'package:cw_evm/tokens/polygon_tokens.dart';
7
@@ -12,6 +13,7 @@ class EVMChainDefaultTokens {
13 137 => PolygonTokens.tokens,
14 8453 => BaseTokens.tokens,
15 42161 => ArbitrumTokens.tokens,
16 + 56 => BSCTokens.tokens,
17 _ => [],
18 };
19 }
cw_evm/lib/evm_chain_registry.dart
+35
@@ -155,6 +155,41 @@ class EvmChainRegistry {
155 WalletType.arbitrum,
156 'ARB',
157 );
158 +
159 + // BNB Smart Chain
160 + _registerChain(
161 + const ChainConfig(
162 + chainId: 56,
163 + name: 'BNB Smart Chain',
164 + shortCode: 'bsc',
165 + caip2: 'eip155:56',
166 + nativeCurrency: CryptoCurrency.bnb,
167 + capabilities: ChainCapabilities(
168 + supportsERC20: true,
169 + supportsEIP1559: true,
170 + supportsInternalTx: true,
171 + supportsSubscriptions: false,
172 + supportsENS: false,
173 + ),
174 + defaultRpcEndpoints: [
175 + 'bsc-dataseed1.binance.org',
176 + 'bsc-dataseed2.binance.org',
177 + 'bsc-dataseed1.defibit.io',
178 + 'bsc-dataseed1.nodereal.io',
179 + 'bsc.llamarpc.com',
180 + 'bsc-rpc.publicnode.com',
181 + ],
182 + explorerUrls: [
183 + 'https://bscscan.com',
184 + ],
185 + feeModel: FeeModel(
186 + type: FeeType.eip1559,
187 + defaultGasLimit: 21000,
188 + ),
189 + ),
190 + WalletType.bsc,
191 + 'BSC',
192 + );
193 }
194
195 void _registerChain(
cw_evm/lib/evm_chain_transaction_info.dart
+7 -1
@@ -50,10 +50,16 @@ class EVMChainTransactionInfo extends TransactionInfo {
50 /// Get fee currency symbol based on wallet type
51 String get feeCurrency => EVMChainUtils.getFeeCurrency(chainId);
52
53 + String get _displayTokenSymbol {
54 + if (chainId == 56 && tokenSymbol.toUpperCase() == 'BSC-USD') return 'USDT';
55 +
56 + return tokenSymbol;
57 + }
58 +
59 @override
60 String amountFormatted() {
61 final amount = formatAmount((ethAmount / BigInt.from(10).pow(exponent)).toString());
56 - return '${amount.substring(0, min(10, amount.length))} $tokenSymbol';
62 + return '${amount.substring(0, min(10, amount.length))} $_displayTokenSymbol';
63 }
64
65 @override
cw_evm/lib/evm_chain_wallet.dart
+1
@@ -368,6 +368,7 @@ abstract class EVMChainWalletBase
368 137 => "0x2791bca1f2de4661ed88a30c99a7a9449aa84174",
369 8453 => "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
370 42161 => "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
371 + 56 => "0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d",
372 _ => throw Exception("Unsupported chain ID: $selectedChainId"),
373 };
374 }
cw_evm/lib/tokens/bsc_tokens.dart new
+88
@@ -0,0 +1,88 @@
1 +import 'package:cw_core/crypto_currency.dart';
2 +import 'package:cw_core/erc20_token.dart';
3 +
4 +/// Default ERC20 tokens for Binance Smart Chain
5 +class BSCTokens {
6 + static List<Erc20Token> get tokens {
7 + final tokens = [
8 + Erc20Token(
9 + name: "USD Coin",
10 + symbol: "USDC",
11 + contractAddress: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",
12 + decimal: 18,
13 + enabled: true,
14 + ),
15 + Erc20Token(
16 + name: "Ethereum",
17 + symbol: "ETH",
18 + contractAddress: "0x2170Ed0880ac9A755fd29B2688956BD959F933F8",
19 + decimal: 18,
20 + enabled: true,
21 + ),
22 + Erc20Token(
23 + name: "Tether USD",
24 + symbol: "USDT",
25 + contractAddress: "0x55d398326f99059fF775485246999027B3197955",
26 + decimal: 18,
27 + enabled: true,
28 + ),
29 + Erc20Token(
30 + name: "USDe",
31 + symbol: "USDe",
32 + contractAddress: "0x5d3a1Ff2b6BAb83b63cd9AD0787074081a52ef34",
33 + decimal: 18,
34 + enabled: true,
35 + ),
36 + Erc20Token(
37 + name: "PancakeSwap Token",
38 + symbol: "CAKE",
39 + contractAddress: "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82",
40 + decimal: 18,
41 + enabled: false,
42 + ),
43 + Erc20Token(
44 + name: "Cardano Token",
45 + symbol: "ADA",
46 + contractAddress: "0x3EE2200Efb3400fAbB9AacF31297cBdD1d435D47",
47 + decimal: 18,
48 + enabled: false,
49 + ),
50 + Erc20Token(
51 + name: "PEPE",
52 + symbol: "PEPE",
53 + contractAddress: "0x25d887ce7a35172c62febfd67a1856f20faebb00",
54 + decimal: 18,
55 + enabled: false,
56 + ),
57 + Erc20Token(
58 + name: "Wrapped BTC",
59 + symbol: "WBTC",
60 + contractAddress: "0x0555E30da8f98308EdB960aa94C0Db47230d2B9c",
61 + decimal: 8,
62 + enabled: false,
63 + ),
64 + Erc20Token(
65 + name: "Wrapped BNB",
66 + symbol: "WBNB",
67 + contractAddress: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",
68 + decimal: 18,
69 + enabled: false,
70 + ),
71 + ];
72 +
73 + return tokens.map((token) {
74 + String? iconPath;
75 + if (token.iconPath?.isEmpty ?? true) {
76 + try {
77 + iconPath = CryptoCurrency.all
78 + .firstWhere((element) => element.title.toUpperCase() == token.symbol.toUpperCase())
79 + .iconPath;
80 + } catch (_) {}
81 + } else {
82 + iconPath = token.iconPath;
83 + }
84 +
85 + return Erc20Token.copyWith(token, icon: iconPath, tag: 'BSC');
86 + }).toList();
87 + }
88 +}
cw_evm/lib/utils/evm_chain_utils.dart
+7
@@ -9,6 +9,7 @@ class EVMChainUtils {
9 1 => _ethereumPriorityFee(priority),
10 137 => _polygonPriorityFee(priority),
11 8453 => _basePriorityFee(priority),
12 + 56 => _ethereumPriorityFee(priority),
13 42161 => 0, // Arbitrum doesn't use priority fees
14 _ => _ethereumPriorityFee(priority),
15 };
@@ -29,6 +30,7 @@ class EVMChainUtils {
30 137 => "${sanitizedName}_${Erc20Token.polygonBoxName}",
31 8453 => "${sanitizedName}_${Erc20Token.baseBoxName}",
32 42161 => "${sanitizedName}_${Erc20Token.arbitrumBoxName}",
33 + 56 => "${sanitizedName}_${Erc20Token.bscBoxName}",
34 _ => "${sanitizedName}_${Erc20Token.ethereumBoxName}",
35 };
36 }
@@ -39,6 +41,7 @@ class EVMChainUtils {
41 137 => 'polygon_transactions.json',
42 8453 => 'base_transactions.json',
43 42161 => 'arbitrum_transactions.json',
44 + 56 => 'bsc_transactions.json',
45 _ => 'transactions_$chainId.json', // Generic format for other chains
46 };
47 }
@@ -50,6 +53,7 @@ class EVMChainUtils {
53 137 => 'use_polygonscan',
54 8453 => 'use_basescan',
55 42161 => 'use_arbiscan',
56 + 56 => 'use_bscscan',
57 _ => 'use_etherscan',
58 };
59 }
@@ -60,6 +64,7 @@ class EVMChainUtils {
64 137 => 'POL',
65 8453 => 'BASE',
66 42161 => 'ARB',
67 + 56 => 'BSC',
68 _ => 'ETH',
69 };
70 }
@@ -70,6 +75,7 @@ class EVMChainUtils {
75 137 => 'MATIC',
76 8453 => 'ETH',
77 42161 => 'ETH',
78 + 56 => 'BNB',
79 _ => 'ETH',
80 };
81 }
@@ -80,6 +86,7 @@ class EVMChainUtils {
86 137 => 'MATIC',
87 8453 => 'BASE',
88 42161 => 'ARBITRUM',
89 + 56 => 'BNB',
90 _ => 'ETH',
91 };
92 }
integration_test/components/common_test_flows.dart
+4
@@ -358,6 +358,8 @@ class CommonTestFlows {
358 return secrets.baseTestWalletSeeds;
359 case WalletType.arbitrum:
360 return secrets.arbitrumTestWalletSeeds;
361 + case WalletType.bsc:
362 + return secrets.bscTestWalletSeeds;
363 case WalletType.tron:
364 return secrets.tronTestWalletSeeds;
365 case WalletType.nano:
@@ -398,6 +400,8 @@ class CommonTestFlows {
400 return secrets.baseTestWalletReceiveAddress;
401 case WalletType.arbitrum:
402 return secrets.arbitrumTestWalletReceiveAddress;
403 + case WalletType.bsc:
404 + return secrets.bscTestWalletReceiveAddress;
405 case WalletType.solana:
406 return secrets.solanaTestWalletReceiveAddress;
407 case WalletType.tron:
ios/Runner/InfoBase.plist
+20
@@ -342,6 +342,26 @@
342 <string>arbitrum-wallet</string>
343 </array>
344 </dict>
345 + <dict>
346 + <key>CFBundleTypeRole</key>
347 + <string>Editor</string>
348 + <key>CFBundleURLName</key>
349 + <string>bsc</string>
350 + <key>CFBundleURLSchemes</key>
351 + <array>
352 + <string>bsc</string>
353 + </array>
354 + </dict>
355 + <dict>
356 + <key>CFBundleTypeRole</key>
357 + <string>Viewer</string>
358 + <key>CFBundleURLName</key>
359 + <string>bsc-wallet</string>
360 + <key>CFBundleURLSchemes</key>
361 + <array>
362 + <string>bsc-wallet</string>
363 + </array>
364 + </dict>
365 <dict>
366 <key>CFBundleTypeRole</key>
367 <string>Viewer</string>
lib/buy/dfx/dfx_buy_provider.dart
+1
@@ -137,6 +137,7 @@ class DFXBuyProvider extends BuyProvider {
137 case WalletType.polygon:
138 case WalletType.base:
139 case WalletType.arbitrum:
140 + case WalletType.bsc:
141 case WalletType.solana:
142 case WalletType.tron:
143 return wallet.signMessage(message);
lib/buy/robinhood/robinhood_buy_provider.dart
+1
@@ -107,6 +107,7 @@ class RobinhoodBuyProvider extends BuyProvider {
107 case WalletType.polygon:
108 case WalletType.base:
109 case WalletType.arbitrum:
110 + case WalletType.bsc:
111 case WalletType.solana:
112 case WalletType.tron:
113 case WalletType.dogecoin:
lib/core/payment_uris.dart
+15
@@ -116,6 +116,21 @@ class ArbitrumURI extends PaymentURI {
116 }
117 }
118
119 +class BSCURI extends PaymentURI {
120 + BSCURI({required super.amount, required super.address});
121 +
122 + @override
123 + String toString() {
124 + var base = 'bsc:$address';
125 +
126 + if (amount.isNotEmpty) {
127 + base += '?amount=${amount.replaceAll(',', '.')}';
128 + }
129 +
130 + return base;
131 + }
132 +}
133 +
134 class BitcoinCashURI extends PaymentURI {
135 BitcoinCashURI({required super.amount, required super.address});
136
lib/core/seed_validator.dart
+1
@@ -37,6 +37,7 @@ class SeedValidator extends Validator<MnemonicItem> {
37 case WalletType.polygon:
38 case WalletType.base:
39 case WalletType.arbitrum:
40 + case WalletType.bsc:
41 return evm!.getEVMWordList(language);
42 case WalletType.bitcoinCash:
43 return getBitcoinWordList(language);
lib/core/wallet_creation_service.dart
+1
@@ -79,6 +79,7 @@ class WalletCreationService {
79 case WalletType.polygon:
80 case WalletType.base:
81 case WalletType.arbitrum:
82 + case WalletType.bsc:
83 case WalletType.solana:
84 case WalletType.tron:
85 case WalletType.dogecoin:
lib/di.dart
+1
@@ -1202,6 +1202,7 @@ Future<void> setup({
1202 case WalletType.polygon:
1203 case WalletType.base:
1204 case WalletType.arbitrum:
1205 + case WalletType.bsc:
1206 return evm!.createEVMWalletService(param1, SettingsStoreBase.walletPasswordDirectInput);
1207 case WalletType.bitcoinCash:
1208 return bitcoinCash!.createBitcoinCashWalletService(_unspentCoinsInfoSource, SettingsStoreBase.walletPasswordDirectInput);
lib/entities/default_settings_migration.dart
+20
@@ -51,6 +51,7 @@ const decredDefaultUri = "default-spv-nodes";
51 const dogecoinDefaultNodeUri = 'dogecoin.stackwallet.com:50022';
52 const baseDefaultNodeUri = 'base.nownodes.io';
53 const arbitrumDefaultNodeUri = 'arbitrum.nownodes.io';
54 +const bscDefaultNodeUri = 'bsc-dataseed.bnbchain.org';
55 const zcashDefaultNodeUri = 'zec-node.cakewallet.com:443';
56
57 Future<void> defaultSettingsMigration(
@@ -572,6 +573,14 @@ Future<void> defaultSettingsMigration(
573 await sharedPreferences.setString(
574 PreferencesKey.syncStatusDisplayMode, SyncStatusDisplayMode.blocksRemaining.name);
575 break;
576 + case 57:
577 + await addWalletNodeList(nodes: nodes, type: WalletType.bsc);
578 + await _changeDefaultNode(
579 + nodes: nodes,
580 + sharedPreferences: sharedPreferences,
581 + type: WalletType.bsc,
582 + currentNodePreferenceKey: PreferencesKey.currentBscNodeIdKey,
583 + );
584 default:
585 break;
586 }
@@ -684,6 +693,8 @@ String _getDefaultNodeUri(WalletType type) {
693 return baseDefaultNodeUri;
694 case WalletType.arbitrum:
695 return arbitrumDefaultNodeUri;
696 + case WalletType.bsc:
697 + return bscDefaultNodeUri;
698 case WalletType.zcash:
699 return zcashDefaultNodeUri;
700 case WalletType.banano:
@@ -1095,6 +1106,7 @@ Future<void> checkCurrentNodes(
1106 final currentPolygonNodeId = sharedPreferences.getInt(PreferencesKey.currentPolygonNodeIdKey);
1107 final currentBaseNodeId = sharedPreferences.getInt(PreferencesKey.currentBaseNodeIdKey);
1108 final currentArbitrumNodeId = sharedPreferences.getInt(PreferencesKey.currentArbitrumNodeIdKey);
1109 + final currentBscNodeId = sharedPreferences.getInt(PreferencesKey.currentBscNodeIdKey);
1110 final currentNanoNodeId = sharedPreferences.getInt(PreferencesKey.currentNanoNodeIdKey);
1111 final currentNanoPowNodeId = sharedPreferences.getInt(PreferencesKey.currentNanoPowNodeIdKey);
1112 final currentDecredNodeId = sharedPreferences.getInt(PreferencesKey.currentDecredNodeIdKey);
@@ -1123,6 +1135,8 @@ Future<void> checkCurrentNodes(
1135 nodeSource.values.firstWhereOrNull((node) => node.key == currentBaseNodeId);
1136 final currentArbitrumNodeServer =
1137 nodeSource.values.firstWhereOrNull((node) => node.key == currentArbitrumNodeId);
1138 + final currentBscNodeServer =
1139 + nodeSource.values.firstWhereOrNull((node) => node.key == currentBscNodeId);
1140 final currentNanoNodeServer =
1141 nodeSource.values.firstWhereOrNull((node) => node.key == currentNanoNodeId);
1142 final currentDecredNodeServer =
@@ -1228,6 +1242,12 @@ Future<void> checkCurrentNodes(
1242 await sharedPreferences.setInt(PreferencesKey.currentArbitrumNodeIdKey, node.key as int);
1243 }
1244
1245 + if (currentBscNodeServer == null) {
1246 + final node = Node(uri: bscDefaultNodeUri, type: WalletType.bsc);
1247 + await nodeSource.add(node);
1248 + await sharedPreferences.setInt(PreferencesKey.currentBscNodeIdKey, node.key as int);
1249 + }
1250 +
1251 if (currentSolanaNodeServer == null) {
1252 final node = Node(uri: solanaDefaultNodeUri, type: WalletType.solana);
1253 await nodeSource.add(node);
lib/entities/ens_record.dart
+1
@@ -38,6 +38,7 @@ class EnsRecord {
38 case WalletType.polygon:
39 case WalletType.base:
40 case WalletType.arbitrum:
41 + case WalletType.bsc:
42 default:
43 return (await ens.withName(name).getAddress()).hex;
44 }
lib/entities/node_list.dart
+6 -1
@@ -59,6 +59,9 @@ Future<List<Node>> loadDefaultNodes(WalletType type) async {
59 case WalletType.zcash:
60 path = 'assets/zcash_node_list.yml';
61 break;
62 + case WalletType.bsc:
63 + path = 'assets/bsc_node_list.yml';
64 + break;
65 case WalletType.banano:
66 case WalletType.none:
67 path = '';
@@ -113,6 +116,7 @@ Future<void> resetToDefault(Box<Node> nodeSource) async {
116 final baseNodes = await loadDefaultNodes(WalletType.base);
117 final arbitrumNodes = await loadDefaultNodes(WalletType.arbitrum);
118 final zcashNodes = await loadDefaultNodes(WalletType.zcash);
119 + final bscNodes = await loadDefaultNodes(WalletType.bsc);
120
121 final nodes = moneroNodes +
122 bitcoinElectrumServerList +
@@ -129,7 +133,8 @@ Future<void> resetToDefault(Box<Node> nodeSource) async {
133 dogecoinElectrumServerList +
134 baseNodes +
135 arbitrumNodes +
132 - zcashNodes;
136 + zcashNodes +
137 + bscNodes;
138
139 await nodeSource.clear();
140 await nodeSource.addAll(nodes);
lib/entities/preferences_key.dart
+3
@@ -10,6 +10,7 @@ class PreferencesKey {
10 static const currentPolygonNodeIdKey = 'current_node_id_matic';
11 static const currentBaseNodeIdKey = 'current_node_id_base';
12 static const currentArbitrumNodeIdKey = 'current_node_id_arbitrum';
13 + static const currentBscNodeIdKey = 'current_node_id_bsc';
14 static const currentNanoNodeIdKey = 'current_node_id_nano';
15 static const currentNanoPowNodeIdKey = 'current_node_id_nano_pow';
16 static const currentDecredNodeIdKey = 'current_node_id_decred';
@@ -56,6 +57,7 @@ class PreferencesKey {
57 static const ethereumTransactionPriority = 'current_fee_priority_ethereum';
58 static const polygonTransactionPriority = 'current_fee_priority_polygon';
59 static const baseTransactionPriority = 'current_fee_priority_base';
60 + static const bscTransactionPriority = 'current_fee_priority_bsc';
61 static const bitcoinCashTransactionPriority = 'current_fee_priority_bitcoin_cash';
62 static const zanoTransactionPriority = 'current_fee_priority_zano';
63 static const wowneroTransactionPriority = 'current_fee_priority_wownero';
@@ -83,6 +85,7 @@ class PreferencesKey {
85 static const usePolygonScan = 'use_polygonscan';
86 static const useBaseScan = 'use_base_scan';
87 static const useArbiScan = 'use_arbitrum_scan';
88 + static const useBscScan = 'use_bscscan';
89 static const useTronGrid = 'use_trongrid';
90 static const useMempoolFeeAPI = 'use_mempool_fee_api';
91 static const evmHiddenChainIds = 'evm_hidden_chain_ids';
lib/entities/priority_for_wallet_type.dart
+1
@@ -23,6 +23,7 @@ List<TransactionPriority> priorityForWalletType(WalletType type) {
23 case WalletType.ethereum:
24 case WalletType.polygon:
25 case WalletType.base:
26 + case WalletType.bsc:
27 return evm!.getTransactionPriorities();
28 case WalletType.bitcoinCash:
29 return bitcoinCash!.getTransactionPriorities();
lib/main.dart
+1 -1
@@ -313,7 +313,7 @@ Future<void> initializeAppConfigs({bool loadWallet = true}) async {
313 payjoinSessionSource: payjoinSessionSource,
314 anonpayInvoiceInfo: anonpayInvoiceInfo,
315 havenSeedStore: havenSeedStore,
316 - initialMigrationVersion: 56,
316 + initialMigrationVersion: 57,
317 );
318 }
319
lib/reactions/wallet_connect.dart
+6 -1
@@ -11,6 +11,7 @@ bool isEVMCompatibleChain(WalletType walletType) {
11 case WalletType.ethereum:
12 case WalletType.base:
13 case WalletType.arbitrum:
14 + case WalletType.bsc:
15 return true;
16 default:
17 return false;
@@ -18,7 +19,6 @@ bool isEVMCompatibleChain(WalletType walletType) {
19 }
20
21 // Blink Protection is supported on Ethereum and Base chains
21 -//TODO: Add BNB Smart Chain to this list when we integrate it
22 bool canSupportBlinkProtection(int? chainId) {
23 if (chainId == null) return false;
24
@@ -32,6 +32,7 @@ bool isNFTACtivatedChain(WalletType walletType, int? chainId) {
32 case 8453:
33 case 137:
34 case 42161:
35 + case 56:
36 return true;
37 default:
38 return false;
@@ -53,6 +54,7 @@ bool isWalletConnectCompatibleChain(WalletType walletType) {
54 case WalletType.ethereum:
55 case WalletType.base:
56 case WalletType.arbitrum:
57 + case WalletType.bsc:
58 return true;
59 default:
60 return false;
@@ -73,6 +75,8 @@ String getChainNameSpaceAndIdBasedOnWalletType(WalletType walletType, {int? chai
75 return EVMChainId.base.chain();
76 case WalletType.arbitrum:
77 return EVMChainId.arbitrum.chain();
78 + case WalletType.bsc:
79 + return EVMChainId.bsc.chain();
80 case WalletType.solana:
81 return SolanaChainId.mainnet.chain();
82 default:
@@ -86,6 +90,7 @@ List<String> getChainSupportedMethodsOnWalletType(WalletType walletType) {
90 case WalletType.polygon:
91 case WalletType.base:
92 case WalletType.arbitrum:
93 + case WalletType.bsc:
94 return EVMSupportedMethods.values.map((e) => e.name).toList();
95 case WalletType.solana:
96 return SolanaSupportedMethods.values.map((e) => e.name).toList();
lib/reactions/wallet_utils.dart
+2
@@ -6,6 +6,7 @@ bool isBIP39Wallet(WalletType walletType) {
6 case WalletType.polygon:
7 case WalletType.base:
8 case WalletType.arbitrum:
9 + case WalletType.bsc:
10 case WalletType.solana:
11 case WalletType.tron:
12 case WalletType.bitcoin:
@@ -46,6 +47,7 @@ bool hasTokens(WalletType walletType) {
47 case WalletType.zano:
48 case WalletType.base:
49 case WalletType.arbitrum:
50 + case WalletType.bsc:
51 return true;
52 default:
53 return false;
lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart
+3
@@ -41,6 +41,7 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
41 final bitcoinCashIcon = Image.asset('assets/images/crypto/bitcoin-cash.webp', height: 24, width: 24);
42 final baseIcon = Image.asset('assets/images/crypto/base_icon.webp', height: 24, width: 24);
43 final arbitrumIcon = Image.asset('assets/images/crypto/arbitrum.webp', height: 24, width: 24);
44 + final bscIcon = Image.asset('assets/images/crypto/BNB.webp', height: 24, width: 24);
45 final nanoIcon = Image.asset('assets/images/crypto/nano.webp', height: 24, width: 24);
46 final bananoIcon = Image.asset('assets/images/crypto/nano.webp', height: 24, width: 24);
47 final solanaIcon = Image.asset('assets/images/crypto/solana.webp', height: 24, width: 24);
@@ -192,6 +193,8 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
193 return baseIcon;
194 case WalletType.arbitrum:
195 return arbitrumIcon;
196 + case WalletType.bsc:
197 + return bscIcon;
198 case WalletType.zcash:
199 return zcashIcon;
200 case WalletType.none:
lib/src/screens/dashboard/widgets/menu_widget.dart
+4 -1
@@ -5,7 +5,6 @@ import 'package:flutter/material.dart';
5 import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
6 import 'package:cw_core/wallet_type.dart';
7 import 'package:flutter_mobx/flutter_mobx.dart';
8 -import 'package:flutter_svg/svg.dart';
8
9 class MenuWidget extends StatefulWidget {
10 MenuWidget(this.dashboardViewModel, Key? key);
@@ -36,6 +35,7 @@ class MenuWidgetState extends State<MenuWidget> {
35 this.polygonIcon = Image.asset('assets/images/crypto/polygon.webp'),
36 this.baseIcon = Image.asset('assets/images/crypto/base_icon.webp'),
37 this.arbitrumIcon = Image.asset('assets/images/crypto/arbitrum.webp'),
38 + this.bscIcon = Image.asset('assets/images/crypto/BNB.webp'),
39 this.solanaIcon = Image.asset('assets/images/crypto/solana.webp'),
40 this.tronIcon = Image.asset('assets/images/crypto/tron.webp'),
41 this.wowneroIcon = Image.asset('assets/images/crypto/wownero.webp'),
@@ -66,6 +66,7 @@ class MenuWidgetState extends State<MenuWidget> {
66 Image polygonIcon;
67 Image baseIcon;
68 Image arbitrumIcon;
69 + Image bscIcon;
70 Image solanaIcon;
71 Image tronIcon;
72 Image wowneroIcon;
@@ -258,6 +259,8 @@ class MenuWidgetState extends State<MenuWidget> {
259 return baseIcon;
260 case WalletType.arbitrum:
261 return arbitrumIcon;
262 + case WalletType.bsc:
263 + return bscIcon;
264 case WalletType.tron:
265 return tronIcon;
266 case WalletType.wownero:
lib/src/screens/settings/privacy_page.dart
+8
@@ -142,6 +142,14 @@ class PrivacyPage extends BasePage {
142 _privacySettingsViewModel.setUseArbiScan(value);
143 },
144 ),
145 + if (_privacySettingsViewModel.canUseBscScan)
146 + SettingsSwitcherCell(
147 + title: S.current.bscscan_history,
148 + value: _privacySettingsViewModel.useBscScan,
149 + onValueChange: (BuildContext _, bool value) {
150 + _privacySettingsViewModel.setUseBscScan(value);
151 + },
152 + ),
153 if (_privacySettingsViewModel.canUseTronGrid)
154 SettingsSwitcherCell(
155 title: S.current.trongrid_history,
lib/src/screens/wallet_connect/services/chain_service/eth/evm_chain_id.dart
+2
@@ -5,6 +5,7 @@ enum EVMChainId {
5 polygon,
6 base,
7 arbitrum,
8 + bsc,
9 }
10
11 extension EVMChainIdX on EVMChainId {
@@ -22,6 +23,7 @@ extension EVMChainIdX on EVMChainId {
23 EVMChainId.polygon => 137,
24 EVMChainId.base => 8453,
25 EVMChainId.arbitrum => 42161,
26 + EVMChainId.bsc => 56,
27 };
28 }
29
lib/src/screens/wallet_connect/services/key_service/wallet_connect_key_service.dart
+2
@@ -22,6 +22,7 @@ class KeyServiceImpl implements WalletConnectKeyService {
22 case WalletType.polygon:
23 case WalletType.base:
24 case WalletType.arbitrum:
25 + case WalletType.bsc:
26 return evm!.getPrivateKey(wallet);
27 case WalletType.solana:
28 return solana!.getPrivateKey(wallet);
@@ -36,6 +37,7 @@ class KeyServiceImpl implements WalletConnectKeyService {
37 case WalletType.polygon:
38 case WalletType.base:
39 case WalletType.arbitrum:
40 + case WalletType.bsc:
41 return evm!.getPublicKey(wallet);
42 case WalletType.solana:
43 return solana!.getPublicKey(wallet);
lib/src/widgets/evm_switcher.dart
+15 -41
@@ -14,52 +14,26 @@ class EvmSwitcherDataItem {
14 required this.svgPath,
15 required this.chainId,
16 });
17 -
18 - static const ethereum = EvmSwitcherDataItem(
19 - name: 'Ethereum',
20 - svgPath: 'assets/images/evm_switcher_icons/ethereum.svg',
21 - chainId: 1,
22 - );
23 -
24 - static const polygon = EvmSwitcherDataItem(
25 - name: 'Polygon',
26 - svgPath: 'assets/images/evm_switcher_icons/polygon.svg',
27 - chainId: 137,
28 - );
29 -
30 - static const arbitrum = EvmSwitcherDataItem(
31 - name: 'Arbitrum',
32 - svgPath: 'assets/images/evm_switcher_icons/arbitrum.svg',
33 - chainId: 42161,
34 - );
35 -
36 - static const base = EvmSwitcherDataItem(
37 - name: 'Base',
38 - svgPath: 'assets/images/evm_switcher_icons/base.svg',
39 - chainId: 8453,
40 - );
41 -
42 - static const items = [
43 - ethereum,
44 - polygon,
45 - arbitrum,
46 - base,
47 - ];
17 }
18
19 String _getSvgPathForChain(String chainName) {
20 final name = chainName.toLowerCase();
52 - if (name.contains('ethereum')) {
53 - return 'assets/images/evm_switcher_icons/ethereum.svg';
54 - } else if (name.contains('polygon')) {
55 - return 'assets/images/evm_switcher_icons/polygon.svg';
56 - } else if (name.contains('arbitrum')) {
57 - return 'assets/images/evm_switcher_icons/arbitrum.svg';
58 - } else if (name.contains('base')) {
59 - return 'assets/images/evm_switcher_icons/base.svg';
21 +
22 + switch (name) {
23 + case 'ethereum':
24 + return 'assets/images/crypto/ethereum.webp';
25 + case 'polygon':
26 + return 'assets/images/crypto/polygon.webp';
27 + case 'arbitrum':
28 + return 'assets/images/crypto/arbitrum.webp';
29 + case 'base':
30 + return 'assets/images/crypto/base_icon.webp';
31 + case 'bnb':
32 + case 'bsc':
33 + return 'assets/images/crypto/BNB.webp';
34 + default:
35 + return 'assets/images/crypto/ethereum.webp';
36 }
61 - // Default to ethereum if unknown
62 - return 'assets/images/evm_switcher_icons/ethereum.svg';
37 }
38
39 class EvmSwitcher extends StatefulWidget {
lib/src/widgets/evm_switcher_row.dart
+13 -12
@@ -1,7 +1,7 @@
1 +import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
2 import 'package:cake_wallet/src/widgets/evm_switcher.dart';
3 import 'package:cake_wallet/src/widgets/standard_switch.dart';
4 import 'package:flutter/material.dart';
4 -import 'package:flutter_svg/flutter_svg.dart';
5
6 class EvmSwitcherRow extends StatelessWidget {
7 const EvmSwitcherRow({
@@ -45,23 +45,24 @@ class EvmSwitcherRow extends StatelessWidget {
45 Row(
46 spacing: 8.0,
47 children: [
48 - SvgPicture.asset(
49 - data.svgPath,
48 + CakeImageWidget(
49 + imageUrl: data.svgPath,
50 width: 16,
51 height: 16,
52 - colorFilter: ColorFilter.mode(
53 - resolvedForegroundColor, BlendMode.srcIn),
52 ),
55 - Text(data.name,
56 - style: TextStyle(
57 - color: resolvedForegroundColor, fontSize: 14)),
53 + Text(
54 + data.name,
55 + style: TextStyle(color: resolvedForegroundColor, fontSize: 14),
56 + ),
57 if (selected && !editMode)
59 - SvgPicture.asset("assets/images/evm_switcher_checkmark.svg",
60 - width: 18, height: 18),
58 + CakeImageWidget(
59 + imageUrl: "assets/images/evm_switcher_checkmark.svg",
60 + width: 18,
61 + height: 18,
62 + ),
63 ],
64 ),
63 - if (editMode)
64 - StandardSwitch(value: editSwitchValue, onTapped: onTap)
65 + if (editMode) StandardSwitch(value: editSwitchValue, onTapped: onTap)
66 ],
67 ),
68 ),
lib/store/settings_store.dart
+45
@@ -112,6 +112,7 @@ abstract class SettingsStoreBase with Store {
112 required this.useEtherscan,
113 required this.useBaseScan,
114 required this.useArbiScan,
115 + required this.useBscScan,
116 required this.usePolygonScan,
117 required this.useTronGrid,
118 required this.useMempoolFeeAPI,
@@ -146,6 +147,7 @@ abstract class SettingsStoreBase with Store {
147 TransactionPriority? initialEVMTransactionPriority,
148 TransactionPriority? initialPolygonTransactionPriority,
149 TransactionPriority? initialBaseTransactionPriority,
150 + TransactionPriority? initialBscTransactionPriority,
151 TransactionPriority? initialBitcoinCashTransactionPriority,
152 TransactionPriority? initialZanoTransactionPriority,
153 TransactionPriority? initialDecredTransactionPriority,
@@ -238,6 +240,10 @@ abstract class SettingsStoreBase with Store {
240 priority[WalletType.base] = initialBaseTransactionPriority;
241 }
242
243 + if (initialBscTransactionPriority != null) {
244 + priority[WalletType.bsc] = initialBscTransactionPriority;
245 + }
246 +
247 if (initialBitcoinCashTransactionPriority != null) {
248 priority[WalletType.bitcoinCash] = initialBitcoinCashTransactionPriority;
249 }
@@ -305,6 +311,9 @@ abstract class SettingsStoreBase with Store {
311 case WalletType.base:
312 key = PreferencesKey.baseTransactionPriority;
313 break;
314 + case WalletType.bsc:
315 + key = PreferencesKey.bscTransactionPriority;
316 + break;
317 case WalletType.zano:
318 key = PreferencesKey.zanoTransactionPriority;
319 break;
@@ -477,6 +486,9 @@ abstract class SettingsStoreBase with Store {
486 reaction((_) => useArbiScan,
487 (bool useArbiScan) => _sharedPreferences.setBool(PreferencesKey.useArbiScan, useArbiScan));
488
489 + reaction((_) => useBscScan,
490 + (bool useBscScan) => _sharedPreferences.setBool(PreferencesKey.useBscScan, useBscScan));
491 +
492 reaction((_) => useTronGrid,
493 (bool useTronGrid) => _sharedPreferences.setBool(PreferencesKey.useTronGrid, useTronGrid));
494
@@ -853,6 +865,9 @@ abstract class SettingsStoreBase with Store {
865 @observable
866 bool useArbiScan;
867
868 + @observable
869 + bool useBscScan;
870 +
871 @observable
872 bool useTronGrid;
873
@@ -981,6 +996,8 @@ abstract class SettingsStoreBase with Store {
996 return PreferencesKey.currentBaseNodeIdKey;
997 case 42161:
998 return PreferencesKey.currentArbitrumNodeIdKey;
999 + case 56:
1000 + return PreferencesKey.currentBscNodeIdKey;
1001 default:
1002 // Default to Ethereum for unknown chainIds
1003 return PreferencesKey.currentEthereumNodeIdKey;
@@ -1043,6 +1060,7 @@ abstract class SettingsStoreBase with Store {
1060 TransactionPriority? evmTransactionPriority;
1061 TransactionPriority? polygonTransactionPriority;
1062 TransactionPriority? baseTransactionPriority;
1063 + TransactionPriority? bscTransactionPriority;
1064 TransactionPriority? bitcoinCashTransactionPriority;
1065 TransactionPriority? wowneroTransactionPriority;
1066 TransactionPriority? zanoTransactionPriority;
@@ -1070,6 +1088,10 @@ abstract class SettingsStoreBase with Store {
1088 baseTransactionPriority = evm?.deserializeEVMTransactionPriority(
1089 sharedPreferences.getInt(PreferencesKey.baseTransactionPriority)!);
1090 }
1091 + if (sharedPreferences.getInt(PreferencesKey.bscTransactionPriority) != null) {
1092 + bscTransactionPriority = evm?.deserializeEVMTransactionPriority(
1093 + sharedPreferences.getInt(PreferencesKey.bscTransactionPriority)!);
1094 + }
1095 if (sharedPreferences.getInt(PreferencesKey.bitcoinCashTransactionPriority) != null) {
1096 bitcoinCashTransactionPriority = bitcoinCash?.deserializeBitcoinCashTransactionPriority(
1097 sharedPreferences.getInt(PreferencesKey.bitcoinCashTransactionPriority)!);
@@ -1098,6 +1120,7 @@ abstract class SettingsStoreBase with Store {
1120 decredTransactionPriority ??= decred?.getDecredTransactionPriorityMedium();
1121 polygonTransactionPriority ??= evm?.getDefaultTransactionPriority();
1122 baseTransactionPriority ??= evm?.getDefaultTransactionPriority();
1123 + bscTransactionPriority ??= evm?.getDefaultTransactionPriority();
1124 zanoTransactionPriority ??= zano?.getDefaultTransactionPriority();
1125
1126 final currentBalanceDisplayMode = BalanceDisplayMode.deserialize(
@@ -1148,6 +1171,7 @@ abstract class SettingsStoreBase with Store {
1171 final usePolygonScan = sharedPreferences.getBool(PreferencesKey.usePolygonScan) ?? true;
1172 final useBaseScan = sharedPreferences.getBool(PreferencesKey.useBaseScan) ?? true;
1173 final useArbiScan = sharedPreferences.getBool(PreferencesKey.useArbiScan) ?? true;
1174 + final useBscScan = sharedPreferences.getBool(PreferencesKey.useBscScan) ?? true;
1175 final useTronGrid = sharedPreferences.getBool(PreferencesKey.useTronGrid) ?? true;
1176 final useMempoolFeeAPI = sharedPreferences.getBool(PreferencesKey.useMempoolFeeAPI) ?? true;
1177 final useBlinkProtection = sharedPreferences.getBool(PreferencesKey.useBlinkProtection) ?? true;
@@ -1200,6 +1224,7 @@ abstract class SettingsStoreBase with Store {
1224 final polygonNodeId = sharedPreferences.getInt(PreferencesKey.currentPolygonNodeIdKey);
1225 final baseNodeId = sharedPreferences.getInt(PreferencesKey.currentBaseNodeIdKey);
1226 final arbitrumNodeId = sharedPreferences.getInt(PreferencesKey.currentArbitrumNodeIdKey);
1227 + final bscNodeId = sharedPreferences.getInt(PreferencesKey.currentBscNodeIdKey);
1228 final nanoNodeId = sharedPreferences.getInt(PreferencesKey.currentNanoNodeIdKey);
1229 final nanoPowNodeId = sharedPreferences.getInt(PreferencesKey.currentNanoPowNodeIdKey);
1230 final solanaNodeId = sharedPreferences.getInt(PreferencesKey.currentSolanaNodeIdKey);
@@ -1225,6 +1250,8 @@ abstract class SettingsStoreBase with Store {
1250 nodeSource.values.firstWhereOrNull((e) => e.uriRaw == baseDefaultNodeUri);
1251 final arbitrumNode = nodeSource.get(arbitrumNodeId) ??
1252 nodeSource.values.firstWhereOrNull((e) => e.uriRaw == arbitrumDefaultNodeUri);
1253 + final bscNode = nodeSource.get(bscNodeId) ??
1254 + nodeSource.values.firstWhereOrNull((e) => e.uriRaw == bscDefaultNodeUri);
1255 final bitcoinCashElectrumServer = nodeSource.get(bitcoinCashElectrumServerId) ??
1256 nodeSource.values.firstWhereOrNull((e) => e.uriRaw == cakeWalletBitcoinCashDefaultNodeUri);
1257 final nanoNode = nodeSource.get(nanoNodeId) ??
@@ -1309,6 +1336,10 @@ abstract class SettingsStoreBase with Store {
1336 nodes[WalletType.arbitrum] = arbitrumNode;
1337 }
1338
1339 + if (bscNode != null) {
1340 + nodes[WalletType.bsc] = bscNode;
1341 + }
1342 +
1343 if (bitcoinCashElectrumServer != null) {
1344 nodes[WalletType.bitcoinCash] = bitcoinCashElectrumServer;
1345 }
@@ -1502,6 +1533,7 @@ abstract class SettingsStoreBase with Store {
1533 usePolygonScan: usePolygonScan,
1534 useBaseScan: useBaseScan,
1535 useArbiScan: useArbiScan,
1536 + useBscScan: useBscScan,
1537 useTronGrid: useTronGrid,
1538 useMempoolFeeAPI: useMempoolFeeAPI,
1539 useBlinkProtection: useBlinkProtection,
@@ -1552,6 +1584,7 @@ abstract class SettingsStoreBase with Store {
1584 initialEVMTransactionPriority: evmTransactionPriority,
1585 initialPolygonTransactionPriority: polygonTransactionPriority,
1586 initialBaseTransactionPriority: baseTransactionPriority,
1587 + initialBscTransactionPriority: bscTransactionPriority,
1588 initialSyncMode: savedSyncMode,
1589 initialSyncAll: savedSyncAll,
1590 shouldShowYatPopup: shouldShowYatPopup,
@@ -1607,6 +1640,10 @@ abstract class SettingsStoreBase with Store {
1640 priority[WalletType.base] = evm!.deserializeEVMTransactionPriority(
1641 sharedPreferences.getInt(PreferencesKey.baseTransactionPriority)!);
1642 }
1643 + if (evm != null && sharedPreferences.getInt(PreferencesKey.bscTransactionPriority) != null) {
1644 + priority[WalletType.bsc] = evm!.deserializeEVMTransactionPriority(
1645 + sharedPreferences.getInt(PreferencesKey.bscTransactionPriority)!);
1646 + }
1647 if (bitcoinCash != null &&
1648 sharedPreferences.getInt(PreferencesKey.bitcoinCashTransactionPriority) != null) {
1649 priority[WalletType.bitcoinCash] = bitcoinCash!.deserializeBitcoinCashTransactionPriority(
@@ -1706,6 +1743,7 @@ abstract class SettingsStoreBase with Store {
1743 usePolygonScan = sharedPreferences.getBool(PreferencesKey.usePolygonScan) ?? true;
1744 useBaseScan = sharedPreferences.getBool(PreferencesKey.useBaseScan) ?? true;
1745 useArbiScan = sharedPreferences.getBool(PreferencesKey.useArbiScan) ?? true;
1746 + useBscScan = sharedPreferences.getBool(PreferencesKey.useBscScan) ?? true;
1747 useTronGrid = sharedPreferences.getBool(PreferencesKey.useTronGrid) ?? true;
1748 useMempoolFeeAPI = sharedPreferences.getBool(PreferencesKey.useMempoolFeeAPI) ?? true;
1749 useBlinkProtection = sharedPreferences.getBool(PreferencesKey.useBlinkProtection) ?? true;
@@ -1744,6 +1782,7 @@ abstract class SettingsStoreBase with Store {
1782 final polygonNodeId = sharedPreferences.getInt(PreferencesKey.currentPolygonNodeIdKey);
1783 final baseNodeId = sharedPreferences.getInt(PreferencesKey.currentBaseNodeIdKey);
1784 final arbitrumNodeId = sharedPreferences.getInt(PreferencesKey.currentArbitrumNodeIdKey);
1785 + final bscNodeId = sharedPreferences.getInt(PreferencesKey.currentBscNodeIdKey);
1786 final nanoNodeId = sharedPreferences.getInt(PreferencesKey.currentNanoNodeIdKey);
1787 final solanaNodeId = sharedPreferences.getInt(PreferencesKey.currentSolanaNodeIdKey);
1788 final tronNodeId = sharedPreferences.getInt(PreferencesKey.currentTronNodeIdKey);
@@ -1760,6 +1799,7 @@ abstract class SettingsStoreBase with Store {
1799 final polygonNode = nodeSource.get(polygonNodeId);
1800 final baseNode = nodeSource.get(baseNodeId);
1801 final arbitrumNode = nodeSource.get(arbitrumNodeId);
1802 + final bscNode = nodeSource.get(bscNodeId);
1803 final bitcoinCashNode = nodeSource.get(bitcoinCashElectrumServerId);
1804 final nanoNode = nodeSource.get(nanoNodeId);
1805 final solanaNode = nodeSource.get(solanaNodeId);
@@ -1802,6 +1842,10 @@ abstract class SettingsStoreBase with Store {
1842 nodes[WalletType.arbitrum] = arbitrumNode;
1843 }
1844
1845 + if (bscNode != null) {
1846 + nodes[WalletType.bsc] = bscNode;
1847 + }
1848 +
1849 if (bitcoinCashNode != null) {
1850 nodes[WalletType.bitcoinCash] = bitcoinCashNode;
1851 }
@@ -1956,6 +2000,7 @@ abstract class SettingsStoreBase with Store {
2000 case WalletType.polygon:
2001 case WalletType.base:
2002 case WalletType.arbitrum:
2003 + case WalletType.bsc:
2004 final chainId = evm!.getChainIdByWalletType(node.type);
2005 final preferenceKey = _getEVMNodePreferenceKey(chainId);
2006 await _sharedPreferences.setInt(preferenceKey, node.key as int);
lib/utils/qr_util.dart
+22 -37
@@ -1,26 +1,19 @@
1 -import 'package:cake_wallet/reactions/wallet_connect.dart';
1 import 'package:cw_core/wallet_type.dart';
2
4 -String getQrImage(WalletType type, {int? selectedChainId}) {
5 - if (isEVMCompatibleChain(type) && selectedChainId != null) {
6 - switch (selectedChainId) {
7 - case 1:
8 - return 'assets/images/eth_chain_qr.svg';
9 - case 137:
10 - return 'assets/images/pol_chain_qr.svg';
11 - case 8453:
12 - return 'assets/images/base_chain_QR.svg';
13 - case 42161:
14 - return 'assets/images/arbitrum_chain_QR.svg';
15 - default:
16 - return 'assets/images/eth_chain_qr.svg';
17 - }
18 - }
3 +String getQrImage(WalletType type) {
4 switch (type) {
20 - case WalletType.solana:
21 - return 'assets/images/sol_chain_qr.svg';
5 + case WalletType.ethereum:
6 + return 'assets/images/eth_chain_qr.svg';
7 case WalletType.polygon:
8 return 'assets/images/pol_chain_qr.svg';
9 + case WalletType.base:
10 + return 'assets/images/base_chain_QR.svg';
11 + case WalletType.arbitrum:
12 + return 'assets/images/arbitrum_chain_QR.svg';
13 + case WalletType.bsc:
14 + return 'assets/images/bnb_chain_QR.svg';
15 + case WalletType.solana:
16 + return 'assets/images/sol_chain_qr.svg';
17 case WalletType.tron:
18 return 'assets/images/trx_chain_qr.svg';
19 case WalletType.zano:
@@ -46,32 +39,24 @@ String getQrImage(WalletType type, {int? selectedChainId}) {
39 case WalletType.banano:
40 case WalletType.haven:
41 case WalletType.none:
49 - default:
42 return 'assets/images/qr-cake.png';
43 }
44 }
45
54 -String getChainMonoImage(WalletType type, {int? selectedChainId}) {
55 - if (isEVMCompatibleChain(type) && selectedChainId != null) {
56 - switch (selectedChainId) {
57 - case 1:
58 - return 'assets/images/eth_chain_mono.svg';
59 - case 137:
60 - return 'assets/images/pol_chain_mono.svg';
61 - case 8453:
62 - return 'assets/images/base_chain_mono.svg';
63 - case 42161:
64 - return 'assets/images/arbitrum_chain_mono.svg';
65 - default:
66 - return 'assets/images/eth_chain_mono.svg';
67 - }
68 - }
69 -
46 +String getChainMonoImage(WalletType type) {
47 switch (type) {
71 - case WalletType.solana:
72 - return 'assets/images/sol_chain_mono.svg';
48 + case WalletType.ethereum:
49 + return 'assets/images/eth_chain_mono.svg';
50 case WalletType.polygon:
51 return 'assets/images/pol_chain_mono.svg';
52 + case WalletType.base:
53 + return 'assets/images/base_chain_mono.svg';
54 + case WalletType.arbitrum:
55 + return 'assets/images/arbitrum_chain_mono.svg';
56 + case WalletType.bsc:
57 + return 'assets/images/bnb_chain_mono.svg';
58 + case WalletType.solana:
59 + return 'assets/images/sol_chain_mono.svg';
60 case WalletType.tron:
61 return 'assets/images/trx_chain_mono.svg';
62 case WalletType.zano:
lib/utils/token_utilities.dart
+4 -6
@@ -89,6 +89,7 @@ class TokenUtilities {
89 case WalletType.polygon:
90 case WalletType.base:
91 case WalletType.arbitrum:
92 + case WalletType.bsc:
93 final tokens = await loadAllUniqueEvmTokens();
94 for (final t in tokens) {
95 if (t.contractAddress.toLowerCase() == lower) return t;
@@ -127,6 +128,7 @@ class TokenUtilities {
128 WalletType.polygon => '${walletKey}_${Erc20Token.polygonBoxName}',
129 WalletType.base => '${walletKey}_${Erc20Token.baseBoxName}',
130 WalletType.arbitrum => '${walletKey}_${Erc20Token.arbitrumBoxName}',
131 + WalletType.bsc => '${walletKey}_${Erc20Token.bscBoxName}',
132 _ => '${walletKey}_${Erc20Token.ethereumBoxName}',
133 };
134 }
@@ -185,7 +187,8 @@ class TokenUtilities {
187
188 // Only check EVM registry for currencies that might be EVM-related
189 final isPotentialEVM = isNativeToken(currency) ||
188 - (tag != null && (tag == 'ETH' || tag == 'POL' || tag == 'BASE' || tag == 'ARB'));
190 + (tag != null &&
191 + (tag == 'ETH' || tag == 'POL' || tag == 'BASE' || tag == 'ARB' || tag == 'BSC'));
192
193 if (isPotentialEVM) {
194 // Try by tag first if available (e.g., 'POL', 'BASE', 'ARB')
@@ -200,11 +203,6 @@ class TokenUtilities {
203 }
204
205 // Fallback to hardcoded values for chains not in registry yet
203 - // BSC (Binance Smart Chain)
204 - if (title == 'bsc' || title == 'bnb' || tag == 'BSC') {
205 - return 56;
206 - }
207 -
206 // Avalanche C-Chain
207 if (title == 'avalanche' || title == 'avax' || tag == 'AVALANCHE') {
208 return 43114;
lib/view_model/advanced_privacy_settings_view_model.dart
+2
@@ -55,6 +55,7 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
55 case WalletType.polygon:
56 case WalletType.base:
57 case WalletType.arbitrum:
58 + case WalletType.bsc:
59 case WalletType.solana:
60 case WalletType.tron:
61 case WalletType.zcash:
@@ -98,6 +99,7 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
99 WalletType.polygon,
100 WalletType.base,
101 WalletType.arbitrum,
102 + WalletType.bsc,
103 WalletType.tron,
104 WalletType.solana,
105 WalletType.monero,
lib/view_model/anon_invoice_page_view_model.dart
+1 -2
@@ -5,7 +5,6 @@ import 'package:cake_wallet/core/execution_state.dart';
5 import 'package:cake_wallet/entities/fiat_currency.dart';
6 import 'package:cake_wallet/entities/preferences_key.dart';
7 import 'package:cake_wallet/utils/qr_util.dart';
8 -import 'package:cw_core/currency_for_wallet_type.dart';
8 import 'package:cw_core/receive_page_option.dart';
9 import 'package:cake_wallet/store/settings_store.dart';
10 import 'package:cw_core/crypto_currency.dart';
@@ -177,7 +176,7 @@ abstract class AnonInvoicePageViewModelBase with Store {
176 String get currentWalletName => _wallet.name;
177
178 @computed
180 - String get qrImage => getQrImage(_wallet.type, selectedChainId: _wallet.chainId);
179 + String get qrImage => getQrImage(_wallet.type);
180
181 @action
182 void reset() {
lib/view_model/dashboard/balance_view_model.dart
+1
@@ -177,6 +177,7 @@ abstract class BalanceViewModelBase with Store {
177 case WalletType.polygon:
178 case WalletType.base:
179 case WalletType.arbitrum:
180 + case WalletType.bsc:
181 case WalletType.solana:
182 case WalletType.tron:
183 return S.current.xmr_full_balance;
lib/view_model/dashboard/dashboard_view_model.dart
+1
@@ -947,6 +947,7 @@ abstract class DashboardViewModelBase with Store {
947 case WalletType.polygon:
948 case WalletType.base:
949 case WalletType.arbitrum:
950 + case WalletType.bsc:
951 case WalletType.solana:
952 case WalletType.nano:
953 case WalletType.banano:
lib/view_model/dashboard/home_settings_view_model.dart
+1
@@ -211,6 +211,7 @@ abstract class HomeSettingsViewModelBase with Store {
211 case WalletType.polygon:
212 case WalletType.base:
213 case WalletType.arbitrum:
214 + case WalletType.bsc:
215 defaultTokenAddresses = evm!.getDefaultTokenContractAddresses(_balanceViewModel.wallet);
216 break;
217 case WalletType.solana:
lib/view_model/dashboard/transaction_list_item.dart
+1
@@ -174,6 +174,7 @@ class TransactionListItem extends ActionListItem with Keyable {
174 case WalletType.polygon:
175 case WalletType.base:
176 case WalletType.arbitrum:
177 + case WalletType.bsc:
178 final asset = evm!.assetOfTransaction(balanceViewModel.wallet, transaction);
179 final price = balanceViewModel.fiatConvertationStore.prices[asset];
180 amount = calculateFiatAmountRaw(
lib/view_model/exchange/exchange_trade_view_model.dart
+8 -2
@@ -365,6 +365,9 @@ abstract class ExchangeTradeViewModelBase with Store {
365 bool _isSplToken() =>
366 wallet.currency == CryptoCurrency.sol && tradeFrom?.tag == CryptoCurrency.sol.title;
367
368 + bool _isBscToken() =>
369 + wallet.currency == CryptoCurrency.bnb && tradeFrom?.tag == CryptoCurrency.bnb.tag;
370 +
371 return tradeFrom == wallet.currency ||
372 tradesStore.trade!.provider == ExchangeProviderDescription.xmrto ||
373 _isEthToken() ||
@@ -372,7 +375,8 @@ abstract class ExchangeTradeViewModelBase with Store {
375 _isSplToken() ||
376 _isTronToken() ||
377 _isBaseToken() ||
375 - _isArbitrumToken();
378 + _isArbitrumToken() ||
379 + _isBscToken();
380 }
381
382 Future<void> registerSwapsXyzTransaction() async {
@@ -452,6 +456,8 @@ abstract class ExchangeTradeViewModelBase with Store {
456 return BaseURI(amount: amount, address: inputAddress);
457 case WalletType.arbitrum:
458 return ArbitrumURI(amount: amount, address: inputAddress);
459 + case WalletType.bsc:
460 + return BSCURI(amount: amount, address: inputAddress);
461 case WalletType.solana:
462 return SolanaURI(amount: amount, address: inputAddress);
463 case WalletType.tron:
@@ -503,5 +509,5 @@ abstract class ExchangeTradeViewModelBase with Store {
509 }
510
511 @computed
506 - String get qrImage => getQrImage(wallet.type, selectedChainId: wallet.chainId);
512 + String get qrImage => getQrImage(wallet.type);
513 }
lib/view_model/exchange/exchange_view_model.dart
+4
@@ -904,6 +904,10 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
904 depositCurrency = CryptoCurrency.arbEth;
905 receiveCurrency = CryptoCurrency.xmr;
906 break;
907 + case WalletType.bsc:
908 + depositCurrency = CryptoCurrency.bnb;
909 + receiveCurrency = CryptoCurrency.xmr;
910 + break;
911 case WalletType.solana:
912 depositCurrency = CryptoCurrency.sol;
913 receiveCurrency = CryptoCurrency.xmr;
lib/view_model/node_list/node_create_or_edit_view_model.dart
+1
@@ -82,6 +82,7 @@ abstract class NodeCreateOrEditViewModelBase with Store {
82 case WalletType.polygon:
83 case WalletType.base:
84 case WalletType.arbitrum:
85 + case WalletType.bsc:
86 case WalletType.solana:
87 case WalletType.banano:
88 case WalletType.nano:
lib/view_model/restore/wallet_restore_from_qr_code.dart
+1
@@ -33,6 +33,7 @@ class WalletRestoreFromQRCode {
33 'polygon-wallet': WalletType.polygon,
34 'base-wallet': WalletType.base,
35 'arbitrum-wallet': WalletType.arbitrum,
36 + 'bsc-wallet': WalletType.bsc,
37 'nano-wallet': WalletType.nano,
38 'nano_wallet': WalletType.nano,
39 'bitcoincash': WalletType.bitcoinCash,
lib/view_model/send/fees_view_model.dart
+2
@@ -90,6 +90,7 @@ abstract class FeesViewModelBase extends WalletChangeListenerViewModel with Stor
90 case WalletType.ethereum:
91 case WalletType.polygon:
92 case WalletType.base:
93 + case WalletType.bsc:
94 return transactionPriority == evm!.getEVMTransactionPrioritySlow();
95 case WalletType.bitcoinCash:
96 return transactionPriority == bitcoinCash!.getBitcoinCashTransactionPrioritySlow();
@@ -199,6 +200,7 @@ abstract class FeesViewModelBase extends WalletChangeListenerViewModel with Stor
200 case WalletType.ethereum:
201 case WalletType.polygon:
202 case WalletType.base:
203 + case WalletType.bsc:
204 _settingsStore.setPriority(
205 wallet.type,
206 evm!.getDefaultTransactionPriority(),
lib/view_model/send/output.dart
+4 -1
@@ -117,6 +117,7 @@ abstract class OutputBase with Store {
117 case WalletType.polygon:
118 case WalletType.base:
119 case WalletType.arbitrum:
120 + case WalletType.bsc:
121 _amount = evm!.formatterEVMParseAmount(_cryptoAmount);
122 break;
123 case WalletType.wownero:
@@ -218,10 +219,12 @@ abstract class OutputBase with Store {
219 case WalletType.polygon:
220 case WalletType.base:
221 case WalletType.arbitrum:
222 + case WalletType.bsc:
223 final isNative = cryptoCurrencyHandler() == CryptoCurrency.eth ||
224 cryptoCurrencyHandler() == CryptoCurrency.maticpoly ||
225 cryptoCurrencyHandler() == CryptoCurrency.baseEth ||
224 - cryptoCurrencyHandler() == CryptoCurrency.arbEth;
226 + cryptoCurrencyHandler() == CryptoCurrency.arbEth ||
227 + cryptoCurrencyHandler() == CryptoCurrency.bnb;
228 String? fee = isNative
229 ? evm!.getEVMNativeEstimatedFee(_wallet)
230 : evm!.getEVMERC20EstimatedFee(_wallet);
lib/view_model/send/send_template_view_model.dart
+1 -4
@@ -61,10 +61,7 @@ abstract class SendTemplateViewModelBase with Store {
61 _wallet.type != WalletType.haven &&
62 _wallet.type != WalletType.solana &&
63 _wallet.type != WalletType.tron &&
64 - _wallet.chainId != 1 &&
65 - _wallet.chainId != 137 &&
66 - _wallet.chainId != 8453 &&
67 - _wallet.chainId != 42161;
64 + !isEVMCompatibleChain(_wallet.type);
65
66 @computed
67 CryptoCurrency get cryptoCurrency => _wallet.currency;
lib/view_model/send/send_view_model.dart
+11 -3
@@ -243,6 +243,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
243 case WalletType.polygon:
244 case WalletType.base:
245 case WalletType.arbitrum:
246 + case WalletType.bsc:
247 case WalletType.tron:
248 case WalletType.solana:
249 return wallet.currency;
@@ -1005,6 +1006,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
1006 case WalletType.polygon:
1007 case WalletType.base:
1008 case WalletType.arbitrum:
1009 + case WalletType.bsc:
1010 return evm!.createEVMTransactionCredentials(
1011 outputs,
1012 priority: priority,
@@ -1166,6 +1168,12 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
1168 }
1169
1170 if (errorMessage.contains('insufficient funds')) {
1171 + final feeCurrency = switch (walletType) {
1172 + WalletType.bsc => "BNB",
1173 + WalletType.polygon => "POL",
1174 + _ => "ETH",
1175 + };
1176 +
1177 final parsedErrorMessageResult =
1178 EVMTransactionErrorFeesHandler.parseEthereumFeesErrorMessage(
1179 errorMessage,
@@ -1184,9 +1192,9 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
1192
1193 // Handle successfully parsed errors with specific values
1194 return '''${S.current.insufficient_funds_for_tx} \n\n'''
1187 - '''${S.current.balance}: ${parsedErrorMessageResult.balanceEth} ${walletType == WalletType.polygon ? "POL" : "ETH"} (${parsedErrorMessageResult.balanceUsd} ${fiatFromSettings.name})\n\n'''
1188 - '''${S.current.transaction_cost}: ${parsedErrorMessageResult.txCostEth} ${walletType == WalletType.polygon ? "POL" : "ETH"} (${parsedErrorMessageResult.txCostUsd} ${fiatFromSettings.name})\n\n'''
1189 - '''${S.current.overshot}: ${parsedErrorMessageResult.overshotEth} ${walletType == WalletType.polygon ? "POL" : "ETH"} (${parsedErrorMessageResult.overshotUsd} ${fiatFromSettings.name})''';
1195 + '''${S.current.balance}: ${parsedErrorMessageResult.balanceEth} ${feeCurrency} (${parsedErrorMessageResult.balanceUsd} ${fiatFromSettings.name})\n\n'''
1196 + '''${S.current.transaction_cost}: ${parsedErrorMessageResult.txCostEth} ${feeCurrency} (${parsedErrorMessageResult.txCostUsd} ${fiatFromSettings.name})\n\n'''
1197 + '''${S.current.overshot}: ${parsedErrorMessageResult.overshotEth} ${feeCurrency} (${parsedErrorMessageResult.overshotUsd} ${fiatFromSettings.name})''';
1198 }
1199
1200 if (errorMessage.contains('max fee per gas less than block base fee')) {
lib/view_model/settings/privacy_settings_view_model.dart
+11
@@ -81,6 +81,9 @@ abstract class PrivacySettingsViewModelBase with Store {
81 @computed
82 bool get useArbiScan => _settingsStore.useArbiScan;
83
84 + @computed
85 + bool get useBscScan => _settingsStore.useBscScan;
86 +
87 @computed
88 bool get useTronGrid => _settingsStore.useTronGrid;
89
@@ -127,6 +130,8 @@ abstract class PrivacySettingsViewModelBase with Store {
130
131 bool get canUseArbiScan => _wallet.chainId == 42161;
132
133 + bool get canUseBscScan => _wallet.chainId == 56;
134 +
135 bool get canUseTronGrid => _wallet.type == WalletType.tron;
136
137 bool get canUseMempoolFeeAPI => _wallet.type == WalletType.bitcoin;
@@ -210,6 +215,12 @@ abstract class PrivacySettingsViewModelBase with Store {
215 evm!.updateScanProviderUsageState(_wallet, value);
216 }
217
218 + @action
219 + void setUseBscScan(bool value) {
220 + _settingsStore.useBscScan = value;
221 + evm!.updateScanProviderUsageState(_wallet, value);
222 + }
223 +
224 @action
225 void setUseMempoolFeeAPI(bool value) => _settingsStore.useMempoolFeeAPI = value;
226
lib/view_model/transaction_details_view_model.dart
+5 -1
@@ -5,7 +5,6 @@ import 'package:cw_core/utils/print_verbose.dart';
5 import 'package:cw_core/wallet_base.dart';
6 import 'package:cw_core/transaction_info.dart';
7 import 'package:cw_core/wallet_type.dart';
8 -import 'package:cake_wallet/reactions/wallet_connect.dart';
8 import 'package:cake_wallet/evm/evm.dart';
9 import 'package:cake_wallet/bitcoin/bitcoin.dart';
10 import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
@@ -72,6 +71,7 @@ abstract class TransactionDetailsViewModelBase with Store {
71 case WalletType.polygon:
72 case WalletType.base:
73 case WalletType.arbitrum:
74 + case WalletType.bsc:
75 _addEVMListItems(tx, dateFormat);
76 break;
77 case WalletType.nano:
@@ -195,6 +195,8 @@ abstract class TransactionDetailsViewModelBase with Store {
195 return 'https://basescan.org/tx/${txId}';
196 case WalletType.arbitrum:
197 return 'https://arbiscan.io/tx/${txId}';
198 + case WalletType.bsc:
199 + return 'https://bscscan.com/tx/${txId}';
200 case WalletType.polygon:
201 return 'https://polygonscan.com/tx/${txId}';
202 case WalletType.nano:
@@ -246,6 +248,8 @@ abstract class TransactionDetailsViewModelBase with Store {
248 return S.current.view_transaction_on + 'nanexplorer.com';
249 case WalletType.polygon:
250 return S.current.view_transaction_on + 'polygonscan.com';
251 + case WalletType.bsc:
252 + return S.current.view_transaction_on + 'bscscan.com';
253 case WalletType.solana:
254 return S.current.view_transaction_on + 'solscan.io';
255 case WalletType.tron:
lib/view_model/wallet_address_list/wallet_address_list_view_model.dart
+17 -6
@@ -126,6 +126,8 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
126 return BaseURI(amount: amount, address: address.address);
127 case 42161:
128 return ArbitrumURI(amount: amount, address: address.address);
129 + case 56:
130 + return BSCURI(amount: amount, address: address.address);
131 default:
132 return EthereumURI(amount: amount, address: address.address);
133 }
@@ -166,6 +168,8 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
168 return BaseURI(amount: amount, address: address.address);
169 case WalletType.arbitrum:
170 return ArbitrumURI(amount: amount, address: address.address);
171 + case WalletType.bsc:
172 + return BSCURI(amount: amount, address: address.address);
173 case WalletType.zcash:
174 return ZcashURI(amount: amount, address: address.address);
175 case WalletType.none:
@@ -436,7 +440,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
440 switch (chainId) {
441 case 1:
442 return [
439 - 'assets/images/eth_icon.svg',
443 + 'assets/images/crypto/ethereum.webp',
444 'assets/images/usdc_icon.svg',
445 'assets/images/usdt_wallet_icon.svg',
446 'assets/images/deuro_icon.svg',
@@ -444,7 +448,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
448 ];
449 case 137:
450 return [
447 - 'assets/images/pol_icon.svg',
451 + 'assets/images/crypto/polygon.webp',
452 'assets/images/eth_pol_icon.svg',
453 'assets/images/usdc_icon.svg',
454 'assets/images/usdt_wallet_icon.svg',
@@ -452,7 +456,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
456 ];
457 case 8453:
458 return [
455 - 'assets/images/eth_icon.svg',
459 + 'assets/images/crypto/ethereum.webp',
460 'assets/images/usdc_icon.svg',
461 'assets/images/more_tokens.svg',
462 ];
@@ -462,9 +466,16 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
466 'assets/images/usdc_icon.svg',
467 'assets/images/more_tokens.svg',
468 ];
469 + case 56:
470 + return [
471 + 'assets/images/crypto/BNB.webp',
472 + 'assets/images/usdc_icon.svg',
473 + 'assets/images/usdt_wallet_icon.svg',
474 + 'assets/images/more_tokens.svg',
475 + ];
476 default:
477 return [
467 - 'assets/images/eth_icon.svg',
478 + 'assets/images/crypto/ethereum.webp',
479 'assets/images/usdc_icon.svg',
480 'assets/images/usdt_wallet_icon.svg',
481 ];
@@ -497,10 +508,10 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
508 }
509
510 @computed
500 - String get qrImage => getQrImage(type, selectedChainId: selectedChainId);
511 + String get qrImage => getQrImage(type);
512
513 @computed
503 - String get monoImage => getChainMonoImage(type, selectedChainId: selectedChainId);
514 + String get monoImage => getChainMonoImage(type);
515
516 @computed
517 bool get isBalanceAvailable => isElectrumWallet;
lib/view_model/wallet_keys_view_model.dart
+3
@@ -143,6 +143,7 @@ abstract class WalletKeysViewModelBase with Store {
143 case WalletType.polygon:
144 case WalletType.base:
145 case WalletType.arbitrum:
146 + case WalletType.bsc:
147 case WalletType.solana:
148 case WalletType.zcash:
149 case WalletType.tron:
@@ -274,6 +275,8 @@ abstract class WalletKeysViewModelBase with Store {
275 return 'base-wallet';
276 case WalletType.arbitrum:
277 return 'arbitrum-wallet';
278 + case WalletType.bsc:
279 + return 'bsc-wallet';
280 case WalletType.solana:
281 return 'solana-wallet';
282 case WalletType.tron:
lib/view_model/wallet_new_vm.dart
+1
@@ -82,6 +82,7 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
82 case WalletType.polygon:
83 case WalletType.base:
84 case WalletType.arbitrum:
85 + case WalletType.bsc:
86 return evm!.createEVMNewWalletCredentials(
87 name: name,
88 password: walletPassword,
lib/view_model/wallet_restore_view_model.dart
+10 -10
@@ -53,6 +53,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
53 case WalletType.polygon:
54 case WalletType.base:
55 case WalletType.arbitrum:
56 + case WalletType.bsc:
57 case WalletType.decred:
58 case WalletType.bitcoin:
59 case WalletType.litecoin:
@@ -82,18 +83,15 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
83 late final bool hasSeedLanguageSelector =
84 [WalletType.monero, WalletType.haven, WalletType.wownero].contains(type);
85
85 - late final bool hasBlockchainHeightSelector = [
86 - WalletType.monero,
87 - WalletType.haven,
88 - WalletType.wownero,
89 - WalletType.zcash
90 - ].contains(type);
91 -
86 + late final bool hasBlockchainHeightSelector =
87 + [WalletType.monero, WalletType.haven, WalletType.wownero, WalletType.zcash].contains(type);
88 +
89 late final bool hasRestoreFromPrivateKey = [
90 WalletType.ethereum,
91 WalletType.polygon,
92 WalletType.base,
93 WalletType.arbitrum,
94 + WalletType.bsc,
95 WalletType.nano,
96 WalletType.banano,
97 WalletType.solana,
@@ -171,6 +169,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
169 case WalletType.polygon:
170 case WalletType.base:
171 case WalletType.arbitrum:
172 + case WalletType.bsc:
173 return evm!.createEVMRestoreWalletFromSeedCredentials(
174 name: name,
175 mnemonic: seed,
@@ -209,9 +208,9 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
208 );
209 case WalletType.decred:
210 return decred!.createDecredRestoreWalletFromSeedCredentials(
212 - name: name,
213 - mnemonic: seed,
214 - password: password,
211 + name: name,
212 + mnemonic: seed,
213 + password: password,
214 );
215 case WalletType.zcash:
216 return zcash!.createZcashRestoreWalletFromSeedCredentials(
@@ -274,6 +273,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
273 case WalletType.polygon:
274 case WalletType.base:
275 case WalletType.arbitrum:
276 + case WalletType.bsc:
277 return evm!.createEVMRestoreWalletFromPrivateKey(
278 name: name,
279 password: password,
pubspec_base.yaml
+1
@@ -243,6 +243,7 @@ flutter:
243 - assets/base_node_list.yml
244 - assets/arbitrum_node_list.yml
245 - assets/zcash_node_list.yml
246 + - assets/bsc_node_list.yml
247 - assets/text/
248 - assets/faq/
249 - assets/animation/
res/values/strings_ar.arb
+1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "بلوك متبقي ${status}",
103 "bluetooth": "بلوتوث",
104 "bright_theme": "مشرق",
105 + "bscscan_history": "تاريخ المسح BCS",
106 "bump_fee": "رسوم عثرة",
107 "buy": "اشتري",
108 "buy_alert_content": ".ﺎﻬﻴﻟﺇ ﻞﻳﺪﺒﺘﻟﺍ ﻭﺃ Monero ﻭﺃ Litecoin ﻭﺃ Ethereum ﻭﺃ Bitcoin ﺔﻈﻔﺤﻣ ءﺎﺸﻧﺇ ﻰﺟﺮﻳ .",
res/values/strings_bg.arb
+1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "${status} оставащи блока",
103 "bluetooth": "Bluetooth",
104 "bright_theme": "Ярко",
105 + "bscscan_history": "История на BSCScan",
106 "bump_fee": "Такса за бум",
107 "buy": "Купуване",
108 "buy_alert_content": "В момента поддържаме само закупуването на Bitcoin, Ethereum, Litecoin и Monero. Моля, създайте или превключете към своя портфейл Bitcoin, Ethereum, Litecoin или Monero.",
res/values/strings_cs.arb
+2 -1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "Zbývá ${status} bloků",
103 "bluetooth": "Bluetooth",
104 "bright_theme": "Jasný",
105 + "bscscan_history": "Historie BSCScan",
106 "bump_fee": "Bump Fee",
107 "buy": "Koupit",
108 "buy_alert_content": "V současné době podporujeme pouze nákup bitcoinů, etherea, litecoinů a monero. Vytvořte nebo přepněte na svou peněženku bitcoinů, etherea, litecoinů nebo monero.",
@@ -1172,4 +1173,4 @@
1173 "youCanGoBackToYourDapp": "Nyní se můžete vrátit do svého dappu",
1174 "your": "Vaše",
1175 "yy": "YY"
1175 -}
1176 +}
\ No newline at end of file
res/values/strings_de.arb
+1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "${status} verbleibende Blöcke",
103 "bluetooth": "Bluetooth",
104 "bright_theme": "Strahlend hell",
105 + "bscscan_history": "BSCScan-Verlauf",
106 "bump_fee": "Gebühr erhöhen",
107 "buy": "Kaufen",
108 "buy_alert_content": "Derzeit unterstützen wir nur den Kauf von Bitcoin, Ethereum, Litecoin und Monero. Bitte erstellen Sie Ihr Bitcoin-, Ethereum-, Litecoin- oder Monero-Wallet oder wechseln Sie zu diesem.",
res/values/strings_en.arb
+2 -1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "${status} Blocks Remaining",
103 "bluetooth": "Bluetooth",
104 "bright_theme": "Bright",
105 + "bscscan_history": "BSCScan History",
106 "bump_fee": "Bump fee",
107 "buy": "Buy",
108 "buy_alert_content": "Currently we only support the purchase of Bitcoin, Ethereum, Litecoin, and Monero. Please create or switch to your Bitcoin, Ethereum, Litecoin, or Monero wallet.",
@@ -1173,4 +1174,4 @@
1174 "youCanGoBackToYourDapp": "You can go back to your dApp now",
1175 "your": "Your",
1176 "yy": "YY"
1176 -}
1177 +}
\ No newline at end of file
res/values/strings_es.arb
+2 -1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "${status} Bloques Restantes",
103 "bluetooth": "Bluetooth",
104 "bright_theme": "Claro",
105 + "bscscan_history": "Historia del escaneo BSC",
106 "bump_fee": "Aumentar tarifa",
107 "buy": "Comprar",
108 "buy_alert_content": "Actualmente solo permitimos la compra de Bitcoin, Ethereum, Litecoin y Monero. Cree o cambie a su billetera de Bitcoin, Ethereum, Litecoin o Monero.",
@@ -1174,4 +1175,4 @@
1175 "youCanGoBackToYourDapp": "Ahora puedes volver a tu dApp",
1176 "your": "Tu",
1177 "yy": "YY"
1177 -}
1178 +}
\ No newline at end of file
res/values/strings_fa.arb
+2 -1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "${status} بلاک باقی‌مانده",
103 "bluetooth": "بلوتوث",
104 "bright_theme": "روشن",
105 + "bscscan_history": "تاریخچه BSCScan",
106 "bump_fee": "افزایش کارمزد",
107 "buy": "خرید",
108 "buy_alert_content": "در حال حاضر ما فقط از خرید بیت‌کوین، اتریوم، لایت‌کوین و مونرو پشتیبانی می‌کنیم.\nلطفاً کیف پول بیت‌کوین، اتریوم، لایت‌کوین یا مونرو خود را ایجاد کرده یا به آن تغییر دهید.",
@@ -1171,4 +1172,4 @@
1172 "youCanGoBackToYourDapp": "اکنون می‌توانید به dApp خود بازگردید",
1173 "your": "شما",
1174 "yy": "YY"
1174 -}
1175 +}
\ No newline at end of file
res/values/strings_fr.arb
+1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "Blocs Restants : ${status}",
103 "bluetooth": "Bluetooth",
104 "bright_theme": "Vif",
105 + "bscscan_history": "Historique du BSCScan",
106 "bump_fee": "Augmenter les frais",
107 "buy": "Acheter",
108 "buy_alert_content": "Actuellement, nous ne prenons en charge que l'achat de Bitcoin, Ethereum, Litecoin et Monero. Veuillez créer ou basculer vers votre portefeuille Bitcoin, Ethereum, Litecoin ou Monero.",
res/values/strings_gn.arb
+1
@@ -84,6 +84,7 @@
84 "Blocks_remaining": "${status} Bloque hembýva",
85 "bluetooth": "Bluetooth",
86 "bright_theme": "Omimbiva",
87 + "bscscan_history": "BSCSCAN HISTORIA GUARANI .",
88 "bump_fee": "Mba’erepy",
89 "buy": "Ejogua",
90 "buy_alert_content": "Ko’ág̃a romoneĩnte Bitcoin, Ethereum, Litecoin ha Monero jejogua. Remoheñóĩ térã reiporavo nde virurenda peteĩva ko’ãva apytégui.",
res/values/strings_ha.arb
+2 -1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "${status} Katanga ya rage",
103 "bluetooth": "Bluetooth",
104 "bright_theme": "Mai haske",
105 + "bscscan_history": "Tarihin BCSC",
106 "bump_fee": "Buin",
107 "buy": "Sayi",
108 "buy_alert_content": "A halin yanzu muna tallafawa kawai siyan Bitcoin, Ethereum, Litecoin, da Monero. Da fatan za a ƙirƙiri ko canza zuwa Bitcoin, Ethereum, Litecoin, ko Monero walat.",
@@ -1175,4 +1176,4 @@
1176 "youCanGoBackToYourDapp": "Kuna iya komawa zuwa DPP ɗinku yanzu",
1177 "your": "Naku",
1178 "yy": "YY"
1178 -}
1179 +}
\ No newline at end of file
res/values/strings_hi.arb
+1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "${status} शेष रहते हैं",
103 "bluetooth": "ब्लूटूथ",
104 "bright_theme": "उज्ज्वल",
105 + "bscscan_history": "बीएससीस्कैन इतिहास",
106 "bump_fee": "बम्प फीस",
107 "buy": "खरीदें",
108 "buy_alert_content": "वर्तमान में हम केवल बिटकॉइन, एथेरियम, लाइटकॉइन और मोनेरो की खरीद का समर्थन करते हैं। कृपया अपना बिटकॉइन, एथेरियम, लाइटकॉइन, या मोनेरो वॉलेट बनाएं या उस पर स्विच करें।",
res/values/strings_hr.arb
+2 -1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "${status} preostalih blokova",
103 "bluetooth": "Bluetooth",
104 "bright_theme": "Jarka",
105 + "bscscan_history": "BSCScan povijest",
106 "bump_fee": "Naplata",
107 "buy": "Kupi",
108 "buy_alert_content": "Trenutno podržavamo samo kupnju Bitcoina, Ethereuma, Litecoina i Monera. Izradite ili prijeđite na svoj Bitcoin, Ethereum, Litecoin ili Monero novčanik.",
@@ -1172,4 +1173,4 @@
1173 "youCanGoBackToYourDapp": "Sada se možete vratiti na svoj dapp",
1174 "your": "Vaš",
1175 "yy": "GG"
1175 -}
1176 +}
\ No newline at end of file
res/values/strings_hy.arb
+1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "${status} Բլոկ է մնացել",
103 "bluetooth": "Bluetooth",
104 "bright_theme": "Պայծառ",
105 + "bscscan_history": "BSCScan պատմություն",
106 "bump_fee": "Բարձրացնել միջնորդավճարը",
107 "buy": "Գնել",
108 "buy_alert_content": "Այժմ մենք աջակցում ենք միայն Bitcoin, Ethereum, Litecoin և Monero արժույթների գնմանը: Խնդրում ենք ստեղծել կամ վերածանցել Bitcoin, Ethereum, Litecoin կամ Monero արժույթների հաշիվը։",
res/values/strings_id.arb
+2 -1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "${status} Blok Tersisa",
103 "bluetooth": "Bluetooth",
104 "bright_theme": "Cerah",
105 + "bscscan_history": "Sejarah Pemindaian BSCS",
106 "bump_fee": "Biaya benjolan",
107 "buy": "Beli",
108 "buy_alert_content": "Saat ini kami hanya mendukung pembelian Bitcoin, Ethereum, Litecoin, dan Monero. Harap buat atau alihkan ke dompet Bitcoin, Ethereum, Litecoin, atau Monero Anda.",
@@ -1175,4 +1176,4 @@
1176 "youCanGoBackToYourDapp": "Anda dapat kembali ke dapp Anda sekarang",
1177 "your": "Milikmu",
1178 "yy": "YY"
1178 -}
1179 +}
\ No newline at end of file
res/values/strings_it.arb
+2 -1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "${status} Blocchi Rimanenti",
103 "bluetooth": "Bluetooth",
104 "bright_theme": "Chiaro",
105 + "bscscan_history": "Cronologia della scansione BSCS",
106 "bump_fee": "Commissione per bump",
107 "buy": "Compra",
108 "buy_alert_content": "Attualmente supportiamo solo l'acquisto di Bitcoin, Ethereum, Litecoin e Monero. Crea o passa al tuo portafoglio Bitcoin, Ethereum, Litecoin o Monero.",
@@ -1175,4 +1176,4 @@
1176 "youCanGoBackToYourDapp": "Puoi tornare al tuo DApp ora",
1177 "your": "Tuo",
1178 "yy": "YY"
1178 -}
1179 +}
\ No newline at end of file
res/values/strings_ja.arb
+1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "${status} 残りのブロック",
103 "bluetooth": "ブルートゥース",
104 "bright_theme": "明るい",
105 + "bscscan_history": "BSCSスキャン履歴",
106 "bump_fee": "バンプ料金",
107 "buy": "購入",
108 "buy_alert_content": "現在、ビットコイン、イーサリアム、ライトコイン、モネロの購入のみをサポートしています。ビットコイン、イーサリアム、ライトコイン、またはモネロのウォレットを作成するか、これらのウォレットに切り替えてください。",
res/values/strings_ko.arb
+1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "${status} 블록 남음",
103 "bluetooth": "블루투스",
104 "bright_theme": "밝은 테마",
105 + "bscscan_history": "BSC스캔 기록",
106 "bump_fee": "수수료 인상",
107 "buy": "구매",
108 "buy_alert_content": "현재 비트코인, 이더리움, 라이트코인, 모네로만 구매를 지원합니다. 비트코인, 이더리움, 라이트코인 또는 모네로 지갑을 생성하거나 전환하세요.",
res/values/strings_my.arb
+1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "${status} ဘလောက်များ ကျန်နေပါသည်။",
103 "bluetooth": "ဘလူးတုသ်",
104 "bright_theme": "တောက်ပ",
105 + "bscscan_history": "BSCScan သမိုင်း",
106 "bump_fee": "ဝင်ငွေ",
107 "buy": "ဝယ်ပါ။",
108 "buy_alert_content": "လက်ရှိတွင် ကျွန်ုပ်တို့သည် Bitcoin၊ Ethereum၊ Litecoin နှင့် Monero တို့ကိုသာ ဝယ်ယူမှုကို ပံ့ပိုးပေးပါသည်။ သင်၏ Bitcoin၊ Ethereum၊ Litecoin သို့မဟုတ် Monero ပိုက်ဆံအိတ်ကို ဖန်တီးပါ သို့မဟုတ် ပြောင်းပါ။",
res/values/strings_nl.arb
+2 -1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "${status} Resterende blokken",
103 "bluetooth": "Bluetooth",
104 "bright_theme": "Helder",
105 + "bscscan_history": "BSCcan-geschiedenis",
106 "bump_fee": "Bult fee",
107 "buy": "Kopen",
108 "buy_alert_content": "Momenteel ondersteunen we alleen de aankoop van Bitcoin, Ethereum, Litecoin en Monero. Maak of schakel over naar uw Bitcoin-, Ethereum-, Litecoin- of Monero-portemonnee.",
@@ -1173,4 +1174,4 @@
1174 "youCanGoBackToYourDapp": "U kunt nu terug naar uw DApp gaan",
1175 "your": "Jouw",
1176 "yy": "JJ"
1176 -}
1177 +}
\ No newline at end of file
res/values/strings_pl.arb
+1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "Pozostało ${status} bloków",
103 "bluetooth": "Bluetooth",
104 "bright_theme": "Jasny",
105 + "bscscan_history": "Historia skanowania BSCS",
106 "bump_fee": "Zwiększ opłatę",
107 "buy": "Kup",
108 "buy_alert_content": "Obecnie obsługujemy wyłącznie zakup Bitcoin, Ethereum, Litecoin i Monero. Utwórz lub przełącz się na swój portfel Bitcoin, Ethereum, Litecoin lub Monero.",
res/values/strings_pt.arb
+1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "${status} blocos restantes",
103 "bluetooth": "Bluetooth",
104 "bright_theme": "Brilhante",
105 + "bscscan_history": "Histórico do BSC Scan",
106 "bump_fee": "Taxa de aumento",
107 "buy": "Comprar",
108 "buy_alert_content": "Atualmente, oferecemos suporte apenas à compra de Bitcoin, Ethereum, Litecoin e Monero. Crie ou troque para sua carteira Bitcoin, Ethereum, Litecoin ou Monero.",
res/values/strings_ru.arb
+1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "${status} Осталось блоков",
103 "bluetooth": "Bluetooth",
104 "bright_theme": "Яркая",
105 + "bscscan_history": "История BSCскана",
106 "bump_fee": "Повысить комиссию",
107 "buy": "Купить",
108 "buy_alert_content": "В настоящее время мы поддерживаем только покупку биткойнов, Ethereum, Litecoin и Monero. Пожалуйста, создайте или переключитесь на свой кошелек Bitcoin, Ethereum, Litecoin или Monero.",
res/values/strings_th.arb
+1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "${status} บล็อกที่เหลืออยู่",
103 "bluetooth": "บลูทู ธ",
104 "bright_theme": "สดใส",
105 + "bscscan_history": "ประวัติ BCScan",
106 "bump_fee": "ค่าธรรมเนียมชน",
107 "buy": "ซื้อ",
108 "buy_alert_content": "ขณะนี้เรารองรับการซื้อ Bitcoin, Ethereum, Litecoin และ Monero เท่านั้น โปรดสร้างหรือเปลี่ยนเป็นกระเป๋าเงิน Bitcoin, Ethereum, Litecoin หรือ Monero",
res/values/strings_tl.arb
+2 -1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "Ang natitirang ${status} ay natitira",
103 "bluetooth": "Bluetooth",
104 "bright_theme": "Bright",
105 + "bscscan_history": "Kasaysayan ng BSCScan",
106 "bump_fee": "Dagdagan ang fee",
107 "buy": "Bumili",
108 "buy_alert_content": "Sa kasalukuyan ay sinusuportahan lamang namin ang pagbili ng Bitcoin, Ethereum, Litecoin, at Monero. Mangyaring lumikha o lumipat sa iyong Bitcoin, Ethereum, Litecoin, o Monero Wallet.",
@@ -1172,4 +1173,4 @@
1173 "youCanGoBackToYourDapp": "Maaari kang bumalik sa iyong dapp ngayon",
1174 "your": "IYONG",
1175 "yy": "YY"
1175 -}
1176 +}
\ No newline at end of file
res/values/strings_tr.arb
+2 -1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "${status} Blok Kaldı",
103 "bluetooth": "Bluetooth",
104 "bright_theme": "Parlak",
105 + "bscscan_history": "BSCScan Geçmişi",
106 "bump_fee": "Çarpma ücreti",
107 "buy": "Alış",
108 "buy_alert_content": "Şu anda yalnızca Bitcoin, Ethereum, Litecoin ve Monero satın alımını destekliyoruz. Lütfen Bitcoin, Ethereum, Litecoin veya Monero cüzdanınızı oluşturun veya cüzdanınıza geçin.",
@@ -1172,4 +1173,4 @@
1173 "youCanGoBackToYourDapp": "Şimdi Dapp'ınıza geri dönebilirsin",
1174 "your": "Senin",
1175 "yy": "YY"
1175 -}
1176 +}
\ No newline at end of file
res/values/strings_uk.arb
+1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "${status} Залишилось блоків",
103 "bluetooth": "Блюдот",
104 "bright_theme": "Яскрава",
105 + "bscscan_history": "Історія BSCScan",
106 "bump_fee": "Підвищити комісію",
107 "buy": "Купити",
108 "buy_alert_content": "Наразі ми підтримуємо купівлю лише Bitcoin, Ethereum, Litecoin і Monero. Створіть або перейдіть на свій гаманець Bitcoin, Ethereum, Litecoin або Monero.",
res/values/strings_ur.arb
+1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "${status} بلاکس باقی ہیں۔",
103 "bluetooth": "بلوٹوتھ",
104 "bright_theme": "روشن",
105 + "bscscan_history": "BSCSCAN کی تاریخ",
106 "bump_fee": "بمپ فیس",
107 "buy": "خریدنے",
108 "buy_alert_content": "۔ﮟﯾﺮﮐ ﭻﺋﻮﺳ ﺮﭘ ﺱﺍ ﺎﯾ ﮟﯿﺋﺎﻨﺑ ﭧﯿﻟﺍﻭ Monero ﺎﯾ ،Bitcoin، Ethereum، Litecoin ﺎﻨﭘﺍ ﻡ",
res/values/strings_vi.arb
+1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "${status} khối còn lại",
103 "bluetooth": "Bluetooth",
104 "bright_theme": "Sáng",
105 + "bscscan_history": "Lịch sử quét BSCS",
106 "bump_fee": "Tăng phí",
107 "buy": "Mua",
108 "buy_alert_content": "Hiện tại chúng tôi chỉ hỗ trợ mua Bitcoin, Ethereum, Litecoin, và Monero. Vui lòng tạo hoặc chuyển sang ví Bitcoin, Ethereum, Litecoin, hoặc Monero của bạn.",
res/values/strings_yo.arb
+1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "Àkójọpọ̀ ${status} kikù",
103 "bluetooth": "Bluetooth",
104 "bright_theme": "Funfun",
105 + "bscscan_history": "BCScan itan",
106 "bump_fee": "Ọya ija",
107 "buy": "Rà",
108 "buy_alert_content": "Lọwọlọwọ a ṣe atilẹyin rira Bitcoin, Ethereum, Litecoin, ati Monero. Jọwọ ṣẹda tabi yipada si Bitcoin, Ethereum, Litecoin, tabi apamọwọ Monero.",
res/values/strings_zh.arb
+1
@@ -102,6 +102,7 @@
102 "Blocks_remaining": "剩余 ${status} 区块",
103 "bluetooth": "蓝牙",
104 "bright_theme": "明亮",
105 + "bscscan_history": "BSC扫描历史",
106 "bump_fee": "追加手续费(RBF)",
107 "buy": "购买",
108 "buy_alert_content": "目前仅支持购买比特币、以太坊、莱特币和门罗币。请创建或切换相应钱包。",
scripts/android/pubspec_gen.sh
+1 -1
@@ -10,7 +10,7 @@ case $APP_ANDROID_TYPE in
10 CONFIG_ARGS="--monero"
11 ;;
12 $CAKEWALLET)
13 - CONFIG_ARGS="--monero --bitcoin --ethereum --polygon --nano --bitcoinCash --solana --tron --wownero --zano --decred --dogecoin --base --zcash --arbitrum"
13 + CONFIG_ARGS="--monero --bitcoin --ethereum --polygon --nano --bitcoinCash --solana --tron --wownero --zano --decred --dogecoin --base --zcash --arbitrum --bsc"
14 ;;
15 esac
16
scripts/ios/app_config.sh
+1 -1
@@ -31,7 +31,7 @@ case $APP_IOS_TYPE in
31 ;;
32
33 $CAKEWALLET)
34 - CONFIG_ARGS="--monero --bitcoin --ethereum --polygon --nano --bitcoinCash --solana --tron --wownero --zano --decred --dogecoin --base --zcash --arbitrum"
34 + CONFIG_ARGS="--monero --bitcoin --ethereum --polygon --nano --bitcoinCash --solana --tron --wownero --zano --decred --dogecoin --base --zcash --arbitrum --bsc"
35 ;;
36 esac
37
scripts/linux/app_config.sh
+1 -1
@@ -13,7 +13,7 @@ CONFIG_ARGS=""
13
14 case $APP_LINUX_TYPE in
15 $CAKEWALLET)
16 - CONFIG_ARGS="--monero --bitcoin --ethereum --polygon --nano --bitcoinCash --solana --tron --wownero --dogecoin --base --arbitrum --excludeFlutterSecureStorage";;
16 + CONFIG_ARGS="--monero --bitcoin --ethereum --polygon --nano --bitcoinCash --solana --tron --wownero --dogecoin --base --arbitrum --bsc --excludeFlutterSecureStorage";;
17 esac
18
19 cp -rf pubspec_description.yaml pubspec.yaml
scripts/macos/app_config.sh
+1 -1
@@ -36,7 +36,7 @@ case $APP_MACOS_TYPE in
36 $MONERO_COM)
37 CONFIG_ARGS="--monero";;
38 $CAKEWALLET)
39 - CONFIG_ARGS="--monero --bitcoin --ethereum --polygon --nano --bitcoinCash --solana --tron --wownero --dogecoin --base --arbitrum";;
39 + CONFIG_ARGS="--monero --bitcoin --ethereum --polygon --nano --bitcoinCash --solana --tron --wownero --dogecoin --base --arbitrum --bsc";;
40 esac
41
42 cp -rf pubspec_description.yaml pubspec.yaml
tool/configure.dart
+14 -10
@@ -34,8 +34,9 @@ Future<void> main(List<String> args) async {
34 final hasDogecoin = args.contains('${prefix}dogecoin');
35 final hasBase = args.contains('${prefix}base');
36 final hasArbitrum = args.contains('${prefix}arbitrum');
37 + final hasBsc = args.contains('${prefix}bsc');
38 final hasZcash = args.contains('${prefix}zcash');
38 - final hasEVM = hasEthereum || hasPolygon || hasBase || hasArbitrum;
39 + final hasEVM = hasEthereum || hasPolygon || hasBase || hasArbitrum || hasBsc;
40 final excludeFlutterSecureStorage = args.contains('${prefix}excludeFlutterSecureStorage');
41
42 await generateBitcoin(hasBitcoin);
@@ -69,6 +70,7 @@ Future<void> main(List<String> args) async {
70 hasDogecoin: hasDogecoin,
71 hasBase: hasBase,
72 hasArbitrum: hasArbitrum,
73 + hasBsc: hasBsc,
74 hasZcash: hasZcash,
75 );
76 await generateWalletTypes(
@@ -87,6 +89,7 @@ Future<void> main(List<String> args) async {
89 hasDogecoin: hasDogecoin,
90 hasBase: hasBase,
91 hasArbitrum: hasArbitrum,
92 + hasBsc: hasBsc,
93 hasZcash: hasZcash,
94 );
95 await injectSecureStorage(!excludeFlutterSecureStorage);
@@ -740,15 +743,12 @@ abstract class BitcoinCash {
743 """;
744
745 const bitcoinCashEmptyDefinition = 'BitcoinCash? bitcoinCash;\n';
743 - const bitcoinCashCWDefinition =
744 - 'BitcoinCash? bitcoinCash = CWBitcoinCash();\n';
746 + const bitcoinCashCWDefinition = 'BitcoinCash? bitcoinCash = CWBitcoinCash();\n';
747
748 final output = '$bitcoinCashCommonHeaders\n' +
749 (hasImplementation ? '$bitcoinCashCWHeaders\n' : '\n') +
750 (hasImplementation ? '$bitcoinCashCwPart\n\n' : '\n') +
749 - (hasImplementation
750 - ? bitcoinCashCWDefinition
751 - : bitcoinCashEmptyDefinition) +
751 + (hasImplementation ? bitcoinCashCWDefinition : bitcoinCashEmptyDefinition) +
752 '\n' +
753 bitcoinCashContent;
754
@@ -883,8 +883,7 @@ abstract class NanoUtil {
883 """;
884
885 const nanoEmptyDefinition = 'Nano? nano;\nNanoUtil? nanoUtil;\n';
886 - const nanoCWDefinition =
887 - 'Nano? nano = CWNano();\nNanoUtil? nanoUtil = CWNanoUtil();\n';
886 + const nanoCWDefinition = 'Nano? nano = CWNano();\nNanoUtil? nanoUtil = CWNanoUtil();\n';
887
888 final output = '$nanoCommonHeaders\n' +
889 (hasImplementation ? '$nanoCWHeaders\n' : '\n') +
@@ -1674,6 +1673,7 @@ Future<void> generatePubspec({
1673 required bool hasDogecoin,
1674 required bool hasBase,
1675 required bool hasArbitrum,
1676 + required bool hasBsc,
1677 required bool hasZcash,
1678 }) async {
1679 const cwCore = """
@@ -1745,8 +1745,7 @@ Future<void> generatePubspec({
1745 final inputLines = inputText.split('\n');
1746 final dependenciesIndex = inputLines.indexWhere((line) => Platform.isWindows
1747 // On Windows it could contains `\r` (Carriage Return). It could be fixed in newer dart versions.
1748 - ? line.toLowerCase() == 'dependencies:\r' ||
1749 - line.toLowerCase() == 'dependencies:'
1748 + ? line.toLowerCase() == 'dependencies:\r' || line.toLowerCase() == 'dependencies:'
1749 : line.toLowerCase() == 'dependencies:');
1750 var output = cwCore;
1751
@@ -1834,6 +1833,7 @@ Future<void> generateWalletTypes({
1833 required bool hasDogecoin,
1834 required bool hasBase,
1835 required bool hasArbitrum,
1836 + required bool hasBsc,
1837 required bool hasZcash,
1838 }) async {
1839 final walletTypesFile = File(walletTypesPath);
@@ -1858,6 +1858,10 @@ Future<void> generateWalletTypes({
1858 outputContent += '\tWalletType.ethereum,\n';
1859 }
1860
1861 + if (hasBsc) {
1862 + outputContent += '\tWalletType.bsc,\n';
1863 + }
1864 +
1865 if (hasSolana) {
1866 outputContent += '\tWalletType.solana,\n';
1867 }
tool/utils/secret_key.dart
+2
@@ -57,6 +57,7 @@ class SecretKey {
57 SecretKey('polygonTestWalletSeeds', () => ''),
58 SecretKey('baseTestWalletSeeds', () => ''),
59 SecretKey('arbitrumTestWalletSeeds', () => ''),
60 + SecretKey('bscTestWalletSeeds', () => ''),
61 SecretKey('solanaTestWalletSeeds', () => ''),
62 SecretKey('tronTestWalletSeeds', () => ''),
63 SecretKey('nanoTestWalletSeeds', () => ''),
@@ -69,6 +70,7 @@ class SecretKey {
70 SecretKey('polygonTestWalletReceiveAddress', () => ''),
71 SecretKey('baseTestWalletReceiveAddress', () => ''),
72 SecretKey('arbitrumTestWalletReceiveAddress', () => ''),
73 + SecretKey('bscTestWalletReceiveAddress', () => ''),
74 SecretKey('solanaTestWalletReceiveAddress', () => ''),
75 SecretKey('tronTestWalletReceiveAddress', () => ''),
76 SecretKey('nanoTestWalletReceiveAddress', () => ''),