如何使用 Crossmint 的铸造 API 空投 Solana NFT

  • QuickNode
  • 发布于 2024-03-12 17:43
  • 阅读 14

该文章详细介绍了如何使用Crossmint API和QuickNode工具批量空投Solana NFT,包括设置项目、定义类型和常量、创建NFT、验证空投结果等步骤。

概述

传递 NFT从未如此简单。无论你是一家希望开始使用NFT的Web2公司,还是有一个希望通过NFT奖励的Web3社区,Crossmint的Mint API允许你只需一个POST请求就能向用户铸造NFT。Crossmint的NFT API可以直接通过QuickNode的市场获得,因此开始起来更加轻松。在本指南中,你将创建一个简单的脚本,允许你将 NFT 直接铸造并交付给一列客户(通过钱包地址或电子邮件地址👀)。

你将要做什么

在本指南中,我们将:

  • 创建带有Crossmint API附加功能的QuickNode端点
  • 创建NFT元数据
  • 使用Crossmint API(使用TypeScript)将NFT空投到Solana钱包和电子邮件地址的组合列表中
  • 验证空投是否成功
  • 将空投细节记录到.json文件中

你将需要什么

要跟随本指南,你将需要以下内容:

  • JavaScript/TypeScript编程语言的基础知识
  • 安装Nodejs(版本16.15或更高)
  • 安装npm或yarn(我们将使用yarn来初始化我们的项目并安装必要的包。如果你更喜欢使用npm,也可以)
  • TypeScript经验和已安装ts-node

设置你的项目

在终端中创建一个新的项目目录:

mkdir crossmint-drop
cd crossmint-drop

为你的应用创建一个文件,app.ts

echo > app.ts

使用“yes”标志初始化你的项目,以使用新包的默认值:

yarn init --yes
#or
npm init --yes

创建一个启用.json导入的tsconfig.json

tsc -init --resolveJsonModule true --target es2020

创建一个results文件夹,用于保存我们空投的输出:

mkdir results

安装Solana Web3依赖项

虽然本练习不是必需的,但我们将使用Solana-Web3库在调用Crossmint API之前验证钱包地址。我们还将使用Axios来向Crossmint发出HTTP请求。在终端中输入:

yarn add @solana/web3.js@1 axios
#or
npm install @solana/web3.js@1 axios

我们需要从这些库和fs中获取一些组件,以便将结果写入文件。在你选择的IDE中打开crossmint-drop文件夹(我们将使用VSCode),并在app.ts的第1行添加以下导入语句:

import { PublicKey } from '@solana/web3.js';
import axios from 'axios';
import fs from 'fs';

使用你的QuickNode端点连接到Solana集群

要快速访问Crossmint API,以便你能够使用一行代码创建并发送NFT给用户,即使他们没有加密钱包,你需要创建带有Crossmint附加功能的QuickNode端点。在此处注册免费账户。创建一个新的Solana Devnet端点,并确保用Crossmint NFT Mint API进行配置:

新附加功能

复制HTTP提供程序链接:

新节点

app.ts中的导入语句下,声明你的RPC(我们在运行脚本时需要这一点):

const QUICKNODE_RPC = 'https://example.solana-devnet.quiknode.pro/0123456/';

你的环境应该看起来像这样。

准备构建

你已准备就绪。让我们开始构建应用!

声明类型

我们将为脚本使用TypeScript,因此我们将定义一些类型和接口,以帮助保持代码的整洁和准确。如果你是JavaScript开发人员或不喜欢使用TypeScript,也没关系。

在代码中的// 类型部分创建,并在应用的顶部(在导入后)添加以下代码:

// TYPES

type Email = string;
type StringPubKey = string;
type Destination = Email | StringPubKey;

interface NftMetadata {
    name: string,
    image: string,
    description: string
    attributes: {trait_type: string, value: string}[],
    properties: {
        files: {uri: string, type: string}[],
        category: string
    }
}

interface MintNftProps {
    destination: Destination,
    qnEndpoint: string,
    collectionId: string,
    nftInfo: NftMetadata
}

