logo

解锁Web3社区力量:掌握Guild SDK,打造你的去中心化王国

Published on

目录

Guild.xyz SDK是构建去中心化自治组织(DAO)的强大工具。本教程带你深入了解SDK的核心功能,从安装到高级应用。无论你是区块链新手还是经验丰富的开发者,都能在这里找到构建下一代Web3社区的关键。

简介

Guild.xyz 是一个用于创建和管理去中心化自治组织(DAO)的平台。Guild SDK 允许开发者将 Guild 的功能集成到他们自己的应用程序中。本教程将指导您完成 Guild SDK 的基本使用,包括安装、初始化、查询用户信息等。

安装

要安装我们的SDK,请打开终端并运行:

npm i @guildxyz/sdk

导入包并创建Guild客户端

import { createGuildClient, createSigner } from "@guildxyz/sdk";

// 唯一的参数是你的项目名称
const guildClient = createGuildClient("我的项目");

签名函数和认证

从ethers钱包创建签名者

import { ethers } from "ethers";

const ethersWallet = new ethers.Wallet(...);

const signerFunction = createSigner.fromEthersWallet(ethersWallet);

为web3-react创建自定义签名者

import { useWeb3React } from "@web3-react/core";

const { account: walletAddress, library } = useWeb3React();

const signerFunction = createSigner.custom(
  (message) => library.getSigner(account).signMessage(signableMessage),
  address
);

为wagmi创建自定义签名者

import { useAccount, useSignMessage } from "wagmi";

const { signMessageAsync } = useSignMessage();
const { address } = useAccount();

const signerFunction = createSigner.custom(
  (message) => signMessageAsync({ message }),
  address
);

支持EIP-1271智能合约钱包

对于EIP-1271钱包产生的签名,在createSigner.custom的第三个参数中传入{ chainIdOfSmartContractWallet: chainId },其中chainId是钱包操作的链。Guild后端将尝试在指定的链上调用isValidSignature

客户端

我们为不同实体提供了多个客户端。这些客户端是从我们之前创建的guildClient中创建的。

Guild客户端

const { guild: client } = guildClient;

// 通过数字ID获取Guild
const guild = await client.get(guildId);

// 通过urlName(slug)获取Guild
const guild = await client.get(urlName);

// 通过ID获取多个Guild
const guilds = await client.getMany([guildId1, guildId2]);

// 搜索Guild(带分页)
const guilds = await client.search({ limit: 10, offset: 0, search: "our" });

// 获取Guild的成员
const members = await client.getMembers(
  guildId,
  signerFunction // 可选,如果提供有效的签名者,结果将包含私有数据
);

// 加入Guild
const joinResult = await client.join(guildId, signerFunction);

// 检查Guild访问权限,需要signerFunction
await client.accessCheck(guildId, signerFunction);

// 创建新的Guild,请根据类型检查可能的创建参数
await client.create(
  {
    // 在这个例子中,我们创建了一个带有一个免费角色的Guild
    name: "我的Guild",
    urlName: "my-guild",
    roles: [{ name: "我的角色", requirements: [{ type: "FREE" }] }],
  },
  signerFunction
);

// 更新现有的Guild,请根据类型检查可能的更新参数
await client.update(guildId, { description: "已编辑" }, signerFunction);

// 删除Guild
await client.delete(guildId, signerFunction);

积分系统

// 为给定角色创建新的积分系统,并分配一些积分作为奖励
const created = await guild.role.reward.create(
  guildId,
  roleId, // 这个角色将有5点奖励
  {
    guildPlatform: {
      platformGuildId: "my-points", // 为你的积分系统取一个唯一的名称
      platformName: "POINTS",
      platformGuildData: { name: "coins" }, // 为积分指定一个自定义名称
    },
    platformRoleData: { score: 5 }, // 成员将获得这么多积分
  },
  signerFunction
);

// 为角色使用现有的积分系统
const created = await guild.role.reward.create(
  guildId,
  roleId, // 这个角色将有10点奖励
  {
    guildPlatformId, // 现有guildPlatform(奖励)对象的ID
    platformRoleData: { score: 10 },
  },
  signerFunction
);

// 获取特定Guild奖励的排行榜
const { leaderboard, aroundUser } = await guild.getLeaderboard(
  guildId,
  guildPlatformId,
  signerFunction // 可选。如果提供,响应将包括"aroundUser"字段,其中包含用户位置周围的排行榜项目,否则为undefined
);

