为 Token2022Form 创建令牌时出错:TypeError:无法读取未定义的属性(读取“call”)

问题描述 投票:0回答:1

在函数执行阶段

createInitializeInstruction
我收到错误:

    Error creating token for Token2022Form: TypeError: Cannot read properties of undefined (reading 'call')
    at Hash.CipherBase (index.js:7:1)
    at new Hash (browser.js:9:1)
    at createHash (browser.js:29:1)
    at splDiscriminate (splDiscriminate.ts:4:1)
    at createInitializeInstruction (instruction.ts:51:1)
    at createInitializeInstructionReact (createInitializeInstructionReact.js:21:1)
    at Object.create (main.b9dcefd2038733fdf419.hot-update.js:218:495)
    at async handleCreateToken2022 (index.jsx:140:1)

name
symbol
umi
具有字符串值,
mint
metadata
minyAuthority
updateAuthority
具有有效值。

这是我的代码:

import { useState } from 'react';
import {
    ComputeBudgetProgram,
    Connection,
    Keypair,
    PublicKey,
    sendAndConfirmRawTransaction,
    SystemProgram,
    Transaction,
    BlockheightBasedTransactionConfirmationStrategy
} from '@solana/web3.js';
import {    
    createInitializeInterestBearingMintInstruction,
    createInitializeMetadataPointerInstruction,
    createInitializeMintCloseAuthorityInstruction,
    createInitializeMintInstruction,
    createInitializeNonTransferableMintInstruction,
    createInitializePermanentDelegateInstruction,
    createInitializeTransferFeeConfigInstruction,
    createInitializeTransferHookInstruction,
    createMintToInstruction,
    createAssociatedTokenAccountInstruction,
    getAssociatedTokenAddressSync,
    ExtensionType,
    getMintLen,
    LENGTH_SIZE,
    TOKEN_2022_PROGRAM_ID,
    TYPE_SIZE} from '@solana/spl-token';
import { TokenMetadata, createInitializeInstruction, pack } from '@solana/spl-token-metadata';
import { useWallet } from "@solana/wallet-adapter-react";
import BigNumber from "bignumber.js";
import API_KEY from "../../action/API_KEY/api_key";
import bs58 from "bs58";

