Giter Club home page Giter Club logo

starrybot-discord's People

Contributors

anselm avatar mikedotexe avatar shroysha avatar sudovickili avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

starrybot-discord's Issues

cw721 addition (not from Stargaze Launchpad link) seems to have issue

As reported in the bugs channel in Discord, it sounds like The Strange Clan and Levana have run into and issue with this contract:
juno1uw3pxkga3dxhqs28rjgpgqkvcuedhmc7ezm2yxvvaey9yugfu3fq7ej2wv

Screen Shot 2022-11-07 at 4 40 40 PM

I attempted to follow the normal process, using the button above, and could reproduce it.

TypeError: Cannot read properties of undefined (reading 'getTokenDetails')
    at getTokenDetails (/Users/mikepurvis/ic/starrybot-discord/src/astrolabe/index.js:27:36)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async Object.getConfig (/Users/mikepurvis/ic/starrybot-discord/src/commands/tokenAdd/createTokenRule.js:30:29)
    at async Object.execute (/Users/mikepurvis/ic/starrybot-discord/src/utils/commands.js:46:9)
    at async Wizard.execute (/Users/mikepurvis/ic/starrybot-discord/src/wizardware/wizard.js:76:14)
    at async Wizardware.continue (/Users/mikepurvis/ic/starrybot-discord/src/wizardware/index.js:56:7)
    at async Client.interactionCreate (/Users/mikepurvis/ic/starrybot-discord/src/handlers/interactionCreate.js:46:4)
TypeError: Cannot read properties of undefined (reading 'name')
    at getTokenDetails (/Users/mikepurvis/ic/starrybot-discord/src/astrolabe/index.js:38:62)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async Object.getConfig (/Users/mikepurvis/ic/starrybot-discord/src/commands/tokenAdd/createTokenRule.js:30:29)
    at async Object.execute (/Users/mikepurvis/ic/starrybot-discord/src/utils/commands.js:46:9)
    at async Wizard.execute (/Users/mikepurvis/ic/starrybot-discord/src/wizardware/wizard.js:76:14)
    at async Wizardware.continue (/Users/mikepurvis/ic/starrybot-discord/src/wizardware/index.js:56:7)
    at async Client.interactionCreate (/Users/mikepurvis/ic/starrybot-discord/src/handlers/interactionCreate.js:46:4)

Wizard system

There doesn't seem to be a wizard system in DiscordJS, so we'll need to build a small system that keeps track of a user's progress through a wizard.

ensure TESTNET_ONLY env var is used properly

We've added the env var TESTNET_ONLY but there are a few places where mainnet is checked and then testnet is automatically checked. let's ensure that all places referencing testnet and mainnet follow the rule

clean up config

Right now the config is inside of db.js and it doesn't feel like the right place for it.

Add database migration for column "cosmos_network" to starry_roles table

As StarryBot grows, we'd like to allow cw20 and cw721s from other Cosmos networks, or even different layer 1s. We want to make sure we're connecting to the right RPC, and it'd be best to have a cosmos_network column that could help us connect to the right network and ensure we've Bech32-encoded the wallet address properly.

Add health check path

Add a GET path that just returns 200 so we have have health checks and uptime monitoring

Screen Shot 2022-01-30 at 1 42 24 PM

[Discord] Command to show token » role rules

The epic in #8 covers add new token roles, but admins may want to be reminded of the rules set up.

This ticket is to create a slash command that displays all the rules for this Discord guild. It will be pulling information from the database.

Let's attempt to have this display in a table or something with a leading index. This way we can allow them to refer to particular roles they may want to edit or remove.

Insert seed phrase into Saganism quote

We have a fun way of signing a message, called a Saganism. It's a bunch of random words from Carl Sagan. You can see that here:
https://github.com/starryzone/starrybot-discord/blob/main/src/logic.js#L31

We haven't had any issues, but we'd like to also add in a normal seed phrase here just to ensure it can never be gamed.

