From 6a3584224debfed964135e8d1facfeedbd2e72a1 Mon Sep 17 00:00:00 2001 From: lza_menace Date: Mon, 23 Dec 2024 01:28:20 -0800 Subject: [PATCH] init --- .gitignore | 177 +++++++++++++++++++++++++++++++++++++++++++++ README.md | 15 ++++ bun.lockb | Bin 0 -> 83090 bytes package.json | 16 ++++ src/contracts.json | 42 +++++++++++ src/index.js | 145 +++++++++++++++++++++++++++++++++++++ tsconfig.json | 27 +++++++ 7 files changed, 422 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100755 bun.lockb create mode 100644 package.json create mode 100644 src/contracts.json create mode 100644 src/index.js create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1e41ab8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,177 @@ +# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore + +# Logs + +logs +_.log +npm-debug.log_ +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Caches + +.cache + +# Diagnostic reports (https://nodejs.org/api/report.html) + +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# Runtime data + +pids +_.pid +_.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover + +lib-cov + +# Coverage directory used by tools like istanbul + +coverage +*.lcov + +# nyc test coverage + +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) + +.grunt + +# Bower dependency directory (https://bower.io/) + +bower_components + +# node-waf configuration + +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) + +build/Release + +# Dependency directories + +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) + +web_modules/ + +# TypeScript cache + +*.tsbuildinfo + +# Optional npm cache directory + +.npm + +# Optional eslint cache + +.eslintcache + +# Optional stylelint cache + +.stylelintcache + +# Microbundle cache + +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history + +.node_repl_history + +# Output of 'npm pack' + +*.tgz + +# Yarn Integrity file + +.yarn-integrity + +# dotenv environment variable files + +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) + +.parcel-cache + +# Next.js build output + +.next +out + +# Nuxt.js build / generate output + +.nuxt +dist + +# Gatsby files + +# Comment in the public line in if your project uses Gatsby and not Next.js + +# https://nextjs.org/blog/next-9-1#public-directory-support + +# public + +# vuepress build output + +.vuepress/dist + +# vuepress v2.x temp and cache directory + +.temp + +# Docusaurus cache and generated files + +.docusaurus + +# Serverless directories + +.serverless/ + +# FuseBox cache + +.fusebox/ + +# DynamoDB Local files + +.dynamodb/ + +# TernJS port file + +.tern-port + +# Stores VSCode versions used for testing VSCode extensions + +.vscode-test + +# yarn v2 + +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config +.DS_Store + +state \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..ce6e853 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# alchemy-nft-scraper + +To install dependencies: + +```bash +bun install +``` + +To run: + +```bash +bun run src/index.js +``` + +This project was created using `bun init` in bun v1.1.27. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..337d0967ad8e4aa630911765ed7ac30e53362673 GIT binary patch literal 83090 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