// 获取用户在特定奖励中的排名
const response = await user.getRankInGuild(userId, guildId, guildPlatformId); // 返回用户在给定奖励中的排行榜位置

// 获取用户在所有相关奖励中的所有积分
const response = await user.getPoints(userId, signerFunction);

Guild管理员客户端

const {
  guild: { admin: adminClient },
} = guildClient;

// 获取Guild的所有管理员
const admins = await adminClient.getAll(guildIdOrUrlName);

// 获取Guild的特定管理员
const admin = await adminClient.get(guildIdOrUrlName, userIdOfAdmin);

Guild奖励客户端

const {
  guild: { reward: guildRewardClient },
} = guildClient;

// 获取Guild奖励(如Discord服务器)
const guildReward = await guildRewardClient.get(
  guildIdOrUrlName,
  guildPlatformId,
  signerFunction // 可选,如果提供有效的签名者,结果将包含私有数据
);

// 获取Guild的所有奖励
const guildRewards = await guildRewardClient.getAll(
  guildIdOrUrlName,
  signerFunction // 可选,如果提供有效的签名者,结果将包含私有数据
);

// 向Guild添加新奖励
const createdGuildReward = await guildRewardClient.create(guildIdOrUrlName, {
  platformName: "DISCORD", // 在这个例子中,我们添加了一个Discord服务器
  platformGuildId: "<SERVER_ID>",
});

// 从Guild删除奖励
await guildRewardClient.delete(
  guildIdOrUrlName,
  guildPlatformId,
  signerFunction
);

角色客户端

const {
  guild: { role: roleClient },
} = guildClient;

// 获取角色
await roleClient.get(
  guildIdOrUrlName,
  roleId,
  signerFunction // 可选,如果提供有效的签名者,结果将包含私有数据
);

// 获取Guild的所有角色
await roleClient.getAll(
  guildIdOrUrlName,
  signerFunction // 可选,如果提供有效的签名者,结果将包含私有数据
);

// 创建新角色。请参考类型定义了解其他可能的输入参数,如描述、逻辑或可见性
const createdRole = await roleClient.create(
  guildIdOrUrlName,
  {
    name: "我的新角色",
    requirements: [{ type: "FREE" }],
  },
  signerFunction
);

// 更新现有角色
const updatedRole = await roleClient.update(
  guildIdOrUrlName,
  roleId,
  { description: "已编辑" },
  signerFunction
);

// 删除角色
await roleClient.delete(guildIdOrUrlName, roleId, signerFunction);

需求客户端

const {
  guild: {
    role: { requirement: requirementClient },
  },
} = guildClient;

// 获取需求
const requirement = await requirementClient.get(
  guildIdOrUrlName,
  roleId,
  requirementId,
  signerFunction // 可选,如果提供有效的签名者,结果将包含私有数据
);

// 获取角色的所有需求
const requirements = await requirementClient.getAll(
  guildIdOrUrlName,
  roleId,
  signerFunction // 可选,如果提供有效的签名者,结果将包含私有数据
);

// 创建新需求
const createdRequirement = await requirementClient.create(
  guildIdOrUrlName,
  roleId,
  { type: "FREE" },
  signerFunction
);

// 更新现有需求(例如ALLOWLIST需求中的地址)
const updatedRequirement = await requirementClient.update(
  guildIdOrUrlName,
  roleId,
  requirementId,
  { data: { addresses: ["0x..."] } }, // 小写地址
  signerFunction
);

// 删除需求
await requirementClient.delete(
  guildIdOrUrlName,
  roleId,
  requirementId,
  signerFunction
);

角色奖励客户端

const {
  guild: {
    role: { reward: rewardClient },
  },
} = guildClient;

// 获取角色奖励
const reward = rewardClient.get(
  guildIdOrUrlName,
  roleId,
  rolePlatformId,
  signerFunction // 可选,如果提供有效的签名者,结果将包含私有数据
);

// 获取角色的所有奖励
const roleReward = rewardClient.getAll(
  guildIdOrUrlName,
  roleId,
  signerFunction // 可选,如果提供有效的签名者,结果将包含私有数据
);

// 创建角色奖励(例如Discord角色)与Guild奖励(Discord服务器)
const createdReward = rewardClient.create(
  guildIdOrUrlName,
  roleId,
  {
    guildPlatform: {
      // 这里我们也创建了一个Guild奖励(Discord服务器)
      platformName: "DISCORD",
      platformGuildId: "<DC_SERVER_ID>",
    },
    platformRoleId: "<DC_ROLE_ID>",
  },
  signerFunction
);