So let's insert a seed phrase using near-seed-phrase (https://www.npmjs.com/package/near-seed-phrase) because it's fast and not a huge priority.

You can see how I used this library in the near-crossword repository.

https://github.com/mikedotexe/near-crossword/blob/e078b5e9027cac59cdcdf5a779ca64c6551c63af/src/index.js#L16

(Note that in the crossword I'm actually using using the GitHub URL for dependency. So if you run into problems you can try that. https://github.com/mikedotexe/near-crossword/blob/e078b5e9027cac59cdcdf5a779ca64c6551c63af/package.json#L13)


So when this is complete you should have something like:

Orion's sword dispassionate extraterrestrial observer tingling of the spine network of wormholes prime number a billion trillion? Hearts of the stars vastness is bearable upset loud source damage mountain galaxy approve second census health evidence segment only through love intelligent beings tendrils of gossamer clouds Sea of Tranquility a mote of dust suspended in a sunbeam and billions upon billions upon billions upon billions upon billions upon billions upon billions.

Note that after the word "bearable" we have a 12-word seed phrase and then continue on with the rest of the Saganism.

Strange error when entering random cw20

When entering a non-existent cw20 shown like the screenshot below, I was expecting it to say:

No contract at that address. Probable black hole.

because of this part:

const getTokenDetails = async ({tokenAddress, network}) => {
  console.log('aloha to of getTokenDetails')
  let tokenDetails;
  const tokenType = await getTokenType(tokenAddress);
  try {
    tokenDetails = await tokenType.getTokenDetails({tokenAddress, network});
  } catch (e) {
    // Throw a more specific error message if we can
    if (e.message.includes('decoding bech32 failed')) {
      throw 'Invalid address. Remember: first you copy, then you paste.';
    } else if (e.message.includes('contract: not found')) {
      throw 'No contract at that address. Probable black hole.';
    } else if (e.message.includes('Error parsing into type')) {
      throw 'That is a valid contract, but cosmic perturbations tell us it is not a cw20.';
    } else {
      console.warn(e.stack);
      throw `Error message after trying to query ${tokenType.name}: ${e.message}`;
    }

Screen Shot 2022-04-08 at 2 26 16 PM

Error when entering random string instead of NFT token

It seems that this bug is specific to #84
See this workflow:

Screen Shot 2022-04-08 at 12 48 47 PM

TypeError: this.error is not a function
    at Wizard.execute (/Users/mike/Documents/starrybot-discord/src/wizardware/wizard.js:36:19)
    at Wizardware.continue (/Users/mike/Documents/starrybot-discord/src/wizardware/index.js:46:18)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async Client.messageCreate (/Users/mike/Documents/starrybot-discord/src/handlers/messageCreate.js:6:2)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Ensure all messages are ephemeral

When you try to do /starry token-rule edit you see:

No roles exist to edit!

Which is not ephemeral. Might be good to make ephemeral

[Discord] Add slash command to remove bot

We'll want to eventually have a better workflow than simply "kicking" StarryBot. We'd like to be able to cleanup anything we've done.

For instance, at the time of this writing, we automatically create the roles osmo-hodler and juno-hodler when the Discord bot is added. We have no opportunity to remove these roles and "clean up our campsite" when we kick the bot.

It would be advisable to have a slash command like /starry-uninstall or something cuter that could clean up database data, roles, etc.

[Discord] Figure out emoji responses

We'll want to have emoji responses be a common interactions, let's begin playing with this and have code that works for us.

See the uses cases in the epic here:
#8

Investigate error

I saw this in the logs:

Oct 16 09:36:49 AM  Comparing 3 against 10
Oct 16 09:41:14 AM  node:events:505
Oct 16 09:41:14 AM        throw er; // Unhandled 'error' event
Oct 16 09:41:14 AM        ^
Oct 16 09:41:14 AM  
Oct 16 09:41:14 AM  DiscordAPIError[50035]: Invalid Form Body
Oct 16 09:41:14 AM  name[BASE_TYPE_REQUIRED]: This field is required
Oct 16 09:41:14 AM      at SequentialHandler.runRequest (/opt/render/project/src/node_modules/discord.js/node_modules/@discordjs/rest/dist/index.js:743:15)
Oct 16 09:41:14 AM      at processTicksAndRejections (node:internal/process/task_queues:96:5)
Oct 16 09:41:14 AM      at async SequentialHandler.queueRequest (/opt/render/project/src/node_modules/discord.js/node_modules/@discordjs/rest/dist/index.js:549:14)
Oct 16 09:41:14 AM      at async REST.request (/opt/render/project/src/node_modules/discord.js/node_modules/@discordjs/rest/dist/index.js:988:22)
Oct 16 09:41:14 AM      at async GuildChannelManager.create (/opt/render/project/src/node_modules/discord.js/src/managers/GuildChannelManager.js:149:18)
Oct 16 09:41:14 AM      at async Client.guildCreate (/opt/render/project/src/src/handlers/guildCreate.js:42:27)
Oct 16 09:41:14 AM  Emitted 'error' event on Client instance at:
Oct 16 09:41:14 AM      at emitUnhandledRejectionOrErr (node:events:384:10)
Oct 16 09:41:14 AM      at processTicksAndRejections (node:internal/process/task_queues:85:21) {
Oct 16 09:41:14 AM    requestBody: {
Oct 16 09:41:14 AM      files: undefined,
Oct 16 09:41:14 AM      json: {
Oct 16 09:41:14 AM        name: undefined,
Oct 16 09:41:14 AM        topic: undefined,
Oct 16 09:41:14 AM        type: undefined,
Oct 16 09:41:14 AM        nsfw: undefined,
Oct 16 09:41:14 AM        bitrate: undefined,
Oct 16 09:41:14 AM        user_limit: undefined,
Oct 16 09:41:14 AM        parent_id: undefined,
Oct 16 09:41:14 AM        position: undefined,
Oct 16 09:41:14 AM        permission_overwrites: undefined,
Oct 16 09:41:14 AM        rate_limit_per_user: undefined,
Oct 16 09:41:14 AM        rtc_region: undefined,
Oct 16 09:41:14 AM        video_quality_mode: undefined,
Oct 16 09:41:14 AM        available_tags: undefined,
Oct 16 09:41:14 AM        default_reaction_emoji: undefined
Oct 16 09:41:14 AM      }
Oct 16 09:41:14 AM    },
Oct 16 09:41:14 AM    rawError: {
Oct 16 09:41:14 AM      code: 50035,
Oct 16 09:41:14 AM      errors: {
Oct 16 09:41:14 AM        name: {
Oct 16 09:41:14 AM          _errors: [
Oct 16 09:41:14 AM            {
Oct 16 09:41:14 AM              code: 'BASE_TYPE_REQUIRED',
Oct 16 09:41:14 AM              message: 'This field is required'
Oct 16 09:41:14 AM            }
Oct 16 09:41:14 AM          ]
Oct 16 09:41:14 AM        }
Oct 16 09:41:14 AM      },
Oct 16 09:41:14 AM      message: 'Invalid Form Body'
Oct 16 09:41:14 AM    },
Oct 16 09:41:14 AM    code: 50035,
Oct 16 09:41:14 AM    status: 400,
Oct 16 09:41:14 AM    method: 'POST',
Oct 16 09:41:14 AM    url: 'https://discord.com/api/v10/guilds/950805706142015538/channels'
Oct 16 09:41:14 AM  }

So it looks like the "name" field is required.

const creationRes = await guild.channels.create('starrybot')

I don't think we even need to create a channel, do we? Feels like we can remove this.

Add local database guide to the README or docs

Let's move away from developing using the production database and instead use a local postgres instance.
Let's add a guide on how to do this properly for current and future developers.

Stargaze flow: allow for non-launchpad URLs

The Stargaze site has grown and changed a lot! Early on it was easy to go to the launchpad and click on a collection's image to give a url like:
https://app.stargaze.zone/launchpad/stars1lndsj2gufd292c35crv97ug2ncdcn9ys4s8e94wlxyeft6mt3k2svkwps9

Now there is a marketplace and a few different routes that people may find easier to use, given that there are so many great projects launching.

For instance, you can go to the Stargaze Marketplace, click on Bad Kids, and navigate your way to a page like this:
https://www.stargaze.zone/marketplace/stars19jq6mj84cnt9p7sagjxqf8hxtczwc8wlpuwe4sh62w45aheseues57n420

Currently starrybot is looking for a different path, like the first link above.

This shouldn't be hard, and it'll likely be a change in stargaze.js

If you were to try to paste the second link instead, it'll give you a not-great error:

Screen Shot 2022-09-30 at 2 06 51 PM

So the task is to make sure we can handle whatever is the most convenient link for end users, which is no longer the Launchpad link.

[Discord] Remove starry-join global application command

We are replacing the starry-join with starry join the subcommand.

We (probably) need to remove it on the application level.

The way we added that was using this code:

const starryJoin = new SlashCommandBuilder()
  .setName('starry-join')
  .setDescription('Connect your account with Keplr');
const rest = new REST().setToken(process.env.DISCORD_TOKEN);
await rest.put(
  Routes.applicationCommands(client.application.id),
  { body: [starryJoin.toJSON()] },
);

So we'll want to find the opposite

Track down crash

The server did a quick crash-and-restart, resuming normal operation, but I've captured the log here:

Nov 8 08:04:37 AM  { guildId: '950805706142015538', authorId: 'redacted' }
Nov 8 08:04:37 AM  DiscordAPIError[10062]: Unknown interaction
Nov 8 08:04:37 AM      at SequentialHandler.runRequest (/opt/render/project/src/node_modules/discord.js/node_modules/@discordjs/rest/dist/index.js:743:15)
Nov 8 08:04:37 AM      at runMicrotasks (<anonymous>)
Nov 8 08:04:37 AM      at processTicksAndRejections (node:internal/process/task_queues:96:5)
Nov 8 08:04:37 AM      at async SequentialHandler.queueRequest (/opt/render/project/src/node_modules/discord.js/node_modules/@discordjs/rest/dist/index.js:549:14)
Nov 8 08:04:37 AM      at async REST.request (/opt/render/project/src/node_modules/discord.js/node_modules/@discordjs/rest/dist/index.js:988:22)
Nov 8 08:04:37 AM      at async ChatInputCommandInteraction.reply (/opt/render/project/src/node_modules/discord.js/src/structures/interfaces/InteractionResponses.js:111:5)
Nov 8 08:04:37 AM      at async Object.execute (/opt/render/project/src/src/utils/commands.js:236:9)
Nov 8 08:04:37 AM      at async Wizard.execute (/opt/render/project/src/src/wizardware/wizard.js:76:14)
Nov 8 08:04:37 AM      at async Wizardware.initiate (/opt/render/project/src/src/wizardware/index.js:31:5)
Nov 8 08:04:37 AM      at async Object.execute (/opt/render/project/src/src/commands/index.js:59:9) {
Nov 8 08:04:37 AM    requestBody: { files: [], json: { type: 4, data: [Object] } },
Nov 8 08:04:37 AM    rawError: { message: 'Unknown interaction', code: 10062 },
Nov 8 08:04:37 AM    code: 10062,
Nov 8 08:04:37 AM    status: 404,
Nov 8 08:04:37 AM    method: 'POST',
Nov 8 08:04:37 AM    url: 'redacted'
Nov 8 08:04:37 AM  }
Nov 8 08:04:37 AM  node:events:505
Nov 8 08:04:37 AM        throw er; // Unhandled 'error' event
Nov 8 08:04:37 AM        ^
Nov 8 08:04:37 AM  
Nov 8 08:04:37 AM  DiscordAPIError[10062]: Unknown interaction
Nov 8 08:04:37 AM      at SequentialHandler.runRequest (/opt/render/project/src/node_modules/discord.js/node_modules/@discordjs/rest/dist/index.js:743:15)
Nov 8 08:04:37 AM      at runMicrotasks (<anonymous>)
Nov 8 08:04:37 AM      at processTicksAndRejections (node:internal/process/task_queues:96:5)
Nov 8 08:04:37 AM      at async SequentialHandler.queueRequest (/opt/render/project/src/node_modules/discord.js/node_modules/@discordjs/rest/dist/index.js:549:14)
Nov 8 08:04:37 AM      at async REST.request (/opt/render/project/src/node_modules/discord.js/node_modules/@discordjs/rest/dist/index.js:988:22)
Nov 8 08:04:37 AM      at async ChatInputCommandInteraction.reply (/opt/render/project/src/node_modules/discord.js/src/structures/interfaces/InteractionResponses.js:111:5)
Nov 8 08:04:37 AM      at async handleGuildCommands (/opt/render/project/src/src/handlers/interactionCreate.js:20:3)
Nov 8 08:04:37 AM  Emitted 'error' event on Client instance at:
Nov 8 08:04:37 AM      at emitUnhandledRejectionOrErr (node:events:384:10)
Nov 8 08:04:37 AM      at processTicksAndRejections (node:internal/process/task_queues:85:21) {
Nov 8 08:04:37 AM    requestBody: {
Nov 8 08:04:37 AM      files: [],
Nov 8 08:04:37 AM      json: {
Nov 8 08:04:37 AM        type: 4,
Nov 8 08:04:37 AM        data: {
Nov 8 08:04:37 AM          content: 'There was an error while executing this command!',
Nov 8 08:04:37 AM          tts: false,
Nov 8 08:04:37 AM          nonce: undefined,
Nov 8 08:04:37 AM          embeds: undefined,
Nov 8 08:04:37 AM          components: undefined,
Nov 8 08:04:37 AM          username: undefined,
Nov 8 08:04:37 AM          avatar_url: undefined,
Nov 8 08:04:37 AM          allowed_mentions: undefined,
Nov 8 08:04:37 AM          flags: 64,
Nov 8 08:04:37 AM          message_reference: undefined,
Nov 8 08:04:37 AM          attachments: undefined,
Nov 8 08:04:37 AM          sticker_ids: undefined,
Nov 8 08:04:37 AM          thread_name: undefined
Nov 8 08:04:37 AM        }
Nov 8 08:04:37 AM      }
Nov 8 08:04:37 AM    },
Nov 8 08:04:37 AM    rawError: { message: 'Unknown interaction', code: 10062 },
Nov 8 08:04:37 AM    code: 10062,
Nov 8 08:04:37 AM    status: 404,
Nov 8 08:04:37 AM    method: 'POST',
Nov 8 08:04:37 AM    url: 'redacted'
Nov 8 08:04:37 AM  }

Improved checks for cosmos addresses

When we lookup a user's cosmos wallet address to update their roles, we currently try to find any wallet address that gets used, in descending order of address. There are a few edgecases here:

  • If a user has never re-joined since we started storing the wallet address, this will fail to find a wallet address
  • If a user is using multiple cosmos wallets, this may find the wrong address
  • If a user has a new cosmos wallet address, this may find the wrong address

We identified a handful of possible fixes to the DB implementation if any of these are an issue:

  1. The getCosmosHubAddressFromDiscordId should also filter on the discord guild ID. In other words, we should allow users to associate one wallet per discord guild that they're joining from
  2. The function should lookup the most recently used wallet address for this user + guild combination via the created_at column, so that we may use the one most likely to be up-to-date
  3. If still no wallet is found, we should have some prompting for the guild admin to ask that user to rejoin

[EPIC] UX Flow

Here are some screenshots Amber made. We can be linking issues to this and consider this ticket the epic:

image

image

image

[Discord] Bot creates channel where settings are done

Since we cannot have emoji responses and are perhaps limited in other ways we'd like to have a wizard, let's have the bot create a channel like starry-settings where admins can use Application Commands (slash commands) without feeling like they're spamming a pubic channel.

Perhaps if an admin allowed to call /starry token-rule add calls it in the public channel, it can reply with an ephemeral (private) message giving a link to this channel. (Or even creating the channel at that moment and then linking to it) saying, "hey buddy, let's keep this channel clean and talk about this over at #starry-discord"

Update the README

This project's README is outdated. For instance, we're using Render instead of cloudflare and aren't using Winston. You also need to add the environment variable before running, for instance:

env DISCORD_TOKEN=O…4 yarn start

We'll want to update this

Add decimals for cw20s

I think we'll need to add decimals column to the rolesSet function in db.js?
For when the cw20 flow gives us tokenInfo that includes the key decimals

related to #68

Sometimes guild.systemChannelId comes back empty

This must be a Discord API problem, as I've run the same code twice and seen the Discord API endpoint fail (with 404) and then succeed.

aloha systemChannelId undefined
starrybot has star(ry)ted.
/Users/mike/Documents/starrybot-discord/node_modules/discord.js/src/rest/RequestHandler.js:349
      throw new DiscordAPIError(data, res.status, request);
            ^

DiscordAPIError: 404: Not Found
    at RequestHandler.execute (/Users/mike/Documents/starrybot-discord/node_modules/discord.js/src/rest/RequestHandler.js:349:13)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async RequestHandler.push (/Users/mike/Documents/starrybot-discord/node_modules/discord.js/src/rest/RequestHandler.js:50:14)
    at async ChannelManager.fetch (/Users/mike/Documents/starrybot-discord/node_modules/discord.js/src/managers/ChannelManager.js:114:18)
    at async login (/Users/mike/Documents/starrybot-discord/src/discord.js:61:17) {
  method: 'get',
  path: '/channels',
  code: 0,
  httpStatus: 404,
  requestData: { json: undefined, files: [] }
}

So anything using guild.systemChannelId needs to be in a try/catch or else look for weirdness of it coming back undefined sometimes.

Allow cw20 tokens to come from testnet

Similar to how we've got the Juno mainnet RPC endpoint here:
b873e85#diff-84cc21cba563e383127fa07f1be91efe212854c08719961c4095fff4a9f262c0R19
^ Actually, we should probably be clear that this is the testnet endoint

we can also have the testnet RPC endpoint as a constant somewhere. That endpoint is:
https://rpc.uni.juno.deuslabs.fi

A Juno mainnet endpoint we can use is:
https://rpc-juno.nodes.guru

Acceptance criteria for this ticket to close is when we have both endpoints as constants and there's a UX interaction such that when a user enters their cw20 token, we first look for it on mainnet. If it isn't there (we've probably used a try/catch) we'll see if it's on testnet. If it is on testnet, we'll want to have a confirmation button for the user confirming this, and make sure there's a database flag indicating we're using testnet.

Add Corde test framework

This doesn't seem quite as relevant as we had hoped, but would be great to try out this testing framework:
https://cordejs.org/docs/expect

Other thoughts during our discussion would be to set up an instance of a bot on a shared server that auto-deploys on some branch like dev or staging and then we could have CI run these tests against that.

[Discord] Allow admin to remove a token rule

This ticket should be done after #12

Allow an admin to remove a token rule from the database. They would likely indicate by "row number" from the table we're displaying from the linked ticket above.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.