1

I just created a new React template from scratch with npx create-react-app my-app --template typescript.

Then I added beacon and taquito package.

And then I wanted as a test first to try to create a connect/disconnect wallet button. But everytime I try to run npm run start it throws this:

Compiled with problems:X

ERROR in ./node_modules/cipher-base/index.js 3:16-43

Module not found: Error: Can't resolve 'stream' in '/home/Programming/TestProjects/tezwallet/node_modules/cipher-base'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "stream": require.resolve("stream-browserify") }'
    - install 'stream-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "stream": false }

I cant figure out why as I really did not change anything after installing the react template. When I look at Taquito Documentation or Beacon I dont see nothing related to this. Maybe I am missing a piece here I dont know? Do I need to do or add something else before I can start right away after creating a React project?

So this is how my dependencies look after installing, I changed nothing only added taquito and beacon:

  "dependencies": {
    "@airgap/beacon-sdk": "^3.2.0",
    "@taquito/beacon-wallet": "^14.0.0",
    "@taquito/taquito": "^14.0.0",
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "@types/jest": "^27.5.2",
    "@types/node": "^16.11.62",
    "@types/react": "^18.0.21",
    "@types/react-dom": "^18.0.6",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "typescript": "^4.8.4",
    "web-vitals": "^2.1.4"
  }

Basically my code structure looks like this. I tried to trimm it down for my problem. I also created it on Codesandbox. But weird thing is that there I am getting the error createHash is not a function while in my React App its throwing always:

REAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

enter image description here

config.ts

import { DAppClientOptions, NetworkType } from '@airgap/beacon-sdk';

export const getPreferredRPC = () => 'https://mainnet.smartpy.io';
export const getPreferredNetworkType = () => NetworkType.MAINNET;

export const getWalletConfig = (): DAppClientOptions => {
    return {
        name: 'Tezos Wallet',
        preferredNetwork: NetworkType.MAINNET,
    };
};

TaquitoWallet.ts

import { BeaconWallet } from '@taquito/beacon-wallet';
import { TezosToolkit } from '@taquito/taquito';
import { AccountInfo, PermissionResponseOutput } from '@airgap/beacon-sdk';
import { getPreferredNetworkType, getPreferredRPC, getWalletConfig } from './config';

export class TaquitoWallet extends BeaconWallet {
    private static instance: TaquitoWallet;

    private constructor() {
        super(getWalletConfig());
    }

    public static getInstance(): TaquitoWallet {
        if (!TaquitoWallet.instance) {
            TaquitoWallet.instance = new TaquitoWallet();
        }

        return TaquitoWallet.instance;
    }

    public getActiveAccount(): Promise<AccountInfo | undefined> {
        return this.client.getActiveAccount();
    }

    public syncAccount(networkType = getPreferredNetworkType()): Promise<PermissionResponseOutput> {
        return this.client.requestPermissions({ network: { type: networkType } });
    }
}

export class Tezos extends TezosToolkit {
    private static instance: Tezos;

    private constructor() {
        super(getPreferredRPC());
        this.setWalletProvider(TaquitoWallet.getInstance());
    }

    public static getInstance(): Tezos {
        if (!Tezos.instance) {
            Tezos.instance = new Tezos();
        }
        return Tezos.instance;
    }
}

index.ts

export { TaquitoWallet } from './TaquitoWallet';
export { Tezos } from './TaquitoWallet';

And my Connect Button in my App.tsx

import React, { useState } from "react";
import { AccountInfo } from "@airgap/beacon-sdk";
import { TaquitoWallet } from "./taquito";
//import { AccountMenu } from "./AccountMenu";

const styles = {
  div: {
    textAlign: "center",
    border: "7px solid black",
    width: "100%",
    height: "100vw",
    paddingTop: "400px",
  } as React.CSSProperties,
  button: {
    fontSize: "20px",
  },
};

function AccountButton(props: { accountInfo?: AccountInfo }) {
  const handleConnect = () => TaquitoWallet.getInstance().syncAccount();

  const handleClick = (event: React.MouseEvent) => {
    //setAnchorEl(event.currentTarget);
  };

  if (props.accountInfo) {
    console.log(props.accountInfo.address);
    return (
      <div style={styles.div}>
        <button style={styles.button} onClick={handleClick}>
          <p>connected</p>
        </button>
      </div>
    );
  } else {
    return (
      <div style={styles.div}>
        <button style={styles.button} onClick={handleConnect}>
          Connect
        </button>
      </div>
    );
  }
}

export default AccountButton;

I appreciate any help.

2 Answers 2

1

You need to provide a browserified version of stream and provide the resolution fallback to your bundler. You may need also crypto and buffer depending of what you are using in taquito.

You can install

npm i stream-browserify buffer crypto-browserify

Since you are using react-create-app, you need to eject your app and modify the webpack config

    ...
         fallback: {
            crypto: require.resolve('crypto-browserify'),
            buffer: require.resolve('buffer'),
            stream: require.resolve('stream-browserify'),
          },
    ...
5
  • 1
    The answer was in the first error message, Webpack 5 doesn't provide polyfills anymore and you must add them yourself Commented Sep 29, 2022 at 15:53
  • Is there really any other solution to this?? Once you eject, you can’t go back and hide the configuration files. I will have to maintain your React app configuration on my own manually. This means that I need to update the dependencies and ensure its not broken when a new version is released. If Create React App released a new version, I can’t update the application to the new version. Create React App is a tool that allows to develop React application without having to configure the required build tools and ejecting is basically the contrary when I do not want maintain my own configuration!
    – user8242
    Commented Sep 29, 2022 at 16:06
  • I really think that managing your own config his better when you have this kind of need. But alternatively you can use react-app-rewired github.com/timarney/react-app-rewired
    – Thomas
    Commented Sep 29, 2022 at 17:59
  • Thank you for your help, I appreciate it. But from the looks rewired could even do more harm than use. I will probably downgrade react scripts and try if it works then. But I guess I have to waive taquito when I do not want to eject :( Is there another alternative library to use? Like on ether with web3,js and ethers.js?
    – user8242
    Commented Sep 30, 2022 at 0:07
  • Taquito is the more complete one. If you need wallet, you will need BeaconSDK (which is wrapped by taquito) and so same need for browserified modules There is ConseilJS also, I never tried but from what i saw their signer is based onn libsodium so you will also need browserified modules Note that this is not a bad design of Taquito: this is common when you have libs that aims to work both for node.js and browser apps, especially in crypto where crypto & Buffer modules are very usefull.
    – Thomas
    Commented Sep 30, 2022 at 8:39
0

The answer from Thomas this is the solution.

In my humble opinion not a great one. What you can do is, to downgrade react-scripts to 4.0.3 and then I think you get rid of your error.

Why? Some background:

react-scripts v4 have Webpack v4.

react-scripts v5 have Webpack v5 now.

Now Webpack v5 was released two years ago in 2020. React added v5 to react-scripts around 12/2021 when I remember correctly.

More and more people do not want to bother with maintaning own configurations, thats one of the reasons to use CRA and dive straight into coding. So if I need to do it on my own and maintaining I see no sense in using React tbh. But sure one can ignore the problem and just say add polyfills yourself.

Now realistically speaking we wont go back to Webpack v4, so when you want to use up to date react-scripts this problem wont go away.

EDIT

enter image description here Source

Great summary to this topic. Need nothing more to add..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.