-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
example: custom point distribution (#28)
* bump @guildxyz/types * add example script * fix tests
- Loading branch information
Showing
6 changed files
with
210 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# Custom point distribution | ||
|
||
This example script shows how you can distribute points on Guild based on custom data / logic | ||
|
||
## Setup | ||
|
||
- Install the dependencies: `npm i` | ||
- Set the `PRIVATE_KEY` environment variable: `export PRIVATE_KEY=0x...` | ||
- If you already have a Guild, in which you intend to create the point reward, the account of the private key has to be an admin in that Guild, so it has the necessary permissions to create and update the points | ||
|
||
## Creating a Guild | ||
|
||
This example app can create a Guild by executing `npx ts-node index.js create-guild` | ||
It will print the Guild's URL, and the relevant ID-s for the point updates | ||
|
||
It sets the following things in the Guild: | ||
|
||
- Basic data (its name, urlName, ...) | ||
- A role with a GUILD_SNAPSHOT requirement. This requirement will be the source of the point distribution | ||
- A POINTS reward, which taks it's input from the requirement | ||
|
||
## Editing the points | ||
|
||
The script shows how you can edit the points by running `npx ts-node index.js edit {guildId} {roleId} {requirementId}` | ||
|
||
The `snapshot` represents the point distribution. It maps addresses to point values | ||
|
||
> When a snapshot is updated this way, the whole previous `data` field fill be overwritten, so you'll have to call this update with the whole list every time it changes |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
import { createGuildClient, createSigner } from "@guildxyz/sdk"; | ||
import { randomBytes } from "crypto"; | ||
import { privateKeyToAccount } from "viem/accounts"; | ||
|
||
const YOUR_PROJECT_NAME = "snapshot-test-snippet"; | ||
|
||
const client = createGuildClient(YOUR_PROJECT_NAME); | ||
|
||
if (!process.env.PRIVATE_KEY) { | ||
throw new Error("Please set the PRIVATE_KEY env var"); | ||
} | ||
|
||
// Load an account here (viem is just an example, any library works by implementing the singer function in createSigner.custom()) | ||
const viemAccount = privateKeyToAccount( | ||
process.env.PRIVATE_KEY as `0x${string}` | ||
); | ||
// Pass a function which signs a message with the admin account, and the address of this account | ||
const signer = createSigner.custom( | ||
(message) => viemAccount.signMessage({ message }), | ||
viemAccount.address | ||
); | ||
|
||
// If you don't have a guild yet, you can create one by calling this function | ||
async function createGuildWithSnapshot() { | ||
try { | ||
const createdGuild = await client.guild.create( | ||
{ | ||
name: "For snapshot testing", | ||
urlName: "snapshot-testing", | ||
contacts: [], | ||
roles: [ | ||
{ | ||
name: "Test role", | ||
requirements: [ | ||
{ | ||
type: "GUILD_SNAPSHOT", | ||
data: { | ||
snapshot: [ | ||
{ | ||
key: "0x0000000000000000000000000000000000000000", | ||
value: 10, | ||
}, | ||
], | ||
}, | ||
}, | ||
], | ||
}, | ||
], | ||
}, | ||
signer | ||
); | ||
|
||
console.log("Guild created!"); | ||
|
||
const guildId = createdGuild.id; | ||
const roleId = createdGuild.roles[0].id; | ||
const requirementId = createdGuild.roles[0].requirements[0].id; | ||
|
||
console.log(createdGuild.guildPlatforms); | ||
|
||
// Created the reward on the guild | ||
await client.guild.role.reward.create( | ||
guildId, | ||
roleId, | ||
{ | ||
guildPlatform: { | ||
platformName: "POINTS", | ||
platformGuildId: `unique-name-${randomBytes(4).toString("hex")}`, | ||
platformGuildData: { | ||
name: "Tokens", | ||
}, | ||
}, | ||
platformRoleData: { score: "0" }, | ||
dynamicAmount: { | ||
operation: { | ||
type: "LINEAR", | ||
input: [ | ||
{ | ||
type: "REQUIREMENT_AMOUNT", | ||
roleId, | ||
requirementId, | ||
}, | ||
], | ||
}, | ||
}, | ||
}, | ||
signer | ||
); | ||
console.log(`https://guild.xyz/${createdGuild.urlName}`); | ||
console.log( | ||
`You can now edit the snapshot with:\nnpx ts-node index.ts edit ${guildId} ${roleId} ${requirementId}` | ||
); | ||
return createdGuild; | ||
} catch (error) { | ||
console.error(error); | ||
throw error; | ||
} | ||
} | ||
|
||
// This function edits an existing snapshot | ||
async function editSnapshot( | ||
guildId: number, | ||
roleId: number, | ||
requirementId: number | ||
) { | ||
try { | ||
const editedRequirement = await client.guild.role.requirement.update( | ||
guildId, | ||
roleId, | ||
requirementId, | ||
{ | ||
data: { | ||
// The provided snapshot overwrites the previous array | ||
snapshot: [ | ||
{ key: "0x0000000000000000000000000000000000000000", value: 12 }, | ||
{ key: "0x0000000000000000000000000000000000000001", value: 10 }, | ||
], | ||
}, | ||
}, | ||
signer | ||
); | ||
console.log("Snapshot edited!"); | ||
return editedRequirement; | ||
} catch (error) { | ||
console.error(error); | ||
throw error; | ||
} | ||
} | ||
|
||
/** | ||
* Set the `PRIVATE_KEY` env var. It should be an admin in the snapshot's guild, | ||
* so it has access to edit the snapshot | ||
* | ||
* Create a guild with `npx ts-node index.ts create-guild` | ||
* | ||
* Edit the snapshot with `npx ts-node index.ts edit {guildId} {roleId} {requirementId}` | ||
* | ||
* The three ID-s for editing can be retrieved by the | ||
* https://api.guild.xyz/v2/guilds/guild-page/{urlName} endpoint. | ||
* The creation command also outputs them for the freshly created guild | ||
* | ||
* If the guild is created externally, make sure that the `PRIVATE_KEY`'s account is | ||
* added to the guild as an admin | ||
*/ | ||
async function main() { | ||
const [, , command, ...params] = process.argv; | ||
switch (command) { | ||
case "create-guild": { | ||
await createGuildWithSnapshot(); | ||
break; | ||
} | ||
case "edit": { | ||
const [guildIdStr, roleIdStr, requirementIdStr] = params; | ||
await editSnapshot(+guildIdStr, +roleIdStr, +requirementIdStr); | ||
break; | ||
} | ||
} | ||
} | ||
|
||
main(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"name": "custom-point-distribution", | ||
"version": "1.0.0", | ||
"description": "", | ||
"main": "index.js", | ||
"scripts": {}, | ||
"author": "", | ||
"license": "ISC", | ||
"dependencies": { | ||
"@guildxyz/sdk": "^2.5.0", | ||
"viem": "^2.17.10" | ||
}, | ||
"devDependencies": { | ||
"ts-node": "^10.9.2" | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters