Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion lib/views/wallet_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import 'package:dynamic_sdk_web3dart/dynamic_sdk_web3dart.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:web3dart/web3dart.dart';
import 'package:my_app/widgets/send_erc20_widget.dart';
import 'package:my_app/widgets/network_switch_widget.dart';

class WalletView extends StatefulWidget {
final String walletId;
Expand Down Expand Up @@ -243,12 +245,15 @@ class _WalletViewState extends State<WalletView> {
'Wallet not found. Go back and select a wallet.',
style: TextStyle(color: Colors.red),
)
else
else ...[
_WalletHeader(
wallet: wallet,
balance: _balance,
loadingBalance: _loadingBalance,
),
const SizedBox(height: 16),
NetworkSwitchWidget(wallet: wallet),
],
const SizedBox(height: 16),
Card(
child: Padding(
Expand Down Expand Up @@ -351,6 +356,8 @@ class _WalletViewState extends State<WalletView> {
),
),
const SizedBox(height: 16),
if (wallet != null) SendErc20Widget(wallet: wallet),
const SizedBox(height: 16),
SizedBox(
width: double.infinity,
child: ElevatedButton.icon(
Expand Down
149 changes: 149 additions & 0 deletions lib/widgets/network_switch_widget.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import 'package:dynamic_sdk/dynamic_sdk.dart';
import 'package:flutter/material.dart';

class NetworkSwitchWidget extends StatefulWidget {
final BaseWallet wallet;
const NetworkSwitchWidget({super.key, required this.wallet});

@override
State<NetworkSwitchWidget> createState() => _NetworkSwitchWidgetState();
}

class _NetworkSwitchWidgetState extends State<NetworkSwitchWidget> {
List<GenericNetwork> _availableNetworks = const [];
GenericNetwork? _selectedNetwork;
bool _loading = false;
bool _switching = false;
String? _error;

@override
void initState() {
super.initState();
_loadNetworksAndCurrent();
}

Future<void> _loadNetworksAndCurrent() async {
setState(() {
_loading = true;
_error = null;
});
try {
final networks = DynamicSDK.instance.networks.evm;
final current = await DynamicSDK.instance.wallets.getNetwork(
wallet: widget.wallet,
);
final currentChainId = current.intValue();

GenericNetwork? selected;
if (currentChainId != null) {
for (final n in networks) {
if (n.chainId == currentChainId) {
selected = n;
break;
}
}
}

setState(() {
_availableNetworks = networks;
_selectedNetwork =
selected ?? (networks.isNotEmpty ? networks.first : null);
});
} catch (e) {
setState(() {
_error = e.toString();
});
} finally {
if (!mounted) return;
setState(() {
_loading = false;
});
}
}

Future<void> _switchNetwork(GenericNetwork target) async {
setState(() {
_switching = true;
_error = null;
});
try {
await DynamicSDK.instance.wallets.switchNetwork(
wallet: widget.wallet,
network: Network(target.chainId),
);
if (!mounted) return;
setState(() {
_selectedNetwork = target;
});
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('Switched to ${target.name}')));
} catch (e) {
setState(() {
_error = e.toString();
});
} finally {
if (!mounted) return;
setState(() {
_switching = false;
});
}
}

@override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Network',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
const SizedBox(height: 12),
if (_loading)
const SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(strokeWidth: 2),
)
else if (_availableNetworks.isEmpty)
const Text(
'No networks available',
style: TextStyle(fontSize: 12, color: Colors.grey),
)
else
DropdownButtonFormField<GenericNetwork>(
value: _selectedNetwork,
items: _availableNetworks
.map(
(n) => DropdownMenuItem<GenericNetwork>(
value: n,
child: Text(n.name),
),
)
.toList(),
onChanged: _switching
? null
: (val) {
if (val != null) {
_switchNetwork(val);
}
},
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Select network',
),
),
if (_error != null) ...[
const SizedBox(height: 8),
Text(_error!, style: const TextStyle(color: Colors.red)),
],
],
),
),
);
}
}
Loading