2

I'm using Next.js to implement server-side rendering in my Ethereum app, however I can't fetch my Metamask address to display it in the top-right corner of the navigation bar in my index.js file. Currently, my getInitialProps() function returns an empty array. Can anyone help me get this to work?

  • I'm using web3 v1.0.0-beta.35
  • I'm logged into Metamask (using v 5.3.1)
  • I'm using web3.eth.getAccounts() to fetch the account from Metamask
  • I've granted permission to the app to access Metamask accounts in accordance with their breaking changes.

There have been a couple of instances where the address does pop up upon refresh, but the majority of the time it doesn't work.

Here's the repo for this project: https://github.com/jviray/buidl-box

Below is the code for my index.js file containing the component that's giving me issues. The address should be showing in the top-right corner of the navigation bar where it says { this.props.accounts[0] }.

import React, { Component } from 'react';
import Head from 'next/head';
import { Jumbotron, Button } from 'react-bootstrap/lib';
import web3 from '../ethereum/web3';

class Welcome extends React.Component {
  static async getInitialProps() {
    const accounts = await web3.eth.getAccounts();

    return { accounts };
  }

  render() {
    const jumbostyle = {
      textAlign: 'center',
      marginTop: '30px'
    };

    return (
      <div>
        <Head>
          <title>BUIDL</title>
          <meta
            name="viewport"
            content="initial-scale=1.0, width=device-width"
          />
          {/* -- Latest compiled and minified CSS */}
          <link
            rel="stylesheet"
            href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
            integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
            crossorigin="anonymous"
          />
        </Head>
        {/* NAVBAR */}
        <nav className="navbar navbar-inverse navbar-fixed-top">
          <div className="container">
            <div className="navbar-header">
              <a href="#" className="navbar-brand">
                BUIDL
              </a>
            </div>

            {/* NAVBAR ITEMS */}
            <ul className="nav navbar-nav navbar-right">
              <li className="navbar-brand">{this.props.accounts[0]}</li>
            </ul>
          </div>
        </nav>
        <Jumbotron>
          <div className="container" style={jumbostyle}>
            <h1>Welcome, Ethereum Devs!</h1>
            <p>
              As a community we need to start building new and powerful
              applications that truly add value.
            </p>
            <p>
              <a href="https://www.coindesk.com/dont-hodl-buidl-blockchain-tech-will-add-value-2018">
                <Button bsStyle="primary">Learn more</Button>
              </a>
            </p>
          </div>
        </Jumbotron>;
      </div>
    );
  }
}

export default Welcome;

What's interesting is that if I add component state and use React's "async componentDidMount()" to setState() with the fetched account, I'm able to get it to work consistently without issues after refreshing.

But again the goal is to fetch the account on the server-side with getInitialprops, and I can't get that to work.

Here's the code that works when I use "async componentDidMount()"

import React, { Component } from 'react';
import Head from 'next/head';
import { Jumbotron, Button } from 'react-bootstrap/lib';
import web3 from '../ethereum/web3';

class Welcome extends React.Component {
  state = {
    accountAddress: ''
  };

  async componentDidMount() {
    const accounts = await web3.eth.getAccounts();

    this.setState({
      accountAddress: accounts[0]
    });
  }

  render() {
    const jumbostyle = {
      textAlign: 'center',
      marginTop: '30px'
    };

    return (
      <div>
        <Head>
          <title>BUIDL</title>
          <meta
            name="viewport"
            content="initial-scale=1.0, width=device-width"
          />
          {/* -- Latest compiled and minified CSS */}
          <link
            rel="stylesheet"
            href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
            integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
            crossorigin="anonymous"
          />
        </Head>
        {/* NAVBAR */}
        <nav className="navbar navbar-inverse navbar-fixed-top">
          <div className="container">
            <div className="navbar-header">
              <a href="#" className="navbar-brand">
                BUIDL
              </a>
            </div>

            {/* NAVBAR ITEMS */}
            <ul className="nav navbar-nav navbar-right">
              <li className="navbar-brand">{this.state.accountAddress}</li>
            </ul>
          </div>
        </nav>
        <Jumbotron>
          <div className="container" style={jumbostyle}>
            <h1>Welcome, Ethereum Devs!</h1>
            <p>
              As a community we need to start building new and powerful
              applications that truly add value.
            </p>
            <p>
              <a href="https://www.coindesk.com/dont-hodl-buidl-blockchain-tech-will-add-value-2018">
                <Button bsStyle="primary">Learn more</Button>
              </a>
            </p>
          </div>
        </Jumbotron>;
      </div>
    );
  }
}

export default Welcome;

While it would be awesome if anyone could solve this, I'd also appreciate input on what the possible issue could be (async/await code, Next.js, web3, React, etc.). Thanks!!

  • Metamask queries can only be executed in client side code. – Ismael Jan 30 at 16:38
  • @Ismael But how does that explain those rare instances where the query works and the address pops up..only to disappear after refreshing. Thanks for insight! – jfviray Jan 30 at 17:41
  • From my understanding Next.js executes on the server only the first time, later interactions are in the client side. The web components needs to be aware of that, the so called isomorphic. – Ismael Jan 30 at 18:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.