forked from 0o-de-lally/status
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
346 additions
and
87 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
name: Deploy static content to Pages | ||
|
||
on: | ||
workflow_dispatch: | ||
|
||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages | ||
permissions: | ||
contents: write | ||
pages: write | ||
id-token: write | ||
|
||
concurrency: | ||
group: "pages" | ||
cancel-in-progress: false | ||
|
||
jobs: | ||
build-and-deploy: | ||
environment: | ||
name: github-pages | ||
url: ${{ steps.deployment.outputs.page_url }} | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v3 | ||
|
||
- name: Setup Pages | ||
uses: actions/configure-pages@v3 | ||
|
||
- name: Set Node.js 18.x | ||
uses: actions/setup-node@v3 | ||
with: | ||
node-version: 18.x | ||
|
||
- name: Run install | ||
uses: borales/actions-yarn@v4 | ||
with: | ||
cmd: install # will run `yarn install` command | ||
|
||
- name: Build production bundle | ||
uses: borales/actions-yarn@v4 | ||
with: | ||
cmd: build # will run `yarn build` command | ||
|
||
- name: Upload artifact | ||
uses: actions/upload-pages-artifact@v2 | ||
with: | ||
path: 'build' | ||
|
||
- name: Deploy to GitHub Pages | ||
id: deployment | ||
uses: actions/deploy-pages@v2 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import { transactions } from '.' | ||
|
||
async function queryTransactions(offset = 0, limit = 100) { | ||
const transactions = await fetch('https://api.0l.fyi/graphql', { | ||
headers: { | ||
accept: '*/*', | ||
'accept-language': 'en,zh-CN;q=0.9,zh;q=0.8,eu;q=0.7', | ||
'content-type': 'application/json', | ||
'sec-ch-ua': '"Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"', | ||
'sec-ch-ua-mobile': '?0', | ||
'sec-ch-ua-platform': '"macOS"', | ||
'sec-fetch-dest': 'empty', | ||
'sec-fetch-mode': 'cors', | ||
'sec-fetch-site': 'same-site', | ||
}, | ||
mode: 'cors', | ||
credentials: 'omit', | ||
body: JSON.stringify({ | ||
operationName: 'GetUserTransactions', | ||
variables: { | ||
limit: limit, | ||
offset: offset, | ||
}, | ||
query: | ||
'query GetUserTransactions($limit: Int!, $offset: Int!) {\n userTransactions(limit: $limit, offset: $offset, order: "DESC") {\n size\n items {\n version\n sender\n moduleAddress\n moduleName\n functionName\n timestamp\n success\n __typename\n }\n __typename\n }\n}', | ||
}), | ||
method: 'POST', | ||
}).then((res) => res.json()) | ||
return transactions.data.userTransactions | ||
} | ||
|
||
async function getTransactionDetail(version) { | ||
const data = await fetch(`https://rpc.0l.fyi/v1/transactions/by_version/${version}`).then((res) => | ||
res.json(), | ||
) | ||
return data.payload.arguments | ||
} | ||
let isFetching = false; | ||
export async function fetchTransactions() { | ||
if (isFetching) return; | ||
const endTime = (Date.now() - 3 * 24 * 60 * 60 * 1000) * 1_000; | ||
const minAmount = 1_000 * 1e6; | ||
const limit = 200 | ||
let page = 0 | ||
const { size } = await queryTransactions(0, 1) | ||
const totalPage = Math.ceil(size / limit) | ||
let allTransferList = [] | ||
isFetching = true; | ||
for (page = 0; page < totalPage; page++) { | ||
try { | ||
const { items } = await queryTransactions(page * limit, limit) | ||
if (items[0] && items[0].timestamp < endTime) { | ||
break | ||
} | ||
let transferList = items.filter( | ||
(item) => | ||
item.functionName === 'transfer' && item.success && item.timestamp >= endTime, | ||
) | ||
|
||
const details = await Promise.all( | ||
transferList.map((item) => getTransactionDetail(item.version)), | ||
) | ||
|
||
transferList = transferList.map((item, index) => { | ||
const [receiver, amount] = details[index] | ||
return { | ||
sender: item.sender.toLowerCase(), | ||
receiver: receiver.slice(2).toLowerCase(), | ||
amount: amount, | ||
ledger_version: item.version, | ||
ledger_timestamp: item.timestamp.toString(), | ||
} | ||
}) | ||
allTransferList = allTransferList.concat(transferList.filter(t => t.amount >= minAmount)); | ||
console.log(`${page + 1}/${totalPage}`) | ||
} catch (error) { | ||
console.log('Fetch error, will retry after 3s') | ||
await new Promise((resolve) => setTimeout(resolve, 3000)) | ||
page-- // Retry the same page | ||
} | ||
} | ||
transactions.set(allTransferList) | ||
isFetching = false | ||
} | ||
|
||
// fetchTransactions() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<script lang="ts"> | ||
import { scaleCoin } from '../utils/coin' | ||
import {transactions} from '../store/index' | ||
</script> | ||
|
||
<main> | ||
<table class="uk-table uk-table-responsive uk-table-divider"> | ||
<thead> | ||
<!-- sender,receiver,amount,version,timestamp --> | ||
<tr> | ||
<th>Sender</th> | ||
<th>Receiver</th> | ||
<th>Amount</th> | ||
<th>Version</th> | ||
<th>Timestamp</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
{#if $transactions.length > 0} | ||
{#each $transactions as tx} | ||
<tr> | ||
<td>{tx.sender}</td> | ||
<td>{tx.receiver}</td> | ||
<td>{scaleCoin(tx.amount)}</td> | ||
<td>{tx.ledger_version}</td> | ||
<td>{new Date(Math.floor(tx.ledger_timestamp / 1_000)).toLocaleString()}</td> | ||
</tr> | ||
{/each} | ||
{/if} | ||
</tbody> | ||
</table> | ||
</main> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<script lang="ts"> | ||
import { fetchUserAccounts, systemInfo, valDataStore } from '../store' | ||
import type { UserAccount } from '../types' | ||
import AccountTable from './AccountTable.svelte' | ||
import { scaleCoin } from '../utils/coin' | ||
let profiles: UserAccount[] | ||
valDataStore.subscribe((valState) => { | ||
if (valState) { | ||
fetchUserAccounts(valState.eligible_validators).then((r) => { | ||
r.map((el) => { | ||
el.in_val_set = valState.current_list.includes(el.address) | ||
}) | ||
r.sort(sortVals) | ||
profiles = r | ||
}) | ||
} | ||
}) | ||
function sortVals(a: UserAccount) { | ||
if (a.in_val_set) return -1 // sort to top | ||
else return 1 | ||
} | ||
</script> | ||
|
||
<main> | ||
{#if $valDataStore && $valDataStore.current_list} | ||
<h5> | ||
Validator Set ({($valDataStore && | ||
$valDataStore.current_list && | ||
$valDataStore.current_list.length) || | ||
0}): | ||
</h5> | ||
{/if} | ||
|
||
{#if $systemInfo} | ||
Epoch Reward: {scaleCoin($systemInfo.consensus_reward)} | ||
{/if} | ||
|
||
{#if profiles && profiles.length > 0} | ||
<AccountTable {profiles} /> | ||
{:else} | ||
loading ... | ||
{/if} | ||
</main> |
Oops, something went wrong.