From a73f98cd24b92b8eeab3679655ed252977969891 Mon Sep 17 00:00:00 2001 From: lza_menace Date: Thu, 26 Dec 2024 00:08:35 -0800 Subject: [PATCH] replace alchemy with moralis --- bun.lockb | Bin 106788 -> 119560 bytes package.json | 4 +- src/index.js | 100 +++++++++++++++++++++++--------------------------- src/server.js | 2 +- 4 files changed, 49 insertions(+), 57 deletions(-) diff --git a/bun.lockb b/bun.lockb index 177ff5b2d44af002e8c9478257112b15ecf7ee35..fb984243d9030d6cf65cac4334bcabe846240ca8 100755 GIT binary patch delta 29589 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 diff --git a/package.json b/package.json index dbc28f6..4a533d1 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "dependencies": { - "alchemy-sdk": "^3.5.0", "better-sqlite3": "^11.7.0", "ethers": "^6.13.4", "express": "^4.21.2", + "moralis": "^2.27.2", "sqlite3": "^5.1.7" }, - "name": "alchemy-nft-scraper", + "name": "nft-sales-scraper", "module": "index.ts", "devDependencies": { "@types/bun": "latest" diff --git a/src/index.js b/src/index.js index e214784..38eef26 100644 --- a/src/index.js +++ b/src/index.js @@ -1,18 +1,15 @@ const ALL_CONTRACTS = require('./contracts'); -const { Alchemy, Network } = require("alchemy-sdk"); +import Moralis from 'moralis'; const { Database } = require('sqlite3'); const fs = require('fs'); const db = new Database('./state/sqlite.db'); const config = { - apiKey: process.env.ALCHEMY_KEY, - network: Network.ETH_MAINNET, + apiKey: process.env.MORALIS_KEY }; -const alchemy = new Alchemy(config); - async function sleep(sec) { return new Promise((resolve) => setTimeout(resolve, Number(sec) * 1000)); @@ -34,7 +31,7 @@ class Scrape { this.lastFile = `./state/${this.contractName}.txt`; } - getpageKey() { + getCursor() { if (fs.existsSync(this.lastFile)) { return fs.readFileSync(this.lastFile).toString(); } else { @@ -44,57 +41,56 @@ class Scrape { } async scrape() { - const pageKey = this.getpageKey() - if (pageKey === '') { - console.log('no page key') + const cursor = this.getCursor() + if (cursor === '') { + console.log(`no cursor for ${this.contractName}. skipping`) return } - console.log(`[+] Scraping ${this.contractName} with pageKey ${pageKey}`) - const response = await alchemy.nft.getNftSales({ + console.log(`[+] Scraping ${this.contractName}`); + const response = await Moralis.EvmApi.nft.getNFTTrades({ + chain: '0x1', + marketplace: 'opensea', fromBlock: this.startBlock, - contractAddress: this.contractAddress, + address: this.contractAddress, limit: process.env.LIMIT, - order: 'asc', - pageKey: pageKey + cursor: cursor }); - fs.writeFileSync(this.lastFile, response.pageKey || '') + fs.writeFileSync(this.lastFile, response.json.cursor || '') - response.nftSales.map(async (sale) => { - const rowExists = await new Promise((resolve) => { - db.get('SELECT * FROM events WHERE tx_hash = ? AND log_index = ?', [sale.transactionHash, sale.logIndex], (err, row) => { - if (err) { resolve(false); } - resolve(row !== undefined); + response.json.result.map(async (sale) => { + sale.token_ids.map(async (tokenId) => { + const rowExists = await new Promise((resolve) => { + db.get('SELECT * FROM events WHERE tx_hash = ? AND token_id = ?', [sale.transaction_hash, tokenId], (err, row) => { + if (err) { resolve(false); } + resolve(row !== undefined); + }); }); - }); - if (!rowExists) { - try { - db.run(` - INSERT INTO events VALUES ( - "${this.contractAddress}", - "${sale.buyerAddress}", - "${sale.sellerAddress}", - "${sale.taker}", - "${sale.tokenId}", - "${sale.sellerFee.amount}", - "${sale.protocolFee.amount}", - "${sale.royaltyFee.amount}", - "", - "${sale.transactionHash}", - "${sale.blockNumber}", - "${sale.logIndex}", - "${sale.bundleIndex}", - "${sale.marketplace}", - "${pageKey}", - 0, 0 - )`); - console.log(` ::: Inserted sale of ${this.contractName} #${sale.tokenId} in block ${sale.blockNumber} for ${sale.sellerFee.amount} wei.`) - } catch(err) { - console.log(`Error when writing to database: ${err}`); - return false; + if (!rowExists) { + try { + db.run(` + INSERT INTO events VALUES ( + "${this.contractAddress}", + "${sale.buyer_address}", + "${sale.seller_address}", + "${tokenId}", + "${sale.price}", + "", + "${sale.transaction_hash}", + "${sale.block_number}", + "opensea", + "${cursor}", + 0, 0 + )`); + console.log(` ::: Inserted sale of ${this.contractName} #${tokenId} in block ${sale.block_number} for ${sale.price} wei.`) + } catch(err) { + console.log(`Error when writing to database: ${err}`); + return false; + } } - } + }); + }); await sleep(1); @@ -119,25 +115,21 @@ class Scrape { contract text, buyer text, seller text, - taker text, token_id number, sale_price text, - protocol_fee text, - royalty_fee text, tx_date text, tx_hash text, block_number number, - log_index number, - bundle_index number, marketplace text, - page_key text, + cursor text, discord_sent number, twitter_sent number, - UNIQUE(tx_hash, log_index, bundle_index) + UNIQUE(tx_hash, token_id) );`, ); }); } + await Moralis.start(config); while(true) { for(const contract in ALL_CONTRACTS) { if (process.env.ONLY && process.env.ONLY != contract) continue diff --git a/src/server.js b/src/server.js index 9a33171..6a807d1 100644 --- a/src/server.js +++ b/src/server.js @@ -61,7 +61,7 @@ app.get('/api/latest', (req, res) => { app.get('/api/:contractAddress/data', (req, res) => { const results = []; const stmt = db.prepare(`select - block_number block, + (block_number / 100) * 100 block, sum(sale_price/1000000000000000000.0) volume, avg(sale_price/1000000000000000000.0) average_price, (select avg(sale_price/1000000000000000000.0) from (select * from events