# Validator-gated Linked Roles in Discord ## Context The Solana Tech Discord would like to be able to gate certain roles (and thus channels) to people and teams that verifiably operate `testnet` and `mainnet-beta` validators. By using Discord's "linked roles": - Prompts to verify gossip identity keypairs can happen directly within the Discord interface - Linked roles provide additional badging within the Discord interface, helping support trust & safety within the server - After linking a wallet, roles can automatically be provided and revoked by Discord itself ## Constraints - Verification of gossip identity keypair should happen entirely within the CLI - (stretch) One keypair may be used for more than on Discord user - Re-evaluation of delinquency should happen once per-epoch ## Implementation ### Role Metadata Linked roles require the declaration of "[metadata](https://discord.com/developers/docs/resources/application-role-connection-metadata#application-role-connection-metadata)" which server admins can then use to parameterize access to roles. Three initial parameters will be set: 1. **Testnet** (Boolean): Whether or not this keypair operates a validator on `testnet` 2. **Mainnet-beta** (Boolean): Whether or not this keypair operates a validator on `mainnet-beta` 3. **Active within last epoch (Testnet)** (Boolean): True if validator has voted within the last epoch on `testnet` 4. **Active within last epoch (mainnet-beta)** (Boolean): True if validator has voted within the last epoch on `testnet` 5. (suggested): **RPC Operator** (Boolean): Whether this person operates an RPC 6. (suggested) **Stake weight** (Number): A proxy of stake weight for visual distinction ## User Flow 1. Click on the relevant role in Discord that one is attempting to qualify for [^1] 2. This will go straight to a Discord OAuth authorization flow[^2] using the [Authorization Code Grant](https://discord.com/developers/docs/topics/oauth2#authorization-code-grant) scheme 3. A successful authorization redirects to a page hosted on [Realms](https://realms.today/) with the following instructions: 1. Send a `cURL` command to `GET realms.today/api/verify-gossip-keypair/:public-key` to receive a timebound "challenge" payload to be signed and verified. The challenge payload adheres to the [Off-chain Message Signing specification](https://docs.solana.com/cli/sign-offchain-message#verify-off-chain-message-signature) 2. Sign the payload using the gossip keypair using the Solana CLI's [sign-offchain-message](https://docs.solana.com/cli/sign-offchain-message#sign-off-chain-message) command 3. `POST` the signed payload to `realms.today/api/verify-gossip-keypair/:public-key/:discord-authorization-code` 4. (stretch) `POST` a signed payload to `realms.today/api/verify-additional-keypair/:public-key/:discord-authorization-code` to verify multiple validator nodes and aggregate roles 5. (stretch) `POST` a signed payload to `realms.today/api/vouch/:public-key/:rpc-public-key` to vouch for another keypair (used for RPC operators) 4. Payload will be verified by the Realms API, and calculated metadata values will be uploaded to Discord - [ ] Do we need to verify custody of a stake account with some minimum threshold? 5. Any roles that the user qualifies for will automatically be provided, and the user can safely return to Discord Upon the completion of an epoch, stored OAuth2 refresh tokens will be used to generate new access tokens that will update the relevant metadata for the stored gossip keypairs. These metadata changes will automatically provide / revoke associated roles in Discord. [^1]: ![](https://i.imgur.com/e68awHd.png) [^2]: ![](https://i.imgur.com/P7vjl2T.png)