Skip to content

Instantly share code, notes, and snippets.

@anpigon
Last active January 14, 2024 01:24
Show Gist options
  • Save anpigon/3b99074a9d078bb90487d38d657ec5ed to your computer and use it in GitHub Desktop.
Save anpigon/3b99074a9d078bb90487d38d657ec5ed to your computer and use it in GitHub Desktop.
obsidian 노트앱의 Tamplater 플러그인용 스팀 수익 자동 조회 스크립트
'use strict';
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all) __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if ((from && typeof from === 'object') || typeof from === 'function') {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, {
get: () => from[key],
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable,
});
}
return to;
};
// src/main.ts
module.exports = main;
var ID = /* @__PURE__ */ ((ID2) => {
ID2['Follow'] = 'follow';
ID2['Notify'] = 'notify';
return ID2;
})(ID || {});
var MaxAcceptedPayout = /* @__PURE__ */ ((MaxAcceptedPayout2) => {
MaxAcceptedPayout2['The1000000000Sbd'] = '1000000.000 SBD';
return MaxAcceptedPayout2;
})(MaxAcceptedPayout || {});
var TentacledOp = /* @__PURE__ */ ((TentacledOp2) => {
TentacledOp2['CommentOptions'] = 'comment_options';
TentacledOp2['CustomJSON'] = 'custom_json';
TentacledOp2['DelegateVestingShares'] = 'delegate_vesting_shares';
return TentacledOp2;
})(TentacledOp || {});
var ConfidentialSbdSupply = /* @__PURE__ */ ((ConfidentialSbdSupply2) => {
ConfidentialSbdSupply2['The0000Sbd'] = '0.000 SBD';
return ConfidentialSbdSupply2;
})(ConfidentialSbdSupply || {});
var StickyOp = /* @__PURE__ */ ((StickyOp2) => {
StickyOp2['AuthorReward'] = 'author_reward';
StickyOp2['ClaimRewardBalance'] = 'claim_reward_balance';
StickyOp2['CommentBenefactorReward'] = 'comment_benefactor_reward';
StickyOp2['CurationReward'] = 'curation_reward';
StickyOp2['Transfer'] = 'transfer';
StickyOp2['TransferToVesting'] = 'transfer_to_vesting';
return StickyOp2;
})(StickyOp || {});
var HEADER = { 'content-type': 'application/json' };
function api(method, params) {
return fetch('https://api.steemit.com/', {
headers: HEADER,
method: 'POST',
body: JSON.stringify({
id: 0,
jsonrpc: '2.0',
method,
params,
}),
}).then((res) => res.json());
}
function call(params) {
return api('call', params);
}
function databaseApi(method, params) {
return call(['database_api', method, params]).then((res) => res.result);
}
function getVestingDelegations(username, start_account = '', limit = 1e3) {
return databaseApi('get_vesting_delegations', [username, start_account, limit]);
}
function getTransfers(username) {
return databaseApi('get_state', [`/@${username}/transfers`]);
}
function getAccountPosts(username, limit = 20) {
return api('bridge.get_account_posts', {
sort: 'posts',
account: username,
observer: username,
limit,
}).then((res) => res.result);
}
async function getCurrentSteemMarketPrice(timestamp) {
const urls = [
`https://api.upbit.com/v1/candles/days?market=KRW-STEEM&count=1&to=${timestamp}T23:59:59`,
`https://api.upbit.com/v1/candles/days?market=KRW-SBD&count=1&to=${timestamp}T23:59:59`,
];
const [steemResponse, sdbResponse] = await Promise.all(urls.map((url) => fetch(url).then((res) => res.json())));
return {
steem: steemResponse[0].trade_price,
sbd: sdbResponse[0].trade_price,
};
}
function calculateSteemPower(vest, total_vesting_fund_steem, total_vesting_shares) {
return parseFloat(
((parseFloat(vest) * parseFloat(total_vesting_fund_steem)) / parseFloat(total_vesting_shares)).toFixed(8),
);
}
async function main(username, timestamp) {
let results = '';
const KRW = await getCurrentSteemMarketPrice(timestamp);
const state = await getTransfers(username);
const { total_vesting_fund_steem, total_vesting_shares } = state.props;
const { base, quote } = state.feed_price;
const steemPrice = parseFloat(base) / parseFloat(quote);
const transferHistory = state.accounts[username].transfer_history
.filter((h) => h.length > 1 && 'timestamp' in h[1] && h[1].timestamp.startsWith(timestamp))
.map((h) => h[1].op);
const vestingDelegations = await getVestingDelegations(username);
const delegations = vestingDelegations.reduce((acc, { delegatee, vesting_shares }) => {
const steemPower = calculateSteemPower(vesting_shares, total_vesting_fund_steem, total_vesting_shares);
return { ...acc, [delegatee]: steemPower };
}, {});
const accountPosts = await getAccountPosts(username);
const activeVotes = accountPosts
.filter((post) => post.created.startsWith(timestamp) && post.active_votes.length > 0)
.map(({ payout, net_rshares, active_votes }) => {
return active_votes
.map(({ rshares, voter }) => ({
voter,
value: (parseFloat(rshares) / net_rshares) * payout,
}))
.filter((vote) => vote.value);
})
.flatMap((votes) => votes);
const transferAccounts = transferHistory
.filter((h) => h[0] === 'transfer')
.map((h) => h[1])
.reduce((acc, cur) => {
const [quantity, currency] = cur.amount.split(' ');
const result = acc[cur.from] || { steem: 0, sbd: 0 };
if (currency === 'STEEM') {
result['steem'] += parseFloat(quantity);
}
if (currency === 'SBD') {
result['sbd'] += parseFloat(quantity);
}
acc[cur.from] = result;
return acc;
}, {});
const delegationsSteem = Object.entries(delegations).map(([delegatee, steemPower]) => {
var _a, _b, _c, _d;
const transferSteem =
(_b = (_a = transferAccounts[delegatee == 'upvu' ? 'upvu.bank' : delegatee]) == null ? void 0 : _a.steem) != null
? _b
: 0;
const upvoteValue =
(_d = (_c = activeVotes.find((vote) => vote.voter === delegatee)) == null ? void 0 : _c.value) != null ? _d : 0;
const upvoteSteem = upvoteValue / steemPrice;
const apr = ((transferSteem + upvoteSteem) / steemPower) * 365 * 100;
return { delegatee, steemPower, transferSteem, upvoteSteem, apr };
});
const history = [];
for (const [type, payload] of transferHistory) {
if (
type === 'transfer' &&
payload.to === username &&
payload.from !== username &&
!payload.from.endsWith('.dunamu')
) {
const isSteem = payload.amount.endsWith(' STEEM');
const isSbd = payload.amount.endsWith(' SBD');
const value = parseFloat(payload.amount);
const steemValue = isSteem ? value : 0;
const sbdValue = isSbd ? value : 0;
history.push({
type,
steem: steemValue,
sbd: sbdValue,
sp: 0,
link: `@${payload.from}`,
});
} else if (type === 'curation_reward' && payload.curator === username) {
const steemPower = calculateSteemPower(payload.reward, total_vesting_fund_steem, total_vesting_shares);
history.push({
type,
steem: 0,
sbd: 0,
sp: steemPower,
link: `@${payload.comment_author}/${payload.comment_permlink}`,
});
} else if (type === 'comment_benefactor_reward' && payload.benefactor === username) {
const link = `@${payload.author}/${payload.permlink}`;
const vestSteem = calculateSteemPower(payload.vesting_payout, total_vesting_fund_steem, total_vesting_shares);
history.push({
type: 'author_reward',
steem: parseFloat(payload.steem_payout),
sbd: parseFloat(payload.sbd_payout),
sp: vestSteem,
link,
});
} else if (type === 'author_reward') {
const link = `@${payload.author}/${payload.permlink}`;
const vestSteem = calculateSteemPower(payload.vesting_payout, total_vesting_fund_steem, total_vesting_shares);
if (
parseFloat(payload.steem_payout) + parseFloat(payload.sbd_payout) + parseFloat(payload.vesting_payout) ===
0
) {
continue;
}
history.push({
type,
steem: parseFloat(payload.steem_payout),
sbd: parseFloat(payload.sbd_payout),
sp: vestSteem,
link,
});
}
}
const totalTransferSteem = history.filter(({ type }) => type === 'transfer').reduce((acc, cur) => acc + cur.steem, 0);
const totalTransferSbd = history.filter(({ type }) => type === 'transfer').reduce((acc, cur) => acc + cur.sbd, 0);
const totalTransferKRW = totalTransferSteem * KRW.steem + totalTransferSbd * KRW.sbd;
const totalCuratorRewardSp = history
.filter(({ type }) => type === 'curation_reward')
.reduce((acc, cur) => acc + cur.sp, 0);
const totalCuratorRewardKRW = totalCuratorRewardSp * KRW.steem;
const totalAuthorRewardSp = history
.filter(({ type }) => type === 'author_reward')
.reduce((acc, cur) => acc + cur.sp, 0);
const totalAuthorRewardSteem = history
.filter(({ type }) => type === 'author_reward')
.reduce((acc, cur) => acc + cur.steem, 0);
const totalAuthorRewardSbd = history
.filter(({ type }) => type === 'author_reward')
.reduce((acc, cur) => acc + cur.sbd, 0);
const totalAuthorRewardKRW =
(totalAuthorRewardSp + totalAuthorRewardSteem) * KRW.steem + totalAuthorRewardSbd * KRW.sbd;
results += `
### Market(\uC885\uAC00)
| Steem Price | SBD Price |
| --- | --- |
`;
results += `| ${KRW.steem} KRW | ${KRW.sbd.toLocaleString()} KRW |
`;
results += `
### Summary
`;
results += `| | STEEM | SBD | SP | KRW |
| --- | --- | --- | --- |--- |
`;
results += `| \uC784\uB300 \uC218\uC775 | ${totalTransferSteem.toFixed(3)} | ${totalTransferSbd.toFixed(
3,
)} | 0 | ${totalTransferKRW.toFixed(0).toLocaleString()} |
`;
results += `| \uC800\uC790 \uC218\uC775 | ${totalAuthorRewardSteem.toFixed(3)} | ${totalAuthorRewardSbd.toFixed(
3,
)} | ${totalAuthorRewardSp.toFixed(3)} | ${Math.floor(totalAuthorRewardKRW).toLocaleString()} |
`;
results += `| \uD050\uB808\uC774\uC158 \uC218\uC775 | 0 | 0 | ${totalCuratorRewardSp.toFixed(3)} | ${Math.floor(
totalCuratorRewardKRW,
).toLocaleString()} |
`;
results += `| Total | ${(totalTransferSteem + totalAuthorRewardSteem).toFixed(3)} | ${(
totalTransferSbd + totalAuthorRewardSbd
).toFixed(3)} | ${(totalAuthorRewardSp + totalCuratorRewardSp).toFixed(3)} | ${Math.floor(
totalTransferKRW + totalAuthorRewardKRW + totalCuratorRewardKRW,
).toLocaleString()} |
`;
results += `
### Delegations
| DELEGATEE | VESTING | TRANSFER | UPVOTE | APR |
| --- | --- | --- | --- | --- |
`;
delegationsSteem
.sort((a, b) => b.apr - a.apr)
.forEach(({ delegatee, steemPower, transferSteem, upvoteSteem, apr }) => {
results += `| ${delegatee} | ${Math.floor(steemPower)} SP | ${transferSteem.toFixed(
3,
)} STEEM | ${upvoteSteem.toFixed(3)} STEEM | ${apr.toFixed(2)}% |
`;
});
results += `
### History
| TYPE | STEEM | SBD | SP | URL |
| --- | --- | --- | --- | --- |
`;
history
.sort((a, b) => a.type.localeCompare(b.type))
.forEach(({ type, steem, sbd, sp, link }) => {
results += `| ${type} | ${steem.toFixed(3)} | ${sbd.toFixed(3)} | ${sp.toFixed(
3,
)} | [${link}](https://steemit.com/${link}) |
`;
});
return results;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment