@@ -7,7 +7,7 @@ const Papa = require('papaparse')
7
7
const ethersProvider = new ethers . JsonRpcProvider (
8
8
'https://ethereum.publicnode.com'
9
9
)
10
- console . info ( 'ethersProvider:' , ethersProvider )
10
+ console . debug ( 'ethersProvider:' , ethersProvider )
11
11
12
12
const passportContract = new ethers . Contract (
13
13
'0x3337dac9f251d4e403d6030e18e3cfb6a2cb1333' ,
@@ -23,50 +23,58 @@ loadPassportMintsByWeek()
23
23
async function loadPassportMintsByWeek ( ) {
24
24
console . info ( 'loadPassportMintsByWeek' )
25
25
26
+ const revocations = await fetchRevocations ( )
27
+ console . debug ( 'revocations:' , revocations )
28
+
26
29
const writer = csvWriter . createObjectCsvWriter ( {
27
30
path : 'output/citizen-count-per-week.csv' ,
28
31
header : [
29
32
{ id : 'week_end' , title : 'week_end' } ,
30
33
{ id : 'total_citizens' , title : 'total_citizens' } ,
31
34
{ id : 'new_citizens' , title : 'new_citizens' } ,
32
- { id : 'total_expired_passports' , title : 'total_expired_passports' }
35
+ { id : 'total_expired_passports' , title : 'total_expired_passports' } ,
36
+ { id : 'total_revoked_passports' , title : 'total_revoked_passports' }
33
37
]
34
38
} )
35
39
let csvRows = [ ]
36
40
37
41
const nextId : number = await getNextId ( )
38
- console . info ( 'nextId:' , nextId )
42
+ console . debug ( 'nextId:' , nextId )
39
43
40
44
let id : number = 0
41
45
42
46
// Iterate every week from the week of [Sun May-29-2022 → Sun Jun-05-2022] until now
43
47
const weekEndDate : Date = new Date ( '2022-06-05T00:00:00Z' )
44
- console . info ( 'weekEndDate:' , weekEndDate )
48
+ console . debug ( 'weekEndDate:' , weekEndDate )
45
49
const nowDate : Date = new Date ( )
46
- console . info ( 'nowDate:' , nowDate )
50
+ console . debug ( 'nowDate:' , nowDate )
47
51
while ( nowDate . getTime ( ) > weekEndDate . getTime ( ) ) {
48
52
const weekBeginDate : Date = new Date ( weekEndDate . getTime ( ) - 7 * 24 * 60 * 60 * 1000 )
49
- console . info ( 'week:' , `[${ weekBeginDate . toISOString ( ) } → ${ weekEndDate . toISOString ( ) } ]` )
53
+ console . debug ( 'week:' , `[${ weekBeginDate . toISOString ( ) } → ${ weekEndDate . toISOString ( ) } ]` )
50
54
51
55
let newCitizensCount : number = 0
52
56
while ( ( id < nextId ) && ( await getTimestamp ( id ) < ( weekEndDate . getTime ( ) / 1000 ) ) ) {
53
- console . info ( 'id:' , id )
57
+ console . debug ( 'id:' , id )
54
58
55
59
newCitizensCount ++
56
- console . info ( 'newCitizensCount:' , newCitizensCount )
60
+ console . debug ( 'newCitizensCount:' , newCitizensCount )
57
61
58
62
id ++
59
63
}
60
64
61
65
const totalExpiredPassports : number = getTotalExpiredPassports ( weekEndDate , id )
62
- console . info ( 'totalExpiredPassports:' , totalExpiredPassports )
66
+ console . debug ( 'totalExpiredPassports:' , totalExpiredPassports )
67
+
68
+ const totalRevokedPassports : number = getTotalRevokedPassports ( weekEndDate , id , revocations )
69
+ console . debug ( 'totalRevokedPassports:' , totalRevokedPassports )
63
70
64
71
// Export to CSV
65
72
const csvRow = {
66
73
week_end : weekEndDate . toISOString ( ) . substring ( 0 , 10 ) ,
67
74
total_citizens : id ,
68
75
new_citizens : newCitizensCount ,
69
- total_expired_passports : totalExpiredPassports
76
+ total_expired_passports : totalExpiredPassports ,
77
+ total_revoked_passports : totalRevokedPassports
70
78
}
71
79
csvRows . push ( csvRow )
72
80
@@ -92,33 +100,36 @@ async function getTimestamp(id: number): Promise<number> {
92
100
}
93
101
}
94
102
103
+ /**
104
+ * Calculates the total number of expired passports up until `weekEndDate`
105
+ */
95
106
function getTotalExpiredPassports ( weekEndDate : Date , maxPassportID : number ) : number {
96
107
console . info ( 'getTotalExpiredPassports' )
97
108
98
109
const weekEndDateString : string = weekEndDate . toISOString ( ) . substring ( 0 , 10 )
99
110
100
111
let totalExpiredPassports = 0
101
112
for ( let passportID = 0 ; passportID < maxPassportID ; passportID ++ ) {
102
- console . info ( `weekEndDate: ${ weekEndDateString } , passportID: ${ passportID } ` )
113
+ // console.debug (`weekEndDate: ${weekEndDateString}, passportID: ${passportID}`)
103
114
104
115
// Fetch voting escrow data from the citizen's data CSV
105
116
const citizenFilePath : string = `output/citizen-${ passportID } .csv`
106
- console . info ( 'Fetching citizen data:' , citizenFilePath )
117
+ // console.debug ('Fetching citizen data:', citizenFilePath)
107
118
const file : File = fs . readFileSync ( citizenFilePath )
108
119
const csvData = file . toString ( )
109
- // console.info ('csvData:\n', csvData)
120
+ // console.debug ('csvData:\n', csvData)
110
121
Papa . parse ( csvData , {
111
122
header : true ,
112
123
skipEmptyLines : true ,
113
124
dynamicTyping : true ,
114
125
complete : ( result : any ) => {
115
- // console.info ('result:', result)
126
+ // console.debug ('result:', result)
116
127
result . data . forEach ( ( row : any , i : number ) => {
117
128
if ( row . week_end == weekEndDateString ) {
118
- console . info ( `row.week_end ${ row . week_end } , row.voting_escrow: ${ row . voting_escrow } ` )
129
+ // console.debug (`row.week_end ${row.week_end}, row.voting_escrow: ${row.voting_escrow}`)
119
130
if ( row . voting_escrow < 1.5 ) {
120
131
// https://etherscan.io/address/0x279c0b6bfcbba977eaf4ad1b2ffe3c208aa068ac#readContract#F9
121
- console . info ( 'Passport ID expired:' , passportID )
132
+ // console.debug ('Passport ID expired:', passportID)
122
133
totalExpiredPassports ++
123
134
}
124
135
}
@@ -130,4 +141,60 @@ function getTotalExpiredPassports(weekEndDate: Date, maxPassportID: number): num
130
141
return totalExpiredPassports
131
142
}
132
143
144
+ /**
145
+ * Calculates the total number of revoked passports up until `weekEndDate`
146
+ */
147
+ function getTotalRevokedPassports ( weekEndDate : Date , maxPassportID : number , revocations : any ) : number {
148
+ console . info ( 'getTotalRevokedPassports' )
149
+
150
+ const weekEndDateString : string = weekEndDate . toISOString ( ) . substring ( 0 , 10 )
151
+
152
+ let totalRevokedPassports = 0
153
+ for ( let passportID = 0 ; passportID < maxPassportID ; passportID ++ ) {
154
+ // console.debug(`weekEndDate: ${weekEndDateString}, passportID: ${passportID}`)
155
+
156
+ revocations . forEach ( ( row : any , i : number ) => {
157
+ // console.debug('row:', row)
158
+ const blockTimestamp : number = Number ( row . blockTimestamp )
159
+ const revocationDate : Date = new Date ( blockTimestamp * 1_000 )
160
+ // console.debug('revocationDate:', revocationDate)
161
+ if ( revocationDate . getTime ( ) <= weekEndDate . getTime ( ) ) {
162
+ const tokenID : number = Number ( row . _tokenId )
163
+ // console.debug('tokenID:', tokenID)
164
+ if ( tokenID == passportID ) {
165
+ console . debug ( 'Passport ID revoked:' , passportID )
166
+ totalRevokedPassports ++
167
+ }
168
+ }
169
+ } )
170
+ }
171
+
172
+ return totalRevokedPassports
173
+ }
174
+
175
+ async function fetchRevocations ( ) {
176
+ console . info ( 'fetchRevocations' )
177
+
178
+ // https://github.com/nation3/subgraphs/blob/main/passportissuance/schema.graphql
179
+ const GRAPHQL_URL : string = 'https://api.thegraph.com/subgraphs/name/nation3/passportissuance'
180
+ const response = await fetch ( GRAPHQL_URL , {
181
+ method : 'POST' ,
182
+ body : JSON . stringify ( {
183
+ query : `
184
+ {
185
+ revokes(first: 420) {
186
+ _tokenId
187
+ blockTimestamp
188
+ }
189
+ }
190
+ `
191
+ } )
192
+ } )
193
+
194
+ const { data } = await response . json ( )
195
+ console . debug ( 'data:' , data )
196
+
197
+ return data . revokes
198
+ }
199
+
133
200
export { }
0 commit comments