javascriptreactjssolana-web3jsmetaplex

How to fix the error Class extends value undefined is not a constructor or null


When importing

import { useUmi } from '../../../../components/mint/umi';
import { useSplMinter } from '../../../../components/mint/tokenMinting';

I get an error in the token creation file. Error:

Class extends value undefined is not a constructor or null
TypeError: Class extends value undefined is not a constructor or null
    at ./node_modules/@metaplex-foundation/mpl-token-metadata/dist/src/errors.js (http://192.168.0.222:3000/static/js/bundle.js:1873:40)
    at options.factory (http://192.168.0.222:3000/static/js/bundle.js:118516:31)
    at __webpack_require__ (http://192.168.0.222:3000/static/js/bundle.js:117945:32)
    at fn (http://192.168.0.222:3000/static/js/bundle.js:118174:21)
    at ./node_modules/@metaplex-foundation/mpl-token-metadata/dist/src/hooked/metadataDelegateRoleSeed.js (http://192.168.0.222:3000/static/js/bundle.js:20702:18)
    at options.factory (http://192.168.0.222:3000/static/js/bundle.js:118516:31)
    at __webpack_require__ (http://192.168.0.222:3000/static/js/bundle.js:117945:32)
    at fn (http://192.168.0.222:3000/static/js/bundle.js:118174:21)
    at ./node_modules/@metaplex-foundation/mpl-token-metadata/dist/src/hooked/index.js (http://192.168.0.222:3000/static/js/bundle.js:20682:14)
    at options.factory (http://192.168.0.222:3000/static/js/bundle.js:118516:31)

I understand that the problem is in the @metaplex-foundation/mpl-token-metadata library, but I don't know how to get rid of this error. Here is my code:

import React, {useRef, useState} from 'react';
import { uploadMetadata } from "../../../../action/tokens_api";
import Add from '../../../../assets/images/icons/add.svg';
import './styles/styles.css';
import { useUmi } from '../../../../components/mint/umi';
import { useSplMinter } from '../../../../components/mint/tokenMinting';

const TokenCreator = () => {    const fileInputRef = useRef(null);
    const [name, setName] = useState('');
    const [symbol, setSymbol] = useState('');
    const [sypply, setSypply] = useState('');
    const [description, setDescription] = useState('');
    const [file, setFile] = useState(null);

    const umi = useUmi('network', 'wallet');
    const splMinter = useSplMinter(umi);

    const handleFileInputClick = () => {
        fileInputRef.current.click();
    };
    const handleFileInputChange = (event) => {
        const file = event.target.files[0];
        setFile(file);
    };
    const handleCreateToken = async () => {
        try {
            const metadataUrl = await uploadMetadata(file, name, description, symbol);
            console.log('Metadata URL:', metadataUrl);
            const mintResult = await splMinter.create({
                name: name,
                symbol: symbol,
                uri: metadataUrl
            }, '3000000000000000000');

            console.log('Mint Result:', mintResult);
        } catch (error) {
            console.error('Error creating token:', error);
        }
    };

    return(
        <div className='creator'>
            form here
        </div>
    )}

export default TokenCreator;
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import { mplTokenMetadata } from '@metaplex-foundation/mpl-token-metadata';
import { walletAdapterIdentity } from '@metaplex-foundation/umi-signer-wallet-adapters';
import API_KEY from'../../action/API_KEY/api_key';

export const useUmi = (network, wallet) => {
    return (
        createUmi(`https://${network}.helius-rpc.com/?api-key=${API_KEY}`)            
            .use(mplTokenMetadata())
            .use(walletAdapterIdentity(wallet))
    );
};
import { percentAmount, generateSigner, createBigInt } from '@metaplex-foundation/umi';
import { fromWeb3JsInstruction } from '@metaplex-foundation/umi-web3js-adapters';
import { ComputeBudgetProgram } from '@solana/web3.js';
import { TokenStandard, createAndMint } from '@metaplex-foundation/mpl-token-metadata';

export const useSplMinter = (umi) => {
    const create = async (metadata = { name: '', symbol: '', uri: '' }, amount = '0') => {
        const mint = generateSigner(umi);
        const priceIx = ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1000000 });

        const transaction = createAndMint(umi, {
            mint,
            authority: umi.identity,
            name: metadata.name,
            symbol: metadata.symbol,
            uri: metadata.uri,
            sellerFeeBasisPoints: percentAmount(0),
            decimals: 9,
            amount: createBigInt(amount),
            tokenOwner: umi.identity.publicKey,
            tokenStandard: TokenStandard.Fungible,
        }).prepend({
            instruction: fromWeb3JsInstruction(priceIx),
            signers: [],
            bytesCreatedOnChain: 0,
        });

        const res = await transaction.sendAndConfirm(umi);

        return { mint: mint.publicKey.toString(), ...res };
    };

    return { create };
};

I would be grateful for any help


Solution

  • And so, I realized that RCA does not have .cjs support and therefore cannot import modules from .cjs. To deal with this error you must first install the modules:

    npm i buffer crypto-browserify https-browserify stream stream-browserify process stream-http react-app-rewired.

    After that add it to package.json

    "browser": {
        "path": false,
        "stream": false,
        "http": false,
        "https": false
    },
    

    Also change from this

    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    

    to this

    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    

    in the root of the project create a file config-overrides.js with the contents:

    const webpack = require("webpack");
    const getCacheIdentifier = require("react-dev-utils/getCacheIdentifier");
    
    module.exports = function override(config, webpackEnv) {
      console.log("Overriding webpack config...");
    
      // Set up environment flags
      const isEnvDevelopment = webpackEnv === "development";
      const isEnvProduction = webpackEnv === "production";
      const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== "false";
    
      // Configure fallbacks for Node environment
      const fallback = config.resolve.fallback || {};
      Object.assign(fallback, {
        crypto: require.resolve("crypto-browserify"),
        stream: require.resolve("stream-browserify"),
        assert: require.resolve("assert"),
        http: require.resolve("stream-http"),
        https: require.resolve("https-browserify"),
        os: require.resolve("os-browserify"),
        url: require.resolve("url"),
        zlib: require.resolve("browserify-zlib"),
      });
      config.resolve.fallback = fallback;
    
      // Configure plugins
      config.plugins = (config.plugins || []).concat([
        new webpack.ProvidePlugin({
          process: "process/browser",
          Buffer: ["buffer", "Buffer"],
        }),
      ]);
    
      // Ignore certain warnings
      config.ignoreWarnings = [/Failed to parse source map/];
    
      // Add source-map loader
      config.module.rules.push({
        test: /\.(js|mjs|jsx)$/,
        enforce: "pre",
        loader: require.resolve("source-map-loader"),
        resolve: {
          fullySpecified: false,
        },
      });
    
      // Modify Babel loader configuration
      const loaders = config.module.rules.find((rule) =>
        Array.isArray(rule.oneOf)
      ).oneOf;
      loaders.splice(loaders.length - 1, 0, {
        test: /\.(js|mjs|cjs)$/,
        exclude: /@babel(?:\/|\\{1,2})runtime/,
        loader: require.resolve("babel-loader"),
        options: {
          babelrc: false,
          configFile: false,
          compact: false,
          presets: [
            [
              require.resolve("babel-preset-react-app/dependencies"),
              { helpers: true },
            ],
          ],
          cacheDirectory: true,
          cacheCompression: false,
          cacheIdentifier: getCacheIdentifier(
            isEnvProduction ? "production" : isEnvDevelopment && "development",
            [
              "babel-plugin-named-asset-import",
              "babel-preset-react-app",
              "react-dev-utils",
              "react-scripts",
            ]
          ),
          sourceMaps: shouldUseSourceMap,
          inputSourceMap: shouldUseSourceMap,
        },
      });
    
      return config;
    };