@@ -4,12 +4,14 @@ import styles from '@/styles/Home.module.css'
4
4
import { BCMR , utf8ToBin , sha256 , binToHex } from 'mainnet-js'
5
5
import { useEffect , useState } from 'react'
6
6
import { queryGenesisSupplyFT , queryActiveMinting , querySupplyNFTs , queryAuthchainLength , queryAllTokenHolders } from '../utils/queryChainGraph' ;
7
+ import { formatTimestamp } from '@/utils/utils'
7
8
8
9
const inter = Inter ( { subsets : [ 'latin' ] } )
9
10
10
11
export default function Home ( ) {
11
12
interface tokenInfo {
12
13
genesisSupplyFT :number ;
14
+ genesisTxTimestamp :number ;
13
15
totalSupplyFT :number ;
14
16
reservedSupplyFT :number ;
15
17
totalSupplyNFTs :number ;
@@ -145,6 +147,7 @@ export default function Home() {
145
147
}
146
148
// calculate genesisSupplyFT
147
149
const genesisTx = respJsonGenesisSupply ?. transaction [ 0 ] ?. hash ?. substring ( 2 ) ;
150
+ const genesisTxTimestamp = Number ( respJsonGenesisSupply . transaction [ 0 ] . block_inclusions [ 0 ] . block . timestamp ) ;
148
151
let genesisSupplyFT = 0 ;
149
152
if ( respJsonGenesisSupply . transaction [ 0 ] . outputs ) {
150
153
genesisSupplyFT = respJsonGenesisSupply . transaction [ 0 ] . outputs . reduce (
@@ -157,10 +160,12 @@ export default function Home() {
157
160
let totalSupplyNFTs = respJsonSupplyNFTs . output . length ;
158
161
let indexOffset = 0 ;
159
162
// limit of items returned by chaingraphquery is 5000
163
+ let fullListNftHolders = respJsonSupplyNFTs . output
160
164
while ( totalSupplyNFTs == 5000 ) {
161
165
indexOffset += 1 ;
162
166
const respJsonSupplyNFTs2 = await querySupplyNFTs ( tokenId , 5000 * indexOffset ) ;
163
167
if ( ! respJsonSupplyNFTs2 ) throw new Error ( "Error in querySupplyNFTs" )
168
+ fullListNftHolders = fullListNftHolders . concat ( respJsonSupplyNFTs2 . output ) ;
164
169
totalSupplyNFTs += respJsonSupplyNFTs2 . output . length ;
165
170
}
166
171
// parse hasActiveMintingToken
@@ -178,13 +183,14 @@ export default function Home() {
178
183
total + parseInt ( output . fungible_token_amount ?? "0" ) ,
179
184
0
180
185
) ;
181
- const uniqueLockingBytecodes = new Set ( respJsonAllTokenHolders . output . map ( output => output . locking_bytecode . slice ( 2 ) ) ) ;
186
+ const listHoldingAddresses = ! genesisSupplyFT ? fullListNftHolders : respJsonAllTokenHolders . output
187
+ const uniqueLockingBytecodes = new Set ( listHoldingAddresses . map ( output => output . locking_bytecode . slice ( 2 ) ) ) ;
182
188
const numberHolders = Array . from ( uniqueLockingBytecodes ) . filter ( locking_bytecode =>
183
189
locking_bytecode . startsWith ( '76a914' )
184
190
) . length ;
185
191
const numberTokenAddresses = uniqueLockingBytecodes . size ;
186
192
187
- setTokenInfo ( { genesisSupplyFT, totalSupplyFT, totalSupplyNFTs, hasActiveMintingToken, genesisTx, authchainLength, authHead, reservedSupplyFT, numberHolders, numberTokenAddresses} ) ;
193
+ setTokenInfo ( { genesisSupplyFT, totalSupplyFT, totalSupplyNFTs, hasActiveMintingToken, genesisTx, genesisTxTimestamp , authchainLength, authHead, reservedSupplyFT, numberHolders, numberTokenAddresses} ) ;
188
194
} catch ( error ) {
189
195
console . log ( error ) ;
190
196
alert ( "The input is not a valid tokenId!" )
@@ -255,14 +261,18 @@ export default function Home() {
255
261
< > total amount NFTs: { tokenInfo . totalSupplyNFTs } < br /> < br /> </ >
256
262
) :null }
257
263
description: { metadataInfo ?. tokenMetadata ?. description } < br /> < br />
258
- genesis transaction: < a href = { "https://explorer.electroncash.de/tx/" + tokenInfo . genesisTx } target = "_blank" rel = "noreferrer" >
259
- { tokenInfo . genesisTx }
260
- </ a > < br />
261
- { tokenInfo . totalSupplyNFTs ? (
262
- < >
263
- has active minting NFT: { tokenInfo . hasActiveMintingToken ? "yes" :"no" } < br /> < br />
264
- </ >
265
- ) :null }
264
+ { metadataInfo ?. tokenMetadata ?. uris ? < >
265
+ web url: { metadataInfo . tokenMetadata . uris ?. web ? < a href = { metadataInfo . tokenMetadata . uris ?. web } target = '_blank' rel = "noreferrer" style = { { display : "inline-block" , color : "#00E" } } >
266
+ { metadataInfo . tokenMetadata . uris ?. web }
267
+ </ a > : "none" } < br /> < br />
268
+ other uris: { Object . keys ( metadataInfo . tokenMetadata . uris ) . filter ( uri => uri != "icon" && uri != "web" ) . length ?
269
+ Object . keys ( metadataInfo . tokenMetadata . uris ) . filter ( uri => uri != "icon" && uri != "web" ) . map ( ( uriKey , index , array ) =>
270
+ < span key = { uriKey } >
271
+ < a href = { metadataInfo ?. tokenMetadata ?. uris [ uriKey ] } target = '_blank' rel = "noreferrer" style = { { display : "inline-block" , color : "#00E" } } > { uriKey } </ a >
272
+ { ( index != array . length - 1 ) ? ", " : null }
273
+ </ span >
274
+ ) : "none" } < br /> < br />
275
+ </ > :null }
266
276
{ metadataInfo && metadataInfo . tokenMetadata ? (
267
277
< >
268
278
{ metadataInfo . tokenMetadata . uris ?. icon && tokenIconUri ? < >
@@ -294,38 +304,35 @@ export default function Home() {
294
304
) :null }
295
305
</ >
296
306
) :null }
307
+ { tokenInfo . totalSupplyNFTs ? (
308
+ < >
309
+ has active minting NFT: { tokenInfo . hasActiveMintingToken ? "yes" :"no" } < br /> < br />
310
+ </ >
311
+ ) :null }
297
312
{ metadataInfo ?. httpsUrl ?
298
313
( < >
299
314
Number of user-addresses holding { metadataInfo ?. tokenMetadata ?. token ?. symbol ?? 'the token' } : { tokenInfo . numberHolders } < br /> < br />
300
315
Total number of addresses holding { metadataInfo ?. tokenMetadata ?. token ?. symbol ?? 'the token' } (including smart contracts):
301
316
{ tokenInfo . numberTokenAddresses } < br /> < br />
302
317
</ > ) :null }
303
- { metadataInfo . tokenMetadata . uris ? < >
304
- web url: { metadataInfo . tokenMetadata . uris ?. web ? < a href = { metadataInfo . tokenMetadata . uris ?. web } target = '_blank' rel = "noreferrer" style = { { display : "inline-block" , color : "#00E" } } >
305
- { metadataInfo . tokenMetadata . uris ?. web }
306
- </ a > : "none" } < br /> < br />
307
- other uris: { Object . keys ( metadataInfo . tokenMetadata . uris ) . filter ( uri => uri != "icon" && uri != "web" ) . length ?
308
- Object . keys ( metadataInfo . tokenMetadata . uris ) . filter ( uri => uri != "icon" && uri != "web" ) . map ( ( uriKey , index , array ) =>
309
- < span key = { uriKey } >
310
- < a href = { metadataInfo ?. tokenMetadata ?. uris [ uriKey ] } target = '_blank' rel = "noreferrer" style = { { display : "inline-block" , color : "#00E" } } > { uriKey } </ a >
311
- { ( index != array . length - 1 ) ? ", " : null }
312
- </ span >
313
- ) : "none" } < br /> < br />
314
- </ > :null }
315
318
</ > ) :null }
316
- { metadataInfo ?. httpsUrl ?
319
+ genesis transaction: < a href = { "https://explorer.electroncash.de/tx/" + tokenInfo . genesisTx } target = "_blank" rel = "noreferrer" >
320
+ { tokenInfo . genesisTx }
321
+ </ a > < br />
322
+ timestamp genesis transaction: { formatTimestamp ( tokenInfo . genesisTxTimestamp ) } < br /> < br />
323
+ { metadataInfo ? < >
324
+ authChain length: { tokenInfo . authchainLength } < br /> < br />
325
+ authChain metadata updates: { metadataInfo . authchainUpdates } < br /> < br />
326
+ authHead txid: < a href = { "https://explorer.electroncash.de/tx/" + tokenInfo . authHead } target = "_blank" rel = "noreferrer" >
327
+ { tokenInfo . authHead }
328
+ </ a > < br />
329
+ { metadataInfo ?. httpsUrl ?
317
330
( < >
318
331
location metadata:
319
332
< a href = { metadataInfo . httpsUrl } target = "_blank" rel = "noreferrer" style = { { maxWidth : "570px" , wordBreak : "break-all" , display : "inline-block" , color : "#00E" } } >
320
333
{ metadataInfo . metaDataLocation }
321
334
</ a > < br /> < br />
322
335
</ > ) :null }
323
- { metadataInfo ? < >
324
- authChain length: { tokenInfo . authchainLength } < br /> < br />
325
- authChain metadata updates: { metadataInfo . authchainUpdates } < br /> < br />
326
- authHead txid: < a href = { "https://explorer.electroncash.de/tx/" + tokenInfo . authHead } target = "_blank" rel = "noreferrer" >
327
- { tokenInfo . authHead }
328
- </ a > < br />
329
336
{ metadataInfo ?. authchainUpdates ? < >
330
337
metadata hash matches: { metadataInfo . metadataHashMatch ? "✅" :"❌" } < br /> < br />
331
338
</ > : null }
0 commit comments