[개발] steem-punks 판매량 정보 가져오기
[스샷 - 대략 22.03.18 08시 기준 정보]
스팀 펑크에서는 graphql 을 제공합니다.
https://www.steempunks.xyz/graphql
위에서 정보를 가져와 판매량 정보를 계산할 수 있습니다 :)
( scrap.js ) - graphql 을 이용하여 1만개의 nft 정보를 가져올 수 있도록 구성합니다.
import fetch from "node-fetch";
function _getOp(id) {
return {
operationName: null,
query: `{\n getMyNFTDetail(SteempunksNFTInput: {id: ${id}}) {\n success\n steempunksNFT {\n id\n score\n ranking\n rarity\n owner_account\n }\n }\n}\n`,
variables: {},
};
}
async function _call(id, url = GRAPH_URL) {
return fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(_getOp(id)),
})
.then((res) => res.json())
.then((res) =>
res.data.getMyNFTDetail ? res.data.getMyNFTDetail.steempunksNFT : {}
);
}
export default async function status() {
let start = 0;
let end = 0;
let results = [];
let buffer = [];
const MAX_LOOP = 50;
const MAX_COUNT = 9999;
const PER_COUNT = 200;
const SLEEP_SEC = 1000 * 1;
for (let k = 0; k < MAX_LOOP; k++) {
start = k * PER_COUNT;
end = Math.min(PER_COUNT + k * PER_COUNT, MAX_COUNT);
for (let i = start; i < end; i++) {
buffer.push(_call(i));
}
await Promise.all(buffer).then((res) => results.push(...res));
await new Promise((r) => setTimeout(r, SLEEP_SEC));
buffer = [];
console.log(k + 1, "/", MAX_LOOP);
}
return results;
}
( save.js ) - 이렇게 가져온 정보를 파일에 기록 합니다.
import fs from "fs";
import status from "./scrap.js";
status().then((res) => {
fs.writeFileSync("./output.json", JSON.stringify(res, null, 2));
console.log(res);
});
( print.js ) - 나름 보기 쉽게 화면에 출력 해 봅니다. ( node-canvas 를 통해 이미지로 만들면 더 좋지만 그냥 귀찮으니 pass )
import fs from "fs";
let ori = JSON.parse(fs.readFileSync("./output.json"));
let lpad = (s, len = 20, char = " ") => s.toString().padStart(len, char);
let rpad = (s, len = 20, char = " ") => s.toString().padEnd(len, char);
let print = (...s) => console.log(lpad(s[0]), ...s.slice(1));
let line = (len, char = "=") => console.log(rpad("", len, char));
line(40);
print("PACKS INFO");
line(40);
print("TOTAL PACKS : ", ori.length / 10);
let notyet = ori.filter((x) => x.owner_account == null);
print("SELL PACKS : ", (ori.length - notyet.length) / 10);
print("REMAIN PACKS : ", notyet.length / 10);
line(40);
print("NFTs MINTING INFO");
line(40);
print("NFTs : ", ori.length);
let common = ori.filter((x) => x.rarity.indexOf("C") == 0);
let rare = ori.filter((x) => x.rarity.indexOf("R") == 0);
let epic = ori.filter((x) => x.rarity.indexOf("E") == 0);
let legendary = ori.filter((x) => x.rarity.indexOf("L") == 0);
let c1 = ori.filter(
(x) => x.rarity.indexOf("C") == 0 && x.owner_account != null
);
print(
"COMMON NFTs : ",
common.length - c1.length,
"/",
c1.length,
"/",
common.length
);
let r1 = ori.filter(
(x) => x.rarity.indexOf("R") == 0 && x.owner_account != null
);
print(
"RARE NFTs : ",
rare.length - r1.length,
"/",
r1.length,
"/",
rare.length
);
let e1 = ori.filter(
(x) => x.rarity.indexOf("E") == 0 && x.owner_account != null
);
print(
"EPIC NFTs : ",
epic.length - e1.length,
"/",
e1.length,
"/",
epic.length
);
let l1 = ori.filter(
(x) => x.rarity.indexOf("L") == 0 && x.owner_account != null
);
print(
"LEGENDARY NFTs : ",
legendary.length - l1.length,
"/",
l1.length,
"/",
legendary.length
);
line(40);
print("BUY PACKS TOP 10");
line(40);
// let EXCEPT_IDS = ["null", "happyberrysboy", "donekim", "realmankwon"];
let EXCEPT_IDS = ["null"];
let buy_buffer = {};
for (let r of ori) {
buy_buffer[r.owner_account] = buy_buffer[r.owner_account]
? buy_buffer[r.owner_account] + 1
: 1;
}
let buy_buffer2 = [];
for (let kv of Object.entries(buy_buffer)) {
buy_buffer2.push({ id: kv[0], nfts: kv[1] });
}
buy_buffer2 = buy_buffer2.filter((x) => !EXCEPT_IDS.includes(x.id));
buy_buffer2.sort((a, b) => b.nfts - a.nfts);
for (let i = 0; i < 10; i++) {
console.log(
lpad(buy_buffer2[i].id),
" : ",
buy_buffer2[i].nfts / 10,
"packs"
);
}
line(40);
print("AVG PACKS BUY");
line(40);
let avg =
buy_buffer2.reduce((prev, curr) => {
return prev + curr.nfts;
}, 0) /
buy_buffer2.length /
10;
print("JOINED STEEMIANs", buy_buffer2.length);
print("AVG BUY PACKs", avg);
// console.log(buy_buffer2);
line(40);
print("Has Legendary Account");
line(40);
let legen_buffer = {};
for (let r of l1) {
legen_buffer[r.owner_account] = legen_buffer[r.owner_account]
? legen_buffer[r.owner_account] + 1
: 1;
}
let legen_buffer2 = [];
for (let kv of Object.entries(legen_buffer)) {
legen_buffer2.push({ id: kv[0], nfts: kv[1] });
}
legen_buffer2 = legen_buffer2.filter((x) => !EXCEPT_IDS.includes(x.id));
legen_buffer2.sort((a, b) => b.nfts - a.nfts);
for (let i = 0; i < legen_buffer2.length; i++) {
console.log(lpad(legen_buffer2[i].id), " : ", legen_buffer2[i].nfts, "nfts");
}
참 쉽...군요...(?!?!)
팩 판매량에 비해서 레전더리가 많이 풀렸네요.
@wonsama transfered 2 KRWP to @krwp.burn. voting percent : 62.10%, voting power : 17.75%, steem power : 1939938.08, STU KRW : 1200.
@wonsama staking status : 1793.429 KRWP
@wonsama limit for KRWP voting service : 1.793 KRWP (rate : 0.001)
What you sent : 2 KRWP
Refund balance : 0.207 KRWP [62513663 - 780fcda6f99d9a73915d165ef487d4385910bd24]
.... 코드 공유 감사합니당. 혹시.... 위에 코드를 복붙해서 실행하면 결과가 나오는 걸까요? 구글코랩에서 해보려구요. 코드 복붙은 할 수 있어서요^^
역시 전문가는 다르시군요~^^