You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Class extends value undefined is not a constructor or null错误

解决@metaplex-foundation/mpl-token-metadata的"Class extends value undefined"错误

问题场景

导入以下代码时触发错误:

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

错误信息

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)

相关代码

TokenCreator组件

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;

useUmi hook

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))
    );
};

useSplMinter hook

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 };
};

解决方案

这个错误核心原因是Metaplex UMI生态包版本不兼容,mpl-token-metadata依赖的UMI核心包版本与项目中安装的UMI版本不一致,导致继承的基类未正确加载。按以下步骤解决:

1. 统一UMI相关包版本

打开项目package.json,确保所有@metaplex-foundation/umi-*前缀的包和@metaplex-foundation/mpl-token-metadata的版本完全一致,比如全部指定为^0.19.0(最新稳定版以官方发布为准),避免混合不同版本。

2. 清理依赖并重新安装

执行命令清理旧依赖后重新安装:

rm -rf node_modules package-lock.json
npm install

若使用yarn:

rm -rf node_modules yarn.lock
yarn install

3. 修复UMI初始化的空值问题

确保useUmi接收的wallet参数不为undefined,否则会导致UMI实例异常,间接触发依赖库错误。修改useUmi增加校验:

export const useUmi = (network, wallet) => {
    if (!wallet) {
        throw new Error('Wallet must be provided to initialize Umi');
    }
    return (
        createUmi(`https://${network}.helius-rpc.com/?api-key=${API_KEY}`)            
            .use(mplTokenMetadata())
            .use(walletAdapterIdentity(wallet))
    );
};

同时在TokenCreator组件中,配合钱包适配器的hook确保钱包连接后再初始化UMI:

import { useWallet } from '@solana/wallet-adapter-react';

const TokenCreator = () => {
    const { wallet, connected } = useWallet();
    // 仅在钱包连接后初始化umi
    const umi = connected ? useUmi('network', wallet) : null;
    const splMinter = umi ? useSplMinter(umi) : null;

    // ...其他逻辑
};

4. 调整事务构建方式(可选)

若版本兼容后仍有问题,改用UMI标准的事务构建方式替代createAndMint的链式调用:

import { createCreateAndMintInstruction } from '@metaplex-foundation/mpl-token-metadata';

// 替换原create函数逻辑
const create = async (metadata = { name: '', symbol: '', uri: '' }, amount = '0') => {
    const mint = generateSigner(umi);
    const priceIx = ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1000000 });

    const createAndMintIx = createCreateAndMintInstruction(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,
    });

    const transaction = umi.transactions.create([
        fromWeb3JsInstruction(priceIx),
        createAndMintIx
    ]);

    const res = await umi.rpc.sendAndConfirmTransaction(transaction, {
        signers: [mint]
    });

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

内容的提问来源于stack exchange,提问作者Rose

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 21:48:14