interface FetchMintProps {
    qnEndpoint: string,
    collectionId: string,
    crossmintId: string
}

interface MintResult {
    destination: string,
    crossmintId: string,
    mint: string
}

以下是每个声明的小介绍:

  • 首先,我们将我们的_destination_声明为_Email_或StringPubKey(这将是我们希望用户的NFT发送到的位置)。
  • 接下来,我们定义了我们的NftMetadata,它接受关于我们的NFT的基本信息,包括一个_traits_数组。
  • _MintNftProps_定义了我们将在铸造函数中使用的输入。我们需要一个接收地址,一个QuickNode端点,集合ID,以及正在铸造的NFT的元数据。
  • _FetchNftProps_定义了我们将用来检查铸造状态的输入。
  • _MintResult_概述了我们将如何记录结果(包括接收地址、来自CrossMint的唯一ID以及铸造地址——在Solana区块链上的唯一公钥)。

定义关键常量

让我们为我们的项目定义一些关键常量。在你的类型下面,添加:

// CONSTANTS

const QUICKNODE_RPC = 'https://example.solana-devnet.quiknode.pro/0123456/';
const COLLECTION_ID = 'default-solana';
const DROP_LIST: Destination[] = [\
    'quickguides@test.com',\
    'CTrLzkrcnqgqSTmzJ146ZTRkLAvwcjnxGSZBvqC5BH3w',\
    'quickdemo@test.com',\
    'DemoKMZWkk483hX4mUrcJoo3zVvsKhm8XXs28TuwZw9H'\
];
const DELAY = 1000;
  • 我们首先将QUICKNODE_RPC移动到其余常量同处。
  • 然后将我们的COLLECTION_ID设置为default-solana。这是Crossmint NFT在Solana上的默认铸造值。如果你计划启动一系列NFT,创建自己的集合可能是明智的。你可以使用cm_createCollection方法做到这一点(文档)。出于本示例的目的,我们将使用默认值。
  • 一份我们希望发送NFT的电子邮件地址和Solana钱包地址列表(我们将设置我们的应用程序以能够同时处理两者)。Crossmint的Mint API为新用户创建钱包,使你可以将NFT发送到他们的电子邮件地址,并轻松地引导新用户。
  • 我们将添加一个简单的延迟,以防止触发任何速率限制。我们建议你查看Crossmint的最佳实践,如果你计划发起任何大规模的NFT空投。我们将DELAY设置为1秒(1,000毫秒)。

让我们添加一个额外的工具常量,即wait函数。我们将使用它在API调用之间创建延迟:

async function wait(ms: number):Promise<void> {
    return new Promise<void>((resolve) => {
      setTimeout(() => {
        resolve();
      }, ms);
    });
}

好的!让我们进入Crossmint API。

创建铸造函数

让我们创建一个HTTP请求到Crossmint来铸造我们的NFT。此函数将完成三件事:

  1. 验证我们的接收地址是否为有效的电子邮件地址或Solana公钥
  2. 组装POST请求
  3. 发送POST请求并处理响应

app.ts中,添加一个requestCrossMintNft函数:

const requestCrossMintNft = async ({ destination, qnEndpoint, collectionId, nftInfo }: MintNftProps) => {
    // 正则表达式验证电子邮件地址
    const emailRegex: RegExp = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;

    // 验证并定义接收者(作为电子邮件地址或Solana钱包,否则抛出错误)
    let recipient: string;
    if (emailRegex.test(destination)) {
        recipient = `email:${destination}:sol`;
    } else if (new PublicKey(destination)) {
        recipient = `solana:${destination}`;
    }
    else {
        throw new Error('无效的接收地址(必须是有效的电子邮件地址或Solana钱包地址)。');
    }

    // 组装POST请求
    const metadata = {
        "name": nftInfo.name,
        "image": nftInfo.image,
        "description": nftInfo.description
    };
    const data = {
        jsonrpc: "2.0",
        id: 1,
        method: "cm_mintNFT",
        params: [collectionId, recipient, metadata], // https://docs.crossmint.com/docs/cm-mintnft
    };
    const config = {
        headers: {
            "Content-Type": "application/json",
        },
    };

    // 发送POST请求
    return new Promise<string>(async (resolve, reject) => {
        try {
          let response =  await axios.post(qnEndpoint, data, config);
          resolve(response.data.result.id as string);
        } catch (error) {
          reject("发送请求到CrossMint时出现错误。检查输入。");
        }
      });
}

