forked from shig2k1/Hicetnunc-Burn-contract-poll
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathget-history-to-number.js
175 lines (151 loc) · 6.18 KB
/
get-history-to-number.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
const fetch = require('node-fetch')
var Airtable = require('airtable');
// go back in time until the desired transaction hash is found
const QUERY_URL = `https://api.tzkt.io/v1/accounts/KT1RJ6PbjHpwc3M5rw5s2Nbmefwbuwbdxton/operations?sort=1&limit=1000&status=applied`
const TOKEN_ID = '81257' // the token id for the burned token on H=N
// the following values should probably be in environment variables
const BASE_ID = '' // your airtable baseid
const API_KEY = '' // your airtable api key
var base = new Airtable({ apiKey: API_KEY }).base(BASE_ID)
let level = 0
// this function adds records to the data store - in this case I have it set up for the columsn of data I need to know about fish token burns
// you could change these to whatever is relevant to you
async function addRecords (records) {
console.log('adding...', records)
return new Promise((resolve, reject) => {
base('Breeding Table').create(records, function(err, records) {
if (err) reject(err)
if (records && records.length > 0) {
const r = [ ...records ]
r.forEach((record) =>{
const { BreederName, BreederTZ, BurnTxnID, BurnCounter } = record.fields
console.log(`New fish! : Breeder ${BreederName} ${BreederTZ} - Hash ${BurnTxnID} : ${BurnCounter}`)
})
}
resolve(records)
})
})
}
async function batchChangesInSets (arrData, func) {
if (arrData.length > 0) {
// break added up into sets of 10 & update
const addAll = [ ...arrData ]
while(addAll.length > 0) {
const toAdd = []
for(let i=0; i< ((addAll.length > 10) ? 10 : addAll.length); i++) {
toAdd.push(addAll.shift())
}
const results = await func(toAdd)
console.log('added', results)
}
}
}
const newBurns = [] // array to hold new burn information
async function getTransactions (burnHistory) {
const query = level === 0 ? `` : `&level.le=${level}`
fetch(`${QUERY_URL}${query}`, {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
})
.then(res => res.json())
.then(async data => {
// iterate over every item - return true if found the last known item
const found = data
// filter out the burn contract calls
.filter(row => {
return row.parameters.match(/tz1burnburnburnburnburnburnburjAYjjX/g) !== null
})
.reduce((prev, curr) => {
if (!!prev) return prev// don't go deeper than known item
//console.log(curr)
if (curr.parameter?.value[0]?.txs[0].token_id == TOKEN_ID) newBurns.push(curr)
if (curr.id === lastKnownTransaction) return true
return prev
}, false)
// if is a burn of our token, add to array
if (!found) {
console.log('not found last known transaction - going deeper', level)
level = data[data.length - 1].level
return getTransactions(burnHistory)
} else {
// get the new data out - ensuring it hasn't somehow collided with old data
const fieldData = newBurns
.filter(txn => !burnHistory.includes(txn.hash))
.map(txn => {
// check the txn parameters - just in case the sender has burned more than one token
const { id, level, timestamp, hash, sender, parameters } = txn
const params = JSON.parse(parameters)
// this looks inside the burn contract to get the quantity
const count = parseInt(params.value[0].args[1][0].args[1].args[1].int)
//console.log(JSON.stringify(params))
return {
TransactionID: id, // store the transaction ID - we can use this later if we need to find all transations which have happened since
TransactionLevel: level,
BurnTxnID: hash,
BreederTZ: sender.address,
BreederName: sender.alias || '',
DOB: timestamp,
Status: 'pending',
count
}
})
.reduce((prev, current) => {
if (current.count === 1) prev.push(current)
else {
const records = []
for (let i=0; i< current.count; i++) {
records.push({ ...current, BurnCounter: i })
}
prev = [ ...prev, ...records ]
}
return prev
}, [])
// remove count
.map(({ TransactionID, TransactionLevel, BurnTxnID, BreederTZ, BreederName, DOB, Status, BurnCounter }) => {
if (!BurnCounter) BurnCounter = 0
return {
fields: { TransactionID, TransactionLevel, BurnTxnID, BreederTZ, BreederName, DOB, Status, BurnCounter }
}
})
// the data came in backwards, so reverse before saving so IDs are correct
.reverse()
if (fieldData.length > 0) {
try {
console.log('batching')
await batchChangesInSets(fieldData, addRecords)
} catch(err) {
console.log('ERROR!', err)
}
}
}
})
}
const burnHistory = []
let lastKnownTransaction
// the script starts by fetching all the previously known burns from the data store - this ensures that burn transaction data isn't recorded twice
// it records the last transaction it saw as "lastKnownTransaction"
// IF THIS IS THE FIRST TIME YOU'VE EVER RUN THIS, YOU'LL PROBABLY WANT TO SET A DEFINITIVE VALUE FOR LAST KNOWN TRANSACTION, BECAUSE OTHERWISE
// IT'LL JUST RUN UNTIL IT'S TRAVERSED THE ENTIRE HISTORY OF TEZOS 1000 BLOCKS AT A TIME
base('Breeding Table').select({
// get the last record
maxRecords: 1000,
sort: [{field: "ID", direction: "asc"}],
view: "Grid view"
}).eachPage((records, fetchNextPage) => {
// This function (`page`) will get called for each page of records.
console.log(records.length)
//console.log('records', records)
records.forEach((record) => {
burnHistory.push(record.fields.BurnTxnID)
lastKnownTransaction = record.fields.TransactionID
});
// To fetch the next page of records, call `fetchNextPage`.
// If there are more records, `page` will get called again.
// If there are no more records, `done` will get called.
fetchNextPage();
}, function done(err) {
console.log(`last known transaction = `, lastKnownTransaction )
getTransactions(burnHistory)
if (err) { console.error(err); return; }
});
//getTransactions()