1
1
import blockies from "ethereum-blockies-base64"
2
+ import { unstable_cache as cache } from "next/cache"
2
3
import type { Address } from "viem"
3
4
import { getPublicClient } from "@wagmi/core"
4
5
@@ -25,7 +26,7 @@ export const isAddressFiltered = (address: string): boolean => {
25
26
type TransferEvent = {
26
27
from : Address
27
28
to : Address
28
- blockNumber : bigint
29
+ blockNumber : number
29
30
transactionHash : string
30
31
timestamp : number
31
32
}
@@ -46,59 +47,63 @@ export type TorchHolderEvent = TorchHolder & {
46
47
event : TransferEvent
47
48
}
48
49
49
- export const getTransferEvents = async ( ) => {
50
- const publicClient = getPublicClient ( config )
51
-
52
- // Get the current block number to ensure consistent results
53
- const currentBlock = await publicClient . getBlockNumber ( )
54
-
55
- // Get Transfer events from the contract
56
- // ERC721 Transfer event signature: Transfer(address indexed from, address indexed to, uint256 indexed tokenId)
57
- const logs = await publicClient . getLogs ( {
58
- address : TORCH_CONTRACT_ADDRESS ,
59
- event : {
60
- type : "event" ,
61
- name : "Transfer" ,
62
- inputs : [
63
- { name : "from" , type : "address" , indexed : true } ,
64
- { name : "to" , type : "address" , indexed : true } ,
65
- { name : "tokenId" , type : "uint256" , indexed : true } ,
66
- ] ,
67
- } ,
68
- args : {
69
- tokenId : BigInt ( 1 ) , // Torch NFT token ID is always 1
70
- } ,
71
- fromBlock : BigInt ( TORCH_BLOCK_NUMBER ) || "earliest" ,
72
- toBlock : currentBlock ,
73
- } )
74
-
75
- // Process logs and get timestamps
76
- const transferEvents : TransferEvent [ ] = [ ]
77
-
78
- for ( const log of logs ) {
79
- if ( log . args ?. from && log . args ?. to ) {
80
- // Get block details to get timestamp
81
- const block = await publicClient . getBlock ( {
82
- blockNumber : log . blockNumber ,
83
- } )
84
-
85
- transferEvents . push ( {
86
- from : log . args . from as Address ,
87
- to : log . args . to as Address ,
88
- blockNumber : log . blockNumber ,
89
- transactionHash : log . transactionHash ,
90
- timestamp : Number ( block . timestamp ) ,
91
- } )
50
+ export const getTransferEvents = cache (
51
+ async ( ) => {
52
+ const publicClient = getPublicClient ( config )
53
+
54
+ // Get the current block number to ensure consistent results
55
+ const currentBlock = await publicClient . getBlockNumber ( )
56
+
57
+ // Get Transfer events from the contract
58
+ // ERC721 Transfer event signature: Transfer(address indexed from, address indexed to, uint256 indexed tokenId)
59
+ const logs = await publicClient . getLogs ( {
60
+ address : TORCH_CONTRACT_ADDRESS ,
61
+ event : {
62
+ type : "event" ,
63
+ name : "Transfer" ,
64
+ inputs : [
65
+ { name : "from" , type : "address" , indexed : true } ,
66
+ { name : "to" , type : "address" , indexed : true } ,
67
+ { name : "tokenId" , type : "uint256" , indexed : true } ,
68
+ ] ,
69
+ } ,
70
+ args : {
71
+ tokenId : BigInt ( 1 ) , // Torch NFT token ID is always 1
72
+ } ,
73
+ fromBlock : BigInt ( TORCH_BLOCK_NUMBER ) || "earliest" ,
74
+ toBlock : currentBlock ,
75
+ } )
76
+
77
+ // Process logs and get timestamps
78
+ const transferEvents : TransferEvent [ ] = [ ]
79
+
80
+ for ( const log of logs ) {
81
+ if ( log . args ?. from && log . args ?. to ) {
82
+ // Get block details to get timestamp
83
+ const block = await publicClient . getBlock ( {
84
+ blockNumber : log . blockNumber ,
85
+ } )
86
+
87
+ transferEvents . push ( {
88
+ from : log . args . from as Address ,
89
+ to : log . args . to as Address ,
90
+ blockNumber : Number ( log . blockNumber ) ,
91
+ transactionHash : log . transactionHash ,
92
+ timestamp : Number ( block . timestamp ) ,
93
+ } )
94
+ }
92
95
}
93
- }
94
96
95
- // Sort by block number (oldest first)
96
- transferEvents . sort ( ( a , b ) => Number ( a . blockNumber - b . blockNumber ) )
97
+ // Sort by block number (oldest first)
98
+ transferEvents . sort ( ( a , b ) => a . blockNumber - b . blockNumber )
97
99
98
- return transferEvents
99
- }
100
+ return transferEvents
101
+ } ,
102
+ [ "torch-transfer-events" ] ,
103
+ { revalidate : 86400 }
104
+ )
100
105
101
- const getHolderEvents = async (
106
+ export const getHolderEvents = async (
102
107
torchHolderMap : Record < string , TorchHolderMetadata > ,
103
108
transferEvents : TransferEvent [ ]
104
109
) => {
@@ -135,47 +140,38 @@ const getHolderEvents = async (
135
140
} )
136
141
}
137
142
138
- export const getHolders = async (
139
- torchHolderMap : Record < string , TorchHolderMetadata >
140
- ) => {
141
- const transferEvents = await getTransferEvents ( )
142
- const torchHoldersEvents = await getHolderEvents (
143
- torchHolderMap ,
144
- transferEvents
145
- )
146
-
147
- // Filter out events where the address is in the filtered list
148
- const filteredHoldersEvents = torchHoldersEvents . filter (
149
- ( holder ) => ! isAddressFiltered ( holder . address )
150
- )
151
-
152
- return filteredHoldersEvents
153
- }
154
-
155
- export const getCurrentHolderAddress = async ( ) => {
156
- const publicClient = getPublicClient ( config )
157
-
158
- // If not burned, get the current holder
159
- const currentHolderAddress = ( await publicClient . readContract ( {
160
- address : TORCH_CONTRACT_ADDRESS ,
161
- abi : TORCH_ABI ,
162
- functionName : "currentHolder" ,
163
- } ) ) as Address
164
-
165
- return currentHolderAddress
166
- }
167
-
168
- export const isTorchBurned = async ( ) => {
169
- const publicClient = getPublicClient ( config )
170
-
171
- const isBurned = ( await publicClient . readContract ( {
172
- address : TORCH_CONTRACT_ADDRESS ,
173
- abi : TORCH_ABI ,
174
- functionName : "isBurned" ,
175
- } ) ) as boolean
176
-
177
- return isBurned
178
- }
143
+ export const getCurrentHolderAddress = cache (
144
+ async ( ) => {
145
+ const publicClient = getPublicClient ( config )
146
+
147
+ // If not burned, get the current holder
148
+ const currentHolderAddress = ( await publicClient . readContract ( {
149
+ address : TORCH_CONTRACT_ADDRESS ,
150
+ abi : TORCH_ABI ,
151
+ functionName : "currentHolder" ,
152
+ } ) ) as Address
153
+
154
+ return currentHolderAddress
155
+ } ,
156
+ [ "torch-current-holder" ] ,
157
+ { revalidate : 86400 }
158
+ )
159
+
160
+ export const isTorchBurned = cache (
161
+ async ( ) => {
162
+ const publicClient = getPublicClient ( config )
163
+
164
+ const isBurned = ( await publicClient . readContract ( {
165
+ address : TORCH_CONTRACT_ADDRESS ,
166
+ abi : TORCH_ABI ,
167
+ functionName : "isBurned" ,
168
+ } ) ) as boolean
169
+
170
+ return isBurned
171
+ } ,
172
+ [ "torch-burned-status" ] ,
173
+ { revalidate : 86400 }
174
+ )
179
175
180
176
export const getBlockieImage = ( address : Address ) => {
181
177
return blockies ( address )
0 commit comments