export const useToken22Minter = () => {    
    const network = 'devnet'
    const [connection] = useState(new Connection(`https://${network}.helius-rpc.com/?api-key=${API_KEY}`, 'confirmed'));
    const { publicKey } = useWallet();
    const wallet = useWallet();

    const toPublicKey = (k) => {
        if (!k) {
            return null;
        }        return new PublicKey(k);
    };

    const buildExtensionsInstructions = (mint, config, nonTransferableData) => {
        const ixs = [];
        const extensionsTypes = [ExtensionType.MetadataPointer];
        const hasExtensions = Object.values(config).some(value => value);

        if (hasExtensions) {
            if (config.transferFee) {
                ixs.push(
                    createInitializeTransferFeeConfigInstruction(
                        mint,
                        toPublicKey(config.transferFee.transferAuthority),
                        toPublicKey(config.transferFee.withdrawAuthority),
                        config.transferFee.basisPoints,
                        new BigNumber(config.transferFee.maximumFee.toString()),
                        TOKEN_2022_PROGRAM_ID
                    )
                );
                extensionsTypes.push(ExtensionType.TransferFeeConfig);
            }
            if (config.transferHook) {
                ixs.push(
                    createInitializeTransferHookInstruction(
                        mint,
                        toPublicKey(config.transferHook.authority),
                        toPublicKey(config.transferHook.programId),
                        TOKEN_2022_PROGRAM_ID
                    )
                );
                extensionsTypes.push(ExtensionType.TransferHook);
            }
            if (config.permanentDelegate) {
                ixs.push(
                    createInitializePermanentDelegateInstruction(
                        mint,
                        toPublicKey(config.permanentDelegate.authority),
                        TOKEN_2022_PROGRAM_ID
                    )
                );
                extensionsTypes.push(ExtensionType.PermanentDelegate);
            }
            if (config.mintCloseAuthority) {
                ixs.push(
                    createInitializeMintCloseAuthorityInstruction(
                        mint,
                        toPublicKey(config.mintCloseAuthority.authority),
                        TOKEN_2022_PROGRAM_ID
                    )
                );
                extensionsTypes.push(ExtensionType.MintCloseAuthority);
            }
            if (config.interestBearing) {
                ixs.push(
                    createInitializeInterestBearingMintInstruction(
                        mint,
                        toPublicKey(config.interestBearing.authority),
                        config.interestBearing.rate,
                        TOKEN_2022_PROGRAM_ID
                    )
                );
                extensionsTypes.push(ExtensionType.InterestBearingConfig);
            }
            if (nonTransferableData) {
                ixs.push(createInitializeNonTransferableMintInstruction(mint, TOKEN_2022_PROGRAM_ID));
                extensionsTypes.push(ExtensionType.NonTransferable);
            }
        }
        return { ixs, extensionsTypes };
    };

    const create = async (metadata = { name: '', symbol: '', uri: '' }, extensionsConfig, amount, decimals2022) => {
        const pubKey = publicKey;
        const mint = Keypair.generate();
        const ata = getAssociatedTokenAddressSync(mint.publicKey, pubKey, undefined, TOKEN_2022_PROGRAM_ID);
        const decimals = decimals2022;

        const metaData: TokenMetadata = {
            mint: mint.publicKey,
            name: metadata.name,
            symbol: metadata.symbol,
            uri: metadata.uri,
            additionalMetadata: [],
        };

        const { ixs, extensionsTypes } = buildExtensionsInstructions(mint.publicKey, extensionsConfig, extensionsConfig.nonTransferable);
        const priceIx = ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1000000 });

        const mintLen = getMintLen(extensionsTypes);
        const metadataLen = TYPE_SIZE + LENGTH_SIZE + pack(metaData).length;

        const mintLamports = await connection.getMinimumBalanceForRentExemption(mintLen + metadataLen);
        const hash = await connection.getLatestBlockhash('confirmed');

        const mintTransaction = new Transaction({
            feePayer: pubKey,
            blockhash: hash.blockhash,
            lastValidBlockHeight: hash.lastValidBlockHeight
        }).add(
            priceIx,
            SystemProgram.createAccount({
                fromPubkey: pubKey,
                newAccountPubkey: mint.publicKey,
                space: mintLen,
                lamports: mintLamports,
                programId: TOKEN_2022_PROGRAM_ID
            }),
            createInitializeMetadataPointerInstruction(mint.publicKey, pubKey, mint.publicKey, TOKEN_2022_PROGRAM_ID),
            ...ixs,
            createInitializeMintInstruction(mint.publicKey, decimals, pubKey, null, TOKEN_2022_PROGRAM_ID),
            createInitializeInstruction({
                programId: TOKEN_2022_PROGRAM_ID,
                mint: mint.publicKey,
                metadata: mint.publicKey,
                name: metaData.name,
                symbol: metaData.symbol,
                uri: metaData.uri,
                mintAuthority: pubKey,
                updateAuthority: pubKey,
            }),
            createAssociatedTokenAccountInstruction(pubKey, ata, pubKey, mint.publicKey, TOKEN_2022_PROGRAM_ID),
            createMintToInstruction(mint.publicKey, ata, pubKey, new BigNumber(amount), undefined, TOKEN_2022_PROGRAM_ID)
        );
        mintTransaction.partialSign(mint);
        const signedTx = await wallet.signTransaction(mintTransaction);
        const rawTx = signedTx.serialize();
        const confirmationStrategy: BlockheightBasedTransactionConfirmationStrategy = {
            lastValidBlockHeight: hash.lastValidBlockHeight,
            signature: bs58.encode(signedTx.signature),
            blockhash: hash.blockhash,
        };
        const signature = await sendAndConfirmRawTransaction(connection, rawTx, confirmationStrategy);

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

    return { create };
};