我们所做的事情如下:

  1. 首先,我们使用JavaScript正则表达式(RegExp)和Solana _PublicKey_类来检查提供的地址是否为有效的目的地。基于你的分发列表(例如,如果你只发送到电子邮件地址,你就不需要Solana PublicKey检查,反之亦然),可以随意修改此内容。如果无效,我们将抛出错误。

正则表达式

如果你从未使用过正则表达式,emailRegex模式检查输入字符串是否以一个或多个来自集合a-zA-Z0-9.!#$%&'*+/=?^_{|}~-的字符开始,后面跟上@符号,然后是一个或多个来自集合a-zA-Z0-9及连字符-的字符,有61个字符的最大限制,并且可以选择在最后添加一个点.后面跟上更多字符,至多61个字符,来自集合a-zA-Z0-9和连字符-

  1. 然后,我们根据Crossmint文档组装我们的POST请求。请注意,我们的metadata是使用我们的nftInfo参数编译的。这意味着我们可以为每个铸造的NFT创建自定义属性!

  2. 最后,我们返回一个承诺以POST cm_mintNFT方法。如果收到成功的响应,承诺将返回Crossmint ID(一个唯一的交易标识符)。

创建获取铸造函数

在我们向Crossmint发送铸造请求后,我们需要一种方法来验证我们的铸造是否成功(到目前为止,我们只知道Crossmint成功接收了我们的请求,而不知道Solana是否确认了铸造的NFT)。为此,我们可以使用从前一步返回的ID进行状态检查。

创建一个新函数,fetchMintAddress

const fetchMintAddress = async ({ collectionId, qnEndpoint, crossmintId }: FetchMintProps) => {

    // 组装POST请求
    const data = {
        jsonrpc: "2.0",
        id: 1,
        method: "cm_getNFTMintStatus",
        params: [collectionId,crossmintId], //https://docs.crossmint.com/docs/cm-getnftmintstatus
    };
    const config = {
        headers: {
            "Content-Type": "application/json",
        },
    };

    // 发送POST请求
    return new Promise<string>(async (resolve, _reject) => {
        try {
          let response =  await axios.post(qnEndpoint, data, config);
          resolve(response.data.result.onChain.mintHash as string);
        } catch (error) {
          //reject("获取铸造地址时出错。");
        }
      });
}

从结构上看,这与我们上一步非常相似:

  1. 我们组装POST请求(这次调用cm_getNFTMintStatus并传入从上一步返回的crossmintId)。
  2. 发送POST请求,并在成功时返回铸造的NFT的唯一链上铸造哈希。

将这两者结合起来,你可以运行这两个函数以铸造单个NFT,但我们想要一些乐趣——让我们空投一堆👀

创建批量空投函数

我们具备了使用Crossmint API铸造和确认NFT所需的所有工具——我们需要一种能够执行批量投放并具有自定义每个NFT的能力的方法。我们需要创建一个dropNfts函数,它将:

  1. 使用.mapdropList中的每个_目的地_创建一个承诺。
  2. 基于某个唯一特征定义我们的元数据(在此情况下,我们将使用索引i为每个NFT赋予一个唯一的名称和特性。你可以根据自己的风格更新元数据!)。
  3. 创建一个承诺:
    • 使用requestCrossMintNft请求Crossmint铸造NFT
    • 通过调用等待1分钟来等待铸造的发生。(注意:这是我们演示的简单方法。根据你的需求,你可能希望设置一些查询/重试逻辑。)
    • 使用fetchMintAddress验证铸造是否成功
    • 返回关于投放NFT的信息
  4. 使用Promise.allSettled()执行所有承诺
  5. results目录中创建我们结果的日志