// 或使用现有的Guild奖励创建角色奖励
const createdReward = rewardClient.create(
  guildIdOrUrlName,
  roleId,
  {
    guildPlatformId, // 这里我们传递现有Guild角色的ID(在这种情况下是Discord服务器)
    platformRoleId: "<DC_ROLE_ID>",
  },
  signerFunction
);

// 更新现有角色奖励
const updatedRoleReward = rewardClient.update(
  guildIdOrUrlName,
  roleId,
  rolePlatformId,
  { visibility: "HIDDEN" }, // 在这个例子中,我们将奖励的可见性更新为HIDDEN
  signerFunction
);

// 删除角色奖励
rewardClient.delete(guildIdOrUrlName, roleId, rolePlatformId, signerFunction);

用户客户端

const { user: userClient } = guildClient;

// 通过数字ID或地址获取用户
const user = await userClient.get(userIdOrAddress);

// 获取用户当前的成员资格
const userMemberships = await userClient.getMemberships(
  userIdOrAddress,
  signerFunction // 可选,如果提供有效的签名者,结果将包含私有数据
);

// 获取用户的个人资料
const profile = await userClient.getProfile(
  userIdOrAddress,
  signerFunction // 可选,如果提供有效的签名者,结果将包含私有数据
);

// 删除用户
await userClient.delete(userIdOrAddress, signerFunction);

用户地址客户端

const {
  user: { address: userAddressClient },
} = guildClient;

// 获取用户地址
const userAddress = await userAddressClient.get(
  userIdOrAddress, // 用于识别Guild用户
  address, // 将返回具有此地址的userAddress
  signerFunction
);

// 获取用户的所有地址
const userAddresses = await userAddressClient.getAll(
  userIdOrAddress,
  signerFunction
);

// 创建(连接/链接)新的用户地址
const linkedAddress = await userAddressClient.create(
  userIdOrAddress,
  signerFunctionOfAddressToLink, // 应该是从正在链接到用户的钱包派生的SignerFunction。可以按上述方式获得
  signerFunction
);

// 更新用户地址
const updatedUserAddress = await userAddressClient.update(
  userIdOrAddress,
  addressToUpdate,
  { isPrimary: true }, // 在这个例子中,我们将地址更新为主要地址
  signerFunction
);

// 删除(断开连接/取消链接)用户地址
await userAddressClient.delete(
  userIdOrAddress,
  addressToUpdate,
  signerFunction
);

用户平台客户端

const {
  user: { platform: userPlatformClient },
} = guildClient;

// 获取用户平台连接
const userPlatform = await userPlatformClient.get(
  userIdOrAddress,
  platformId,
  signerFunction
);

// 获取用户的所有平台连接
const userPlatforms = await userPlatformClient.getAll(
  userIdOrAddress,
  signerFunction
);

// 删除(断开连接/取消链接)平台连接
await userPlatformClient.delete(userIdOrAddress, platformId, signerFunction);

模块化/多平台架构

Guild.xyz 不再将其平台访问控制功能限制于单一的可控制访问的 Discord 服务器或 Telegram 群组。在新的多平台架构中,你可以在单个 guild/role 中控制多个平台的访问。

guildPlatform 实体指的是由 guild 控制访问的平台。它包含有关访问控制平台的信息,例如:Discord 服务器的 id(platformGuildId,这是该平台的唯一标识符)以及可选的一些附加数据,如在这种情况下 platformRoleData 属性中的 inviteChannel

rolePlatform 实体将 guildPlatform 连接到一个角色,表示该角色可以访问该平台。它还可以包含有关平台的一些额外信息(platformRoleIdplatformRoleData),在 Discord 的情况下,它是 Discord 角色的 id。

请注意,例如在 Telegram 的情况下,不需要 platformRoleId;只需要在 guildPlatform 中提供 platformGuild(它指的是 telegram 群组的 id)。

示例

从创建 Guild 到加入的示例流程

import { createGuildClient, createSigner } from "@guildxyz/sdk";
import { Wallet } from "ethers";
import { randomBytes } from "crypto";

// 创建一个 guild 客户端
const guildClient = createGuildClient("sdk-readme-example");

// 为示例创建一个随机钱包
const wallet = new Wallet(randomBytes(32).toString("hex"));

// 创建一个签名函数
const signerFunction = createSigner.fromEthersWallet(wallet);

