trufflesuite / drizzle

Reactive Ethereum dapp UI suite
907 stars 238 forks source link

Allow Dapp to initiate connection to Web3 #20

Open jklepatch opened 4 years ago

jklepatch commented 4 years ago

Currently, when Drizzle is loaded, it automatically tries to connect to Web3.

What we should do is allow Dapp developer to specify when Drizzle should try to connect to Web3.

More specifically, when we create the drizzle object, it doesn't kickstart the connection process. Instead, it waits for a start() method to be executed.

cds-amal commented 4 years ago

This is definitely a better UX @jklepatch. Let's spec it out.

OnlyOneJMJQ commented 4 years ago

For optimal UX we could consider a read-only connection as the default so the dApp UI will populate, assuming it's only calls.

Take Ethlance for example: ideally users could view job postings without having to connect a wallet. Then, only if they want to actually bid on or post a job (make a state change), is wallet access requested.

cds-amal commented 4 years ago

The motivation for this issue was the UX interruption caused by automatically connecting to the wallet. @DiscRiskandBisque's suggestion solves this and allows for content to be read from the blockchain which may be necessary to present a view to the client.

jklepatch commented 4 years ago

Here is my proposal, taking @DiscRiskandBisque suggestion into consideration:

  1. Let Drizzle initialize automatically when Drizzle is instantiated
  2. Remove the call to enable() in the DRIZZLE_INITIALIZING saga
  3. Replace the single drizzle status ready to 2 statuses: [DRIZZLE_READ_READY, DRIZZLE_WRITE_READY]. Any attempt to send a transaction before we have DRIZZLE_WRITE_READY will throw
  4. Add a method askWalletWriteAccess() (not super happy of the verbose name :( any shorter ideas?) connected to a saga that calls the window.ethereum.enable() method ONLY if it exist

The workflow will be like this:

...
const drizzle = new Drizzle();
// Can do read-only operations
...
...
//Once user asks for write-level operation:
try {
  `await drizzle.askWalletWriteAccess()`

} catch(e) {
  //User refused access :(
}
//User granted access, we can allow transactions, yeah!
OnlyOneJMJQ commented 4 years ago

LGTM @jklepatch thank you!

Potential method names: connectWallet(), requestWallet().

alanarvelo commented 4 years ago

Hi @jklepatch @cds-amal @DiscRiskandBisque,

Thanks for the above discussion and plan for this feature. I made some progress stopping the enable() with a flag passed via drizzleOptions.web3, see it in this PR.

However, I am not sure how to allow read-only access to contracts when web3 is undefined. Web3 is used to get the networkId and accounts, see below the initializeDrizzle function from the drizzleStatusSaga.js file:

if (web3) {
      const networkId = yield call(getNetworkId, { web3 })

      // Check whether network is allowed
      const networkWhitelist = options.networkWhitelist
      if (networkWhitelist.length &&
          networkId !== NETWORK_IDS.ganache &&
          !networkWhitelist.includes(networkId)) {
        yield put({ type: NETWORK_MISMATCH, networkId })
      } else {
        // Get initial accounts list and balances.
        yield call(getAccounts, { web3 })
        yield call(getAccountBalances, { web3 })

The networkId is needed to know which deployed address to use for each contract (in the case a contract is deployed in various networks) and the accounts are needed to be the from or sender of the cacheCall()s. Any suggestions on how to go about this. My apologies if I am missing something.

SalahAdDin commented 3 years ago

@alanarvelo How is it going on?

bitfede commented 3 years ago

Very, very horrible UX the fact that as soon as drizzle loads the metamask popup comes up and asks to connect... Users should be able to click a "login" or "connect" button which then makes drizzle connect to metamask.

Anything has been done for this? I really cannot use Drizzle if this problem persists :(

PXLFuSSeL commented 3 years ago

To fetch Data from the blockchain, you need a web3 Connection, so the only way to implement this, is to Stop drizzle initialize web3 Connection, even i think the whole drizzle initialize, and when Data is need to be fetched from the Network Just Show a Button with a hint, that "You now need to Connect" or Something Like that. @alanarvelo Please correct me If am am wrong

bitfede commented 3 years ago

I'm gonna rewrite what I wrote in another similar issue, basically I gave up on Drizzle. It is just so important to have a login/logout out of the box without having to hack around anything, UX is important.

I found useDapp to be the best and easiest framework as of now. Discard Drizzle until their dev team decides to wake up, and try this out instead! https://usedapp.readthedocs.io/en/latest/getting-started.html#example . These guys helped me with a bug fix over the weekend in 2 days, totally a more professional dApp framework and developers to work with.

AND there is a login/logout with metamask feature which can be implemented super easy and works with hooks.

Sorry guys, natural selection.

JackDiSalvatore commented 3 years ago

I'm gonna rewrite what I wrote in another similar issue, basically I gave up on Drizzle. It is just so important to have a login/logout out of the box without having to hack around anything, UX is important.

I found useDapp to be the best and easiest framework as of now. Discard Drizzle until their dev team decides to wake up, and try this out instead! https://usedapp.readthedocs.io/en/latest/getting-started.html#example . These guys helped me with a bug fix over the weekend in 2 days, totally a more professional dApp framework and developers to work with.

AND there is a login/logout with metamask feature which can be implemented super easy and works with hooks.

Sorry guys, natural selection.

Hey @bitfede thanks for posting. I am running into the same limitation of drizzle and was looking for alternatives. I'm looking to build a dapp where users can interact with both my a smart contract as well as Ether and other ERC20 tokens. Nothing of unorthodox complexity, but I just want the ability to interact with my own smart contract as well as other existing ones. Would you recommend I start off with https://usedapp.io/ or just use web3 if its more extensible?

bitfede commented 3 years ago

Wassup @JackDiSalvatore !

if you like react as a framework then start with usedapp.io because you get started immediately super fast with a metamask login functionality. Calling contracts is well documented.

If not just web3 or just ethersJS is super valid.

I was a bit lost when I had to implement a metamask signature, but then I realized that I could use ethersJS and https://github.com/NoahZinsmeister/web3-react to do things like that

JackDiSalvatore commented 3 years ago

Wassup @JackDiSalvatore !

if you like react as a framework then start with usedapp.io because you get started immediately super fast with a metamask login functionality. Calling contracts is well documented.

If not just web3 or just ethersJS is super valid.

I was a bit lost when I had to implement a metamask signature, but then I realized that I could use ethersJS and https://github.com/NoahZinsmeister/web3-react to do things like that

Awesome! Thanks for the info.