From 2b387f299afdab3109356c76dc5150734e539e93 Mon Sep 17 00:00:00 2001 From: grant Date: Fri, 8 Aug 2025 15:05:47 -0500 Subject: [PATCH 1/7] starting set work --- src/Classes/ArtIndexerBot.ts | 130 +++++++++++++++++- .../graphql/artbot-hasura-queries.graphql | 22 +++ src/Data/queryGraphQL.ts | 52 +++++++ src/Utils/smartBotResponse.ts | 1 + 4 files changed, 204 insertions(+), 1 deletion(-) diff --git a/src/Classes/ArtIndexerBot.ts b/src/Classes/ArtIndexerBot.ts index 7ee4d0f..198f622 100644 --- a/src/Classes/ArtIndexerBot.ts +++ b/src/Classes/ArtIndexerBot.ts @@ -13,6 +13,8 @@ import { getArtblocksNextUpcomingProject, getEntryByTag, getEntryByVertical, + getAllSets, + getSetByName, } from '../Data/queryGraphQL' import { projectConfig, triviaBot } from '..' import { @@ -55,6 +57,7 @@ export enum MessageTypes { WALLET = 'wallet', RECENT = 'recent', ENTRY = 'entry', + SET = 'set', PLATFORM = 'platform', UPCOMING = 'upcoming', UNKNOWN = 'unknown', @@ -75,6 +78,7 @@ export class ArtIndexerBot { projectsById: { [id: string]: ProjectBot } = {} contracts: { [id: string]: ContractDetailFragment } = {} walletTokens: { [id: string]: TokenDetailFragment[] } = {} + sets: { [id: string]: boolean } = {} initialized = false platforms: { [id: string]: ProjectBot[] } = {} @@ -93,6 +97,7 @@ export class ArtIndexerBot { if (this.projectFetch === getAllProjects) { await this.buildContracts() + await this.buildSets() projectConfig.initializeProjectBots() } setInterval(async () => { @@ -114,6 +119,7 @@ export class ArtIndexerBot { console.log(`projectsById: ${Object.keys(this.projectsById).length}`) console.log(`contracts: ${Object.keys(this.contracts).length}`) console.log(`walletTokens: ${Object.keys(this.walletTokens).length}`) + console.log(`sets: ${Object.keys(this.sets).length}`) console.log(`platforms: ${Object.keys(this.platforms).length}`) console.log(`flagship: ${Object.keys(this.flagship).length}`) } @@ -140,6 +146,22 @@ export class ArtIndexerBot { } } + async buildSets() { + try { + this.sets = {} + const setsArr = await getAllSets() + console.log(`ArtIndexerBot: Building ${setsArr.length} sets`) + for (let i = 0; i < setsArr.length; i++) { + const setName = setsArr[i].name + if (typeof setName === 'string') { + this.sets[setName.toLowerCase()] = true + } + } + } catch (e) { + console.error('Error in buildSets', e) + } + } + async buildProjectBots() { try { this.clearDictionaries() @@ -261,7 +283,7 @@ export class ArtIndexerBot { this.projectsById = {} this.platforms = {} this.flagship = {} - // Don't clear contracts or walletTokens as they are managed separately + // Don't clear contracts, walletTokens, or sets as they are managed separately } // Please update HASHTAG_MESSAGE in smartBotResponse.ts if you add more options here @@ -280,6 +302,8 @@ export class ArtIndexerBot { return MessageTypes.RECENT } else if (messageContent?.startsWith('#entry')) { return MessageTypes.ENTRY + } else if (messageContent?.startsWith('#set')) { + return MessageTypes.SET } else if (key === 'open') { return MessageTypes.OPEN } else if (isVerticalName(key)) { @@ -364,6 +388,18 @@ export class ArtIndexerBot { return } + // Handle #set commands for set collections + if (content.toLowerCase().startsWith('#set')) { + try { + await this.handleSetMessage(msg) + } catch (error) { + msg.channel.send(`Sorry, I had trouble understanding that: ${content}`) + console.error('Error handling #set message', error) + return + } + return + } + let afterTheHash = content .substr(content.indexOf(' ') + 1) .replace('?details', '') @@ -828,4 +864,96 @@ export class ArtIndexerBot { await projectBot?.handleNumberMessage(msg) return } + + /** + * Handle #set commands for set collections + */ + async handleSetMessage(msg: Message) { + if (!msg.channel.isSendable()) { + return + } + + const content = msg.content.trim() + const parts = content.split(' ') + + if (parts.length < 2) { + msg.channel.send( + 'Please specify a set name. Format: `#set [set name]`\n' + + 'Example: `#set Curated`' + ) + return + } + + // Extract the set name (everything after "#set") + const setName = content.substring(4).trim() // Remove "#set" + const setKey = setName.toLowerCase() + + // Check if the set exists and is valid + if (!this.sets[setKey]) { + msg.channel.send( + `Sorry, I wasn't able to find a set named "${setName}". Make sure the set name is spelled correctly.` + ) + return + } + + try { + // Get the set data with all its buckets + const setData = await getSetByName(setName) + + if (!setData || !setData.set_buckets) { + msg.channel.send( + `Sorry, I wasn't able to find data for the set "${setName}".` + ) + return + } + + // Filter out buckets that don't have valid projects with listings + const validBuckets = setData.set_buckets.filter( + (bucket) => + bucket.project && + bucket.project.lowest_listing !== null && + bucket.project.lowest_listing !== undefined && + bucket.project.lowest_listing > 0 + ) + + if (validBuckets.length === 0) { + msg.channel.send( + `Sorry, there are no tokens currently for sale in any projects from the set "${setName}".` + ) + return + } + + // Calculate total entry price + let totalPrice = 0 + const projectDetails: string[] = [] + + for (const bucket of validBuckets) { + if (bucket.project && bucket.project.lowest_listing) { + const price = Number(bucket.project.lowest_listing) + totalPrice += price + projectDetails.push(`${bucket.project.name}: ${price.toFixed(4)} ETH`) + } + } + + // Format the response + const response = [ + `**Set: ${setData.name}**`, + `**Total Entry Price: ${totalPrice.toFixed(4)} ETH**`, + '', + '**Project Breakdown:**', + ...projectDetails, + '', + `*Based on ${validBuckets.length} project${ + validBuckets.length === 1 ? '' : 's' + } with tokens currently for sale*`, + ].join('\n') + + msg.channel.send(response) + } catch (error) { + console.error('Error in handleSetMessage:', error) + msg.channel.send( + `Sorry, there was an error retrieving data for the set "${setName}". Please try again later.` + ) + } + } } diff --git a/src/Data/graphql/artbot-hasura-queries.graphql b/src/Data/graphql/artbot-hasura-queries.graphql index 10716df..8ce469e 100644 --- a/src/Data/graphql/artbot-hasura-queries.graphql +++ b/src/Data/graphql/artbot-hasura-queries.graphql @@ -294,3 +294,25 @@ query GetEntryByVertical($vertical_name: String!, $limit: Int!) { project_id } } + +query GetAllSets { + sets(where: { set_buckets: { project: {} } }) { + name + } +} + +query GetSetByName($set_name: String!) { + sets(where: { name: { _eq: $set_name } }) { + name + set_buckets { + project { + lowest_listing + name + id + project_id + artist_name + contract_address + } + } + } +} diff --git a/src/Data/queryGraphQL.ts b/src/Data/queryGraphQL.ts index 13fa99a..8219e93 100644 --- a/src/Data/queryGraphQL.ts +++ b/src/Data/queryGraphQL.ts @@ -30,6 +30,8 @@ import { LookupUserByAddressDocument, GetEntryByTagDocument, GetEntryByVerticalDocument, + GetAllSetsDocument, + GetSetByNameDocument, } from '../../generated/graphql' import { isArbitrumContract, @@ -654,3 +656,53 @@ export async function getEntryByVertical( return data.projects_metadata } + +export interface SetBucketProject { + __typename?: 'projects_metadata' | undefined + lowest_listing?: any + name?: string | null | undefined + id: string + project_id: string + artist_name?: string | null | undefined + contract_address: string +} + +export interface SetBucket { + __typename?: 'set_buckets' | undefined + project?: SetBucketProject | null | undefined +} + +export interface SetData { + __typename?: 'sets' | undefined + name: string + set_buckets: SetBucket[] +} + +export interface SetListData { + __typename?: 'sets' | undefined + name: string +} + +export async function getAllSets(): Promise { + const { data } = await client.query(GetAllSetsDocument, {}).toPromise() + + if (!data || !data.sets) { + throw Error('No data returned from GetAllSets query') + } + + return data.sets +} + +export async function getSetByName(setName: string): Promise { + const { data } = await client + .query(GetSetByNameDocument, { + set_name: setName, + }) + .toPromise() + + if (!data || !data.sets || data.sets.length === 0) { + return null + } + + return data.sets[0] +} diff --git a/src/Utils/smartBotResponse.ts b/src/Utils/smartBotResponse.ts index 602bf71..690fead 100644 --- a/src/Utils/smartBotResponse.ts +++ b/src/Utils/smartBotResponse.ts @@ -220,6 +220,7 @@ const HASHTAG_MESSAGE = new EmbedBuilder() \`#[token number] [project name]\` = Specific token from project \`#entry [project name]\` = Show entry-level (lowest priced) token from project \`#entry [grouping]\` = Show entry-level price for grouping (e.g. AB500, Curated, Series 1-8, etc) + \`#set [set name]\` = Show total cost to complete a set (sum of lowest listings for all projects in set) \`#explore [project name]\` = Out of bounds sample from upcoming/open project \`#? [artist name]\` = Random token from artist \`#? [vertical]\` = Random token from vertical (e.g. Curated, Explorations, Presents, Engine, Collaborations, etc) From c2216f245c4ed57953daad897dd9bcc2d24ebdf8 Mon Sep 17 00:00:00 2001 From: grant Date: Mon, 11 Aug 2025 10:14:21 -0500 Subject: [PATCH 2/7] saving set names --- src/Classes/ArtIndexerBot.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Classes/ArtIndexerBot.ts b/src/Classes/ArtIndexerBot.ts index 198f622..bb591c4 100644 --- a/src/Classes/ArtIndexerBot.ts +++ b/src/Classes/ArtIndexerBot.ts @@ -78,7 +78,7 @@ export class ArtIndexerBot { projectsById: { [id: string]: ProjectBot } = {} contracts: { [id: string]: ContractDetailFragment } = {} walletTokens: { [id: string]: TokenDetailFragment[] } = {} - sets: { [id: string]: boolean } = {} + sets: { [id: string]: string } = {} initialized = false platforms: { [id: string]: ProjectBot[] } = {} @@ -154,7 +154,8 @@ export class ArtIndexerBot { for (let i = 0; i < setsArr.length; i++) { const setName = setsArr[i].name if (typeof setName === 'string') { - this.sets[setName.toLowerCase()] = true + // Store lowercase key mapping to actual set name for case-insensitive lookup + this.sets[setName.toLowerCase()] = setName } } } catch (e) { @@ -888,8 +889,9 @@ export class ArtIndexerBot { const setName = content.substring(4).trim() // Remove "#set" const setKey = setName.toLowerCase() - // Check if the set exists and is valid - if (!this.sets[setKey]) { + // Check if the set exists and get the correct case + const actualSetName = this.sets[setKey] + if (!actualSetName) { msg.channel.send( `Sorry, I wasn't able to find a set named "${setName}". Make sure the set name is spelled correctly.` ) @@ -897,8 +899,8 @@ export class ArtIndexerBot { } try { - // Get the set data with all its buckets - const setData = await getSetByName(setName) + // Get the set data with all its buckets using the correct case + const setData = await getSetByName(actualSetName) if (!setData || !setData.set_buckets) { msg.channel.send( From 85cae9aca6e40dbb0ae4f1b493d863649c852e12 Mon Sep 17 00:00:00 2001 From: grant Date: Mon, 11 Aug 2025 14:58:00 -0500 Subject: [PATCH 3/7] adding set command --- src/Classes/APIBots/utils.ts | 4 + src/Classes/ArtIndexerBot.ts | 210 +++++++++++++++--- .../graphql/artbot-hasura-queries.graphql | 28 ++- src/Data/queryGraphQL.ts | 16 +- 4 files changed, 209 insertions(+), 49 deletions(-) diff --git a/src/Classes/APIBots/utils.ts b/src/Classes/APIBots/utils.ts index c8442fb..8324005 100644 --- a/src/Classes/APIBots/utils.ts +++ b/src/Classes/APIBots/utils.ts @@ -225,6 +225,10 @@ export function getTokenUrl( return buildArtBlocksTokenURL(contractAddr, tokenId) } +export function getProjectSlugUrl(slug: string): string { + return `https://www.artblocks.io/collection/${slug}` +} + export function getProjectUrl(contractAddr: string, projectId: string): string { return `https://www.artblocks.io/collections/${contractAddr}-${projectId}` } diff --git a/src/Classes/ArtIndexerBot.ts b/src/Classes/ArtIndexerBot.ts index d555919..e8c5ac3 100644 --- a/src/Classes/ArtIndexerBot.ts +++ b/src/Classes/ArtIndexerBot.ts @@ -1,5 +1,5 @@ /* eslint-disable no-case-declarations */ -import { Channel, Collection, Message } from 'discord.js' +import { Channel, Collection, EmbedBuilder, Message } from 'discord.js' import * as dotenv from 'dotenv' import { ProjectBot } from './ProjectBot' @@ -28,8 +28,11 @@ import { getVerticalName, isVerticalName, resolveEnsName, + getProjectUrl, + getProjectSlugUrl, } from './APIBots/utils' import { ProjectConfig } from '../ProjectConfig/projectConfig' +import { randomColor } from '../Utils/smartBotResponse' dotenv.config() const deburr = require('lodash.deburr') @@ -158,6 +161,7 @@ export class ArtIndexerBot { this.sets[setName.toLowerCase()] = setName } } + this.sets['ab500'] = 'Art Blocks 500' } catch (e) { console.error('Error in buildSets', e) } @@ -889,10 +893,26 @@ export class ArtIndexerBot { return } + // Helper function for smart price formatting + const formatPrice = (price: number): string => { + if (price < 0.01) { + // For very small prices, use 5-6 decimals to show meaningful precision + return price < 0.001 ? price.toFixed(6) : price.toFixed(5) + } else if (price >= 10) { + // For larger numbers, trim trailing zeros + const formatted = price.toFixed(4) + return formatted.replace(/\.?0+$/, '') + } else { + // Standard 4 decimals for most cases + return price.toFixed(4) + } + } + // Extract the set name (everything after "#set") const setName = content.substring(4).trim() // Remove "#set" const setKey = setName.toLowerCase() + console.log(this.sets) // Check if the set exists and get the correct case const actualSetName = this.sets[setKey] if (!actualSetName) { @@ -906,6 +926,8 @@ export class ArtIndexerBot { // Get the set data with all its buckets using the correct case const setData = await getSetByName(actualSetName) + console.log(setData) + if (!setData || !setData.set_buckets) { msg.channel.send( `Sorry, I wasn't able to find data for the set "${setName}".` @@ -915,11 +937,7 @@ export class ArtIndexerBot { // Filter out buckets that don't have valid projects with listings const validBuckets = setData.set_buckets.filter( - (bucket) => - bucket.project && - bucket.project.lowest_listing !== null && - bucket.project.lowest_listing !== undefined && - bucket.project.lowest_listing > 0 + (bucket) => bucket.project ) if (validBuckets.length === 0) { @@ -929,32 +947,172 @@ export class ArtIndexerBot { return } - // Calculate total entry price + // Calculate total entry price and collect all prices for statistics let totalPrice = 0 - const projectDetails: string[] = [] + const totalProjects = validBuckets.length + let totalProjectsWithListings = 0 + const projectPrices: { + price: number + name: string + contractAddress: string + projectId: string + slug?: string + }[] = [] + const projectsWithoutListings: { + name: string + contractAddress: string + projectId: string + slug?: string + }[] = [] for (const bucket of validBuckets) { - if (bucket.project && bucket.project.lowest_listing) { - const price = Number(bucket.project.lowest_listing) - totalPrice += price - projectDetails.push(`${bucket.project.name}: ${price.toFixed(4)} ETH`) + if (bucket.project) { + const projectName = bucket.project.name || 'Unknown Project' + const contractAddress = bucket.project.contract_address + const projectId = bucket.project.project_id + const slug = bucket.project.slug + + if (bucket.project.lowest_listing) { + const price = Number(bucket.project.lowest_listing) + totalPrice += price + totalProjectsWithListings++ + projectPrices.push({ + price, + name: projectName, + contractAddress, + projectId, + slug, + }) + } else { + // Project exists but has no listings + projectsWithoutListings.push({ + name: projectName, + contractAddress, + projectId, + slug, + }) + } } } - // Format the response - const response = [ - `**Set: ${setData.name}**`, - `**Total Entry Price: ${totalPrice.toFixed(4)} ETH**`, - '', - '**Project Breakdown:**', - ...projectDetails, - '', - `*Based on ${validBuckets.length} project${ - validBuckets.length === 1 ? '' : 's' - } with tokens currently for sale*`, - ].join('\n') - - msg.channel.send(response) + // Calculate price statistics + let cheapestProject = 0 + let mostExpensiveProject = 0 + let medianProject = 0 + + if (projectPrices.length > 0) { + // Sort prices to find min, max, and median + const sortedProjectPrices = [...projectPrices].sort( + (a, b) => a.price - b.price + ) + + cheapestProject = sortedProjectPrices[0].price + mostExpensiveProject = + sortedProjectPrices[sortedProjectPrices.length - 1].price + + // Calculate median + const prices = sortedProjectPrices.map((p) => p.price) + const midIndex = Math.floor(prices.length / 2) + if (prices.length % 2 === 0) { + // Even number of prices - average of two middle values + medianProject = (prices[midIndex - 1] + prices[midIndex]) / 2 + } else { + // Odd number of prices - middle value + medianProject = prices[midIndex] + } + } + + const embedContent = new EmbedBuilder() + // Set the title of the field. + .setTitle(`${setData.name} Set - Data Snapshot`) + .setDescription( + `Current Price for a **full ${setData.name} Set** is **${formatPrice( + totalPrice + )} ETH**` + ) + // Add link to title. + .setURL(`https://www.artblocks.io/sets/${setData.slug}`) + .setColor(randomColor()) + + embedContent.addFields({ + name: 'Availability', + value: `${totalProjectsWithListings}/${totalProjects} (${( + (totalProjectsWithListings / totalProjects) * + 100 + ).toFixed(2)}%)`, + inline: true, + }) + embedContent.addFields({ + name: 'Median Price', + value: `${formatPrice(medianProject)} Ξ`, + inline: true, + }) + + // Add price range and top 3 lists if we have projects with listings + if (totalProjectsWithListings > 0) { + embedContent.addFields({ + name: 'Range', + value: `${formatPrice(cheapestProject)} Ξ - ${formatPrice( + mostExpensiveProject + )} Ξ`, + inline: true, + }) + + // Generate top 3 cheapest and priciest lists + const sortedProjectPrices = [...projectPrices].sort( + (a, b) => a.price - b.price + ) + + // Top 3 cheapest (already sorted ascending) + const top3Cheapest = sortedProjectPrices.slice(0, 3) + const cheapestText = top3Cheapest + .map((p) => { + const projectUrl = p.slug + ? getProjectSlugUrl(p.slug) + : getProjectUrl(p.contractAddress, p.projectId) + return `— [${p.name}](${projectUrl}) • ${formatPrice(p.price)} Ξ` + }) + .join('\n') + + // Top 3 priciest (reverse order - most expensive first) + const top3Priciest = sortedProjectPrices.slice(-3).reverse() + const priciestText = top3Priciest + .map((p) => { + const projectUrl = p.slug + ? getProjectSlugUrl(p.slug) + : getProjectUrl(p.contractAddress, p.projectId) + return `— [${p.name}](${projectUrl}) • ${formatPrice(p.price)} Ξ` + }) + .join('\n') + + embedContent.addFields({ + name: 'Easiest Entries', + value: cheapestText, + }) + + embedContent.addFields({ + name: 'Steepest Entries', + value: priciestText, + }) + } + + // Add projects without listings if any exist + if (projectsWithoutListings.length > 0) { + const noListingsText = projectsWithoutListings + .map((p) => { + const projectUrl = p.slug + ? getProjectSlugUrl(p.slug) + : getProjectUrl(p.contractAddress, p.projectId) + return `[${p.name}](${projectUrl})` + }) + .join(' • ') + embedContent.addFields({ + name: 'Unavailable (No Current Listings)', + value: noListingsText, + }) + } + + msg.channel.send({ embeds: [embedContent] }) } catch (error) { console.error('Error in handleSetMessage:', error) msg.channel.send( diff --git a/src/Data/graphql/artbot-hasura-queries.graphql b/src/Data/graphql/artbot-hasura-queries.graphql index 8ce469e..ef37577 100644 --- a/src/Data/graphql/artbot-hasura-queries.graphql +++ b/src/Data/graphql/artbot-hasura-queries.graphql @@ -301,18 +301,24 @@ query GetAllSets { } } +fragment SetData on sets { + name + slug + set_buckets { + project { + lowest_listing + slug + name + id + project_id + artist_name + contract_address + } + } +} + query GetSetByName($set_name: String!) { sets(where: { name: { _eq: $set_name } }) { - name - set_buckets { - project { - lowest_listing - name - id - project_id - artist_name - contract_address - } - } + ...SetData } } diff --git a/src/Data/queryGraphQL.ts b/src/Data/queryGraphQL.ts index 9919319..9930d07 100644 --- a/src/Data/queryGraphQL.ts +++ b/src/Data/queryGraphQL.ts @@ -32,6 +32,7 @@ import { GetEntryByVerticalDocument, GetAllSetsDocument, GetSetByNameDocument, + SetDataFragment, } from '../../generated/graphql' import { isArbitrumContract, @@ -666,17 +667,6 @@ export interface SetBucketProject { contract_address: string } -export interface SetBucket { - __typename?: 'set_buckets' | undefined - project?: SetBucketProject | null | undefined -} - -export interface SetData { - __typename?: 'sets' | undefined - name: string - set_buckets: SetBucket[] -} - export interface SetListData { __typename?: 'sets' | undefined name: string @@ -692,7 +682,9 @@ export async function getAllSets(): Promise { return data.sets } -export async function getSetByName(setName: string): Promise { +export async function getSetByName( + setName: string +): Promise { const { data } = await client .query(GetSetByNameDocument, { set_name: setName, From 7590aece993d7888a753bb45a5d696c07f7f174e Mon Sep 17 00:00:00 2001 From: grant Date: Mon, 11 Aug 2025 15:03:33 -0500 Subject: [PATCH 4/7] clean up --- src/Classes/ArtIndexerBot.ts | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/Classes/ArtIndexerBot.ts b/src/Classes/ArtIndexerBot.ts index e8c5ac3..5ea986e 100644 --- a/src/Classes/ArtIndexerBot.ts +++ b/src/Classes/ArtIndexerBot.ts @@ -912,7 +912,6 @@ export class ArtIndexerBot { const setName = content.substring(4).trim() // Remove "#set" const setKey = setName.toLowerCase() - console.log(this.sets) // Check if the set exists and get the correct case const actualSetName = this.sets[setKey] if (!actualSetName) { @@ -926,27 +925,18 @@ export class ArtIndexerBot { // Get the set data with all its buckets using the correct case const setData = await getSetByName(actualSetName) - console.log(setData) - if (!setData || !setData.set_buckets) { msg.channel.send( - `Sorry, I wasn't able to find data for the set "${setName}".` + `Sorry, I had trouble retrieving data for the set "${setName}". Try again later!` ) return } - // Filter out buckets that don't have valid projects with listings + // Filter out buckets that don't have valid projects const validBuckets = setData.set_buckets.filter( (bucket) => bucket.project ) - if (validBuckets.length === 0) { - msg.channel.send( - `Sorry, there are no tokens currently for sale in any projects from the set "${setName}".` - ) - return - } - // Calculate total entry price and collect all prices for statistics let totalPrice = 0 const totalProjects = validBuckets.length @@ -1051,7 +1041,7 @@ export class ArtIndexerBot { // Add price range and top 3 lists if we have projects with listings if (totalProjectsWithListings > 0) { embedContent.addFields({ - name: 'Range', + name: 'Price Range', value: `${formatPrice(cheapestProject)} Ξ - ${formatPrice( mostExpensiveProject )} Ξ`, From b100e5b7400a3aaa75e723292abcd2e6ef9a6116 Mon Sep 17 00:00:00 2001 From: grant Date: Mon, 11 Aug 2025 15:04:15 -0500 Subject: [PATCH 5/7] cleanup --- src/Data/queryGraphQL.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/Data/queryGraphQL.ts b/src/Data/queryGraphQL.ts index 9930d07..0f0e600 100644 --- a/src/Data/queryGraphQL.ts +++ b/src/Data/queryGraphQL.ts @@ -657,16 +657,6 @@ export async function getEntryByVertical( return data.projects_metadata } -export interface SetBucketProject { - __typename?: 'projects_metadata' | undefined - lowest_listing?: any - name?: string | null | undefined - id: string - project_id: string - artist_name?: string | null | undefined - contract_address: string -} - export interface SetListData { __typename?: 'sets' | undefined name: string From 2e614daeaa061c1c971ba7ffd94e3b66c31fe4f1 Mon Sep 17 00:00:00 2001 From: grant Date: Mon, 11 Aug 2025 15:05:50 -0500 Subject: [PATCH 6/7] more cleanup!! --- src/Classes/ArtIndexerBot.ts | 2 +- src/Utils/smartBotResponse.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Classes/ArtIndexerBot.ts b/src/Classes/ArtIndexerBot.ts index 5ea986e..24d83ee 100644 --- a/src/Classes/ArtIndexerBot.ts +++ b/src/Classes/ArtIndexerBot.ts @@ -916,7 +916,7 @@ export class ArtIndexerBot { const actualSetName = this.sets[setKey] if (!actualSetName) { msg.channel.send( - `Sorry, I wasn't able to find a set named "${setName}". Make sure the set name is spelled correctly.` + `Sorry, I wasn't able to find a set named "${setName}". Make sure the set name is spelled correctly. Some examples of valid set names are: \`Curated Series 4\`, \`AB500\`, \`Explorations\`, etc.` ) return } diff --git a/src/Utils/smartBotResponse.ts b/src/Utils/smartBotResponse.ts index 690fead..244ce70 100644 --- a/src/Utils/smartBotResponse.ts +++ b/src/Utils/smartBotResponse.ts @@ -220,7 +220,7 @@ const HASHTAG_MESSAGE = new EmbedBuilder() \`#[token number] [project name]\` = Specific token from project \`#entry [project name]\` = Show entry-level (lowest priced) token from project \`#entry [grouping]\` = Show entry-level price for grouping (e.g. AB500, Curated, Series 1-8, etc) - \`#set [set name]\` = Show total cost to complete a set (sum of lowest listings for all projects in set) + \`#set [set name]\` = Show a data snapshot for a particular set \`#explore [project name]\` = Out of bounds sample from upcoming/open project \`#? [artist name]\` = Random token from artist \`#? [vertical]\` = Random token from vertical (e.g. Curated, Explorations, Presents, Engine, Collaborations, etc) From a6ca3913ef4725786143bea3514e53fe9e1c7061 Mon Sep 17 00:00:00 2001 From: grant Date: Mon, 11 Aug 2025 15:33:53 -0500 Subject: [PATCH 7/7] fixing where --- src/Data/graphql/artbot-hasura-queries.graphql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/graphql/artbot-hasura-queries.graphql b/src/Data/graphql/artbot-hasura-queries.graphql index ef37577..d899fdc 100644 --- a/src/Data/graphql/artbot-hasura-queries.graphql +++ b/src/Data/graphql/artbot-hasura-queries.graphql @@ -296,7 +296,7 @@ query GetEntryByVertical($vertical_name: String!, $limit: Int!) { } query GetAllSets { - sets(where: { set_buckets: { project: {} } }) { + sets(where: { is_public: { _eq: true } }) { name } }