@ -1,5 +1,5 @@
const fs = require ( 'fs' ) ;
const { BigNumber , ethers } = require ( 'ethers' ) ;
const { BigNumber , ethers } = require ( 'ethers' ) ;
const fs = require ( 'fs' ) ;
const { Database } = require ( 'sqlite3' ) ;
const { Database } = require ( 'sqlite3' ) ;
const { postDiscord } = require ( './poster' ) ;
const { postDiscord } = require ( './poster' ) ;
@ -15,10 +15,11 @@ const CHUNK_SIZE = Number(process.env.CHUNK_SIZE);
const ALL _CONTRACTS = require ( '../data/contracts' ) ;
const ALL _CONTRACTS = require ( '../data/contracts' ) ;
const ERC721 _ABI = require ( '../data/erc721' ) ;
const ERC721 _ABI = require ( '../data/erc721' ) ;
const ERC1155 _ABI = require ( '../data/erc1155' ) ;
const ERC1155 _ABI = require ( '../data/erc1155' ) ;
const MARKETPLACE _ABI = require ( '../data/marketplace' ) ;
const SEAPORT _ABI = require ( '../data/seaport' ) ;
const SEAPORT _ABI = require ( '../data/seaport' ) ;
const WYVERN _ABI = require ( '../data/wyvern' ) ;
const WYVERN _ABI = require ( '../data/wyvern' ) ;
const LOOKSRARE _ABI = require ( '../data/looksrare' ) ;
const LOOKSRARE _ABI = require ( '../data/looksrare' ) ;
const BLUR_ABI = require ( '../data/blur ') ;
const X2Y2_ABI = require ( '../data/x2y2 ') ;
const WETH _ADDRESS = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' ;
const WETH _ADDRESS = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' ;
const TRANSFER _TOPIC = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef' ;
const TRANSFER _TOPIC = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef' ;
const TRANSFER _SINGLE _TOPIC = '0xc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62' ;
const TRANSFER _SINGLE _TOPIC = '0xc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62' ;
@ -26,11 +27,10 @@ const LOOKSRARE_SALE_TOPIC = '0x95fb6205e23ff6bda16a2d1dba56b9ad7c783f67c96fa149
const SEAPORT _SALE _TOPIC = '0x9d9af8e38d66c62e2c12f0225249fd9d721c54b83f48d9352c97c6cacdcb6f31' ;
const SEAPORT _SALE _TOPIC = '0x9d9af8e38d66c62e2c12f0225249fd9d721c54b83f48d9352c97c6cacdcb6f31' ;
const WYVERN _SALE _TOPIC = '0xc4109843e0b7d514e4c093114b863f8e7d8d9a458c372cd51bfe526b588006c9'
const WYVERN _SALE _TOPIC = '0xc4109843e0b7d514e4c093114b863f8e7d8d9a458c372cd51bfe526b588006c9'
const X2Y2 _SALE _TOPIC = '0x3cbb63f144840e5b1b0a38a7c19211d2e89de4d7c5faf8b2d3c1776c302d1d33' ;
const X2Y2 _SALE _TOPIC = '0x3cbb63f144840e5b1b0a38a7c19211d2e89de4d7c5faf8b2d3c1776c302d1d33' ;
const BLUR _SALE _TOPIC = '0x61cbb2a3dee0b6064c2e681aadd61677fb4ef319f0b547508d495626f5a62f64' ;
const seaportInterface = new ethers . utils . Interface ( SEAPORT _ABI ) ;
const seaportInterface = new ethers . utils . Interface ( SEAPORT _ABI ) ;
const looksrareInterface = new ethers . utils . Interface ( LOOKSRARE _ABI ) ;
const looksrareInterface = new ethers . utils . Interface ( LOOKSRARE _ABI ) ;
const wyvernInterface = new ethers . utils . Interface ( WYVERN _ABI ) ;
const wyvernInterface = new ethers . utils . Interface ( WYVERN _ABI ) ;
const blur Interface = new ethers . utils . Interface ( BLUR _ABI ) ;
const x2y2 Interface = new ethers . utils . Interface ( X2Y2 _ABI ) ;
const provider = new ethers . providers . WebSocketProvider ( process . env . GETH _NODE ) ;
const provider = new ethers . providers . WebSocketProvider ( process . env . GETH _NODE ) ;
const db = new Database ( './storage/sqlite.db' ) ;
const db = new Database ( './storage/sqlite.db' ) ;
@ -43,7 +43,7 @@ class Collection {
}
}
const data = ALL _CONTRACTS [ contractName ] ;
const data = ALL _CONTRACTS [ contractName ] ;
this . contractName = contractName ;
this . contractName = contractName ;
this . contractAddress = data [ 'contract_address' ] ;
this . contractAddress = data [ 'contract_address' ] .toLowerCase ( ) ;
this . erc1155 = data [ 'erc1155' ] ;
this . erc1155 = data [ 'erc1155' ] ;
this . startBlock = data [ 'start_block' ] ;
this . startBlock = data [ 'start_block' ] ;
if ( this . erc1155 ) {
if ( this . erc1155 ) {
@ -109,10 +109,8 @@ class Scrape extends Collection {
while ( lastScrapedBlock >= latestEthBlock ) {
while ( lastScrapedBlock >= latestEthBlock ) {
latestEthBlock = await this . provider . getBlockNumber ( ) ;
latestEthBlock = await this . provider . getBlockNumber ( ) ;
console . log ( ` [ ${ ( new Date ( ) ) . toISOString ( ) } ][ ${ this . contractName } ] [ waiting ] \n ` )
console . log ( ` [ ${ ( new Date ( ) ) . toISOString ( ) } ][ ${ this . contractName } ] [ waiting ] \n ` )
await sleep ( 90 0) ;
await sleep ( 12 0) ;
}
}
await sleep ( 1 ) ;
}
}
}
}
@ -131,6 +129,7 @@ class Scrape extends Collection {
// get transfer events from a batch from filtering
// get transfer events from a batch from filtering
async getTransferEvents ( txEvents ) {
async getTransferEvents ( txEvents ) {
let platform = 'contract' ;
txEvents . forEach ( async tx => {
txEvents . forEach ( async tx => {
let tokenId ;
let tokenId ;
if ( this . erc1155 ) {
if ( this . erc1155 ) {
@ -157,7 +156,7 @@ class Scrape extends Collection {
txDate : timestamp
txDate : timestamp
}
}
writeToDatabase ( q )
writeToDatabase ( q )
. then ( ( _ ) => this . writeLastBlock ( tx . blockNumber ) )
. then ( ( res ) => this . writeLastBlock ( tx . blockNumber ) )
. catch ( ( err ) => console . log ( ` Error writing to database: ${ err } ` ) ) ;
. catch ( ( err ) => console . log ( ` Error writing to database: ${ err } ` ) ) ;
} ) ;
} ) ;
}
}
@ -167,8 +166,6 @@ class Scrape extends Collection {
try {
try {
const receipt = await this . provider . getTransactionReceipt ( txHash ) ;
const receipt = await this . provider . getTransactionReceipt ( txHash ) ;
const timestamp = await this . getBlockTimestamp ( receipt . blockNumber ) ;
const timestamp = await this . getBlockTimestamp ( receipt . blockNumber ) ;
const _logs = receipt . logs . filter ( ( l ) => l . address . toLowerCase ( ) === this . contractAddress . toLowerCase ( ) ) ;
if ( _logs == 0 ) return
// Evaluate each log entry and determine if it's a sale for our contract and use custom logic for each exchange to parse values
// Evaluate each log entry and determine if it's a sale for our contract and use custom logic for each exchange to parse values
receipt . logs . map ( async log => {
receipt . logs . map ( async log => {
let logIndex = log . logIndex ;
let logIndex = log . logIndex ;
@ -176,68 +173,53 @@ class Scrape extends Collection {
let platform ;
let platform ;
let fromAddress ;
let fromAddress ;
let toAddress ;
let toAddress ;
let amountWei = 0 ;
let amountWei ;
let amountEther ;
let tokenId ;
let tokenId ;
if ( log . topics [ 0 ] . toLowerCase ( ) === SEAPORT _SALE _TOPIC . toLowerCase ( ) ) {
if ( log . topics [ 0 ] . toLowerCase ( ) === SEAPORT _SALE _TOPIC . toLowerCase ( ) ) {
// Handle Opensea/Seaport sales
// Handle Opensea/Seaport sales
const logDescription = seaportInterface . parseLog ( log ) ;
const logDescription = seaportInterface . parseLog ( log )
platform = 'opensea' ;
const matchingOffers = logDescription . args . offer . filter (
if ( logDescription . args . offer [ 0 ] . token . toLowerCase ( ) == this . contractAddress . toLowerCase ( ) ) {
o => o . token . toLowerCase ( ) == this . contractAddress
// buyer has accepted seller offer
) ;
if ( matchingOffers . length === 0 ) return ;
sale = true ;
sale = true ;
platform = 'opensea' ;
fromAddress = logDescription . args . offerer . toLowerCase ( ) ;
fromAddress = logDescription . args . offerer . toLowerCase ( ) ;
toAddress = logDescription . args . recipient . toLowerCase ( ) ;
toAddress = logDescription . args . recipient . toLowerCase ( ) ;
logDescription . args . consideration . map ( ( o ) => {
tokenId = logDescription . args . offer . map ( o => o . identifier . toString ( ) ) ;
if ( Number ( o . amount ) > 0 ) amountWei += Number ( o . amount ) ;
let amounts = logDescription . args . consideration . map ( c => BigInt ( c . amount ) ) ;
} ) ;
// add weth
amountWei = amountWei . toString ( ) ;
const wethOffers = matchingOffers . map ( o => o . token . toLowerCase ( ) === WETH _ADDRESS . toLowerCase ( ) && o . amount > 0 ? BigInt ( o . amount ) : BigInt ( 0 ) ) ;
let rl = logDescription . args . offer . filter ( ( l ) => l . token . toLowerCase ( ) === this . contractAddress . toLowerCase ( ) ) ;
if ( wethOffers . length > 0 && wethOffers [ 0 ] != BigInt ( 0 ) ) {
if ( rl . length > 0 ) tokenId = rl [ 0 ] . identifier . toString ( ) ;
amounts = wethOffers
} else if ( logDescription . args . offer [ 0 ] . token . toLowerCase ( ) == WETH _ADDRESS . toLowerCase ( ) ) {
}
// seller has accepted buyer bid (uses WETH)
amountWei = amounts . reduce ( ( previous , current ) => previous + current , BigInt ( 0 ) ) ;
// filter down only sales on the contract
const _c = logDescription . args . consideration . filter ( ( c ) => c . token . toLowerCase ( ) === this . contractAddress . toLowerCase ( ) ) ;
_c . map ( ( o ) => {
sale = true ;
toAddress = logDescription . args . offerer . toLowerCase ( ) ;
fromAddress = logDescription . args . recipient . toLowerCase ( ) ;
amountWei = BigNumber . from ( logDescription . args . offer [ 0 ] . amount ) . toString ( ) ;
tokenId = _c [ 0 ] . identifier . toString ( ) ;
} )
} else {
// unknown condition
}
} else if ( log . topics [ 0 ] . toLowerCase ( ) === WYVERN _SALE _TOPIC . toLowerCase ( ) ) {
} else if ( log . topics [ 0 ] . toLowerCase ( ) === WYVERN _SALE _TOPIC . toLowerCase ( ) ) {
// Handle Opensea/Wyvern sales
// Handle Opensea/Wyvern sales
let txEventType = TRANSFER _TOPIC . toLowerCase ( ) ;
const logDescription = wyvernInterface . parseLog ( log ) ;
const logDescription = wyvernInterface . parseLog ( log ) ;
sale = true ;
sale = true ;
platform = 'opensea' ;
platform = 'opensea' ;
if ( this . erc1155 ) txEventType = TRANSFER _SINGLE _TOPIC . toLowerCase ( ) ;
// get transfer log to deduce from/to/token_id
const txLog = receipt . logs . filter (
l => (
l . topics [ 0 ] . toLowerCase ( ) == txEventType
&&
l . address . toLowerCase ( ) === this . contractAddress . toLowerCase ( )
&&
l . logIndex === logIndex - 1 // transfer should be immediately before sale
)
) ;
if ( txLog . length === 0 ) return ;
const txLogDescription = this . interface . parseLog ( txLog [ 0 ] ) ;
fromAddress = txLogDescription . args . from . toLowerCase ( ) ;
toAddress = txLogDescription . args . to . toLowerCase ( ) ;
if ( this . erc1155 ) {
if ( this . erc1155 ) {
tokenId = BigNumber . from ( txLogDescription . args . id ) . toString ( ) ;
const txLog = receipt . logs . map ( l => l ) . filter ( _l =>
( _l . topics [ 0 ] . toLowerCase ( ) == TRANSFER _SINGLE _TOPIC . toLowerCase ( ) )
) . map ( t => this . interface . parseLog ( t ) ) [ 0 ] . args ;
fromAddress = txLog . from . toLowerCase ( ) ;
toAddress = txLog . to . toLowerCase ( ) ;
tokenId = BigNumber . from ( txLog . id ) . toString ( ) ;
} else {
} else {
tokenId = BigNumber . from ( txLogDescription . args . tokenId ) . toString ( ) ;
const txLog = receipt . logs . map ( l => l ) . filter ( _l =>
( _l . topics [ 0 ] . toLowerCase ( ) == TRANSFER _TOPIC . toLowerCase ( ) )
) . map ( t => this . interface . parseLog ( t ) ) [ 0 ] . args ;
fromAddress = txLog . from . toLowerCase ( ) ;
toAddress = txLog . to . toLowerCase ( ) ;
tokenId = BigNumber . from ( txLog . tokenId ) . toString ( ) ;
}
}
amountWei = BigInt ( logDescription . args . price ) ;
amountWei = BigInt ( logDescription . args . price ) ;
} else if ( log . topics [ 0 ] . toLowerCase ( ) === LOOKSRARE _SALE _TOPIC . toLowerCase ( ) ) {
} else if ( log . topics [ 0 ] . toLowerCase ( ) === LOOKSRARE _SALE _TOPIC . toLowerCase ( ) ) {
// Handle LooksRare sales
// Handle LooksRare sales
const logDescription = looksrareInterface . parseLog ( log ) ;
const logDescription = looksrareInterface . parseLog ( log ) ;
if ( logDescription . args . collection . toLowerCase ( ) != this . contractAddress .toLowerCase ( ) ) return ;
if ( logDescription . args . collection . toLowerCase ( ) != this . contractAddress ) return ;
sale = true ;
sale = true ;
platform = 'looksrare' ;
platform = 'looksrare' ;
fromAddress = logDescription . args . maker . toLowerCase ( ) ;
fromAddress = logDescription . args . maker . toLowerCase ( ) ;
@ -246,6 +228,8 @@ class Scrape extends Collection {
amountWei = logDescription . args . price . toString ( ) ;
amountWei = logDescription . args . price . toString ( ) ;
} else if ( log . topics [ 0 ] . toLowerCase ( ) === X2Y2 _SALE _TOPIC . toLowerCase ( ) ) {
} else if ( log . topics [ 0 ] . toLowerCase ( ) === X2Y2 _SALE _TOPIC . toLowerCase ( ) ) {
// Handle x2y2 sales
// Handle x2y2 sales
const logDescription = x2y2Interface . parseLog ( log ) ;
return
const data = log . data . substring ( 2 ) ;
const data = log . data . substring ( 2 ) ;
const dataSlices = data . match ( /.{1,64}/g ) ;
const dataSlices = data . match ( /.{1,64}/g ) ;
sale = true ;
sale = true ;
@ -257,27 +241,9 @@ class Scrape extends Collection {
if ( amountWei === BigInt ( 0 ) ) {
if ( amountWei === BigInt ( 0 ) ) {
amountWei = BigInt ( ` 0x ${ dataSlices [ 26 ] } ` ) ;
amountWei = BigInt ( ` 0x ${ dataSlices [ 26 ] } ` ) ;
}
}
} else if ( log . topics [ 0 ] . toLowerCase ( ) === BLUR _SALE _TOPIC . toLowerCase ( ) ) {
// Handle Blur sales
sale = true ;
platform = 'blur' ;
const logDescription = blurInterface . parseLog ( log ) ;
fromAddress = logDescription . args . maker ;
toAddress = logDescription . args . taker ;
tokenId = BigInt ( logDescription . args . sell . tokenId ) ;
amountWei = BigInt ( logDescription . args . sell . price ) ;
// console.log(logDescription)
// Blur's marketplace orders don't include the purchaser, only their proxy contract which passes the token through
// This little hack just grabs the Transfer event after the Blur sale to get the end recipient
let rl = receipt . logs . filter (
l => l . logIndex === log . logIndex + 2 && l . topics [ 0 ] . toLowerCase ( ) === TRANSFER _TOPIC
) ;
if ( rl . length > 0 ) {
toAddress = ethers . utils . defaultAbiCoder . decode ( [ 'address' ] , rl [ 0 ] . topics [ 2 ] ) [ 0 ] . toLowerCase ( ) ;
}
}
}
if ( sale ) {
if ( sale ) {
let amountEther = ethers . utils . formatEther ( amountWei . toString ( ) ) ;
amountEther = ethers . utils . formatEther ( amountWei ) ;
let msg = ` [ ${ timestamp . toISOString ( ) } ][ ${ this . contractName } ][ sale ] # ${ tokenId } : ${ fromAddress } => ${ toAddress } for ${ amountEther } Ξ ( ${ platform } ) in tx ${ txHash } : ${ logIndex } \n ` ;
let msg = ` [ ${ timestamp . toISOString ( ) } ][ ${ this . contractName } ][ sale ] # ${ tokenId } : ${ fromAddress } => ${ toAddress } for ${ amountEther } Ξ ( ${ platform } ) in tx ${ txHash } : ${ logIndex } \n ` ;
console . log ( msg ) ;
console . log ( msg ) ;
const q = {
const q = {
@ -289,24 +255,14 @@ class Scrape extends Collection {
eventSource : platform ,
eventSource : platform ,
sourceOwner : fromAddress ,
sourceOwner : fromAddress ,
targetOwner : toAddress ,
targetOwner : toAddress ,
tokenId : tokenId .toString ( ) ,
tokenId : tokenId ,
amount : amountWei ,
amount : amountWei ,
txDate : timestamp
txDate : timestamp
}
}
writeToDatabase ( q )
writeToDatabase ( q )
. then ( async _ => {
. then ( ( res ) => this . writeLastBlock ( log . blockNumber ) )
let notifSent = await checkUnsentNotif ( txHash , logIndex ) ;
if ( process . env . DISCORD _ACTIVE == 1 && ( notifSent || process . env . FORCE == 1 ) ) {
postDiscord ( q )
. then ( async res => {
await markSent ( txHash , logIndex ) ;
console . log ( ` [ ${ timestamp . toISOString ( ) } ][ ${ this . contractName } ][ discord ] ${ res } \n ` )
} )
. catch ( ( err ) => console . log ( ` Error posting to Discord: ${ err } ` ) ) ;
}
this . writeLastBlock ( log . blockNumber ) ;
} )
. catch ( ( err ) => console . log ( ` Error writing to database: ${ err } ` ) ) ;
. catch ( ( err ) => console . log ( ` Error writing to database: ${ err } ` ) ) ;
await postDiscord ( q ) ;
}
}
} ) ;
} ) ;
} catch ( err ) {
} catch ( err ) {
@ -366,7 +322,7 @@ async function createDatabaseIfNeeded() {
` CREATE TABLE events (
` CREATE TABLE events (
contract text , event _type text , from _wallet text , to _wallet text ,
contract text , event _type text , from _wallet text , to _wallet text ,
token _id number , amount number , tx _date text , tx text ,
token _id number , amount number , tx _date text , tx text ,
log _index number , platform text , discord _sent number , twitter _sent number ,
log _index number , platform text ,
UNIQUE ( tx , log _index )
UNIQUE ( tx , log _index )
) ; ` ,
) ; ` ,
) ;
) ;
@ -392,35 +348,13 @@ async function checkRowExists(txHash, logIndex) {
return rowExists ;
return rowExists ;
}
}
async function checkUnsentNotif ( txHash , logIndex ) {
const rowExists = await new Promise ( ( resolve ) => {
db . get ( 'SELECT * FROM events WHERE tx = ? AND log_index = ? AND discord_sent != 1' , [ txHash , logIndex ] , ( err , row ) => {
if ( err ) {
resolve ( false ) ;
}
resolve ( row !== undefined ) ;
} ) ;
} ) ;
return rowExists ;
}
async function markSent ( txHash , logIndex ) {
try {
const stmt = db . prepare ( 'UPDATE events SET discord_sent = 1 WHERE tx = ? AND log_index = ?' ) ;
stmt . run ( txHash , logIndex ) ;
stmt . finalize ( ) ;
} catch ( err ) {
console . log ( ` Error writing to database: ${ err } ` )
}
}
async function writeToDatabase ( _q ) {
async function writeToDatabase ( _q ) {
// txHash, logIndex, contractName, contractAddress, eventName, eventSource, sourceOwner, targetOwner, tokenId, amount, txDate
// txHash, logIndex, contractName, contractAddress, eventName, eventSource, sourceOwner, targetOwner, tokenId, amount, txDate
const rowExists = await checkRowExists ( _q . txHash , _q . logIndex , _q . contractAddress ) ;
const rowExists = await checkRowExists ( _q . txHash , _q . logIndex , _q . contractAddress ) ;
if ( ! rowExists ) {
if ( ! rowExists ) {
let stmt ;
let stmt ;
try {
try {
stmt = db . prepare ( 'INSERT INTO events VALUES (?,?,?,?,?,?,?,?,?,? ,?,? )') ;
stmt = db . prepare ( 'INSERT INTO events VALUES (?,?,?,?,?,?,?,?,?,?)' ) ;
stmt . run (
stmt . run (
_q . contractAddress ,
_q . contractAddress ,
_q . eventName ,
_q . eventName ,
@ -431,9 +365,7 @@ async function writeToDatabase(_q) {
_q . txDate . toISOString ( ) ,
_q . txDate . toISOString ( ) ,
_q . txHash ,
_q . txHash ,
_q . logIndex ,
_q . logIndex ,
_q . eventSource ,
_q . eventSource
0 ,
0
) ;
) ;
stmt . finalize ( ) ;
stmt . finalize ( ) ;
return true ;
return true ;
@ -447,11 +379,11 @@ async function writeToDatabase(_q) {
}
}
// Sample events for testing functionality and detecting sales
// Sample events for testing functionality and detecting sales
// let c = new Scrape('non-fungible-soup');
let c = new Scrape ( 'mondriannft' ) ;
// c.getSalesEvents('0x2f8961209daca23288c499449aa936b54eec5c25720b9d7499a8ee5bde7fcdc7')
// c.getSalesEvents('0x2f8961209daca23288c499449aa936b54eec5c25720b9d7499a8ee5bde7fcdc7')
// c.getSalesEvents('0xb20853f22b367ee139fd800206bf1cba0c36f1a1dd739630f99cc6ffd0471edc')
// c.getSalesEvents('0xb20853f22b367ee139fd800206bf1cba0c36f1a1dd739630f99cc6ffd0471edc')
// c.getSalesEvents('0x71e5135a543e17cc91992a2229ae5811461c96b84d5e2560ac8db1dd99bb17e3')
// c.getSalesEvents('0x71e5135a543e17cc91992a2229ae5811461c96b84d5e2560ac8db1dd99bb17e3')
// c.getSalesEvents('0x5dc68e0bd60fa671e7b6702002e4ce374de6a5dd49fcda00fdb45e26771bcbd9')
c . getSalesEvents ( '0xe567d00bb0c16928d5d8c258de8dd928e93209b40f7c958bc485d2a6c549b8a9' )
// c.getSalesEvents('0x975d10cdd873ee5bb29e746c2f1f3b776078cace9c04ce419cb66949239288b5')
// c.getSalesEvents('0x975d10cdd873ee5bb29e746c2f1f3b776078cace9c04ce419cb66949239288b5')
// c.getSalesEvents('0x8d45ed8168a740f8b182ec0dbad1c37d6c6dbd8aa865be408d865ca01fb0fa94')
// c.getSalesEvents('0x8d45ed8168a740f8b182ec0dbad1c37d6c6dbd8aa865be408d865ca01fb0fa94')
// c.getSalesEvents('0x27ab6f12604bf17a9e7c93bf1a7cc466d7dfd922565d267eac10879b59d5d0b5')
// c.getSalesEvents('0x27ab6f12604bf17a9e7c93bf1a7cc466d7dfd922565d267eac10879b59d5d0b5')
@ -459,16 +391,14 @@ async function writeToDatabase(_q) {
// c.getSalesEvents('0x04746b6ba1269906db8e0932263b86a6fc35a30a31cf73d2b7db078f6f4ed442')
// c.getSalesEvents('0x04746b6ba1269906db8e0932263b86a6fc35a30a31cf73d2b7db078f6f4ed442')
// c.getSalesEvents('0x24d6523c5048b2df3e7f8b24d63a6644e4c0ed33cfae6396190e3ded5fc79321')
// c.getSalesEvents('0x24d6523c5048b2df3e7f8b24d63a6644e4c0ed33cfae6396190e3ded5fc79321')
// c.getSalesEvents('0xe56dc64c44a3cbfe3a1e68f8669a65f17ebe48d64e944673122a565b7c641d1e')
// c.getSalesEvents('0xe56dc64c44a3cbfe3a1e68f8669a65f17ebe48d64e944673122a565b7c641d1e')
// c.getSalesEvents('0xe567d00bb0c16928d5d8c258de8dd928e93209b40f7c958bc485d2a6c549b8a9')
return
// return
if ( process . env . SCRAPE ) {
for ( const key in ALL _CONTRACTS ) {
let c = new Scrape ( process . env . SCRAPE )
if ( process . env . ONLY && process . env . ONLY != key ) continue
c . scrape ( )
} else {
for ( const key in ALL _CONTRACTS ) {
const c = new Scrape ( key ) ;
const c = new Scrape ( key ) ;
if ( process . env . TX ) {
c . getSalesEvents ( process . env . TX ) ;
continue ;
}
c . scrape ( ) ;
c . scrape ( ) ;
}
}
}