js}!6pzK?I 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 literal 0 HcmV?d00001 diff --git a/package.json b/package.json new file mode 100644 index 0000000..2aaa4fe --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "dependencies": { + "alchemy-sdk": "^3.5.0", + "ethers": "^6.13.4", + "sqlite3": "^5.1.7" + }, + "name": "alchemy-nft-scraper", + "module": "index.ts", + "type": "module", + "devDependencies": { + "@types/bun": "latest" + }, + "peerDependencies": { + "typescript": "^5.7.2" + } +} \ No newline at end of file diff --git a/src/contracts.json b/src/contracts.json new file mode 100644 index 0000000..805ec17 --- /dev/null +++ b/src/contracts.json @@ -0,0 +1,42 @@ +{ + "non-fungible-soup": { + "contract_address": "0xdc8bEd466ee117Ebff8Ee84896d6aCd42170d4bB", + "erc1155": false, + "start_block": 13105421 + }, + "mondriannft": { + "contract_address": "0x7f81858ea3b43513adfaf0a20dc7b4c6ebe72919", + "erc1155": false, + "start_block": 13239362 + }, + "bauhausblocks": { + "contract_address": "0x62C1e9f6830098DFF647Ef78E1F39244258F7bF5", + "erc1155": false, + "start_block": 13439681 + }, + "nftzine": { + "contract_address": "0xc918F953E1ef2F1eD6ac6A0d2Bf711A93D20Aa2b", + "erc1155": false, + "start_block": 13698461 + }, + "basedvitalik": { + "contract_address": "0xea2dc6f116a4c3d6a15f06b4e8ad582a07c3dd9c", + "erc1155": false, + "start_block": 14254106 + }, + "rmutt": { + "contract_address": "0x6c61fB2400Bf55624ce15104e00F269102dC2Af4", + "erc1155": false, + "start_block": 14940603 + }, + "nftisse": { + "contract_address": "0x343b68141129ec115c1fc523c5ae90586fe95b77", + "erc1155": false, + "start_block": 15358089 + }, + "renascence": { + "contract_address": "0x501a31185927136E87cDfC97dDd4553D8eC1bb4A", + "erc1155": false, + "start_block": 15973593 + } +} diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..3b9983a --- /dev/null +++ b/src/index.js @@ -0,0 +1,145 @@ +const ALL_CONTRACTS = require('./contracts'); + +const { Alchemy, Network } = require("alchemy-sdk"); +const { Database } = require('sqlite3'); +const { ethers } = require("ethers"); +const fs = require('fs'); + + +const db = new Database('./state/sqlite.db'); +const config = { + apiKey: process.env.ALCHEMY_KEY, + network: Network.ETH_MAINNET, +}; + +const alchemy = new Alchemy(config); + + +async function sleep(sec) { + return new Promise((resolve) => setTimeout(resolve, Number(sec) * 1000)); +} + + +class Scrape { + + constructor (contractName) { + if (!(contractName in ALL_CONTRACTS)) { + console.warn(`[!] That contract name does not exist in data/contracts.json`); + process.exit(); + } + const data = ALL_CONTRACTS[contractName]; + this.contractName = contractName; + this.contractAddress = data['contract_address']; + this.erc1155 = data['erc1155']; + this.startBlock = data['start_block']; + this.lastFile = `./state/${this.contractName}.txt`; + } + + getpageKey() { + if (fs.existsSync(this.lastFile)) { + return fs.readFileSync(this.lastFile).toString(); + } else { + fs.writeFileSync(this.lastFile, ''); + return null + }; + } + + async scrape() { + const pageKey = this.getpageKey() || null + console.log(`[+] Scraping ${this.contractName} with pageKey ${pageKey}`) + const response = await alchemy.nft.getNftSales({ + fromBlock: this.startBlock, + contractAddress: this.contractAddress, + limit: process.env.LIMIT, + order: 'asc', + pageKey: pageKey + }); + fs.writeFileSync(this.lastFile, response.pageKey) + 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); + }); + }); + if (!rowExists) { + try { + db.run(` + INSERT INTO events VALUES ( + "${sale.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}", + 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; + } + } + }); + + await sleep(1); + + } + +} + +(async () => { + const tableExists = await new Promise((resolve) => { + db.get('SELECT name FROM sqlite_master WHERE type="table" AND name="events"', [], (err, row) => { + if (err) { + resolve(false); + } + resolve(row !== undefined); + }); + }); + if (!tableExists) { + db.serialize(() => { + db.run( + `CREATE TABLE events ( + 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, + discord_sent number, + twitter_sent number, + UNIQUE(tx_hash, log_index, bundle_index) + );`, + ); + }); + } + while(true) { + for(const contract in ALL_CONTRACTS) { + if (process.env.ONLY && process.env.ONLY != contract) continue + const c = new Scrape(contract); + try { + await c.scrape(); + } catch(e) { + console.log(e); + } + await sleep(3); + } + } +})(); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..238655f --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + // Enable latest features + "lib": ["ESNext", "DOM"], + "target": "ESNext", + "module": "ESNext", + "moduleDetection": "force", + "jsx": "react-jsx", + "allowJs": true, + + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + // Best practices + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + + // Some stricter flags (disabled by default) + "noUnusedLocals": false, + "noUnusedParameters": false, + "noPropertyAccessFromIndexSignature": false + } +}