以下函数有点长,但我们已经在前面的步骤中完成了所有繁重的工作!在app.ts中创建一个dropNfts函数,该函数接受_目的地_列表、你的QuickNode端点和集合ID:

const dropNfts = async (dropList: Destination[], qnEndpoint: string, collectionId: string) => {
    console.log('生成承诺中...');
    let promises = dropList.map((drop, i) => {
        // 1-定义自定义元数据
        const nftNumber = (i+1).toString();
        const nftInfo = {
            name: `Demo Airdrop # ${nftNumber}`,
            image: 'https://arweave.net/UTFFfaVA3HoFcxwoMHEcvBLq19HrW6FuzpyygXqxduk',
            description: '通过Quicknode附加功能使用Crossmint铸造API的演示空投NFT',
            attributes: [\
                {\
                    trait_type: "background",\
                    value: "blue"\
                },\
                {\
                    trait_type: "type",\
                    value: "pixel"\
                },\
                {\
                    trait_type: "id",\
                    value: nftNumber\
                }\
            ],
            properties: {
                files: [\
                    {\
                        "uri": "https://arweave.net/UTFFfaVA3HoFcxwoMHEcvBLq19HrW6FuzpyygXqxduk",\
                        "type": "image/png"\
                    }\
                ],
                category: "image"
            }
        };
        // 2-创建承诺
        return new Promise< MintResult >(async (resolve, reject)=>{
            setTimeout(async ()=>{
                try {
                    let crossmintId = await requestCrossMintNft({
                      destination: drop,
                      qnEndpoint,
                      collectionId,
                      nftInfo
                    });
                    if (!crossmintId) throw new Error('未收到CrossMint ID。');
                    await wait(60000); // 等待1分钟
                    let mint = await fetchMintAddress({
                        collectionId,
                        qnEndpoint,
                        crossmintId
                    });
                    resolve({
                        destination: drop,
                        crossmintId: crossmintId,
                        mint: mint ?? ''
                    });
                } catch (error) {
                    reject('发送请求到CrossMint时出现未知错误。');
                }
            },i * DELAY);
        })
    });
    // 3-执行承诺
    console.log('执行承诺...(这将需要1分钟以上)');
    let results = await Promise.allSettled(promises);
    // 4-保存结果
    console.log('正在写入结果到./results/results.json');
    let data = JSON.stringify(results);
    fs.writeFileSync('./results/results.json',data);
}

太棒了!让我们开始吧。

空投你的NFT 🪂

在你的app.ts末尾,调用你的dropNfts函数:

dropNfts(DROP_LIST, QUICKNODE_RPC, COLLECTION_ID);

在终端中输入以下内容:

ts-node app

大约等待一分钟后,你应该看到新生成的results.json,其中包含你的铸造结果数组:

[\
    {\
        "status": "fulfilled",\
        "value": {\
            "destination": "quickguides@test.com",\
            "crossmintId": "60f33f72-a8d8-41ce-b28a-bc899aa7b929",\
            "mint": "AbJjT4j9MYQTya9aZ9qmCd36dspwoMnhfsEpZL91sFwG"\
        }\
    },\
    {\
        "status": "fulfilled",\
        "value": {\
            "destination": "DemoKMZWkk483hX4mUrcJoo3zVvsKhm8XXs28TuwZw9H",\
            "crossmintId": "0c4836cb-26dc-48a2-a55f-5d3ca40699da",\
            "mint": "5RRDSrq6ME5Yz9qXcKRvSQeGD1F2AEnURnjfCs7BTEvN"\
        }\
    },\
    // 等等。\
]

干得不错!

结束语

就这样,你可以批量空投NFT给你的web2和web3客户!如果你在本指南中遇到任何问题或只是想展示你的NFT项目,请联系我们,通过DiscordTwitter告诉我们你在做什么!

  • 原文链接: quicknode.com/guides/sol...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
QuickNode
QuickNode
江湖只有他的大名,没有他的介绍。