本教程演示如何使用 Polkadot API(PAPI) 构建一个简单的命令行界面(CLI)应用,用于在中继链(Relay Chain)上监听某个账户是否触发了 system.remarkWithEvent extrinsic。

system.remarkWithEvent extrinsic 允许用户在链上提交任意数据。本教程中,这段数据是由 账户地址 + 字符串 "email"(即 address+email)组合后生成的哈希值。应用会在链上监听该哈希,并捕获发送给指定账户的 remark 事件。

当应用检测到有发送给指定账户的 remark 时,会播放一段 “You’ve Got Mail!” 的提示音。

前置条件

在开始之前,请确保你已经安装并具备以下环境与工具:
    •    Node.js(版本 ≥ 18)
    •    包管理器(npm 或 yarn)
    •    Polkadot.js 浏览器插件(钱包)
    •    一个拥有 Westend 测试网代币的账户

克隆仓库

你可以直接运行示例代码,或使用模板作为起点。本教程使用了一个已包含 Polkadot API 与 TypeScript 依赖的模板。

请克隆 polkadot-api-example-cli 项目,并切换到 empty-cli 分支:

git clone https://github.com/polkadot-developers/dapp-examples/tree/v0.0.2
cd polkadot-api-example-cli
git checkout empty-cli

然后安装依赖:

npm install

探索模板(轻客户端)

打开仓库后,你会看到如下代码结构(省略 import):

// index.ts

async function withLightClient(): Promise<PolkadotClient> {
  // 启动轻客户端
  const smoldot = start();
  // Westend 中继链
  const relayChain = await smoldot.addChain({ chainSpec: westEndChainSpec });
  return createClient(getSmProvider(relayChain));
}

async function main() {
  // CLI 代码写在这里
}

main();

其中 withLightClient 函数非常关键。
它使用 smoldot 提供的内置轻客户端能力,在应用内部直接同步并与 Polkadot 网络交互,无需连接外部 RPC 节点。

创建 CLI

CLI 功能在 main 函数中实现,支持通过 -a / --account 参数指定要监听的账户:

// index.ts

const program = new Command();
console.log(chalk.white.dim(figlet.textSync('Web3 Mail Watcher')));

program
  .version('0.0.1')
  .description(
    'Web3 Mail Watcher - 一个用于监听 Polkadot 网络 remark 的简单 CLI 工具'
  )
  .option('-a, --account <account>', '要监听的账户')
  .parse(process.argv);

// 从 commander 中读取 CLI 参数
const options = program.opts();

监听 Remark 事件

应用会监听 Westend 网络上发送给指定账户的 remark。
以下代码应放在 main 函数中:

// index.ts

if (options.account) {
  console.log(
    chalk.black.bgRed('正在监听账户:'),
    chalk.bold.whiteBright(options.account)
  );

  // 创建轻客户端,连接到 Polkadot(Westend)网络
  const lightClient = await withLightClient();

  // 获取类型安全的 API
  const dotApi = lightClient.getTypedApi(wnd);

  // 订阅 System.Remarked 事件
  dotApi.event.System.Remarked.watch().subscribe((event) => {
    const { sender, hash } = event.payload;

    const calculatedHash = bytesToHex(
      blake2b(`${options.account}+email`, { dkLen: 32 })
    );

    if (`0x${calculatedHash}` === hash.asHex()) {
      sound.play('youve-got-mail-sound.mp3');

      console.log(chalk.black.bgRed('你收到邮件了!'));
      console.log(
        chalk.black.bgCyan('来自:'),
        chalk.bold.whiteBright(sender.toString())
      );
      console.log(
        chalk.black.bgBlue('Hash:'),
        chalk.bold.whiteBright(hash.asHex())
      );
    }
  });
} else {
  console.error('必须指定账户');
  return;
}

逻辑说明:
    •    监听 System.Remarked 事件
    •    使用 address + "email" 生成 Blake2b 哈希
    •    若链上事件中的 hash 与本地计算结果一致,则触发提示音并打印信息

编译并运行

使用以下命令编译并运行应用:

npm start -- --account <account-address>

示例:

npm start -- --account 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY

示例输出如下:

 __ __ _ _____ __ __ _ _ __ __ _ _
 \ \ / /__| |__|___ / | \/ | __ _(_) | \ \ / /_ _| |_ ___| |__ ___ _ __
 \ \ /\ / / _ \ '_ \ |_ \ | |\/| |/ _` | | | \ \ /\ / / _` | __/ __| '_ \ / _ \ '__|
 \ V V / __/ |_) |__) | | | | | (_| | | | \ V V / (_| | || (__| | | | __/ |
 \_/\_/ \___|_.__/____/ |_| |_|\__,_|_|_| \_/\_/ \__,_|\__\___|_| |_|\___|_|

📬 正在监听账户: 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
⚙️ [smoldot] Smoldot v2.0.34
✅ [smoldot] Westend 链初始化完成
🔗 名称: "Westend"
🧬 创世哈希: 0xe143…423e
⛓️ 链规格起始于: 0x10cf…b908 (#23920337)

测试 CLI

要测试该应用,请打开 PAPI Dev Console 的 Extrinsics 页面:
    1.    选择 System pallet
    2.    调用 remark_with_event
    3.    输入内容需遵循 address+email 格式

例如,监听账户:

5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY

则输入内容应为:

5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY+email

提交 extrinsic,并使用 Polkadot.js 钱包签名。

CLI 将显示如下输出,并播放 “You’ve Got Mail!” 音效:

📥 你收到邮件了!
👤 来自: 5Cm8yiG45rqrpyV2zPLrbtr8efksrRuCXcqcB4xj8AejfcTB
🔖 Hash: 0xb6999c9082f5b1dede08b387404c9eb4eb2deee4781415dfa7edf08b87472050

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