1+ const fetch = require ( "node-fetch" ) ;
2+ const path = require ( "path" ) ;
3+ const basePath = process . cwd ( ) ;
4+ const fs = require ( "fs" ) ;
5+
6+ const AUTH = 'YOUR API KEY HERE' ;
7+ const CONTRACT_ADDRESS = 'YOUR CONTRACT ADDRESS HERE' ;
8+ const ACCOUNT_ADDRESS = 'METAMASK ACCOUNT THAT MINTED NFTs' ;
9+ const CHAIN = 'rinkeby' ; // Test: rinkeby, Real: polygon
10+ const TIMEOUT = 1000 ; // Milliseconds. This a timeout for errors only. If there is an error, it will wait then try again. 5000 = 5 seconds.
11+ const INTERVAL = 900000 ; // Milliseconds. This is the interval for it to check for sales and reveal the NFT. 900000 = 15 minutes.
12+
13+ const ownedNFTs = [ ]
14+
15+ if ( ! fs . existsSync ( path . join ( `${ basePath } /build` , "/revealed" ) ) ) {
16+ fs . mkdirSync ( path . join ( `${ basePath } /build` , "revealed" ) ) ;
17+ }
18+
19+ async function checkOwnedNFTs ( ) {
20+ let page = 1
21+ let lastPage = 1
22+ let url = `https://api.nftport.xyz/v0/accounts/${ ACCOUNT_ADDRESS } ?chain=${ CHAIN } &page_number=`
23+ let options = {
24+ method : "GET" ,
25+ headers : {
26+ "Content-Type" : "application/json" ,
27+ Authorization : AUTH ,
28+ }
29+ } ;
30+
31+ let ownedNFTsData = await fetchWithRetry ( `${ url } ${ page } ` , options )
32+ for ( ownedNFT of ownedNFTsData . nfts ) {
33+ if ( ownedNFT . contract_address === CONTRACT_ADDRESS ) {
34+ ownedNFTs . push ( parseInt ( ownedNFT . token_id ) )
35+ }
36+ }
37+ lastPage = Math . ceil ( ownedNFTsData . total / 50 )
38+ while ( page < lastPage ) {
39+ page ++
40+ ownedNFTsData = await fetchWithRetry ( `${ url } ${ page } ` , options )
41+ for ( ownedNFT of ownedNFTsData . nfts ) {
42+ if ( ownedNFT . contract_address === CONTRACT_ADDRESS ) {
43+ ownedNFTs . push ( parseInt ( ownedNFT . token_id ) )
44+ }
45+ }
46+ }
47+
48+ reveal ( )
49+ }
50+
51+ async function reveal ( ) {
52+ const ipfsMetas = JSON . parse (
53+ fs . readFileSync ( `${ basePath } /build/ipfsMetas/_ipfsMetas.json` )
54+ ) ;
55+ for ( const meta of ipfsMetas ) {
56+ const edition = meta . custom_fields . edition
57+ if ( ! ownedNFTs . includes ( edition ) ) {
58+ const revealedFilePath = `${ basePath } /build/revealed/${ edition } .json` ;
59+ try {
60+ fs . accessSync ( revealedFilePath ) ;
61+ const revealedFile = fs . readFileSync ( revealedFilePath )
62+ if ( revealedFile . length > 0 ) {
63+ const revealedFileJson = JSON . parse ( revealedFile )
64+ if ( revealedFileJson . updateData . response !== "OK" ) throw 'not revealed'
65+ console . log ( `${ meta . name } already revealed` ) ;
66+ } else {
67+ throw 'not revealed'
68+ }
69+ } catch ( err ) {
70+ try {
71+ let url = "https://api.nftport.xyz/v0/mints/customizable" ;
72+
73+ const updateInfo = {
74+ chain : CHAIN ,
75+ contract_address : CONTRACT_ADDRESS ,
76+ metadata_uri : meta . metadata_uri ,
77+ token_id : meta . custom_fields . edition ,
78+ } ;
79+
80+ let options = {
81+ method : "PUT" ,
82+ headers : {
83+ "Content-Type" : "application/json" ,
84+ Authorization : AUTH ,
85+ } ,
86+ body : JSON . stringify ( updateInfo ) ,
87+ } ;
88+ let updateData = await fetchWithRetry ( url , options , meta )
89+ console . log ( `Updated: ${ meta . name } ` ) ;
90+ const combinedData = {
91+ metaData : meta ,
92+ updateData : updateData
93+ }
94+ writeMintData ( meta . custom_fields . edition , combinedData )
95+ } catch ( err ) {
96+ console . log ( err )
97+ }
98+ }
99+ }
100+ }
101+ console . log ( `Done revealing! Will run again in ${ ( INTERVAL / 1000 ) / 60 } minutes` )
102+ }
103+
104+ async function fetchWithRetry ( url , options , meta ) {
105+ return new Promise ( ( resolve , reject ) => {
106+ const fetch_retry = ( _url , _options , _meta ) => {
107+
108+ return fetch ( url , options ) . then ( async ( res ) => {
109+ const status = res . status ;
110+
111+ if ( status === 200 ) {
112+ return res . json ( ) ;
113+ }
114+ else {
115+ console . error ( `ERROR STATUS: ${ status } ` )
116+ console . log ( 'Retrying' )
117+ await timer ( TIMEOUT )
118+ fetch_retry ( _url , _options , _meta )
119+ }
120+ } )
121+ . then ( async ( json ) => {
122+ if ( json . response === "OK" ) {
123+ return resolve ( json ) ;
124+ } else {
125+ console . error ( `NOK: ${ json . error } ` )
126+ console . log ( 'Retrying' )
127+ await timer ( TIMEOUT )
128+ fetch_retry ( _url , _options , _meta )
129+ }
130+ } )
131+ . catch ( async ( error ) => {
132+ console . error ( `CATCH ERROR: ${ error } ` )
133+ console . log ( 'Retrying' )
134+ await timer ( TIMEOUT )
135+ fetch_retry ( _url , _options , _meta )
136+ } ) ;
137+ }
138+ return fetch_retry ( url , options , meta ) ;
139+ } ) ;
140+ }
141+
142+ function timer ( ms ) {
143+ return new Promise ( res => setTimeout ( res , ms ) ) ;
144+ }
145+
146+ const writeMintData = ( _edition , _data ) => {
147+ fs . writeFileSync ( `${ basePath } /build/revealed/${ _edition } .json` , JSON . stringify ( _data , null , 2 ) ) ;
148+ } ;
149+
150+ setInterval ( checkOwnedNFTs , INTERVAL )
151+ checkOwnedNFTs ( )
0 commit comments