Activity Overview

Commits and releases over time

  • Commits
  • Releases
  • Authors

Repository Explorer

17 commits in all time Aug 14, 2026 01:14 – Nov 12, 2026 01:14 UTC
pbennett reti
Merge pull request #414 from algorandfoundation/dev
Release v1.5.2
Git Commit 41d94744 Branch main Document 4/26 ++ 24 --
pbennett reti
chore: release v1.5.2
Git Commit 4caca165 Branch dev Document 3/3 ++ 3 --
pbennett reti
Merge pull request #413 from d13co/chore/pq-accts-fix-algokit-utils-9.2.2
fix: bump algokit-utils to 9.2.2, fixes PQ txn confirmations
Git Commit a25c303e Branch dev Document 2/23 ++ 21 --
d13co reti
Merge 35981bfe47383e17ee86b1ce49495d9d9be3165f into bdb51c26c3f8c5b9a5ebad9fe8947063f4c4feec
Git Commit 243dffd4 Branch pull/413/merge Document 2/23 ++ 21 --
d13co reti
merge dev, resolve pnpm-lock.yaml conflict
Git Commit 35981bfe Branch pull/413/head Document 58/3,161 ++ 531 --
d13co reti
fix: bump algokit-utils to 9.2.2, fixes PQ txn confirmations
Git Commit 65b3dcc3 Branch pull/413/head Document 2/23 ++ 7 --
pbennett reti
Merge pull request #412 from algorandfoundation/dev
Release v1.5.1
Git Commit 2935ceea Branch main Document 13/230 ++ 55 --
pbennett reti
Merge branch 'main' into dev
Git Commit bdb51c26 Branch dev Document No file changes
pbennett reti
Merge a271b9097624a13e99b9e53e9804903d5efdad4a into e23077f58b271d84aa77333b12dfce6552fda47e
Git Commit 659648d1 Branch undefined Document 13/230 ++ 55 --
pbennett reti
chore: release v1.5.1
Git Commit a271b909 Branch dev Document 3/3 ++ 3 --
pbennett reti
fix(ui): recover pool global state the bulk read didn't carry
Moving pool state to a single accountInformation read on the registry left two
gaps where a pool the bulk request missed stayed missed.

`processPoolData` fell back on the presence of the entry, not on what it held. A
pool whose state came back partial decodes to `{}`, which is truthy, so it kept
the empty entry and returned no lastPayout - which the Status column renders as
"Payouts stopped".

`algodVer` lost its fallback entirely. It came off LocalPoolInfo, and
StakingPoolInfo now reads it only from the bulk map; the per-pool read inside the
metrics query keeps lastPayout and discards the algodVer it fetched. Any pool the
map lacks reported its node version as "--" for the rest of the session.

Both now gate on `isPoolGlobalStateComplete`. It tests lastPayout rather than the
field being displayed, because lastPayout is written when the pool is created -
stakingPool.algo.ts sets it to the creation round as the first epoch's baseline -
so every pool has one and its absence can only mean an incomplete read. Gating on
algodVer instead would have been wrong: it is only written once the node daemon
reports in, and 88 of MainNet's 283 pools legitimately have none, so keying on it
would re-read a third of all pools on every visit and still show "--".

The 1020 fixture claimed a missing lastPayout stood for "a pool that has never
paid out", which the contract does not do. It now models the case that does
occur - a pool whose daemon has never reported, so no algodVer - and the tests
around it cover the fallback firing on an incomplete entry and staying put on a
complete one.
Git Commit 8e278262 Branch dev Document 5/98 ++ 14 --
pbennett reti
fix(ui): match Nodely perf rows on numeric validatorid
Every validator's Status column rendered a red gauge tooltipped "Not active".

Nodely serializes the uint64 columns of poolvotingperformance/24hr as bare JSON
numbers, but the lookup compared `validatorid` strictly against a string:

    (q) => q.validatorid === baseValidator.id.toString()   // 147 === "147"

so `validator.perf` was undefined for all 56 validators the feed covers. The
interface declared those columns as `string`, which is what hid it from tsc.

The miss then presented as a measurement rather than as missing data, because
the branch that renders "Not active" was only reachable via NaN:

    const perfScore = Number(validator.perf)   // Number(undefined) -> NaN
    if (perfScore >= 0.7) { Normal }           // NaN >= 0.7 -> false
    else if (perfScore < 0.7) { Watch }        // NaN <  0.7 -> false
    else { Error; 'Not active' }               // NaN only

