WalletConnect / Web3ModalFlutter

The Web3Modal for WalletConnect built using Flutter.
https://pub.dev/packages/web3modal_flutter
Apache License 2.0
27 stars 30 forks source link

Unable To Send Transactions #82

Closed OmkarSsawant closed 3 months ago

OmkarSsawant commented 4 months ago

Describe the bug I am Developing a application that can interact with a locally developed smart contract . The Connection and normal method contract calling works but I did not found any implementation for send transaction . In documentation it said to use the web3dart , but this requires private key to be stored in app . So I am trying this since 2 days now to just send the transaction using the session got from this plugin and tried many ways to do it but any of them did not work . Also looked at example app of this repo and tried to figure out, but is not working .Below are approches and their undesired outputs. I would really appreciate the response as soon as possible.

To Reproduce Steps to reproduce the behavior:

  1. Run your own Smart Contract Locally and start node and deploy
  2. Setup web3modal_flutter as said in docs
  3. Try to call a method that is not just view and can also be payable
  4. See error or undesired behaviour

Expected behavior Output should be transaction Id as it ,when done using web3dart . When done only using web3dart output is fine.But Real Wallet needs to be connected.

Screenshots/Codes and Outputs

 function registerDeveloper(
        bytes32 _name,
        bytes32 _profile_photo_ipfs,
        bytes32[] memory _techstack,
        bytes32 _profession
    )
    public returns (bool ){...}

Approches:

using Just web3dart (which works):

 return await _ethClient.sendTransaction(
        _mCreds,
        Transaction.callContract(
            contract: _contract,
            function: _registerDeveloper,
            parameters: [
              name.bytes32,
              profilePhotoIpfs.bytes32,
              techstack.map((e) => e.bytes32).toList(),
              profession.bytes32
            ]),
        chainId: 31337);

But when using wallet Credentials to pass in method sendTransaction. According to this solution

A2:

    var credentials = WalletConnectEthereumCredentials(
      wcClient: dapp,
      session: session,
    );
    final max = await _ethClient.estimateGas(
      data: _registerDeveloper.encodeCall( [
        name.bytes32,
        profilePhotoIpfs.bytes32,
        techstack.map((e) => e.bytes32).toList(),
        profession.bytes32
      ])
    );
    debugPrint(max.toString());

    var txn =  Transaction.callContract(
        contract: _contract,
        function: _registerDeveloper,
        maxGas: max.toInt(),
        parameters: [
          name.bytes32,
          profilePhotoIpfs.bytes32,
          techstack.map((e) => e.bytes32).toList(),
          profession.bytes32
        ]);

    var r  =  await _ethClient.sendTransaction(
        credentials,
       txn);
    debugPrint(r);

    return r;

A3: using how it was called in example :


    final Transaction t = Transaction.callContract(  contract: _contract,
        function: _registerDeveloper,
        parameters: [
          name.bytes32,
          profilePhotoIpfs.bytes32,
          techstack.map((e) => e.bytes32).toList(),
          profession.bytes32
        ]);

debugPrint("---------------------------------------------------------------------------------");
    var s =  await  EIP155.ethSendTransaction(
        w3mService: _dapp,
        topic: topic,
        chainId: chainId,
        transaction: EthereumTransaction(
            from: from,
            to: _contract.address.hex,
          data: c.hex.encode(List<int>.from(t.data!))
          , value: "0x"),
        method: EIP155UIMethods.ethSendTransaction.name);
    debugPrint(s);
    return s;

The behaviour of above A2 & A3 is different the transaction is getting stuck , the control does not reach down to print s even after some minutes . When Direct web3dart send-transaction takes 2-3 secs. In case of A2 the maxgas is printed but r does not

Desktop (please complete the following information):

Smartphone (please complete the following information):(Emulator)

quetool commented 4 months ago

