devopsdao / webthree

MIT License
7 stars 3 forks source link

Question: Connecting Metamask on Flutter Web #26

Open andrewkimjoseph opened 4 months ago

andrewkimjoseph commented 4 months ago

How do I open Metamask and connect to a wallet using this plugin?

redDwarf03 commented 4 months ago

here is an example

import 'dart:html';
import 'package:flutter/material.dart';
import 'package:js/js.dart';
import 'package:webthree/browser.dart';
import 'package:webthree/webthree.dart';

class EVMWalletProvider extends ChangeNotifier {
  String? currentAddress;
  String? get accountName => currentAddress;
  int? currentChain;
  bool walletConnected = false;
  Ethereum? eth;
  BinanceChainWallet? bsc;
  OkxWallet? okx;

  Web3Client? web3Client;
  CredentialsWithKnownAddress? credentials;

  Future<int> getChainId() async {
    if (window.OkxChainWallet != null) {
      try {
        okx = window.OkxChainWallet;
        final okxRPC = okx!.asRpcService();

        web3Client = Web3Client.custom(okxRPC);
        if (web3Client == null) {
          throw Exception('EVM Wallet is not available');
        }
        final currentChain = await web3Client!.getChainId();
        return currentChain.toInt();
      } catch (e) {
        throw Exception('Please, connect your Wallet.');
      }
    } else {
      if (window.BinanceChain != null) {
        try {
          bsc = window.BinanceChain;
          final bscRPC = bsc!.asRpcService();

          web3Client = Web3Client.custom(bscRPC);
          if (web3Client == null) {
            throw Exception('EVM Wallet is not available');
          }
          final currentChain = await web3Client!.getChainId();
          return currentChain.toInt();
        } catch (e) {
          throw Exception('Please, connect your Wallet.');
        }
      } else {
        if (window.ethereum != null) {
          try {
            eth = window.ethereum;
            final ethRPC = eth!.asRpcService();

            web3Client = Web3Client.custom(ethRPC);
            if (web3Client == null) {
              throw Exception('EVM Wallet is not available');
            }
            final currentChain = await web3Client!.getChainId();
            return currentChain.toInt();
          } catch (e) {
            throw Exception('Please, connect your Wallet.');
          }
        } else {
          throw Exception('No provider installed');
        }
      }
    }
  }

  Future<void> connect(int chainId) async {
    walletConnected = false;

    currentChain = await getChainId();
    if (currentChain != chainId) {
      await changeChainId(chainId);
    }

    var credentialsList = <CredentialsWithKnownAddress>[];
    if (okx != null) {
      credentialsList = await okx!.requestAccounts();
    } else {
      if (bsc != null) {
        credentialsList = await bsc!.requestAccounts();
      } else {
        if (eth != null) {
          credentialsList = await eth!.requestAccounts();
        }
      }
    }

    if (credentialsList.isNotEmpty) {
      credentials = credentialsList.first;
      currentAddress = credentials!.address.hex;
      walletConnected = true;

      notifyListeners();
    }
  }

  Future<void> changeChainId(int chainId) async {
    if (okx != null) {
      await okx!.rawRequest(
        'wallet_switchEthereumChain',
        params: [
          JSrawRequestParams(chainId: '0x${chainId.toRadixString(16)}'),
        ],
      );
    } else {
      if (bsc != null) {
        await bsc!.rawRequest(
          'wallet_switchEthereumChain',
          params: [
            JSrawRequestParams(chainId: '0x${chainId.toRadixString(16)}'),
          ],
        );
      } else {
        if (eth != null) {
          await eth!.rawRequest(
            'wallet_switchEthereumChain',
            params: [
              JSrawRequestParams(chainId: '0x${chainId.toRadixString(16)}'),
            ],
          );
        }
      }
    }

    currentChain = chainId;
    notifyListeners();
  }

  Future<void> disconnect() async {
    walletConnected = false;
    currentAddress = null;
    notifyListeners();
  }
}

@JS()
@anonymous
class JSrawRequestParams {
  external factory JSrawRequestParams({String chainId});
  external String get chainId;
}

Reference: https://github.com/archethic-foundation/bridge/blob/dev/lib/application/evm_wallet.dart