@solana/spl-token-metadata 库中 createInitializeInstruction 函数的代码:

import type { StructToEncoderTuple } from '@solana/codecs-data-structures';
import { getBooleanEncoder, getBytesEncoder, getDataEnumCodec, getStructEncoder } from '@solana/codecs-data-structures';
import { getU64Encoder } from '@solana/codecs-numbers';
import { getStringEncoder } from '@solana/codecs-strings';
import { getOptionEncoder } from '@solana/options';
import { splDiscriminate } from '@solana/spl-type-length-value';
import type { PublicKey } from '@solana/web3.js';
import { TransactionInstruction } from '@solana/web3.js';

import type { Field } from './field.js';
import { getFieldCodec, getFieldConfig } from './field.js';

function packInstruction<T extends object>(
    layout: StructToEncoderTuple<T>,
    discriminator: Uint8Array,
    values: T): Buffer {
    const encoder = getStructEncoder(layout);
    const data = encoder.encode(values);
    return Buffer.concat([discriminator, data]);
}/** * Initializes a TLV entry with the basic token-metadata fields. * * Assumes that the provided mint is an SPL token mint, that the metadata * account is allocated and assigned to the program, and that the metadata * account has enough lamports to cover the rent-exempt reserve. */export interface InitializeInstructionArgs {    programId: PublicKey;
    metadata: PublicKey;
    updateAuthority: PublicKey;
    mint: PublicKey;
    mintAuthority: PublicKey;
    name: string;
    symbol: string;
    uri: string;
}
export function createInitializeInstruction(args: InitializeInstructionArgs): TransactionInstruction {
    const { programId, metadata, updateAuthority, mint, mintAuthority, name, symbol, uri } = args;
    return new TransactionInstruction({
        programId,
        keys: [
            { isSigner: false, isWritable: true, pubkey: metadata },
            { isSigner: false, isWritable: false, pubkey: updateAuthority },
            { isSigner: false, isWritable: false, pubkey: mint },
            { isSigner: true, isWritable: false, pubkey: mintAuthority },
        ],
        data: packInstruction(
            [
                ['name', getStringEncoder()],
                ['symbol', getStringEncoder()],
                ['uri', getStringEncoder()],
            ],
            splDiscriminate('spl_token_metadata_interface:initialize_account'),
            { name, symbol, uri }
        ),
    });
}/** * If the field does not exist on the account, it will be created. * If the field does exist, it will be overwritten. */export interface UpdateFieldInstruction {
    programId: PublicKey;
    metadata: PublicKey;
    updateAuthority: PublicKey;
    field: Field | string;
    value: string;
}
export function createUpdateFieldInstruction(args: UpdateFieldInstruction): TransactionInstruction {    
    const { programId, metadata, updateAuthority, field, value } = args;
    return new TransactionInstruction({
        programId,
        keys: [
            { isSigner: false, isWritable: true, pubkey: metadata },
            { isSigner: true, isWritable: false, pubkey: updateAuthority },
        ],
        data: packInstruction(
            [
                ['field', getDataEnumCodec(getFieldCodec())],
                ['value', getStringEncoder()],
            ],
            splDiscriminate('spl_token_metadata_interface:updating_field'),
            { field: getFieldConfig(field), value }
        ),
    });
}
export interface RemoveKeyInstructionArgs {
    programId: PublicKey;
    metadata: PublicKey;
    updateAuthority: PublicKey;
    key: string;
    idempotent: boolean;
}
export function createRemoveKeyInstruction(args: RemoveKeyInstructionArgs) {
    const { programId, metadata, updateAuthority, key, idempotent } = args;
    return new TransactionInstruction({
        programId,
        keys: [
            { isSigner: false, isWritable: true, pubkey: metadata },
            { isSigner: true, isWritable: false, pubkey: updateAuthority },
        ],
        data: packInstruction(
            [
                ['idempotent', getBooleanEncoder()],
                ['key', getStringEncoder()],
            ],
            splDiscriminate('spl_token_metadata_interface:remove_key_ix'),
            { idempotent, key }
        ),
    });
}
export interface UpdateAuthorityInstructionArgs {
    programId: PublicKey;
    metadata: PublicKey;
    oldAuthority: PublicKey;
    newAuthority: PublicKey | null;
}

