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

如何基于React实现Solana NFT冻结功能?

实现方案与React代码示例

核心流程拆解

要实现你的需求,核心分四步走:

  1. 按指定collectionKey筛选用户钱包内的目标NFT
  2. 展示NFT列表,提供「限时冻结/永久冻结」选项
  3. 执行NFT冻结操作
  4. 冻结成功后触发系统奖励发放

关键技术解析与文档翻译

你之前参考的三篇文档核心内容翻译如下:

  • SPL Token冻结文档:讲解SPL Token程序的账户冻结机制,要求调用者持有NFT mint账户的freezeAuthority权限,冻结后代币无法转移,解冻需同样权限。
  • Metaplex Token Metadata锁文档:介绍通过Token Metadata程序给NFT添加锁的功能,支持设置解锁时间,锁信息存储在NFT元数据中,用户可自行锁定自己的NFT,到期自动解锁(永久锁需额外逻辑处理)。
  • Candy Machine冻结支付守卫文档:这是Candy Machine发售时的支付冻结机制,仅用于发售场景,和你的需求关联度极低,可忽略。

技术选型建议

优先用Metaplex的Token Metadata锁机制,因为不需要你的系统持有NFT的冻结权限,用户可自主操作,更符合你的业务场景。

React代码实现示例

1. 依赖安装

先安装必要的库:

npm install @metaplex-foundation/js @solana/web3.js @solana/wallet-adapter-react

2. 查询用户指定Collection的NFT组件

import { useConnection, useWallet } from '@solana/wallet-adapter-react';
import { Metaplex, keypairIdentity } from '@metaplex-foundation/js';
import { useEffect, useState } from 'react';

// 替换成你的目标Collection mint地址
const TARGET_COLLECTION = '你的collection地址';

export const UserNFTList = () => {
  const { connection } = useConnection();
  const { publicKey, wallet } = useWallet();
  const [targetNFTs, setTargetNFTs] = useState([]);

  useEffect(() => {
    if (!publicKey || !wallet) return;

    const fetchFilteredNFTs = async () => {
      const metaplex = Metaplex.make(connection)
        .use(keypairIdentity(wallet.payer));

      // 获取用户钱包内所有NFT
      const allUserNFTs = await metaplex.nfts().findAllByOwner({ owner: publicKey });
      // 筛选属于目标Collection的NFT
      const filtered = allUserNFTs.filter(nft => 
        nft.collection?.address.toBase58() === TARGET_COLLECTION
      );

      setTargetNFTs(filtered);
    };

    fetchFilteredNFTs();
  }, [publicKey, wallet, connection]);

  return (
    <div className="nft-grid">
      {targetNFTs.map(nft => (
        <div key={nft.address.toBase58()} className="nft-card">
          <img src={nft.json?.image} alt={nft.name} className="nft-img" />
          <h4>{nft.name}</h4>
          <FreezeControl nft={nft} />
        </div>
      ))}
    </div>
  );
};

3. 冻结控制组件(支持时长设置)

import { useState } from 'react';
import { Metaplex } from '@metaplex-foundation/js';
import { useConnection, useWallet } from '@solana/wallet-adapter-react';

export const FreezeControl = ({ nft }) => {
  const { connection } = useConnection();
  const { wallet } = useWallet();
  const [freezeSeconds, setFreezeSeconds] = useState(''); // 空值表示永久冻结
  const [isProcessing, setIsProcessing] = useState(false);

  const handleFreeze = async () => {
    setIsProcessing(true);
    try {
      const metaplex = Metaplex.make(connection)
        .use(keypairIdentity(wallet.payer));

      const lockConfig = freezeSeconds 
        ? {
            type: 'timed',
            unlockDate: new Date(Date.now() + parseInt(freezeSeconds) * 1000),
          }
        : { type: 'permanent' };

      // 执行NFT锁定操作
      const txResult = await metaplex.nfts().lock({
        nftOrSft: nft,
        lock: lockConfig,
      });

      // 调用后端接口发放奖励(需后端验证交易有效性)
      await fetch('/api/grant-reward', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          userAddress: wallet.publicKey.toBase58(),
          nftAddress: nft.address.toBase58(),
          txSignature: txResult.signature,
        }),
      });

      alert('NFT冻结成功,奖励已发放!');
    } catch (err) {
      console.error('冻结失败:', err);
      alert('冻结失败,请检查钱包连接或重试');
    } finally {
      setIsProcessing(false);
    }
  };

  return (
    <div className="freeze-controls">
      <input
        type="number"
        placeholder="冻结时长(秒,留空永久)"
        value={freezeSeconds}
        onChange={(e) => setFreezeSeconds(e.target.value)}
        disabled={isProcessing}
        min="1"
      />
      <button 
        onClick={handleFreeze} 
        disabled={isProcessing}
        className="freeze-btn"
      >
        {isProcessing ? '处理中...' : '冻结NFT'}
      </button>
    </div>
  );
};

注意事项

  1. 权限验证:用Metaplex Lock机制时,用户无需额外授权,直接操作自己的NFT即可;若用SPL Token冻结,你的系统必须持有对应NFT mint的freezeAuthority,不推荐这种方案。
  2. 奖励安全:后端必须验证冻结交易的有效性(通过Solana RPC查询交易状态、NFT锁状态),避免伪造请求刷奖励。
  3. 状态同步:冻结后可定期查询NFT的锁状态,更新前端展示,提升用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 14:07:05