Hello @OmkarSsawant ! We might need to take a closer look at what you are describing but that won't be quick. What I can tell you right now is that there's no other way to interact with smart contracts than with web3dart (which is indeed the only way it works for you). You can check this answer https://github.com/WalletConnect/WalletConnectFlutterV2/issues/246#issuecomment-1884650667 And this one just in case https://github.com/WalletConnect/WalletConnectFlutterV2/issues/219#issuecomment-1805780710

quetool commented 3 months ago

Hello @OmkarSsawant! Could you check this reply? It might help https://github.com/WalletConnect/WalletConnectFlutterV2/issues/246#issuecomment-1900855332

Mash-Woo commented 3 months ago

I also happened to encounter this problem, and you can go ahead and consult my solution.

Step 1: Please add this

class CustomCredentialsSender extends CustomTransactionSender { CustomCredentialsSender({ required this.signingEngine, required this.sessionTopic, required this.chainId, required this.credentialsAddress, });

final ISignEngine signingEngine; final String sessionTopic; final String chainId; final EthereumAddress credentialsAddress;

@override EthereumAddress get address => credentialsAddress;

@override Future sendTransaction(Transaction transaction) async { if (kDebugMode) { print( 'CustomCredentialsSender: sendTransaction - transaction: ${transaction.prettyPrint}'); }

if (!signingEngine.getActiveSessions().keys.contains(sessionTopic)) {
  if (kDebugMode) {
    print(
        'sendTransaction - called with invalid sessionTopic: $sessionTopic');
  }
  return 'Internal Error - sendTransaction - called with invalid sessionTopic';
}

SessionRequestParams sessionRequestParams = SessionRequestParams(
  method: 'eth_sendTransaction',
  params: [
    {
      'from': transaction.from?.hex ?? credentialsAddress.hex,
      'to': transaction.to?.hex,
      'data':
          (transaction.data != null) ? bytesToHex(transaction.data!) : null,
      if (transaction.value != null)
        'value':
            '0x${transaction.value?.getInWei.toRadixString(16) ?? '0'}',
      if (transaction.maxGas != null)
        'gas': '0x${transaction.maxGas?.toRadixString(16)}',
      if (transaction.gasPrice != null)
        'gasPrice': '0x${transaction.gasPrice?.getInWei.toRadixString(16)}',
      if (transaction.nonce != null) 'nonce': transaction.nonce,
    }
  ],
);

if (kDebugMode) {
  print(
      'CustomCredentialsSender: sendTransaction - blockchain $chainId, sessionRequestParams: ${sessionRequestParams.toJson()}');
}

final hash = await signingEngine.request(
  topic: sessionTopic,
  chainId: chainId,
  request: sessionRequestParams,
);
return hash;

}

@override Future extractAddress() { // TODO: implement extractAddress throw UnimplementedError(); }

@override Future signToSignature(Uint8List payload, {int? chainId, bool isEIP1559 = false}) { // TODO: implement signToSignature throw UnimplementedError(); }

@override MsgSignature signToEcSignature(Uint8List payload, {int? chainId, bool isEIP1559 = false}) { // TODO: implement signToEcSignature throw UnimplementedError(); } }

Step 2: Use this in your function:

Credentials credentials = CustomCredentialsSender( signingEngine: w3mService.web3App!.signEngine, sessionTopic: w3mService.session!.topic!, chainId: w3mService.selectedChain!.namespace, credentialsAddress: EthereumAddress.fromHex(w3mService!.address!), );

final transaction = Transaction.callContract( contract: (your contract), function: (name your function), parameters: [ //According to your contract parameters ]); final result = ethClient.sendTransaction(credentials, transaction, chainId: int.parse(loginProvider.w3mService.selectedChain!.chainId));

   w3mService.launchConnectedWallet();
   w3mService.addListener(() {
      result;
    });
   w3mService.notifyListeners();

      Good luck !!!

      @OmkarSsawant 
crypblizz8 commented 3 months ago

@quetool Can you follow up here>

quetool commented 3 months ago

For smart contract interaction please follow this issue https://github.com/WalletConnect/WalletConnectFlutterV2/issues/255