@@ -13,69 +13,85 @@ import { Ddao__factory } from '../../types/ethers-contracts/factories/Ddao__fact
13
13
const MAX_SUPPLY = 8000 ;
14
14
const PUBLIC_MAX_SUPPLY = 7777 ;
15
15
16
- export default function useDevNFTSupply ( ) {
16
+ export function useDevNFTSupply ( ) {
17
17
const [ totalSupply , setTotalSupply ] = useState < number > ( - 1 ) ;
18
18
const [ lockedSupply , setLockedSupply ] = useState < number > ( - 1 ) ;
19
+ const [ uniqueTokenHolderCount , setUniqueTokenHolderCount ] =
20
+ useState < number > ( - 1 ) ;
19
21
20
22
useEffect ( ( ) => {
21
- const contract = Ddao__factory . connect (
22
- DEVELOPER_DAO_CONTRACT ,
23
- new FallbackProvider ( [
24
- { provider : new InfuraProvider ( ) } ,
25
- { provider : new AlchemyProvider ( ) } ,
26
- ] ) ,
27
- ) ;
28
-
29
- // Fetches the count of minted DEV NFTs
30
- const fetchTotalSupply = async ( ) => {
31
- const totalSupply : number = ( await contract . totalSupply ( ) ) . toNumber ( ) ;
32
- setTotalSupply ( totalSupply ) ;
33
- } ;
23
+ const fetch = async ( ) => {
24
+ const contract = Ddao__factory . connect (
25
+ DEVELOPER_DAO_CONTRACT ,
26
+ new FallbackProvider ( [
27
+ { provider : new InfuraProvider ( ) } ,
28
+ { provider : new AlchemyProvider ( ) } ,
29
+ ] ) ,
30
+ ) ;
31
+
32
+ // Get all TransferEvents
33
+ const transferredTokens = await contract . queryFilter (
34
+ contract . filters . Transfer ( ) ,
35
+ 0 ,
36
+ 'latest' ,
37
+ ) ;
38
+
39
+ // Track the latest owner of each token
40
+ const claimedTokens : Record < string , string > = { } ;
41
+ transferredTokens . forEach ( ( tx ) => {
42
+ const tokenId = tx . args . tokenId . toNumber ( ) ;
43
+ claimedTokens [ tokenId ] = tx . args . to ;
44
+ } ) ;
45
+
46
+ // Amount of minted tokens
47
+ const totalSupply = Object . keys ( claimedTokens ) . length ;
34
48
35
- // Counts how many tokens of the locked supply have been minted
36
- const fetchLockedSupply = async ( ) => {
37
- const requests = [ ] ;
49
+ // Put the addresses in a set to get the amount of unique addresses
50
+ const uniqueAddresses = new Set < string > ( Object . values ( claimedTokens ) ) ;
38
51
52
+ // Count how many tokens of the locked supply have been minted
53
+ let countLockedAndMinted = 0 ;
39
54
for (
40
55
let lockedTokenId = PUBLIC_MAX_SUPPLY + 1 ;
41
56
lockedTokenId <= MAX_SUPPLY ;
42
57
lockedTokenId ++
43
58
) {
44
- requests . push (
45
- contract . ownerOf ( lockedTokenId ) . then (
46
- // Return the owner's address
47
- ( addressResponse ) => addressResponse ,
48
- // Return the zero-address if no owner was found
49
- ( ) => ethers . constants . AddressZero ,
50
- ) ,
51
- ) ;
59
+ if (
60
+ claimedTokens [ lockedTokenId ] &&
61
+ claimedTokens [ lockedTokenId ] !== ethers . constants . AddressZero
62
+ )
63
+ countLockedAndMinted ++ ;
52
64
}
53
65
54
- const addresses = await Promise . all ( requests ) ;
55
-
56
- const countMinted = addresses . reduce (
57
- ( count , address ) =>
58
- address !== ethers . constants . AddressZero ? ++ count : count ,
59
- 0 ,
60
- ) ;
61
-
62
- setLockedSupply ( countMinted ) ;
66
+ setLockedSupply ( countLockedAndMinted ) ;
67
+ setTotalSupply ( totalSupply ) ;
68
+ setUniqueTokenHolderCount ( uniqueAddresses . size ) ;
63
69
} ;
64
70
65
- fetchTotalSupply ( ) ;
66
- fetchLockedSupply ( ) ;
71
+ fetch ( ) ;
67
72
} , [ ] ) ;
68
73
69
74
return {
70
- isLoading : totalSupply === - 1 || lockedSupply === - 1 ,
75
+ isLoading :
76
+ totalSupply === - 1 ||
77
+ lockedSupply === - 1 ||
78
+ uniqueTokenHolderCount === - 1 ,
79
+
71
80
// This is the amount of total minted DEV NFTs, same as calling `totalSupply()` on the contract
72
81
totalSupply,
82
+
83
+ // Count of unique token holder addresses
84
+ uniqueTokenHolders : uniqueTokenHolderCount ,
85
+
73
86
// This is the amount of minted DEV NFTs that only the contract owner can mint (TokenIDs 7778-8000, incl.)
74
87
lockedSupply,
88
+
75
89
// This is the amount of publicly minted DEV NFTs, which is open to mint by anyone (TokenIDs 1-7777, incl.)
76
90
publicSupply : totalSupply - lockedSupply ,
91
+
77
92
// Total number of possible DEV NFT. This is a constant that cannot be changed
78
93
maxSupply : MAX_SUPPLY ,
94
+
79
95
// Some calculations to make these values easily accessible for display in UI
80
96
remainingTotalSupply : MAX_SUPPLY - totalSupply ,
81
97
remainingPublicSupply : PUBLIC_MAX_SUPPLY - ( totalSupply - lockedSupply ) ,
0 commit comments