The lookup moves to `findValidatorPerf`, which coerces both sides - the feed has
flipped these columns between quoted strings and raw numbers once already, and a
strict compare turns that into a silent blank for every row. ValidatorStatus now
tests for absence directly, so "Nodely has no row for this validator" and "this
validator is performing badly" stop sharing a branch, and formats the tooltip
through formatAmount (it was rendering 99.87096774193549%).

Two defects in the sibling payout indicator go with it: `!roundsSinceLastPayout`
treated a fresh 0 as "Payouts stopped, behind 0 seconds", and a Number was
compared against bigint literals. Threshold bands and colors are unchanged.
Git Commit 0547d4fa Branch dev Document 5/129 ++ 38 --
pbennett reti
Merge pull request #411 from algorandfoundation/dev
v1.5.0
Git Commit e23077f5 Branch dev Document 55/2,887 ++ 472 --
pbennett reti
chore: release v1.5.0
Git Commit 813a7ced Branch dev Document 3/3 ++ 3 --
pbennett reti
Merge pull request #410 from algorandfoundation/perf/ui-bulk-data-loading
perf(ui): load validator and pool state in bulk, persist the query cache
Git Commit 54aa20fd Branch dev Document 55/2,884 ++ 469 --
pbennett reti
perf(ui): load validator and pool state in bulk, persist the query cache
The dashboard opened with roughly 900 algod requests: four simulate calls per
validator (config/state/pools/nodePoolAssignments), one global state read per
pool, then enrichment lookups on top. All four validator reads come out of the
same `v` + validatorId box, and every pool is created by the registry's app
account, so both collapse into a single request each.

Bulk reads:

- `fetchAppBoxes` reads box names and values together using algosdk 3.6's
  `include('values')` with cursor pagination, pinning every page after the
  first to the round the first returned so a multi-page read is one snapshot.
  It throws if a node returns names without values rather than rendering an
  app's state as empty.
- `fetchAllValidatorData` decodes those boxes through the generated ARC-56
  struct and seeds the per-validator query caches inside the queryFn, so
  components and route loaders reading the individual keys resolve from cache.
  The validator detail route seeds the same four keys from one box read when
  arriving cold.
- `fetchPoolGlobalStates` reads every pool's `lastPayout`/`algodVer` from one
  `accountInformation` call on the registry address, and warns when algod
  truncates the created-app list. `processPoolData` takes that state as an
  argument, falling back to a per-pool read only for what the bulk read missed.
- xGov request boxes move off the typed client's `requestBox.getMap()`, which
  issued a request per box across the whole registry.
- `validatorMetricsQueryOptions` takes its per-validator inputs explicitly
  instead of re-deriving them through `ensureQueryData`, which would refetch
  once those entries are garbage collected. The per-row Rewards and Status
  queries observe rather than fetch, keeping metrics traffic inside the
  metered queue.

Caching and pacing:

- `queryPersister` persists an allowlist of query key roots to IndexedDB,
  chosen over localStorage because protocol data is full of bigints and
  structured clone handles them natively. Busted on `__APP_VERSION__`.
  main.tsx hydrates before the router runs, so the table paints from disk and
  refreshes underneath; index.html holds a static spinner and applies the
  stored theme before first paint.
- `useQueuedQueries` meters only work that will actually hit the network,
  returns results positionally aligned with its input, and learns a per-host
  batch size by AIMD (`utils/rateLimit`) - additive increase on clean ticks,
  halving on 429/503, persisted so the next load starts near a known-good rate.
- `axiosNfdApi` gains a localStorage-backed HTTP cache and exponential backoff.
  The retry has to register after `setupCache`: registered first it swallows
  the rejection before the cache settles the entry it opened, and the retry
  then blocks forever on that entry. Covered by a test.

algosdk 3.6 types `asset.params` as optional, hence the `?.` on every params
access. axios and axios-cache-interceptor are bumped alongside.

Specs added for the box reads, pool global state decoding, the batching queue,
the persister, the rate limit controller, and the NFD interceptor ordering.
Git Commit d3865871 Branch dev Document 52/2,764 ++ 469 --
pbennett reti
chore: add repo agent instructions and ignore bare .env / .idea
AGENTS.md documents the three deliverables, the localnet-dependent dev loop, the per-package commands CI enforces, and which paths are generated build output. CLAUDE.md points at it.

.gitignore only had `.env.*`, which doesn't match a bare `.env` - and bootstrap writes mnemonics into nodemgr env files.
Git Commit 6ff8dda9 Branch dev Document 3/120 ++ 0 --