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