// 创建一个 Guild
await guildClient.guild.create(
  {
    name: "我的新 Guild",
    urlName: "my-new-guild-123", // 可选
    description: "很酷的内容", // 可选
    admins: ["0x916b1aBC3C38852B338a22B08aF19DEe14113627"], // 可选
    showMembers: true, // 可选
    hideFromExplorer: false, // 可选
    theme: [{ color: "#000000" }], // 可选
    guildPlatforms: [
      // 可选(声明受控制的平台)
      {
        platformName: "DISCORD",
        platformGuildId: "717317894983225012",
        platformGuildData: { inviteChannel: "832195274127999019" },
      },
    ],
    roles: [
      {
        name: "我的第一个角色",
        logic: "AND",
        requirements: [
          {
            type: "ALLOWLIST",
            data: {
              addresses: [
                "0xedd9C1954c77beDD8A2a524981e1ea08C7E484Be",
                "0x1b64230Ad5092A4ABeecE1a50Dc7e9e0F0280304",
              ],
            },
          },
        ],
        rolePlatforms: [
          // 可选(将受控制的平台连接到角色)
          {
            guildPlatformIndex: 0,
            platformRoleId: "947846353822178118",
          },
        ],
      },
      {
        name: "我的第二个角色",
        logic: "OR",
        requirements: [
          {
            type: "ERC20",
            chain: "ETHEREUM",
            address: "0xf76d80200226ac250665139b9e435617e4ba55f9",
            data: {
              amount: 1,
            },
          },
          {
            type: "ERC721",
            chain: "ETHEREUM",
            address: "0x734AA2dac868218D2A5F9757f16f6f881265441C",
            data: {
              amount: 1,
            },
          },
        ],
        rolePlatforms: [
          // 可选(将受控制的平台连接到角色)
          {
            guildPlatformIndex: 0,
            platformRoleId: "283446353822178118",
          },
        ],
      },
    ],
  },
  signerFunction
);

// 如果给定地址可以访问任何角色,则加入 Guild
await guildClient.guild.join(myGuild.id, signerFunction);

多个 Telegram 群组的 Guild

const myGuild = await guildClient.guild.create(
  {
    name: "我的 Telegram Guild",
    guildPlatforms: [
      {
        platformName: "TELEGRAM", // Telegram 群组 0
        platformGuildId: "-1001190870894",
      },
      {
        platformName: "TELEGRAM", // Telegram 群组 1
        platformGuildId: "-1003847238493",
      },
      {
        platformName: "TELEGRAM", // Telegram 群组 2
        platformGuildId: "-1008347384212",
      },
    ],
    roles: [
      {
        name: "我的第一个角色",
        logic: "AND",
        requirements: [
          {
            type: "ALLOWLIST",
            data: {
              addresses: [
                "0xedd9C1954c77beDD8A2a524981e1ea08C7E484Be",
                "0x1b64230Ad5092A4ABeecE1a50Dc7e9e0F0280304",
              ],
            },
          },
        ],
        rolePlatforms: [
          {
            guildPlatformIndex: 0, // Telegram 群组 0
          },
          {
            guildPlatformIndex: 2, // Telegram 群组 2
          },
        ],
      },
      {
        name: "我的第二个角色",
        logic: "OR",
        requirements: [
          {
            type: "ERC20",
            chain: "ETHEREUM",
            address: "0xf76d80200226ac250665139b9e435617e4ba55f9",
            data: {
              amount: 1,
            },
          },
        ],
        rolePlatforms: [
          {
            guildPlatformIndex: 1, // Telegram 群组 1
          },
        ],
      },
    ],
  },
  signerFunction
);

结语

通过本教程,您已经了解了如何使用 Guild.xyz SDK 来创建和管理去中心化自治组织(DAO)。从安装和初始化,到创建 Guild、角色和奖励,再到管理用户和平台连接,我们涵盖了 SDK 的主要功能。

记住,Guild.xyz 的强大之处在于其灵活性和可扩展性。您可以根据自己的需求创建复杂的角色和权限系统,跨多个平台管理社区,并为您的 DAO 成员提供独特的奖励和体验。

随着您对 SDK 的深入使用,您可能会发现更多高级用例和功能。我们建议您经常查看官方文档,因为 Guild.xyz 团队可能会不断添加新功能和改进。

最后,在构建您的 DAO 时,始终考虑安全性和用户体验。确保正确处理身份验证和授权,并为您的社区成员创建一个直观且有吸引力的界面。

祝您在使用 Guild.xyz SDK 构建下一代 Web3 社区的过程中取得成功!