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:
- Automate POKT Arcade, dramatically improving the UX
- Create a database of scores, linked to POKTDAO wallets, for use with Snapshot strategies, unlocking significant possibilities for RFP-1: Research and Build Custom Snapshot Strategies to Reinforce Governance Security
Team Needed
- Leader: @JackALaing (Governance Lead)
- Script developers: @BenVan @Andrew (work already completed)
- Designer (for bot profile pic): @Valebeflo
- Bot Developer: ?
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
-
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
-
Phase 2 – Q2 '21:
- Subject to there being gaps in Q1 and these gaps being filled, build the remaining functionality
-
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:
- Verifying POKT wallet ownership
- Verifying on-chain POKT Arcade quest completion
- Levelling up users based on POKT Arcade quests completed
- Verifying POKTDAO wallet ownership
- 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:
- A registry of verified POKT wallets, linked to Discord IDs
- A registry of verified POKTDAO wallets, linked to Discord IDs
- 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:
- !pokt-verify
- !poktdao-verify
- !qualify
- !verify (BrightID)
- !me (BrightID)
- !claim-vote
- !become-nodege
- !become-nodemad
- !become-node-runner
- !become-netizen
- !become-savant
- !become-cyberpunk
- !become-farmer
- !become-shepherd
- !become-regen
- !become-biohacker
- !become-cyborg
- !become-singularity
- !complete-server
- !complete-sync
- !complete-jailbreak
- !complete-datacenter
- !complete-cloud
- !complete-transmission
- !complete-broadcast
- !complete-livestream
- !complete-relay-station
- !complete-gateway
- !complete-torrent-1
- !complete-torrent-2
- !complete-torrent-3
- !complete-torrent-4
- !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.