Wallet Portfolio
Connect a wallet to see what it holds. ← Back to BRIAN Pool
Read-only: reads your stake address's public ADA and native-token balances, never asks for a signature or builds a transaction. Shown: ADA and native-token quantities, ADA converted to fiat. Not yet included: LP-pool positions and loan/debt subtraction. This project's repository is private, so instead of a source link, the actual code behind every step is reproduced and explained below - read it yourself rather than take our word for it.
How this works, step by step
The real code, in the order it runs. Each excerpt below is copied unmodified from this site's own source files.
1. Connecting only ever asks for read access, never a signature
Clicking a wallet button calls three wallet-API methods, in this exact order:
enable() - the wallet extension's own permission prompt, the one asking to let
this site read the wallet, nothing more - then getNetworkId() (rejects anything
but Cardano mainnet) and getRewardAddresses() (returns the stake address, already
plain data, nothing that needs signing to read). No other wallet method is called at this
step.
const api = await window.cardano[walletKey].enable();
const networkId = await api.getNetworkId();
if (networkId !== 1) {
setStatus("This wallet is on a test network. Switch it to Cardano mainnet and try again.", true);
return;
}
const rewardAddresses = await api.getRewardAddresses();
2. The stake address is derived entirely in your browser
The wallet already hands back the reward address as plain hex bytes - this function turns
those bytes into the familiar stake1… form, entirely on your device, following
Cardano's own CIP-19 address format. No private key, seed phrase or signature is involved at
any point.
// CIP-19: a mainnet reward/stake address is always 29 bytes (1 header
// byte + 28-byte credential hash), header byte 0xE1 (type 14 = stake
// credential, network tag 1 = mainnet). Anything else (wrong length,
// testnet address, a non-reward address type) is rejected rather than
// guessed at, since this pool and this widget are mainnet-only.
function rewardAddressHexToBech32(hex) {
const bytes = hexToBytes(hex);
if (bytes.length !== 29) throw new Error("Unexpected reward address length");
if (bytes[0] !== 0xe1) throw new Error("Not a mainnet stake address");
return bech32Encode("stake", bytes);
}
3. Only that public address is ever sent anywhere
That address - public information, the same one any Cardano block explorer would show for this wallet - is the only thing sent off your device, in a request to this site's own server. Nothing else about the wallet is included.
fetch(PORTFOLIO_PROXY_URL, {
method: "POST",
signal,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ stake_address: stakeAddress }),
})
4. The server only ever asks Koios, a public Cardano data provider
The server-side endpoint that receives that address queries exactly these three read-only Koios API endpoints and returns the combined result - the same public on-chain data any block explorer shows for any stake address (see the Koios credit in the footer below).
const KOIOS_ACCOUNT_INFO_URL = "https://api.koios.rest/api/v1/account_info";
const KOIOS_ACCOUNT_ASSETS_URL = "https://api.koios.rest/api/v1/account_assets";
const KOIOS_ASSET_INFO_URL = "https://api.koios.rest/api/v1/asset_info";
5. What the code never does
Across both files behind this page, none of the following ever appears: signTx,
signData, submitTx, or getBalance() (the CBOR-encoded
balance method the wallet API also offers, deliberately unused here). Every value shown on
this page - stake address, token names, error messages - is written with
.textContent, never innerHTML, so nothing returned by a wallet or
the network can render as active markup.
This tool is temporarily disabled by the pool operator. Please check back later.
Connect a wallet
Mainnet only. Works with any CIP-30-compatible extension (e.g. Eternl, Lace).
Stake address:
| Native token | Quantity | Value |
|---|
No native tokens found for this wallet.