A static, no-backend dashboard for the PowFi Round 0 campaign on Alephium: xALPH liquid staking plus the ALPH farming pools. Every number is read live from mainnet in the browser — there is no server or API key.
- xALPH liquid staking (
225WevmFp5ZgzPsyVJTvyp2v2uyKrvp329HfrVmzffnWj) — ALPH staked vs. the 20.5M target, share of circulating ALPH, and the xALPH:ALPH redemption rate. - ALPH × USDT farming pool (
xRF7AKLwpGjWzDpFFnUkdXBALKtotFcnD5XFf2EAyioZ) — pool TVL vs. the $200k target, implied ALPH price, and raw reserves. - xALPH × ALPH pool (
22QumTFozFy6HyndPMna2t4KjjVNGYNATgY2reeV2d6nj) — TVL and market price vs. the vault's redemption rate (peg deviation).
A second page, /activity/, lists the vault's most recent stake / unstake / reward
events, decoded straight from its on-chain event log (no private API involved).
Data sources, all called directly from the client:
| Source | Used for |
|---|---|
node.mainnet.alephium.org (via @alephium/web3's NodeProvider) |
contract state / reserves |
backend.mainnet.alephium.org (via @alephium/web3's ExplorerProvider) |
circulating ALPH supply, token metadata |
api.powfi.alephium.org |
pool spot prices and TVL (ALPH/USD comes from the ALPH × USDT pool) |
The campaign targets (20.5M ALPH staked, $200k pool TVL, 5%/15% target APYs, 15% of
circulating ALPH) are fixed constants in src/chain.ts — update them there if a new round changes them.
The dedicated /staking/ page, available from the Stake with us menu, includes a form using @alephium/powfi-sdk and the official @alephium/web3-react
AlephiumWalletProvider. The chooser supports browser extensions, the desktop
wallet, and WalletConnect. Users connect a mainnet wallet, enter ALPH,
preview the estimated xALPH received, and review/sign in their wallet. The app
tracks transaction confirmation and refreshes live data afterward. The existing
unstake calculator remains read-only. Disconnect waits for connector cleanup and
clears the provider state; clicking Connect wallet afterward reopens the method
chooser. The wallet provider stays mounted while the form updates. Desktop and
WalletConnect sessions reconnect only after choosing a method, so an offline
wallet cannot block the chooser during page load.
The SDK requires a group-0 mainnet account for this staking vault; the connection requests that group. It approves the stake amount plus 0.1 ALPH for transaction funding. The form checks the unlocked wallet balance as the amount changes and again before submission. Max leaves that 0.1 ALPH plus a 0.01 ALPH network fee buffer; insufficient funds disable staking. The wallet determines the final transaction costs and network fee, which may differ from the buffer.
Stakes default to referral attribution for
3cUsjeBfMTggytagJXCsvyhtYPy5HydRePWftyE4WBuXSvGvNR2k7, using
powfi.staking.stakeAlphWithReferral(amount, referral). To override it, set the
public build-time variable in .env.local or the build environment:
VITE_STAKING_REFERRAL_ADDRESS=YOUR_ALEPHIUM_ADDRESSSetting it to an empty string uses stakeAlph(amount) without a custom referral.
Changing build-time values requires restarting Vite or rebuilding. The address
is included in the public bundle but is not displayed in the interface; it is not a secret.
Referral attribution is not an additional fee. The staking SDK exposes a referral address, but does not expose an arbitrary app fee recipient/rate in these staking methods. This integration adds no app fee and makes no claim that referral attribution automatically pays a commission.
Run npm test for amount validation and an inert-signer test of the real SDK's
stake transaction construction. These tests do not sign or broadcast transactions.
The standalone script misc/scripts/staking-distribution.py fetches the xALPH vault's
staking events and creates an 1800×1200 PNG plus an editable SVG. It does not
add anything to the dashboard.
Generated by the script from the snapshot dated in the image. Running the script with the default output directory refreshes this preview.
Use Python 3.10 or newer. From the repository root:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r misc/scripts/requirements-staking-distribution.txtEach run fetches fresh event history from the default public mainnet node:
python misc/scripts/staking-distribution.pyIn a new terminal, activate the environment again with source .venv/bin/activate
before running the script.
To select a fullnode, pass its base URL with --fullnode (--node-url is an alias):
python misc/scripts/staking-distribution.py --fullnode https://node.mainnet.alephium.orgFor a locally running mainnet fullnode:
python misc/scripts/staking-distribution.py --fullnode http://127.0.0.1:12973The selected node must be synced to Alephium mainnet and expose the vault's
complete indexed contract-event history through /events/contract/.... Pass the
base URL, without an /events suffix. This script assumes an API accessible
without authentication.
To change the output directory:
python misc/scripts/staking-distribution.py --output-dir ./output/shareOptions can be combined. Run python misc/scripts/staking-distribution.py --help
for the full list, including replaying previously saved events offline.
By default, files are written to output/staking-distribution/:
powfi-deposit-distribution.png: the shareable 1800×1200 image.powfi-deposit-distribution.svg: the scalable chart.summary.json: address counts, mean, median, distribution bins and methodology.staking-events.json: deduplicated source events for reproducibility.
Running again replaces these files; use a different --output-dir to preserve a
previous snapshot.
All deposits to the same recipient address are added together into one observation. For example, deposits of 100, 500 and 1,000 ALPH to the same address count as one address with 1,600 ALPH deposited. The mean, median and size ranges are calculated from these combined address totals. The two charts show the number of addresses in each range and their share of all deposited ALPH.
The script reads only Staked events, removes duplicate event records, and
retains exact integer attoALPH amounts until display conversion. It captures the
node's event cursor count before pagination so incoming deposits do not shift
the snapshot.
These are cumulative gross deposits, not current wallet balances. Withdrawals, xALPH transfers, rewards and unstake cancellations are not added or subtracted. One address is not necessarily one person. The image includes the snapshot date and these calculation notes.
npm install
npm run devnpm run build # outputs to dist/
npm run preview # serve the production build locallyA workflow at .github/workflows/deploy.yml builds and publishes dist/ on every push to
main. To enable it:
- Push this repo to GitHub.
- In the repo's Settings → Pages, set Source to GitHub Actions.
- Push to
main(or run the workflow manually from the Actions tab).
The workflow sets Vite's base to / for the custom domain
https://powfi.notrustverify.ch. Configure that hostname in Settings → Pages →
Custom domain. Asset URLs must start at the domain root, without /powfi-overview/.
If switching back to a https://<owner>.github.io/<repo-name>/ project URL, change
the workflow's VITE_BASE to /<repo-name>/ and rebuild.
