RFP-2: Build a Custom Discord Bot to Automate POKT Arcade Quest Verifications & Generate a Database for Snapshot Strategies

Summary

Build a custom Discord bot which can automate wallet verifications, POKT Arcade quest verifications, and record the data for integrating with Snapshot strategies.

Objective(s)

Build a stronger operational foundation for scaling the DAO.

Objective Key Results

  • Less manual work is required to maintain the POKT Arcade inbound pipeline.
  • The POKT Arcade UX is improved, leading to more engagement.
  • The DAO is able to adopt more robust, sophisticated and/or secure governance that incorporates on-chain activities into vote weightings.

Background

The Opportunity to Automate POKT Arcade Quest Verifications

POKT Arcade is a community gamification and onboarding system that we use to recognize community members’ participation in the network/community and, based on this, qualify them for a vote in the DAO.

At the moment quest verifications are done manually. This is manageable for now but may become a burden as the community scales and the volume of POKT Arcade inbounds multiplies. A significant amount of quests involve on-chain activities, which gives us the opportunity to automate the verification of those quests.

The Opportunity to Create a Database of Scores for Snapshot Strategies

We are also using Snapshot for off-chain voting, using POKTDAO tokens that are airdropped by the CollabLand Discord bot, once users have qualified as described above.

Snapshot uses strategies (JavaScript functions) to score voters (weight their votes) and can obtain these scores using any external data source such as a node, a subgraph, or an API.

Since we’d already be recording wallets and their on-chain activities in a database for the purpose of POKT Arcade quest verification, and a user’s Discord ID will be a common link between the on-chain activities of their POKT wallet and the wallet they receive their POKTDAO airdrop to, the Discord bot we use for automated quest verifications could also become the data source that Snapshot uses to score POKTDAO wallets.

Feeding Two Birds with One Scone

Therefore this project has the potential to feed two birds with one scone:


Team Needed

Budget Proposed

Budget for Discord bot developer to be negotiated. The scope of this project is quite large, with database requirements, various scripts/automations, and the ability to communicate with the Pocket blockchain. Will include $ paid by PNI and can include additional POKT paid for by DAO, subject to DAO approval.

Milestones & Timeline

  1. Phase 1 – Q1 '21:
    • Build the bot using all of the functionality (in terms of parsing on-chain data) that is available today
    • Submit protocol feature requests, or work with Script developers listed above, for any gaps that need to be filled
  2. Phase 2 – Q2 '21:
    • Subject to there being gaps in Q1 and these gaps being filled, build the remaining functionality
  3. Undefined:
    • If/when updates are made to the POKT Arcade quests, update the bot to reflect these

Technical Specification

The bot should be able to handle the full cycle of onboarding, verification and scoring in our DAO:

  1. Verifying POKT wallet ownership
  2. Verifying on-chain POKT Arcade quest completion
  3. Levelling up users based on POKT Arcade quests completed
  4. Verifying POKTDAO wallet ownership
  5. Maintaining database of POKTDAO owners and associated on-chain “scores”

In order to do all of this, the bot will need to be able to:

  • Run scripts as detailed below
  • Maintain its own full node (or use Pocket as an app) for queries to the Pocket blockchain
  • Maintain a database of verified POKT wallets, which it matches to on-chain datapoints about those wallets
  • Maintain a database of relays serviced/submitted by all nodes/apps on the chain
  • Run eth_sign to verify POKTDAO token ownership
  • Maintain a database of verified POKTDAO wallets, which it matches to POKT wallets (and their datapoints) via the linked Discord ID
  • Expose the POKTDAO database (with rolled up datapoints per the previous bullet) via API for the purpose of a Snapshot strategy calling the database

1. Verifying POKT wallet ownership

We have already built the script required to verify a POKT wallet signature, found here.

Users are required to sign a message with their POKT wallet using their address as the contents of the message, then post to the #achievement-unlocked channel the following details: <address> <public key> <signature>

I currently verify these signatures using my terminal with the following command: !pocket-arcade verify-sign <address> <public key> <signature>

