NFT 通用发售中的钱包登录与链切换技术解析

NFT发售过程中如何更加通用一点,如何节省开发时长

Posted by Warden_Gfs on February 16, 2023

在 NFT 快速发售场景中,用户登录和验证是一个核心环节。本文将结合代码实现和业务流程图,深入解析 useMetaLogin Hook 的功能、设计思路及其在 NFT 快速发售中的应用。

useMetaLogin Hook 的设计与实现

useMetaLogin 是我之前开发的一个React Hook,主要用于处理区块链钱包连接、账户切换、签名验证和登录状态管理等功能。下面给大家讲一讲主要的实现。

核心功能概览

1 检测钱包环境:通过 isWalletInstalled 方法判断用户是否安装了钱包插件(如 MetaMask)。 2 连接钱包:默认激活 MetaMask,获取用户的账户地址和链 ID。 3 链切换:提供链切换功能,支持用户切换到应用所需的目标链。 4 签名验证:生成登录验证消息,利用钱包签名,完成后端验证。 5 本地存储管理:将登录状态和 token 存储到 localStorage 以简化后续操作。 useMetaLogin Hook

⠀代码解析 以下是 useMetaLogin Hook 的部分关键逻辑解读: 1. 检测钱包环境并激活钱包

useEffect(() => {
  const hasEthereum = isWalletInstalled();
  if (!hasEthereum) return;

  activate(injected); // 默认连接 injected(如 MetaMask)
  if (account) {
    localStorage.setItem("currentAddress", account);
    initLogin(); // 初始化登录状态
  }
}, [account, chainId]);
  • 判断是否安装钱包插件(isWalletInstalled)。
  • 激活 MetaMask 并自动连接账户。
  • 如果账户已存在,调用 initLogin 检查登录状态。

2. 用户登录逻辑 initLogin 是核心登录逻辑,包含获取 nonce、生成签名、调用后端接口认证等步骤:

const initLogin = useCallback(async () => {
  if (!library || !account) return;

  try {
    const token = window.localStorage.getItem(account) || "";
    if (token) {
      setToken(token);
      setIsLogin(true);
      return;
    }

    const nonce = await getNonce({ address: account });
    const msg = await produceMessage(
      window.location.origin,
      account,
      statement,
      window.location.href,
      1,
      nonce?.data?.value,
      1
    );

    const signature = await library.provider.request({
      method: "personal_sign",
      params: [msg, account],
    });

    const { data, error } = await loginApi({
      userAddress: account,
      invitationCode,
      signature,
      nonce: nonce?.data?.value,
      message: msg,
    });

    if (data) {
      localStorage.setItem(account, data);
      setToken(data);
      setIsLogin(true);
    }
  } catch (error) {
    setToken('');
    setIsLogin(false);
  }
}, [library, account]);
  • 获取 nonce:通过后端接口请求 nonce,用作签名的动态校验码。
  • 生成签名消息:结合 produceMessage 工具生成符合 EIP-712 标准的签名消息。
  • 签名验证:调用钱包的 personal_sign 方法完成签名。
  • 后端登录验证:将签名和相关参数发送至后端,获取 token 并存储。

3. 链切换功能

const switchChainId = async (chainId, callback) => {
  try {
    await library.provider.request({
      method: "wallet_switchEthereumChain",
      params: [{ chainId: toHex(chainId) }],
    });
    if (callback) callback();
  } catch (error) {
    toast.error(error.message || "It is something wrong", { duration: 1500 });
  }
};
  • 通过钱包的 wallet_switchEthereumChain 方法实现链切换。
  • 使用 toHex 工具将链 ID 转换为十六进制格式。

业务流程解析

业务流程解析 结合业务流程图,useMetaLogin Hook 在 NFT 快速发售中的应用主要体现在以下几个方面:

1. NFT 快速发售主流程

从需求提出到最终上线,NFT 快速发售主流程分为多个阶段: 1 需求分析与配置: * 配置活动信息及设计元素。 * 调用 useMetaLogin Hook 完成钱包登录和验证。 2 用户身份验证: * 判断用户是否需要实名认证。 * 如果需要,调用服务端接口验证用户身份。 3 发售上线: * 完成前端和合约配置后即可上线。

⠀流程图解读 登录封装的主要步骤 根据流程图,useMetaLogin Hook 的封装步骤如下: 1 检查是否需要签名: * 如果钱包地址在本地已存储 token,则检查其是否过期。 * 如果过期或不存在,则生成 nonce 并请求签名。 2 调用后端登录接口: * 提交签名、nonce 和用户地址,获取 token 并存储。 3 提供统一接口: * 返回 activate、deactivate、switchChainId 等方法,供其他组件调用。

跨链 Mint 通信机制 NFT 项目中,跨链 Mint 是复杂场景之一。流程包括: 1 用户支付并触发链 A 上的合约事件; 2 后端监听事件,协助完成链 B 上的 Mint; 3 前端监听链 B 的事件,确认交易完成。

模块化功能设计

结合功能设计图,NFT 发售系统可划分为以下模块: 1 NFT 模块:名称、图片、数量、价格等基本信息。 2 活动信息模块:活动周期、场次时间、供应量等。 3 链相关模块: * 合约名称、地址、ERC20 代币类型等。 * 是否需要签名验证。 4 用户模块:用户角色、购买限制、身份类型等。

⠀useMetaLogin Hook 在链相关模块和用户模块中扮演关键角色,提供钱包连接、签名验证等功能支持。

跨链注意事项

跨链注意事项 在跨链场景中,需要重点关注以下问题:

  • 事件监听:确保后端准确监听链 A 上的支付事件,并在链 B 上触发对应的 Mint 操作。
  • 前端实时更新:前端应监听链 B 的合约事件,及时反馈交易状态。
  • 多链兼容性:支持不同链间的交互机制,例如 Ethereum 和 Polygon。