-
-
Starrybot Homepage!
-
As an admin you can add Starrybot to your server
-
You'll be asked to enable secure slash commands on Discord
-
Your users will use /starry-join to Authenticate
-
Verification link visible only to the user (securely sent, not over DMs)
-
Users will be taken to a Keplr wallet authentication link to check for tokens
-
Users will sign with their Keplr wallet
-
The user's role is elevated and they are added to the secret channel!
Inspiration
The Cosmos ecosystem needs a bot! We thought that it would be fun to make a helpful bot that detects Cosmos ecosystem tokens and NFTs, then promotes users with those tokens or NFTs in their wallets to different roles in Discord. We've already heard feedback from various communities and DAOs building with Cosmos that this would be an extremely helpful (and currently nonexistent) tool!
Starrybot is a project created by me (Amber Case), Anselm Hook and Mike Purvis as a way of getting into the Cosmos ecosystem. We're all part of a little dinner group called Dinner DAO, and after one of our group dinners, we got together to start building it!
I’m interested in DAOs, regenerative ecosystems (currently working on a Juno validator that donates profit to Amber Initiative). I’ve built a number of large-scale projects, including a developer platform and tools eventually used by over 5 million people.
Anselm Hook has created lots of small conferences, like WhereCamp, and has been a hacker on many art projects, community projects and super large projects since he grew up working out of a tiny computer shop run by his dad in Alberta.
Mike Purvis currently works as a dev evangelist at NEAR, but got hooked on the Cosmos ecosystem when I showed him what was being built. He has great energy and enthusiasm for making tools that help emerging ecosystems and people.
You can find out more about the project by visiting the Discord and saying hello: https://discord.gg/MCrnh73EDn
What it does
The project currently has a test website, support for cw20 tokens, and a running bot that can be added to a Discord Server. Next on our roadmap is cw721 support, testing of the user interface, and website updates. After that, we’ll write some basic documentation before testing the bot with the DAO/DAO server. Then we’ll go through a few revisions and bug fixes before unleashing the bot more widely.
DAOs and DAO tooling groups like DAO DAO would like to accept members into their Discords that have specific governance tokens, but there is no solution for the Cosmos ecosystem at this time.
Token-gated bots are helpful for DAOs because they allow Discords to verify DAO members by membership NFTs or tokens
Token gates can help verify trusted members of the community via checking wallets. Discord admins can create levels of membership depending on how specific tokens or number of tokens, giving them more flexibility in their communities.
Collabland is the closest to what’s out there for token-gating, but it does not support the Cosmos ecosystem or follow along with the theme of the Cosmos ecosystem.
How we built it
We have four parts to StarryBot, all deployed to Render:
- Static welcome website, inviting folks to add StarryBot to their Discord server.
- Static verification subdomain website, where folks use Keplr to sign a message that goes to a backend. (https://github.com/starryzone/cosmos-webapp)
- Discord bot + ExpressJS backend. The backend receives the offline signature, verifies it, and uses its access to the Discord token to add roles where needed. (https://github.com/starryzone/starrybot-discord)
- Database — postgresql database with two tables tracking the conditions to add roles to users and members who need to sign custom Carl Sagan jibberish, matching them to their unique session token during verification.
Libraries used from the Cosmos ecosystem:
- @cosmjs/amino
- @cosmjs/crypto
- @cosmjs/encoding
- @cosmjs/stargate
They were great.
Overview
Here is an overview of Starrybot’s two main components: the Keplr offline signing workflow and the Discord bot.
Kepler Signing
The Keplr signing used the browser window’s keplr object and the offline signer available with it.
Unlike similar Discord gating bots, instead of signing a message like “salt0312219” we decided to have each user sign a unique Carl Sagan ipsum phrase.
Once signed, the signature and other items are sent to a backend where the signature is confirmed. After signature confirmation, two RPC endpoints (Juno and Osmosis) are called, checking for native token balances of juno and uosmo. For the purposes of the demonstration of this app, we check for these two native tokens, although cw20 and cw721 are a trivial update.
We also use Bech32 to decode and encode the address so the user can see both balances from their one signed message, which abides by ADR36 to the best of its ability.
Discord bot
The Discord bot utilizes a fairly new system: application commands. These behave like “slash commands” folks may be familiar with in Slack. This feature was announced in March of this year, and changes the way the UX can work for Discord bots. The Discord bot uses the discordjs package to accomplish its objectives. It creates two roles by default:
- osmo-hodler
- juno-hodler
When the Discord bot is first added, an event is fired, creating two rows in a database table. This database table allows StarryBot to scale and be far more customizable than a quick demo might show. Having a database allows StarryBot to behave in an “if-this-than-that” manner, storing token conditions and what role to assign a user. By default, if a user holds JUNO or OSMO, those roles will be applied respectively.
Finally, the Discord bot also ushers the admin through the onboarding experience, showing how to get slash commands working properly. Once set up, the slash command for users is /starry-join. This will reply to their slash command in a private message in that same channel, only visible to them.
Challenges we ran into
After discovering the ADR36 standard, we ran into the issue where at least 1 gas is required to sign using Keplr. (Again, an issue was created in that repo, including a couple of other minor fixes.)
While we were building the Discord bot, a timely thread appeared on Twitter revealing that there are security concerns to a common approach. When a user executed a traditional command (like !join) we would send them a direct message. Note these tweets:
- Security concerns: https://twitter.com/nix_eth/status/1465741803185971201
- Response from CollabLand, a similar Discord bot: https://twitter.com/Collab_Land_/status/1465743609571934209
- General fatigue from Ric Burton about hunting down a direct message on Discord: https://twitter.com/ricburton/status/1465767692342759425
The solution: we decided we needed to pivot to avoid using direct messages. Without getting too much into it, the feature of having a “private message” in a public channel only works with interactions, and it made the most sense to move to using slash commands and abandon traditional commands.
Lastly, while it’s common to add a Discord bot with one authorization step, to use application commands (like /starry-join) there is an additional step needed once the bot is added. It seems that Discord wants to give server admins more granular permissions, even if the bot is granted administrator privileges. After a couple hours of confirming this need, the team had to come up with a workflow and set of instructions when the bot joins. And also a system where the user can confirm they’ve completed the instructions, and if they haven’t, kindly remind them again with a dash of sass. :)
The last challenge was figuring out how to sign an offline message. Simon Warta from Confio had a great draft pull request for signing ADR36 messages, but in the end there was some code using Amino signing and verification that was gleaned from unit test code.
Accomplishments that we're proud of
We used the new Slash commands for Discord, which are much more secure!
We learned a LOT about the Cosmos ecosystem, as well as emerging projects like Stargaze and Juno!
What we learned
We learned that even silly-sounding DAOs like DinnerDAO can lead to amazing hackathon friends.
We learned that given the new updates to Discord, there is an opportunity to strengthen security and invent a brand new workflow that hasn’t been done yet.
We learned that folks from Stargate and Juno are incredibly responsive to questions. We also received replies in GitHub to questions and saw tickets move along. This ecosystem is attentive and roaring. We’re excited to be a part of it!
What's next for Starrybot
For the next step to use cw20 and cw721, we’ll be using logic straight from an example repo Jake Hartnell graciously created. The ability to use cw20 and cw721 tokens for token gating is within arm’s reach.
On the Discord front, we’re learning how to reinvent the UX for onboarding with their new features. We’ll want to make sure the app is able to clean up after itself, and help admins of Discord servers if they run into edges cases. (For instance, if you kick the bot and read it in a certain way, the StarryBot role needs to be dragged up in the settings. See this, this, this, this, and this.)
To truly make an “if-this-than-that” system of token ownership and the roles that should be applied, we’ll want to make it easy for admins to customize these rules. We’ll explore options for more slash commands, as well as an OAuth2 approach. An amazing feature might be to have a settings website that allows Discord admins to log in and modify their database settings using simple modern form submissions.
We already have a few beta testers from a couple of DAO Discords lined up for our token support handling, and we plan to apply for several ecosystem grants to keep this project going. Our vision is to build Starrybot into a core tool for the entire Cosmos ecosystem!
Built With
- adr36
- amino
- api
- bech32
- commands
- cosmos
- discord
- figma
- github
- juno
- keplr
- osmos
- postgresql




Log in or sign up for Devpost to join the conversation.