export function createUpdateAuthorityInstruction(args: UpdateAuthorityInstructionArgs): TransactionInstruction {
    const { programId, metadata, oldAuthority, newAuthority } = args;

    const newAuthorityBuffer = Buffer.alloc(32);
    if (newAuthority) {
        newAuthorityBuffer.set(newAuthority.toBuffer());
    } else {
        newAuthorityBuffer.fill(0);
    }
    return new TransactionInstruction({
        programId,
        keys: [
            { isSigner: false, isWritable: true, pubkey: metadata },
            { isSigner: true, isWritable: false, pubkey: oldAuthority },
        ],
        data: packInstruction(
            [['newAuthority', getBytesEncoder({ size: 32 })]],
            splDiscriminate('spl_token_metadata_interface:update_the_authority'),
            { newAuthority: newAuthorityBuffer }
        ),
    });
}
export interface EmitInstructionArgs {
    programId: PublicKey;
    metadata: PublicKey;
    start?: bigint;
    end?: bigint;
}
export function createEmitInstruction(args: EmitInstructionArgs): TransactionInstruction {
    const { programId, metadata, start, end } = args;
    return new TransactionInstruction({
        programId,
        keys: [{ isSigner: false, isWritable: false, pubkey: metadata }],
        data: packInstruction(
            [
                ['start', getOptionEncoder(getU64Encoder())],
                ['end', getOptionEncoder(getU64Encoder())],
            ],
            splDiscriminate('spl_token_metadata_interface:emitter'),
            { start: start ?? null, end: end ?? null }
        ),
    });}

如有任何帮助,我将不胜感激。

我很困惑,我浏览了一堆指南,但这些建议对我不起作用

javascript reactjs web3js solana spl
1个回答
0
投票

Rose 我对 Solana 比较陌生,但我可以提供建议。我会尝试(学习和利用)命令行界面。

我有多种语言的经验,我几乎可以保证你的代码 100% 完美。

我在开发中发现的问题是(环境)。也就是说,在您的计算机上,无论您如何安装所有依赖项,都可能在安装设置时出现一些问题。

我的意思是,如果你运行 blablaxyz -- 版本,我确信一切看起来都很好。

我花了大约 3 天的时间设置一个环境来进行一些 solana 开发,我可以告诉你这些来自 github 的依赖项以及任何非常挑剔的地方。

作为一个技巧,我可能会尝试不在您的计算机上全局安装并创建一个文件夹 ((( SOLANA )) 并 cd 到该文件夹中并将所有内容重新安装到该文件夹中。

然后从该主文件夹中工作并进入每个项目......

C:\SOLANA C:\SOLANA est01 C:\SOLANA est02

...等等。

这很可能可以解决您的问题。我自己从未在任何其他堆栈上遇到过更多问题。 Solana 非常(((咳咳眨眼BETA)))。

solana explorer 说 BETA 并非偶然,RPC === mainnet-beta 也是如此。

但最终......通过使用命令行界面(出于某种原因开发人员避免使用)实际上是您的最佳选择。

CLI === 更快、更可靠、更高效、更少的工作、更少的错误。

为什么 CODE 189 行是 TS 或 RS 或 JS,而 Solana 团队已经尝试通过将所有这些命令预编码到 CLI 中来帮助您。

© www.soinside.com 2019 - 2024. All rights reserved.