We can automate this stage by having users submit a bot command like follows: !pokt-verify <address> <public key> <signature>

The bot would then parse this command, record the parameters in the database (including the user’s Discord ID), run the script itself, then record true/false in the database and return a success/failure message to the user.

Users should be able to do the above multiple times to verify ownership of multiple POKT wallets, all of which would be recorded in the database and referenced in stages 2 and 5 below.

2. Verifying on-chain POKT Arcade quest completion

Currently, all on-chain quests are verified manually by me using my own Pocket full node, with the help of some scripts that we have already built.

We should be able to automate verifying that these quests were completed, by programming the bot to maintain a database of relays, and run scripts when the user submits a command like !complete-<quest>, for all of the wallets that have been verified by the user.

The quest types are as follows:

  • Staking Quests: stake your node / app in mainnet (see the server and sync quests)
  • Stay Unjailed Quests (for Nodes): successfully avoid getting jailed for a consecutive period of blocks, in increasing amounts (see the jailbreak, datacenter and cloud quests)
  • Relay Servicing Quests (for Nodes): successfully service relays for apps, in increasing amounts, verified by proof transactions (see the transmission, broadcast, livestream and relay-station quests)
  • Relay Submission Quests (for Apps): submit relays through the network, in increasing amounts (see the gateway and torrent1-4 quests)

Staking Quests

These will be verified with a simple pocket query node/app <address> command via a Pocket full node, then checking if the wallet is staked.

Stay Unjailed Quests

These quests can be verified, albeit with some wait time depending on the length of the period being checked, using our jailcounter script with the following command: ./jailcounter.sh <address> <starting block> <ending block>

Relay Servicing/Submission Quests

These quests will be harder to verify and will require maintaining a database of total relays serviced/submitted by all wallets on the chain.

With a simple config file, the relay_counter script uses binary search to find the nearest blocks to the start/end, then tallies up the relays using valid claims and proofs transactions. The results are outputted in a json file that specifies for each app/node, all of the apps/nodes that serviced or were serviced by each other, as well as their total relays serviced/submitted.

However, this script takes a while to process. If we tried to run the script every time a user wants to verify a related quest, the UX would be awful. Ideally all quest completions will be instant, so that users don’t think the command has failed and submit it multiple times.

Therefore it would probably be wise to maintain a database of the results which, in effect, will be a total count of all relays serviced/submitted by all apps/nodes on the network. We will need to run relay_counter once with a config that specifies enough blocks to take us back to genesis, assuming our system memory allows us, then set the bot to periodically run relay_counter (e.g. on a weekly basis with a config going back one week).

When someone submits a relay servicing/submission quest completion, the bot will check this against the database rather than the blockchain.

3. Leveling up users based on POKT Arcade quests completed

Another important part of POKT Arcade is leveling up or “evolution”. Each level of POKT Arcade includes a quest completion requirement in order to level up:

  • garage: 3/3
  • boot_camp: 5/7
  • factory: 17/17 (all node quests)
  • street_cafe: 1/3
  • hackers_den: 5/10
  • the_grid: 17/17 (all app quests)
  • the_ranch: 6/8
  • the_citadel: 4/6
  • shepherds_station: 21/21 (all community quests)
  • street_clinic: 3/3
  • rave: 3/5
  • cyborg_laboratory: 12/12 (all DAO quests)

We currently automate evolutions using custom Carl-bot tags which are written in Tagscript (which I believe is a custom language made for Carl-bot). When this script is triggered by a user, it checks the user’s roles and grants a new role if the user has enough of the required roles.

Here is an example for earning the Nodégé role, using the !become-nodege command:

