Open 0xCaso opened 2 years ago
Hi, I have the same problem. Stuck with researching more data for opening Matamusk app and auto sync wallets. Which packages did you use for blockchain connection inside Flutter Mobile? Have you thought about something like external_app_luncher https://pub.dev/packages/external_app_launcher?
Hi! Yesterday I managed to make the connection using https://pub.dev/documentation/walletconnect_dart/latest/. As they suggest, you should also use https://pub.dev/packages/url_launcher.
Basically you should launch the uri (in the format wc:00e46b69-d0cc-4b3e-b6a2-cee442f97188@1?bridge=https%3A%2F%2Fbridge.walletconnect.org&key=91303dedf64285cbbaf9120f6e9d160a5c8aa3deb67017a3874cd272323f48ae) when the user presses the button "Connect Wallet".
Check also this https://docs.walletconnect.com/mobile-linking
For blockchain connection I used https://pub.dev/packages/dart_web3
Hi again Matteo, could you show me your logical steps you did, when implementing connections? I read what you have showed me and more, but can't put it together in a logical whole... :/
EDIT: should be like this?
Is it correct way of thinking?
Basically you should merge these two examples:
Create a file with your contract's ABI, contract.abi.json
.
From this you can generate contract.g.dart
, with the command flutter pub run build_runner build
.
Then you'll need the class WalletConnectEthereumCredentials
from https://github.com/RootSoft/walletconnect-dart-sdk/blob/master/example/mobile/lib/ethereum_transaction_tester.dart, in order to send transactions.
Now you can write this function, maybe the code is not reliable but this is what I've written:
_walletConnect() async {
final connector = WalletConnect(
bridge: 'https://bridge.walletconnect.org',
clientMeta: const PeerMeta(
name: 'WalletConnect',
description: 'WalletConnect Developer App',
url: 'https://walletconnect.org',
icons: [
'https://gblobscdn.gitbook.com/spaces%2F-LJJeCjcLrr53DcT1Ml7%2Favatar.png?alt=media'
],
),
);
// Subscribe to events
connector.on('connect', (session) => print(session));
connector.on('session_update', (payload) => print(payload));
connector.on('disconnect', (session) => print(session));
// Create a new session
if (!connector.connected) {
session = await connector.createSession(
chainId: 43113,
onDisplayUri: (uri) async => {print(uri), await launch(uri)});
}
setState(() {
account = session.accounts[0];
});
if (account != null) {
final client = Web3Client(rpcUrl, Client());
EthereumWalletConnectProvider provider =
EthereumWalletConnectProvider(connector);
credentials = WalletConnectEthereumCredentials(provider: provider);
yourContract = YourContract(address: contractAddr, client: client);
}
}
This function has to be called when user presses your "Connect Wallet" button, something like this:
Row(
children: [
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.white24,
padding: const EdgeInsets.all(16.0),
textStyle: const TextStyle(fontSize: 22, fontFamily: 'Poppins'),
),
onPressed: () async => _walletConnect(),
child: const Text('Connect Wallet'),
),
],
mainAxisAlignment: MainAxisAlignment.center,
)
Note you can use every EVM compatible chain: here I'm using Avalanche Fuji Testnet (chainId: 43113
); Also I put session
, account
, credentials
and yourContract
as global variables cause you could need them in other functions. rpcUrl
in my case is https://api.avax-test.network/ext/bc/C/rpc. await launch(uri)
will let the user chose the wallet to connect, then it will open the wallet app, for example Metamask. Then user will allow (or not) the connection between app and Metamask.
You can now interact with your smart contract. For getter methods (view-functions in Solidity), you won't need to build the object transaction
, but if you have to "write" in the blockchain then you'll need it (here escrow
is my smart contract variable). For example I wrote this:
Future<void> _confirmOrder(String orderID) async {
final transaction = Transaction(
to: contractAddr,
from: EthereumAddress.fromHex(account),
value: EtherAmount.fromUnitAndValue(EtherUnit.finney, 0),
);
launch("https://metamask.app.link/");
String returned = await escrow.confirmOrder(BigInt.parse(orderID),
credentials: credentials, transaction: transaction);
}
Let me know if you manage to do it :)
Hi, thanks for extensive answer! :) I will try to implement it in my enviroment. I'll let you know my results
Why do I need to create contract.abi.json?
Wont be enough to connect wallets Flutter app <=> Metamask accout and then proceed transactions?
I try do implement same logic like we have in OpenSea mobile app (when you press the button and integrate OpenSea account with Metamask)
Sorry, I took for granted you wanted to interact with a smart contract. If not, you won't need that.
Have to say, it is quite complicated, but you showed me appropriate way! I am grateful. :)
It works without contract. By pressing the button it open Metamask app and ask for connection. Great! Thank you! Now I have to menage transactions and onther autentication stuff.
Perfect! Good luck then :)
Thanks for the explanation. I had the same problem.
hi, When the Metamsk opens, cann't the user automatically return to the app? how can I handle this?
Hi, Do you mean, can't go back when pressing 'connect' button on Metamusk? I haven't done this yet. But if you've found solution, lets us know :)
yea didn't think about it honestly, I think it's something Metamask app has to manage, but not sure about it
@matteocasonato Have you menaged sending transactions via Metamusk?
yes, I showed it a bit in the example above.
The problem I have now is that when it connects to Metamsk, it doesn't show a connection page to the user and doesn't ask if it wants to connect but this screen is displayed to connect to the Trustwallet.
The code is executed up to this line: if (!connector.connected) { session = await connector.createSession( chainId: 43113, onDisplayUri: (uri) async => {print(uri), await launch(uri)}); } , when it enters Metamask, the rest of the line isn't executed: account is still null
Your chain id should be validated with RPC server, check this case.
pon., 21 lut 2022, 17:28 użytkownik EBP20 @.***> napisał:
The code is executed up to this line: if (!connector.connected) { session = await connector.createSession( chainId: 43113, onDisplayUri: (uri) async => {print(uri), await launch(uri)}); } , when it enters Metamask, the rest of the line isn't executed: account is still null
— Reply to this email directly, view it on GitHub https://github.com/MetaMask/metamask-mobile/issues/3735#issuecomment-1047052052, or unsubscribe https://github.com/notifications/unsubscribe-auth/AXVFDX3OI5E3GILILTGAWI3U4JR37ANCNFSM5OG6KZ4A . You are receiving this because you commented.Message ID: @.***>
Your chain id should be validated with RPC server, check this case. pon., 21 lut 2022, 17:28 użytkownik EBP20 @.> napisał: … The code is executed up to this line: if (!connector.connected) { session = await connector.createSession( chainId: 43113, onDisplayUri: (uri) async => {print(uri), await launch(uri)}); } , when it enters Metamask, the rest of the line isn't executed: account is still null — Reply to this email directly, view it on GitHub <#3735 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AXVFDX3OI5E3GILILTGAWI3U4JR37ANCNFSM5OG6KZ4A . You are receiving this because you commented.Message ID: @.>
I used rinkeby, chain id for that is 4 Do you think this code has a problem?
_walletConnect() async { final connector = WalletConnect( bridge: 'https://bridge.walletconnect.org', clientMeta: const PeerMeta( name: 'WalletConnect', description: 'WalletConnect Developer App', url: 'https://walletconnect.org', icons: [ 'https://gblobscdn.gitbook.com/spaces%2F-LJJeCjcLrr53DcT1Ml7%2Favatar.png?alt=media' ], ), ); // Subscribe to events connector.on('connect', (session) => print(session)); connector.on('session_update', (payload) => print(payload)); connector.on('disconnect', (session) => print(session));
// Create a new session
if (!connector.connected) {
session = await connector.createSession(
chainId: 4,
onDisplayUri: (uri) async => {print(uri), await launch(uri)});
}
setState(() {
account = session.accounts[0];
print(account);
});
if (account != null) {
print('account != null');
final client = Web3Client(infura, Client());
EthereumWalletConnectProvider provider =
EthereumWalletConnectProvider(connector);
credentials = WalletConnectEthereumCredentials(provider: provider);
print('test_credentials${credentials}');
yourContract = ethUtils.getDeployedContract(contractAddress!, client);
}
}
Show me infura URL :P
I did the same. I also had to create project on infura dashboard. RPC Infura URL should also provide project id. Tomorow I will show you how infura URL looks like in my code.
My connection is ok, but I stucked on sending transactions :/
String infura = "https://rinkeby.infura.io/v3/" + dotenv.env['INFURA_PROJECT_ID']!; Why it doesn't work for me :( If everything is correct, when I return to the app from Metamsk, the account shouldn't be null, right?
I have as fallow: final rpcUrl = 'https://rinkeby.infura.io/v3/$INFURA_PROJECT_ID';
just replace INFURA_PROJECT_ID with yours infura project id :)
Make sure your dontenv dependency incjections works well
I found this problem. What is it about?
E/flutter (20605): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: PlatformException(ACTIVITY_NOT_FOUND, No Activity found to handle intent { wc:c33f9376-8b62-45c0-bf98-c1a6fca4645a@1?bridge=https%3A%2F%2Ff.bridge.walletconnect.org&key=491b6b728805351d3f0eb757e14666f6c29132c88c1e9450968a6207066b71c9 }, null, null)
No idea.. But if it throw exception, go that way. Have you debuged line by line part of code where the exception was thrown?
@matteocasonato Hello, sorry if you think this is rude, is it possible to look at your source code, it's interesting to see how everything is implemented for you, I would be sincerely grateful.
No idea.. But if it throw exception, go that way. Have you debuged line by line part of code where the exception was thrown?
hi. Could you please look at my code? I still couldn't find the problem and all the ways I found it are for web flutter :( I appreciate you very much
@matteocasonato Thank you for your provided answer. Thanks to that I am now able to connect my app to Metamask, fetch the wallet's address and sign transactions. So far, so good.
The problem comes when trying to implement an asymemetric/plubic key encryption system for an Authentication workflow. In order to do that, I need to sign a message (a nonce) that comes from the backend. The class WalletConnectEthereumCredentials
has a method called signToSignature
but is marked as a TODO to implement.
Future<MsgSignature> signToSignature(Uint8List payload,
{int? chainId, bool isEIP1559 = false}) {
// TODO: implement signToSignature
throw UnimplementedError();
}
I'm pretty sure that's the method I need to use to sign the message. Have you by any chance implemented this function in your application? Any guess on how could I?
Thank you so much!
Hey, @Pablo4Coding I am also able to connect wallet and fetch wallet addresses but not able to sign transactions. How you have managed to do that? It would be better if you can give some hints, processes, or code snippet for signing transactions.
Thanks in advance.
Hi there! I want to connect metamask to my app to make sure users can buy items in a shop and make a transaction to my address. How can i achieve this?
@matteocasonato Thank you for your provided answer. Thanks to that I am now able to connect my app to Metamask, fetch the wallet's address and sign transactions. So far, so good.
The problem comes when trying to implement an asymemetric/plubic key encryption system for an Authentication workflow. In order to do that, I need to sign a message (a nonce) that comes from the backend. The class
WalletConnectEthereumCredentials
has a method calledsignToSignature
but is marked as a TODO to implement.Future<MsgSignature> signToSignature(Uint8List payload, {int? chainId, bool isEIP1559 = false}) { // TODO: implement signToSignature throw UnimplementedError(); }
I'm pretty sure that's the method I need to use to sign the message. Have you by any chance implemented this function in your application? Any guess on how could I?
Thank you so much!
Hi, how did you manage to sign transactions? I can't get it to work. Could you please help me out?
I have an example Flutter app that connects to Metamask mobile using a WalletConnect plugin (and handles some of the IOS intent trickiness.). It's not ready for wide sharing but if it helps - https://gitlab.com/graflr/flutter_rarible_example
That said - I am hitting this issue:
I do not see the issue with the Rainbow wallet or trust wallet. So if you get to the same point +1 my Metamask mobile bug :-)
Hello Guys i am also stuck at signtransaction, is this thread still on ? please someone should throw some more light.
Same issue with the signTransaction.
How can I get the private key when clicking on the "Connect Wallet" Button? I have this code snippet. I want to replace EthPrivateKey tempCredentials with the private key or the credentials that I'll get from the metamask application when the connection is happening! so to pass it to ethClient!.sendTransaction method
Future<String> submit(String functionName, List<dynamic> args) async {
EthPrivateKey tempCredentials = EthPrivateKey.fromHex(
"c58e17d53714f56c3ded7e9eed18863301055b78e141dc4ccf2c9cd9c156a4b3");
WalletConnectEthereumCredentials credentials = this.credentials;
debugPrint("Credentials: ${credentials}");
final ethFunction = deployedContract!.function(functionName);
final result = await ethClient!.sendTransaction(
tempCredentials ,
Transaction.callContract(
from: EthereumAddress.fromHex(account!),
contract: deployedContract!,
function: ethFunction,
parameters: args,
maxGas: 100000,
),
fetchChainIdFromNetworkId: false,
chainId: 3,
);
return result;
}
How can I get the private key when clicking on the "Connect Wallet" Button? I have this code snippet. I want to replace EthPrivateKey tempCredentials with the private key or the credentials that I'll get from the metamask application when the connection is happening! so to pass it to ethClient!.sendTransaction method
Future<String> submit(String functionName, List<dynamic> args) async { EthPrivateKey tempCredentials = EthPrivateKey.fromHex( "c58e17d53714f56c3ded7e9eed18863301055b78e141dc4ccf2c9cd9c156a4b3"); WalletConnectEthereumCredentials credentials = this.credentials; debugPrint("Credentials: ${credentials}"); final ethFunction = deployedContract!.function(functionName); final result = await ethClient!.sendTransaction( tempCredentials , Transaction.callContract( from: EthereumAddress.fromHex(account!), contract: deployedContract!, function: ethFunction, parameters: args, maxGas: 100000, ), fetchChainIdFromNetworkId: false, chainId: 3, ); return result; }
You cannot get the private key out of Metamask vault by security design.
@matteocasonato @Pablo4Coding I also stuck on "signToSignature" due to the method was not implemented,
Future<MsgSignature> signToSignature(Uint8List payload,
{int? chainId, bool isEIP1559 = false}) {
// TODO: implement signToSignature
throw UnimplementedError();
}
I need to sign my transaction before send it, like:
final signedTrans = await ethClient.signTransaction(credentials, transaction);
final txnHash = await ethClient.sendRawTransaction(signedTrans);
Have you got any idea to implement it?
i dont know if this helps but this blog really explains things, cause i was going through the same thing too
https://dev.to/bhaskardutta/building-with-flutter-and-metamask-8h5
Hello, folks. Sorry for this stupid question, but I'm new to Flutter mobile development and I now need to interact with Metamask on my app (no need to sign transactions, but need users the user select his/her Metamask to get the wallet address). I followed all the instructions you've described above and I'm wondering how to install Metamask Mobile App (external app).
I'm using MacOS (installed on VM running on Windows10) and using iPhone 13 Pro - iOS 15.5 as the Emulator.
Any advice/help is welcome! Thanks! 🙇♂️
Hello, folks. Sorry for this stupid question, but I'm new to Flutter mobile development and I now need to interact with Metamask on my app (no need to sign transactions, but need users the user select his/her Metamask to get the wallet address). I followed all the instructions you've described above and I'm wondering how to install Metamask Mobile App (external app).
I'm using MacOS (installed on VM running on Windows10) and using iPhone 13 Pro - iOS 15.5 as the Emulator.
- First of all, on which platform (Emulator or MacOS) should I install Metamask?
- How to install it? Apple Store shows an error.
Any advice/help is welcome! Thanks! 🙇♂️
Where are you trying to install the metamask app
on the Emulator? I'm not sure where to instal it (anyways, I'm now trying to fork the Metamask repo & build locally & run to the Emulator - but fails)
The goal is: to allow my app to interact with Metamask (only need to get wallet address) on iOS (not web app)
It's written in Flutter.
Can you please tell me how I can figure out this issue?
Really urgent. Still working on this issue. 😢
i dont know if this helps but this blog really explains things, cause i was going through the same thing too
https://dev.to/bhaskardutta/building-with-flutter-and-metamask-8h5
I was following these steps, but failed with the following error message
i dont know if this helps but this blog really explains things, cause i was going through the same thing too
https://dev.to/bhaskardutta/building-with-flutter-and-metamask-8h5
I was following these steps, but failed with the following error message
Mine is on windows so i downloaded metamask on my phone(physical device) and then I used the information on the article I sent earlier
Thanks! 🙇♂️
What do you think about this, @Colin-Stark @pozniejzmienie @0xCaos @EBP20 @Pablo4Coding @akshay-bhimani-pedalsup ? To summarize:
It's been about 1 week for me working on this issue, but not yet solved. Rock head mine is, lol 🤣
Can you tell me how I can solve this problem soon?
Thanks
https://dev.to/bhaskardutta/building-with-flutter-and-metamask-8h5
When I follow those steps, I'm facing errors while installing Metamask. I cannot install from Apple Store for iOS. The only way is to
But this shows an error like the image I uploaded before.
Maybe you should look into installing apps in xcode first.
Like tackle one issue at a time
@Colin-Stark Your advice helped me for sure and now Installed Metamask on my Simulator. Can you please share your code for the whole code? I've tried with several code snippets but all failed.
like: how to initiate connector and how to ...
Preferably screenshot of your code? 🙇♂️
Now when click on
Sorry bruh I was in hiatus but I'm back, can you share your source code so I can see what is going on
Hi everyone. I've been researching a lot online but I can't figure out how to perform a connection between a Mobile app (which we're building with Flutter) and Metamask.
Connecting with a blockchain isn't a problem, I just have to figure out how to take private keys from a Metamask account in order to interact with the chain (for know I'm using a private key imported manually, but would be great to have a "connect wallet" button which opens the Metamask Mobile app, asking for permissions).
I found about "deeplinking" and interacting with WalletConnect, but still can't find anything for Flutter Mobile, just Web versions (which is useless).