From 5f2df25409b8cafc2836c28577ec7e7e64aa3091 Mon Sep 17 00:00:00 2001 From: grant Date: Tue, 3 Dec 2024 15:11:59 -0600 Subject: [PATCH] removing old AB marketplace stuff --- package.json | 2 +- src/Classes/ProjectBot.ts | 38 ++++++++-- .../graphql/artbot-hasura-queries.graphql | 2 - src/index.ts | 75 ++++++++++--------- yarn.lock | 10 +-- 5 files changed, 79 insertions(+), 48 deletions(-) diff --git a/package.json b/package.json index f6caf99..da02fe8 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "@graphql-codegen/typescript-urql": "^3.7.3", "@graphql-codegen/urql-introspection": "^2.2.1", "@graphql-tools/utils": "^8.3.0", - "@reservoir0x/reservoir-sdk": "^2.4.11", + "@reservoir0x/reservoir-sdk": "^2.4.32", "@supabase/supabase-js": "^2.29.0", "@types/node": "20.1.2", "@types/node-cron": "^3.0.8", diff --git a/src/Classes/ProjectBot.ts b/src/Classes/ProjectBot.ts index 5954246..a62c4d6 100644 --- a/src/Classes/ProjectBot.ts +++ b/src/Classes/ProjectBot.ts @@ -29,9 +29,13 @@ import { ProjectConfig } from '../ProjectConfig/projectConfig' import { ProjectHandlerHelper } from './ProjectHandlerHelper' import { UpcomingProjectDetailFragment } from '../../generated/graphql' import { getDayName, getMonthName, getDayOfMonth } from '../Utils/common' +import { paths } from '@reservoir0x/reservoir-sdk' const ONE_MILLION = 1e6 +type ReservoirTokenResponse = + paths['/tokens/v7']['get']['responses']['200']['schema'] + /** * Bot for handling projects */ @@ -327,13 +331,35 @@ export class ProjectBot { inline: true, }) - if (tokenMetadata.list_price && !tokenMetadata.is_flagged) { - embedContent.addFields({ - name: 'Buy Now', - value: `[${tokenMetadata.list_price} ${ - tokenMetadata.list_currency_symbol - } on Art Blocks Marketplace](${tokenUrl + PROJECTBOT_BUY_UTM})`, + try { + const response = await axios.request({ + method: 'GET', + url: `https://api.reservoir.tools/tokens/v7?tokens=${this.coreContract}%3A${tokenID}`, + headers: { accept: '*/*', 'x-api-key': process.env.RESERVOIR_API_KEY }, + timeout: 3000, }) + + if ( + response.data && + response.data.tokens && + response.data.tokens.length > 0 + ) { + const price = + response.data.tokens[0].market?.floorAsk?.price?.amount?.native + const symbol = + response.data.tokens[0].market?.floorAsk?.price?.currency?.symbol + + if (price && symbol) { + embedContent.addFields({ + name: 'Buy Now', + value: `[${price} ${symbol} on Art Blocks Marketplace](${ + tokenUrl + PROJECTBOT_BUY_UTM + })`, + }) + } + } + } catch (e) { + console.error('Error getting price info for token:', tokenID, e) } msg.channel.send({ embeds: [embedContent] }) } diff --git a/src/Data/graphql/artbot-hasura-queries.graphql b/src/Data/graphql/artbot-hasura-queries.graphql index 807e963..dc2e3db 100644 --- a/src/Data/graphql/artbot-hasura-queries.graphql +++ b/src/Data/graphql/artbot-hasura-queries.graphql @@ -36,8 +36,6 @@ fragment TokenDetail on tokens_metadata { } preview_asset_url live_view_url - list_currency_symbol - list_price owner { public_address } diff --git a/src/index.ts b/src/index.ts index 8be8168..a154710 100644 --- a/src/index.ts +++ b/src/index.ts @@ -28,6 +28,8 @@ import { } from './Classes/APIBots/utils' import { ScheduleBot } from './Classes/SchedulerBot' import { verifyTwitter } from './Utils/twitterUtils' +import axios from 'axios' +import { paths } from '@reservoir0x/reservoir-sdk' const smartBotResponse = require('./Utils/smartBotResponse').smartBotResponse @@ -243,43 +245,40 @@ const initReservoirBots = async () => { const studioContracts = await waitForStudioContracts() const engineContracts = await waitForEngineContracts() - const buildContractsString = (contracts: string[]): string => { - const ans = 'contracts=' + contracts.join('&contracts=') - return ans - } - - const createReservoirBots = ( - listParams: string, - saleParams: string, - pollTimeMs: number - ) => { - new ReservoirListBot( - `https://api.reservoir.tools/orders/asks/v5?${listParams}&sortBy=createdAt&limit=${reservoirListLimit}&normalizeRoyalties=true`, - pollTimeMs, - bot, - { - Accept: 'application/json', - 'x-api-key': process.env.RESERVOIR_API_KEY, - } - ) - - new ReservoirSaleBot( - `https://api.reservoir.tools/sales/v4?${saleParams}&limit=${reservoirSaleLimit}`, - pollTimeMs, - bot, - { - Accept: 'application/json', - 'x-api-key': process.env.RESERVOIR_API_KEY, - } - ) - } - const allContracts = Object.values(CORE_CONTRACTS) .concat(Object.values(COLLAB_CONTRACTS)) .concat(Object.values(EXPLORATIONS_CONTRACTS)) .concat(studioContracts ?? []) .concat(engineContracts ?? []) + type ReservoirContractSetResponse = + paths['/contracts-sets/v1']['post']['responses']['200']['schema'] + + const response = await axios.request({ + method: 'POST', + url: 'https://api.reservoir.tools/contracts-sets/v1', + headers: { + accept: '*/*', + 'content-type': 'application/json', + 'x-api-key': process.env.RESERVOIR_API_KEY, + }, + data: { contracts: allContracts }, + }) + + const contractSetID = response.data.contractsSetId + + // List endpoint lets you use contractSet param which is very nice + new ReservoirListBot( + `https://api.reservoir.tools/orders/asks/v5?contractsSetId=${contractSetID}&sortBy=createdAt&limit=${reservoirListLimit}&normalizeRoyalties=true`, + API_POLL_TIME_MS, + bot, + { + Accept: 'application/json', + 'x-api-key': process.env.RESERVOIR_API_KEY, + } + ) + + // Sadly sales endpoint does not support contractSet param yet - need to batch by 20 contracts const RESERVOIR_CONTRACT_LIMIT = 20 const numBotInstances = Math.ceil( allContracts.length / RESERVOIR_CONTRACT_LIMIT @@ -287,10 +286,18 @@ const initReservoirBots = async () => { for (let i = 0; i < numBotInstances; i++) { const start = i * RESERVOIR_CONTRACT_LIMIT const end = start + RESERVOIR_CONTRACT_LIMIT - const listParams = buildContractsString(allContracts.slice(start, end)) - const saleParams = listParams.replaceAll('contracts', 'contract') + const saleParams = + 'contract=' + allContracts.slice(start, end).join('&contract=') - createReservoirBots(listParams, saleParams, API_POLL_TIME_MS + i * 3000) + new ReservoirSaleBot( + `https://api.reservoir.tools/sales/v4?${saleParams}&limit=${reservoirSaleLimit}`, + API_POLL_TIME_MS + i * 3000, + bot, + { + Accept: 'application/json', + 'x-api-key': process.env.RESERVOIR_API_KEY, + } + ) } } diff --git a/yarn.lock b/yarn.lock index e230160..2b56c09 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2619,14 +2619,14 @@ __metadata: languageName: node linkType: hard -"@reservoir0x/reservoir-sdk@npm:^2.4.11": - version: 2.4.11 - resolution: "@reservoir0x/reservoir-sdk@npm:2.4.11" +"@reservoir0x/reservoir-sdk@npm:^2.4.32": + version: 2.4.32 + resolution: "@reservoir0x/reservoir-sdk@npm:2.4.32" dependencies: axios: "npm:^1.6.7" peerDependencies: viem: ~2.17.4 - checksum: 10c0/0b90356a47b66ae31c6976616d5511249f6f859678b8a737fa9de3e05c7a0bc072da40b80b3451faac0cd3a1464d1830125a0464eaccc4b197e3f8bbe4f43de3 + checksum: 10c0/c383bc4d431fb96426f4704a645bb289c27f4da3b99ef791173586f216bb014d853ec7b8a21e075a3981ee3a60f71c538f258f93603b232a6df9fc382cf0678c languageName: node linkType: hard @@ -3630,7 +3630,7 @@ __metadata: "@graphql-codegen/typescript-urql": "npm:^3.7.3" "@graphql-codegen/urql-introspection": "npm:^2.2.1" "@graphql-tools/utils": "npm:^8.3.0" - "@reservoir0x/reservoir-sdk": "npm:^2.4.11" + "@reservoir0x/reservoir-sdk": "npm:^2.4.32" "@supabase/supabase-js": "npm:^2.29.0" "@types/node": "npm:20.1.2" "@types/node-cron": "npm:^3.0.8"