{=():}{override}{silence}
{=(comment):server, transmission, jailbreak; 3/3 required}
{=(roles):761021896858664960 761021820400828456 763129778856525874}
{=(newrole):724024348142469130}
{=(msg):What?! {user(mention)} is evolving! Congratulations! Your Node evolved into a Nodégé! Tweet about it here https://bit.ly/Nodégé_POKTarcade}
{=(number.of.roles.to.evolve):3}

{=(total.role.count):{index(end):{user(roleids)} end}}
{=(new.role.count):{index(end):{replace({roles(1)},. .):{replace({roles(2)},. .):{replace({roles(3)},. .):{user(roleids)}}}} end}}
{=(included.roles):{m:trunc({new.role.count}-{total.role.count})}}

{{if({included.roles}>={number.of.roles.to.evolve}):c:role custom {user(id)} +{newrole}}}
{if({included.roles}>={number.of.roles.to.evolve}):{msg}}

While it is mostly automated, it still relies on the user triggering each script that is associated with each new role, meaning we must tell the user in each level which command they must use to level up.

It would be a far better UX if the bot could periodically scan the roles of participating users (it could make this more efficient by limiting the scan to users who have already opted in to playing POKT Arcade), check their roles, and then automatically grant an evolution if enough roles have been earned.

This would have the added benefit of making evolution more of a surprise, like it is in Pokémon. When the bot says “What?! User is evolving!..”, this should happen at a random time that surprises the user and pulls them back into the Arcade loop.

4. Verifying POKTDAO wallet ownership

This one should be pretty simple as it’s being done with many Discord bots in the crypto space.

There are a few methods we could try…

  • Weak verification: A simple signing UI that requires the user to type in their Discord username and then sign the message using eth_sign, which will identify the presence of a POKTDAO token and link it to the username in the message. One weakness of this method is that usernames change; to properly link this to the Discord ID that the bot picked up in previous stages, we should aim to use a method that records and verifies the Discord ID.
  • Strong verification: A simple signing UI that DMs the user with a unique link when they submit a !poktdao-verify command, which the user then clicks through and signs (no message required). Since the link was DMed to them, the bot can know for sure that the wallet signing is owned by the Discord ID that submitted the command.
  • Strong verification with smoothest UX: Since the POKTDAO token is being airdropped by CollabLand, which DMs the user a unique link and remembers if the user has already received the airdrop, there should be a datastore that has recorded all of the Discord IDs who own POKTDAO tokens. If this is the case, we should simply be able to feed this into our bot’s database and link it up. We should confirm this with the CollabLand team.

5. Maintaining database of POKTDAO owners and associated on-chain “scores”

At this stage our database has the following:

  1. A registry of verified POKT wallets, linked to Discord IDs
  2. A registry of verified POKTDAO wallets, linked to Discord IDs
  3. A database of relays serviced/submitted by all POKT wallets

Via the commonality of Discord IDs, we should now be able to link POKTDAO wallets to all of their POKT wallets, and from there link POKTDAO wallet owners to the total relays they have serviced/submitted.

But we don’t need to stop there, using the bot’s full node (or integration with Pocket as an app), we can maintain all sorts of other valuable datapoints about each POKTDAO owner.

For nodes:

  • Staking status
  • Jailed status
  • Chains they’re servicing relays for
  • Total tokens staked

For apps:

  • Staking status
  • Chains they’re submitting relays for
  • Total tokens staked / max throughput

Since a Snapshot strategy can call an external API, in addition to the standard node/subgraph calls that most Snapshot users are doing, if we expose this database via an API the Snapshot strategy should be able to retrieve all of these scores for each POKTDAO address.

In other words, this Discord bot would ultimately enable us to use on-chain data for off-chain signaling.


Other Considerations

wPOKT

We don’t currently have plans to do wPOKT quests in POKT Arcade, but I think it is likely that we will. Therefore we may also need the bot to be able to verify wallets that the user is using to participate in wPOKT and call the wPOKT subgraph to verify that the user has completed wPOKT quests, for example, they’ve staked X tokens in the wPOKT contract.

Further to that, we may want wPOKT to be treated equally to POKT in matters of governance, which would mean we’d want this wPOKT data to also be linked to the POKTDAO account for the Snapshot strategy as per Stage 5.

Removing Reliance on User Triggers

A lot of our Discord flows above require on user-driven triggers to execute a bot workflow.

Assuming we do all of the above but we are unable to scan for triggers, in the worst case, the user commands will include:

  1. !pokt-verify
  2. !poktdao-verify
  3. !qualify
  4. !verify (BrightID)
  5. !me (BrightID)
  6. !claim-vote
  7. !become-nodege
  8. !become-nodemad
  9. !become-node-runner
  10. !become-netizen
  11. !become-savant
  12. !become-cyberpunk
  13. !become-farmer
  14. !become-shepherd
  15. !become-regen
  16. !become-biohacker
  17. !become-cyborg
  18. !become-singularity
  19. !complete-server
  20. !complete-sync
  21. !complete-jailbreak
  22. !complete-datacenter
  23. !complete-cloud
  24. !complete-transmission
  25. !complete-broadcast
  26. !complete-livestream
  27. !complete-relay-station
  28. !complete-gateway
  29. !complete-torrent-1
  30. !complete-torrent-2
  31. !complete-torrent-3
  32. !complete-torrent-4
  33. !airdrop (CollabLand)

That’s a grand total of 33 commands in the worst case scenario. And every command has a corresponding instruction that users must read or be reminded of.

Even if we manage to achieve the goal of Stage 3, that only eliminates the evolution commands that start with !become, as well as !qualify and !claim-vote since they use the same Carl-bot method, which leaves us with 19 commands.

If, further to this, we can have the bot periodically scan the wallets that have been verified by users, looking for on-chain quest completions, then automatically award those roles to the users, we cut the total number of user commands down to 5. This also has the nice effect of making the Arcade feel more like a real-life videogame, since a game awards you achievements automatically when you complete them. If there is a success message that tags the user when these quests are automatically verified, this will also serve to bring the user back into the Arcade loop.

This leaves us with !pokt-verify, !poktdao-verify, !verify (BrightID), !me (BrightID), and !airdrop (CollabLand). If we are able to eliminate !poktdao-verify by incorporating the CollabLand datastore, as described in Stage 4, we’re down to 4 commands.

This is the UX we should strive for. In practice, this would only require 3 types of actions from the user:

  • Verify their POKT wallets using !pokt-verify
  • Verify their uniqueness using BrightID, with a 2-step command - !verify then !me
  • Claim their CollabLand POKTDAO airdrop using !airdrop

Once these actions are done, users would be able to proceed with no more instructions required.

2 Likes

I think we should go ahead with this sooner rather than later.

Traction is picking up in the community and best to make things as scalable as possible before the crowds come.

I believe that this is necessary, but out of interest; what budget does this come from?

1 Like

Any USD budget would come from PNI but the DAO could also opt to add POKT as a further incentive. The $1.2k was specified for the Discord bot because I’ve been told that’s roughly how much it would cost, but I’m not sure what we’d need to pay for the remaining Bash scripts that we need. @BenVan has kindly already put together a few that are already helping us verify most of the node quests.

I agree with this statement

And I am in support for this proposal

Scaling the community and governance to be more efficient will pay off in dividends over the long term

It would also free up time from doing POKT Arcade admin work that can be redirected to other high leverage governance projects

I’d also prefer if the Bot would proactively scan the users to see if they are eligible for evolving / ranking up then triggering that automatically. It makes for great UX (and a surprise!)

What would be the cost of maintenance?

No idea on costs yet because the scope of this is quite large. Waiting for feedback on the spec as it stands then will share with some bot developers to get their input.

Looks good to me

Makes me wonder of a future where I can use a bot/chat to check up on my node(s) as well.

Ooh yes, with the existing functionality that should be possible. In addition to DMing when you’ve completed a quest, the bot could theoretically also automatically DM you when it notices one of your nodes is jailed, or DM you daily updates with the amount of relays you’ve done (and % change from yesterday).

1 Like

yeah that would be really cool functionality. for another time lol

I mean it sounds like it could be quite easy to add. And it would be extra incentive for people to register.

Do the words in brackets refer to different types of nodes? It’s not clear.

It’s also not clear what the words in brackets are for the other types also. Maybe it will be more obvious to node runners themselves, but it might help to flesh this out?

What kind of attack vectors does this new system open up for Pocket? I’m very in favour of the proposal, but do wonder if we are creating any unintended consequences in terms of single points of failure or otherwise?

Who controls the various off-chain database stores?

And one more thought that comes to mind; I think we could move much of the technical specification (below the bullet points) and most of the “other considerations” to a separate document, like a gdoc or Notion, as such a long piece of text may reduce engagement. Should we recommend a max word count for governance posts?

All of the words in brackets refer to the names of the quests that fit the category being described.

This is an RfP not a proposal. So the intended audience is builders who need to understand the nuances of the implementation, rather than voters who need to approve/reject the idea.

that makes sense.

you could consider amending the brackets to spell it out for slow folks like me?

Eg Staking Quests: stake your node / app in mainnet(for example, see the server quest in #garage and the sync quest in #[***])?

fair point.

And do we think that our forum pages is the best place to discuss proposals like this? Answering this myself, that’s the whole point?? I’m just trying to think through how to get more engagement and to pull people in from discord to engage with the proposal, and whether a shorter summary (ie a TLDR) should also be shared elsewhere (discord, twitter, etc), so people can more easily see what’s involved and can put themselves forward or recommend someone else they know.

Part of the purpose of an RfP (request for proposal, not proposal) like this is to start a need-finding process wherein the prospective builder can go back and forth with the RfP submitter to more deeply understand the problem being solved and whether the proposed specification is actually the best way to achieve that.

When I share this with some Discord bot developers that I’ve already been reaching out to, my hope is that they can advise on the gaps in the specification, and that the detail in the specification will minimize any confusion or back-and-forth that would arise from them getting up to speed.

As for whether this is the correct place, I think so, because we’re trying to consolidate all of our community discussions into the same place. If a PEP is ultimately submitted to the DAO to fund work on this, that PEP would be a separate digestible document that links to this.

Sharing RfPs on Twitter might be a good idea in the long-run for sure.

This is a good question and one I would need to defer to someone more technical than myself.

It wouldn’t be possible to create new voting identities, because Snapshot will ultimately only check for the scores of people who are signing with a POKTDAO token in their wallet. So that’s not a vector.

In theory, it might be possible to gain access to a datastore and modify the scores for an existing voter identity, but I’m inclined to believe that this wouldn’t go unnoticed and could be defended against like any other database. In any case, this might be justification to pursue a decentralized data storage solution, but I’m not sure which would be most appropriate for this use case. That’s one of the things I’m hoping to uncover by starting the discussion with developers.

Some related ideas to this:

  • If the bot is already tracking network relays, it could post daily/weekly relay updates to a public channel.
  • As part of these updates, the bot could also highlight the app and node that were responsible for the most relays. If these apps/nodes have been verified through the POKT Arcade, the bot can actually tag the user rather than listing the address. If those users specify the project they belong to, e.g. “Name | Project”, this would also show our community who our traction is coming from.
  • If the bot is already tracking jailed status, it could post daily updates to a public channel tagging all of the verified nodes who are jailed, along with how long they’ve been jailed for. This would both provide an additional notification to those node operators as well as a “social shaming” mechanism to make unjailing a higher priority for them.
1 Like

These are all great ideas!

It would enable us to construct a dynamic leaderboard / shameboard, too.

Alongside that, would it be worth it to enable community members to use certain commands to interact with the bot?

I’ve seen some examples on other discords to check the price of a token. Could we replicate that but for checking relay count?

Oh damn, let’s add that to the list. That would be so cool. We could have a #leaderboards channel with embeds that automatically update to display the most relays performed by any node (as well as tagging the user if they verified they own the wallet), the most relays submitted by any app (also tagging if verified), and the most blocks jailed.

I know from the sesh bot (events bot), that it is possible to post an embed and update the contents without needing to resend a message, so this would be feasible.

I’d want to make sure that the use case makes sense. If there’s something worth checking publicly that can’t be checked via DMs, sent out periodically, or displayed in the role sidebar, then this could be worthwhile. Otherwise I’d want to limit potential for bot command spam.