-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.js
148 lines (124 loc) · 3.68 KB
/
app.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
import { createClient } from "@supabase/supabase-js";
import Web3 from "web3";
import Contract from "web3-eth-contract";
import dNFT_ABI from "./abi/dNFT.json" assert { type: "json" };
import * as dotenv from "dotenv";
import { sleep } from "./utils/sleep.js";
import { getEnsName } from "./utils/ensName.js";
dotenv.config();
const SYNC_LOG_SIGNATURE =
"0xff14d8520387b9b85d2a017dc41ae15db04a22d4c67deac04eb45048631ffa86";
const TIME_BETWEEN_NFT_INSERTIONS = 10; // ms
const supabase = createClient(
process.env.MODE === "DEV"
? process.env.SUPABASE_URL_DEV
: process.env.SUPABASE_URL_PROD,
process.env.MODE === "DEV"
? process.env.SUPABASE_KEY_DEV
: process.env.SUPABASE_KEY_PROD
);
var web3 = new Web3(process.env.INFURA_RPC);
Contract.setProvider(process.env.INFURA_RPC);
const dNftContract = new Contract(dNFT_ABI["abi"], process.env.dNFT_ADDRESS);
/**
* Get the dNFT with the given index and insert it into the nfts table.
* @param {i} index from 0 to totalSupply
* @param {nextVersion} version of the sync
*/
async function insertNft(tokenId, nextVersion) {
console.log(tokenId);
const nft = await dNftContract.methods.idToNft(tokenId).call();
const owner = await dNftContract.methods.ownerOf(tokenId).call();
const _nft = {
xp: nft.xp,
deposit: nft.deposit,
withdrawn: nft.withdrawal,
tokenId: tokenId,
owner: owner,
contractAddress: process.env.dNFT_ADDRESS,
version_id: nextVersion,
};
console.log(`insert ${tokenId}`);
const { error } = await supabase.from("nfts").insert(_nft);
console.log("insert", error);
}
async function getLastVersion() {
let lastVersion = await supabase
.from("versions")
.select("version")
.order("version", {
ascending: false,
})
.limit(1);
try {
return lastVersion.data[0].version;
} catch {
return 0;
}
}
async function insertNextVersion(nextVersion, syncId) {
console.log(`inserting next version: ${nextVersion}`);
const { error } = await supabase.from("versions").insert({
version: nextVersion,
contractAddress: process.env.dNFT_ADDRESS,
mode: process.env.MODE,
sync_id: syncId,
});
console.log(error);
}
async function upsertEns() {
const lastVersion = await getLastVersion();
const { data } = await supabase
.from("nfts")
.select("*")
.eq("version_id", lastVersion);
const owners = data.map((nft) => nft.owner);
const ensNames = await getEnsName(owners);
const ensObjects = owners.map((owner, i) => {
return {
address: owner,
ens: ensNames[i],
};
});
const { error } = await supabase.from("ens").upsert(ensObjects, {});
console.log("upsertEns error:", error);
}
/**
* Get all dNFTs for this sync version and insert them into the nfts table.
*/
async function insertNfts(event) {
const lastVersion = await getLastVersion();
const nextVersion = lastVersion + 1;
const syncId = parseEvent(event).syncId;
insertNextVersion(nextVersion, syncId);
const totalSupply = await dNftContract.methods.totalSupply().call();
for (let i = 0; i < totalSupply; i++) {
// without this supabase will throw an error, because of too many requests
await sleep(TIME_BETWEEN_NFT_INSERTIONS);
insertNft(i, nextVersion);
}
}
function parseEvent(event) {
return {
syncId: parseInt(event["data"]),
};
}
/**
* Listen to sync events. If a sync event is emitted, get all dNFTs and insert
* them into the nfts table.
*/
function subscribeToSync() {
console.log("subscribing to sync");
web3.eth.subscribe(
"logs",
{
address: process.env.dNFT_ADDRESS,
topics: [SYNC_LOG_SIGNATURE],
},
(_, event) => {
insertNfts(event);
// upsertEns();
}
);
}
subscribeToSync();