release: Wayfinder v2.0.0 — Solana migration + AR.IO rebrand#252
Conversation
chore: main to alpha
Replace all hardcoded arweave.net and permagate.io defaults with turbo-gateway.com, which is a verified AR.IO gateway supporting all AR.IO-specific APIs. Changes: - Update DEFAULT_TRUSTED_GATEWAY in wayfinder-core - Replace preferred routing default - Update round-robin default gateways - Update extension fallback gateways - Update CLI default gateway - Update all README examples - Update test script defaults Rationale: - arweave.net is no longer an AR.IO gateway - Does not support /ar-io/peers, /ar-io/info endpoints - turbo-gateway.com confirmed to support all AR.IO APIs No breaking changes - all user configurations still work. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Update test gateway from permagate.io to turbo-gateway.com to match the gateway defaults changed in commit 954e60e. The tests were failing in CI with 502 Bad Gateway errors because permagate.io was experiencing issues. Fixes 4 failing integration tests: - should emit default events on the wayfinder event emitter when request is made - should emit events and trigger request callbacks when request is made with custom events - should execute callbacks provided to the wayfinder constructor - should call verification for ArNS names with resolved transaction ID All tests now pass (124/124). Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The x-arns-resolved-at header contains a timestamp that varies between parallel requests, causing the test to be flaky. Even when using Promise.all, the requests don't start at exactly the same millisecond, so the gateway generates different timestamps. Fix by: - Filtering out x-arns-resolved-at from the deep equality check - Adding explicit assertions that the timestamp header exists on both responses This ensures we still verify ArNS functionality while avoiding flaky timestamp comparisons. Fixes the intermittent failure: ✖ should fetch the data using the selected gateway Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add test fix details to the gateway replacement changeset: - Updated integration tests to use turbo-gateway.com - Fixed flaky timestamp comparison in ArNS header test Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Releases: @ar.io/wayfinder-core@1.9.2 @ar.io/wayfinder-extension@1.0.23 @ar.io/wayfinder-cli@0.0.5 @ar.io/wayfinder-react@1.0.29 [skip ci]
chore(release): version packages
npm publish was failing with a warning that the bin path was invalid. The published v0.0.4 uses 'dist/index.js' without the './' prefix. This matches the format that npm expects for bin scripts. Fixes the publish error: npm warn publish "bin[wayfinder]" script name dist/index.js was invalid and removed Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
First step of the Solana migration. wayfinder-core's only @ar.io/sdk touchpoint is a type-only import of `AoARIORead` in network.ts; that type has the same shape on the 4.x-solana.X line as on 3.x, so no code changes are required. Bumping the devDependency exercises the Solana-capable SDK during local + CI test runs, giving us confidence the package stays compatible as we migrate the rest of the monorepo. - packages/wayfinder-core/package.json: devDep `@ar.io/sdk` `^3.13.0` -> `^4.0.0-solana.8`. peerDependency `>=3.12.0` left unchanged (the constraint already permits 4.x; loosening lockstep with AO-era consumers is intentional). - packages/wayfinder-core/src/version.ts: synced by the build's update-version script. No semantic change. - package-lock.json: regenerated by npm install. - .changeset/wayfinder-core-solana-sdk.md: patch-bump changeset documenting the SDK-compat verification. Verified: - npm run lint:check (biome) passes - npm run build (tsc) passes — confirms the SDK boundary still type-checks against 4.x-solana.8 - npm test passes against the bumped SDK Out of scope for this commit (deferred to follow-up): the wayfinder-extension AR.IO SDK migration (Solana-only refactor of storage schema, settings UI, and ARIO.init call sites). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The Solana migration uses `solana` as a long-lived integration branch (mirroring the same pattern used in ar-io-node, ar-io-sdk, ar-io-observer). Without `solana` in the CI workflow triggers, none of the feature PRs we land into the branch get lint/test/build signal before merge — only the eventual `solana -> alpha` rollup would. Add `solana` to the `branches:` list in: - pr-check.yml (Diff Check — paths-filter classification) - core.yml (Core Library — lint/test/build) - extension.yml (Chrome Extension — lint/test/build) - react.yml (React Components & Hooks — lint/test/build) Deliberately NOT touched: - chrome.yml is workflow_dispatch only (manual publish to the Chrome store); branch triggers don't apply. - release.yaml drives changesets-based publishing — we don't want it accidentally publishing from the `solana` integration branch. It stays scoped to main/alpha. No changeset required: workflow-only change, no consumer impact. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ding (#246) Foundation work for the AO -> Solana migration (PR A of two). Purely additive — no existing code consumes the new exports yet, so this commit introduces zero runtime behavior change. - src/types.ts: * NetworkPreset enum ('mainnet' | 'devnet' | 'custom') * SolanaNetworkConfig shape (rpcUrl + 4 program IDs) - src/constants.ts: * AR_IO_SOLANA_DEVNET preset carrying the public devnet RPC and the four program addresses from ar-io-solana-contracts/program-ids/ devnet.json. Includes a docstring noting the public RPC's rate limits. * AR_IO_SOLANA_MAINNET = null placeholder (AR.IO Solana mainnet is not yet deployed; will be populated in a future commit). * AR_IO_SOLANA_PRESETS keyed lookup for use by the settings UI. - src/config/defaults.ts: * SOLANA_NETWORK_DEFAULTS = { network: 'devnet', ...devnet preset } for use by the upcoming migration commit when it populates EXTENSION_DEFAULTS / chrome.storage on first install. The follow-up PR ('refactor(extension): drop AO entirely; route through Solana') will: rewrite the four ARIO.init call sites in background.ts and settings.ts; replace the AO Process ID / CU URL form fields in settings.html with a network preset selector + Solana RPC + program ID inputs; add storage migration logic for existing AO-era users (silent reset to devnet defaults + force GAR resync); drop @permaweb/aoconnect; bump @ar.io/sdk to ^4.0.0-solana.8. Verified: - npm run build -w @ar.io/wayfinder-extension passes (tsc + bundle) - biome lint clean Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* refactor(extension)!: drop AO entirely; route through Solana
BREAKING change: AO support is removed from wayfinder-extension. The
extension now talks to AR.IO exclusively through the Solana-backed
@ar.io/sdk@4.x. Default network on fresh install is AR.IO Solana
devnet; mainnet is reserved for when the AR.IO Solana mainnet
deployment ships.
Builds on the additive foundation landed in the previous commit
(refactor(extension): add Solana network type/constant/default
scaffolding).
Code:
- src/background.ts: drop AOProcess + @permaweb/aoconnect + AO process
constant imports; add arioFromStorage() helper that constructs a
read-only Solana ARIO from chrome.storage.local with EXTENSION_
DEFAULTS fallback; rewrite the four ARIO.init call sites to use it;
add migrateStorageFromAOEra() that detects pre-existing AO-era
storage keys, removes them, invalidates the cached gateway registry,
and lets the next sync repopulate from Solana.
- src/settings.ts: drop ARIO.mainnet() fallback in favor of a
Solana-backed ARIO.init({backend: 'solana', ...}) built from current
storage; replace handleProcessIdChange + handleAoCuUrlChange with a
consolidated handleNetworkConfigChange covering all six new fields
(network, rpcUrl, four program IDs); validate inputs via URL() for
the RPC and @solana/kit `address()` for program IDs; preset
selection auto-fills + disables the per-field inputs.
- src/constants.ts: remove ARIO_MAINNET_PROCESS_ID and
DEFAULT_AO_CU_URL.
- src/config/defaults.ts: drop the AO `processId`/`aoCuUrl` entries
from EXTENSION_DEFAULTS; replace with the Solana network defaults
(`network`, `rpcUrl`, four program IDs).
- src/settings.html: replace "AR.IO Process ID" + "AO Compute Unit
URL" sections with a Network preset selector, a Solana RPC URL
input, and a collapsible "Advanced: AR.IO Program IDs" panel
exposing the per-program addresses. Mainnet preset is `disabled`
until AR.IO Solana mainnet ships.
Dependencies:
- @ar.io/sdk: ^3.21.0 -> ^4.0.0-solana.8
- @solana/kit: added at ^2.1.0 (used by SDK's Solana backend and by
the extension's address() validation in settings + the settings-
side fallback ARIO instance)
- @permaweb/aoconnect: removed
Storage migration:
- AO-era users had `processId` + `aoCuUrl` in chrome.storage.local.
On first run after upgrade migrateStorageFromAOEra() removes them
along with the cached `localGatewayAddressRegistry`, then the
startup defaults block writes the new Solana keys. Background
re-init then connects to AR.IO Solana devnet and the next sync
repopulates the registry from a Solana gateway source. Users see
the extension keep working with no settings prompt.
Verified locally:
- `npm run build -w @ar.io/wayfinder-extension` passes (tsc + vite)
- `biome check` passes
- Bundle size shrinks (vendor chunk: 5.3 MB -> 3.8 MB) thanks to
dropping the AO compute stack and the aoconnect dependency.
Out of scope (deferred): no automated tests exist in the extension
package; validation is purely manual via a Chrome dev profile. The
PR description includes a step-by-step smoke-test checklist.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(extension): clean up AO relics + wire reinitializeArIO
Follow-up on the AO -> Solana migration: a self-review surfaced six
remaining AO relics + one real bug. Bundled here as a single
clean-up commit; the original 02a7660 stays as the readable
migration commit.
Real bugs:
- gateways.ts: the gateway-ping health check probed `info.processId`
on /ar-io/info, which AR.IO Solana gateways no longer emit (replaced
by `programIds`). Without this fix, every modern AR.IO gateway
would be marked Unhealthy by the extension's ping tool. Switched
the check to `info.programIds` (typeof object).
- background.ts (updateAdvancedSettings handler): handler was
calling `chrome.storage.local.set(request.settings)`, but the
settings page already writes storage directly and now sends the
message with no `settings` field. The handler was effectively a
no-op for storage and never rebuilt the ARIO instance — so a user
changing the Solana RPC URL or program IDs wouldn't see the
underlying SDK pick up the change until the next service-worker
restart. Replaced the (dead) storage write with a call to
`reinitializeArIO()` so the ARIO read instance rebuilds from the
new storage on every settings change.
Dead code removed:
- background.ts: `setAoCuUrl` message handler (only reachable from
the now-deleted AO CU URL form field). Plus its allowlist entry.
Plus the orphan `setArIOProcessId` allowlist entry that never had
a handler.
- settings.ts: the "Reset all settings" button still removed the
legacy `processId` / `aoCuUrl` storage keys instead of the new
Solana keys, so pressing it left the user's storage untouched.
Updated to remove the six new network keys; the startup defaults
block then repopulates them with the devnet preset on next load.
Build hygiene:
- vite.config.js: the manualChunks `webIndex` chunk still listed
`@permaweb/aoconnect` (now removed from dependencies). Replaced
with `@solana/kit` to keep the chunk grouping useful.
Docs:
- README.md: "Network Configuration" section described the old
"Process ID" + "AO CU URL" fields. Replaced with the new Network
preset / Solana RPC URL / Advanced program IDs description.
Note: `reinitializeArIO` (now wired into `updateAdvancedSettings`)
was orphaned by the `setAoCuUrl` removal; lint would have flagged
it. Pre-emptively re-wired before lint caught it.
Verified locally:
- `npm run build -w @ar.io/wayfinder-extension` passes (tsc + vite)
- `biome check` passes
- Final grep: no remaining unintentional AO references in the
extension src/, README, vite config, or manifest. The remaining
AO references in background.ts are all inside
`migrateStorageFromAOEra()` (intentional — that function detects
and removes AO-era storage keys).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* ci: re-trigger workflows after base retarget
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
…robustness + dead code) (#248) Surfaced by a post-merge end-to-end scan of the extension's Solana migration. Three categories of cleanup: 1. Cross-network contamination via the mainnet fallback gateway FALLBACK_GATEWAY in constants.ts is hardcoded to turbo-gateway.com (mainnet). routing.ts uses it as a last-resort fallback when normal routing fails. After the migration the extension defaults to AR.IO Solana devnet, where the gateway registry is sparsely populated — so the fallback fires often and silently serves mainnet content under the user's devnet network. Now the fallback is gated on `network === 'mainnet'` in storage; on devnet or a custom network the original routing error is propagated instead, surfacing the empty-registry condition to the user rather than masking it with mainnet data. 2. Startup robustness against bad stored network config The boot IIFE in background.ts called `arIO = await arioFromStorage()` without a try/catch. arioFromStorage() invokes @solana/kit's address() on each stored program-ID, which throws on non-base58 input. If a user previously persisted a bad value via the custom-network preset, the IIFE would crash before reaching debouncedInitializeWayfinder(), leaving routing inoperable until manual reset. Now wrapped with a fallback to bundled EXTENSION_DEFAULTS that mirrors the existing reinitializeArIO() catch path. 3. Dead-code removal - `resetAdvancedSettings` message handler: had logic but no UI button calling it after the migration. The startup defaults block plus the existing `updateAdvancedSettings` flow cover the same surface. - `updateVerificationMode` allowlist entry: pure dead string, no handler ever existed in the post-migration tree. Both removed from the validMessages allowlist; the resetAdvanced Settings handler body removed too. Verified locally: - npm run build -w @ar.io/wayfinder-extension passes - npm run lint:check (biome + eslint, 121 files) passes - No new tests added (extension package has none; smoke test remains a manual Chrome dev-profile exercise). Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
…249) wayfinder-core itself is chain-agnostic — it consumes only the `AoARIORead` type and delegates instance construction to the caller. But the published README only showed `ARIO.mainnet()` (the AO-era AR.IO mainnet) examples, which is misleading in the post-Solana- migration ecosystem. Rewrite the four example blocks to use the SDK 4.x Solana backend: const ario = ARIO.init({ backend: 'solana', rpc: createSolanaRpc('https://api.devnet.solana.com'), coreProgramId: address('...'), garProgramId: address('...'), arnsProgramId: address('...'), antProgramId: address('...'), }); The first example carries a comment explaining how to switch to mainnet (drop the program-ID overrides; the SDK ships mainnet defaults) once AR.IO Solana mainnet deploys, and reaffirms that wayfinder-core is chain-agnostic — same APIs work for any backend the SDK supports. Sections updated: - Getting Started: Using with AR.IO Network - NetworkGatewaysProvider reference - CompositeGatewaysProvider example - CompositeRoutingStrategy examples 1 + 2 Docs-only. No code changes. wayfinder-core's `network.ts` already type-checked against SDK 4.x in the earlier compat-verification commit (991e450). Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
BREAKING CHANGE: Drop AO backend support entirely; Solana is now the only backend for the AR.IO on-chain registry. SDK migration: - Rename Ao-prefixed types: AoARIORead→ARIORead, AoGateway→Gateway, AoGatewayWithAddress→GatewayWithAddress across all packages - Remove `backend: 'solana'` from all ARIO.init() calls (Solana is the only backend, parameter no longer exists) - Bump @ar.io/sdk from ^4.0.0-solana.8 to ^4.0.2 - Bump @solana/kit from ^2.1.0 to ^6.8.0 - Bump wayfinder-core peer dep from @ar.io/sdk>=3.12.0 to >=4.0.0 Program IDs & mainnet: - Update devnet program IDs to match SDK v4.0.2 deployment - Populate mainnet program IDs (AR.IO Solana mainnet is now live) - Enable mainnet preset in extension settings UI - Add storage migration for users with stale devnet program IDs Build: - Fix Vite bundling for @solana/kit v6 (resolve.alias to deduplicate conflicting v5/v6 @solana/* sub-packages from x402-fetch) Version bumps: - wayfinder-core: 1.9.2 → 2.0.0 - wayfinder-extension: 1.0.23 → 2.0.0 - wayfinder-react: 1.0.29 → 2.0.0 - monorepo: 0.0.14 → 1.0.0 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The previous hardcoded paths to @solana/kit/node_modules/ only worked with yarn's nesting layout. CI uses npm, which hoists differently and the nested paths don't exist. Switch to createRequire anchored to @solana/kit's main entry, so each @solana/* sub-package resolves to the version kit was built against regardless of package manager hoisting strategy. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. Fetch timeouts — prevent indefinite hangs on slow/dead endpoints:
- TrustedPeersGatewaysProvider: 10s timeout (configurable)
- ContiguousDataRetrievalStrategy: 30s timeout (configurable)
- ChunkDataRetrievalStrategy: 10s metadata, 30s per chunk (configurable)
- Extension DNS lookup: 5s timeout
2. Ping result caching — avoid re-pinging all gateways on every request:
- Wrap FastestPingRoutingStrategy with SimpleCacheRoutingStrategy
(120s TTL) in the extension's routing setup
- Stale cache is returned on ping failure (built into SimpleCacheRoutingStrategy)
3. Periodic gateway registry sync — recover from failed startup syncs:
- chrome.alarms fires every 60 minutes
- Skips sync if last sync was recent (staleness check via lastSyncTime)
- Added "alarms" permission to manifest.json
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Switch default network preset from devnet to mainnet - Restyle the Advanced: AR.IO Program IDs section: - Proper collapsible disclosure triangle - Stacked label+input layout with spacing - Monospace font for pubkey inputs - Description text with muted styling Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The public Solana RPC endpoints (mainnet-beta, devnet) aggressively rate-limit, returning HTTP 403 / SolanaError #8100002. Each getGateways() page fetch is now wrapped in retryWithBackoff() which: - Retries up to 5 times on 403, 429, 5xx, and network errors - Uses exponential backoff with jitter (2s base, 15s cap) - Lets application errors (bad address, deserialization) bubble immediately This makes the gateway sync work reliably with the free public RPC endpoints without requiring a premium QuickNode/Helius endpoint. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The public api.mainnet-beta.solana.com actively rejects requests from Chrome extension service workers (HTTP 403). Switch the mainnet default to a QuickNode endpoint that works from browser contexts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Update Chrome Web Store section (no longer "coming soon") - Add yarn install + core build step to dev instructions - Update project structure with actual .ts filenames and new files - Add @ar.io/sdk v4.x and @solana/kit to key technologies - Clarify network preset defaults and RPC details Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update the entire extension UI to match the AR.IO brand kit (v2026-03-30): Colors: - Primary accent: teal rgb(45, 211, 190) → purple #5427C8 - Secondary: dark teal → lavender #DFD6F7 - Dark backgrounds: neutral grays (#050505 scale) → purple-tinted darks (#0e0a1c scale) - Text on dark: gray #cacad6 → lavender #D4C6FF - Gradients: peach-to-purple (#f7c3a1→#df9be8) → purple spectrum (#5427C8→#DFD6F7) - Light theme: slate grays → Lavender Wash #f1ecff / Warm Neutral #F6F4EF Typography: - Headings: Rubik → Besley (weight 800, tight line-height 1.08) - Body: Rubik/Inter → Plus Jakarta Sans - Monospace: JetBrains Mono (kept) Layout: - Border radii increased: 4/8/12/16px → 8/12/20/24px - Strokes: neutral gray-blue rgba → purple-tinted rgba Files updated: - variables.css: Complete design token rewrite - popup.css, settings.css, gateways.css, gateways-enhanced.css, performance.css: All hardcoded colors replaced with new brand values - All 4 HTML files: Google Fonts updated to Besley + Plus Jakarta Sans Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- All Besley headings: font-weight 800, letter-spacing -0.025em, line-height 1.08 - Popup logo h1: switched from body font to heading font (Besley) - Nav card h3s: switched to Besley heading font - Toggle unchecked state: #0e0a1c → #26203a for visible contrast - Focus rings: added box-shadow glow on all text/url inputs - Filter buttons: border-radius 6px → var(--radius-sm, 8px) - Back buttons: border-radius 10px → var(--radius-md, 12px) - Fixed 4 remaining font-weight: 600 headings in settings.css Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tooltips, buttons, selects, close buttons, and list items had 4-6px radii. Brand spec minimum is 8px (--radius-sm). Updated 13 elements across popup.css, settings.css, gateways.css, and performance.css. Intentionally kept small radii on: scrollbar thumbs (3px), range slider tracks (3px), decorative accent bars (2px), tiny badges (3px), checkboxes (3px), and progress bars (3px) — these are sub-element details where 8px would look wrong. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…bg consistency Theme support: - gateways.ts and performance.ts had NO theme application — light mode was completely broken on these pages. Added applyTheme() + system preference listener to both, matching popup.ts/settings.ts pattern. Card background consistency: - Gateways container used L1 (#1a1527) instead of L0 (#0e0a1c) as page background — one shade off from popup/settings/performance. - Gateways back-button used L1 instead of L0 (inconsistent with settings/performance back buttons). - 8 hardcoded #26203a hover states replaced with var(--colors-container-containerL2) so light theme hovers work. - Toggle switch border/bg hardcoded values → CSS variables. All 4 pages now have identical theme detection, identical background hierarchy (L0 page → L1 cards → L2 hover → L3 inputs), and all container colors use CSS variables for correct light/dark theming. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extension icon: - Replace old icon with latest AR.IO brand icon from brand kit (ario-white-on-black-round) at 128/48/16px sizes Theme flicker fix: - Add inline <script> in <head> of all 4 HTML pages that sets data-theme synchronously before CSS paints — eliminates the flash of dark theme when navigating pages in light mode Popup layout tightening: - Reduce section gap from 18px to 12px - Reduce stat card height from 89.7px to 72px - Reduce nav card gap from 16px to 8px between cards - Reduce card padding from 16px to 12px vertically - Shrink strategy/feature icons from 32px to 28px - Remove transform/box-shadow from nav-card hover (was inconsistent with strategy-card hover behavior — now all cards hover identically) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…pages - Popup: replaced var(--bg-secondary) alias with explicit var(--colors-container-containerL1) on stat-card, strategy-card, nav-card — matches settings/gateways/performance convention - Fixed duplicate .strategy-card block (second override) that still used --bg-secondary with larger padding - Settings: network-option background was containerL0 (same as page bg, invisible) — changed to containerL1 to match other cards All cards across all 4 pages now use identical token: background: var(--colors-container-containerL1, #1a1527) hover: var(--colors-container-containerL2, #26203a) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Apply consistent design token usage across all CSS: - Card/section elements use containerL1 (raised from page background) - Hover states use containerL2 - Input fields use containerL3 - Page background, headers, footers remain containerL0 Fixes: - popup.css: nav-cards gap 8px→12px to match parent section gap - settings.css: .theme-option, .advanced-option, .mode-option, .option-card, .provider-option, .verification-strategy-selector .strategy-option, .trusted-gateways-config .mode-option all changed from L0 to L1; hover states from L0 to L2 - performance.css: .filter-section, .usage-section, .action-card changed from L0 to L1 - gateways.css: .search-box input changed from L0 to L3 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…s light mode - Fix advanced settings section hover: .advanced-options → .advanced-config in the :not() exclusion list so hovering sub-items doesn't grey out the entire card - Improve toggle switch unchecked state: use containerL3 instead of L2 with visible border for better contrast against card backgrounds - Add light mode overrides for gateways page: header border, filter section, filter buttons, search input all now use proper light theme tokens instead of dark-mode rgba values Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Full pixel-level audit of popup, settings, gateways, and performance pages. Every element checked against the L0/L1/L2/L3 container hierarchy, font families, and text color tokens. Popup: - .stat-label: textHigh → textMid (secondary text should be muted) - .strategy-description: textHigh → textMid - .nav-content p: textHigh → textMid Settings: - .back-button:hover: L0 → L2 (was invisible hover state) - .input-with-button input: L0 → L3 (input fields must be L3) Performance: - .back-button:hover: L0 → L2 (no visual hover feedback) - .stat-card: --bg-secondary → containerL1 (undefined legacy var) - .stat-value: --text-high → neutrals-100 (undefined legacy var) - .stat-label: --text-high → textMid (secondary text muted) - Light mode: add missing overrides for filter-section, filter-btn, sort-select, stat-card, stat-value, stat-label, usage-section, section-header Gateways: - .stat-card: --bg-secondary → containerL1 (undefined legacy var) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rings Structural consistency: - Gateways page header/footer now fixed-position (was relative), matching popup/settings/performance — fixes inconsistent scroll behavior. Content padding updated to account for fixed elements. - Settings back-button radius 10px → var(--radius-md, 12px) to match gateways/performance pages. Border consistency: - Popup stat-cards now have 1px solid var(--border-subtle) border (was missing — strategy/nav cards had it, stat-cards didn't). - Normalized ALL border opacities from 0.08 to 0.10 across settings.css (14 occurrences — strategy options, theme options, advanced options, buttons, mode options, etc.). Focus accessibility: - Added purple focus ring (box-shadow glow) to network select dropdown in settings — was the only input without one. Light theme: - Added [data-theme="light"] block to gateways-enhanced.css for modal stat cards — was completely missing, causing dark styles in light mode. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…e pages - Add explicit light mode background override for .gateways-container and .performance-container (CSS variable fallback was showing dark bg) - Add light mode overrides for gateways header, footer, stat cards - Add light mode overrides for performance container Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove overflow:hidden from .gateways-container — it was clipping the scrollable .gateways-content child, preventing scrolling to the top of the gateway list behind the fixed header. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dark is the default theme, so it should appear first in the theme selector. Having Light first was confusing since it visually stood out with its white preview styling, making users think it was selected. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Page was painting with dark defaults before the async
chrome.storage.local.get() resolved with the user's theme preference.
Fix: hide the page via `html:not([data-theme-ready]) { opacity: 0 }`
inline style, then set `data-theme-ready` in the same callback that
applies the theme. The browser only paints once the theme is set,
eliminating the flash. Applied to all 4 HTML pages.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ance Chrome MV3 Content Security Policy blocks inline scripts. Move the theme initialization logic from inline <script> tags to an external theme-init.js file loaded via <script src="theme-init.js">. The opacity:0 → data-theme-ready technique still prevents the dark-to-light flash, now without violating CSP. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Gateways and performance pages had dark fallback (#0e0a1c) on the html/body elements that was bleeding through as a grey hue at the top of the page in light mode. Override html, body, and the main container to #ffffff directly in the [data-theme="light"] block. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Text colors: - textHigh: #d4c6ff (lavender) → #ffffff (white) for primary text - textMid: #9b93b4 → #d4c6ff (lavender) for secondary/description text - iconHigh: #d4c6ff → #ffffff for primary icons - Muted text (#9b93b4) unchanged Gateways scroll: - Restore overflow:hidden on .gateways-container (needed for flex child scroll constraint) - Change min-height:100vh → height:100vh so the container is fixed size and .gateways-content overflow-y:auto actually activates Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New routing strategy that round-robins across the top 20 gateways by total delegated stake, with ping health checks on each selection. - Add `limit` option to ChromeStorageGatewayProvider - Add `topStaked` case in routing.ts using RoundRobinRoutingStrategy with a stake-sorted, limited gateway provider wrapped in PingRoutingStrategy for health verification - Add strategy card in settings UI with star icon - Add label mapping in popup.ts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- CLAUDE.md: fix default network to mainnet (was still saying devnet) - Extension CLAUDE.md: add topStaked strategy, update cache TTL - Extension README: add Top Staked to features list and routing config Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore(core): bump @ar.io/sdk devDependency to ^4.0.0-solana.8 First step of the Solana migration. wayfinder-core's only @ar.io/sdk touchpoint is a type-only import of `AoARIORead` in network.ts; that type has the same shape on the 4.x-solana.X line as on 3.x, so no code changes are required. Bumping the devDependency exercises the Solana-capable SDK during local + CI test runs, giving us confidence the package stays compatible as we migrate the rest of the monorepo. - packages/wayfinder-core/package.json: devDep `@ar.io/sdk` `^3.13.0` -> `^4.0.0-solana.8`. peerDependency `>=3.12.0` left unchanged (the constraint already permits 4.x; loosening lockstep with AO-era consumers is intentional). - packages/wayfinder-core/src/version.ts: synced by the build's update-version script. No semantic change. - package-lock.json: regenerated by npm install. - .changeset/wayfinder-core-solana-sdk.md: patch-bump changeset documenting the SDK-compat verification. Verified: - npm run lint:check (biome) passes - npm run build (tsc) passes — confirms the SDK boundary still type-checks against 4.x-solana.8 - npm test passes against the bumped SDK Out of scope for this commit (deferred to follow-up): the wayfinder-extension AR.IO SDK migration (Solana-only refactor of storage schema, settings UI, and ARIO.init call sites). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * chore(ci): track `solana` branch alongside main/alpha The Solana migration uses `solana` as a long-lived integration branch (mirroring the same pattern used in ar-io-node, ar-io-sdk, ar-io-observer). Without `solana` in the CI workflow triggers, none of the feature PRs we land into the branch get lint/test/build signal before merge — only the eventual `solana -> alpha` rollup would. Add `solana` to the `branches:` list in: - pr-check.yml (Diff Check — paths-filter classification) - core.yml (Core Library — lint/test/build) - extension.yml (Chrome Extension — lint/test/build) - react.yml (React Components & Hooks — lint/test/build) Deliberately NOT touched: - chrome.yml is workflow_dispatch only (manual publish to the Chrome store); branch triggers don't apply. - release.yaml drives changesets-based publishing — we don't want it accidentally publishing from the `solana` integration branch. It stays scoped to main/alpha. No changeset required: workflow-only change, no consumer impact. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * refactor(extension): add Solana network type/constant/default scaffolding (#246) Foundation work for the AO -> Solana migration (PR A of two). Purely additive — no existing code consumes the new exports yet, so this commit introduces zero runtime behavior change. - src/types.ts: * NetworkPreset enum ('mainnet' | 'devnet' | 'custom') * SolanaNetworkConfig shape (rpcUrl + 4 program IDs) - src/constants.ts: * AR_IO_SOLANA_DEVNET preset carrying the public devnet RPC and the four program addresses from ar-io-solana-contracts/program-ids/ devnet.json. Includes a docstring noting the public RPC's rate limits. * AR_IO_SOLANA_MAINNET = null placeholder (AR.IO Solana mainnet is not yet deployed; will be populated in a future commit). * AR_IO_SOLANA_PRESETS keyed lookup for use by the settings UI. - src/config/defaults.ts: * SOLANA_NETWORK_DEFAULTS = { network: 'devnet', ...devnet preset } for use by the upcoming migration commit when it populates EXTENSION_DEFAULTS / chrome.storage on first install. The follow-up PR ('refactor(extension): drop AO entirely; route through Solana') will: rewrite the four ARIO.init call sites in background.ts and settings.ts; replace the AO Process ID / CU URL form fields in settings.html with a network preset selector + Solana RPC + program ID inputs; add storage migration logic for existing AO-era users (silent reset to devnet defaults + force GAR resync); drop @permaweb/aoconnect; bump @ar.io/sdk to ^4.0.0-solana.8. Verified: - npm run build -w @ar.io/wayfinder-extension passes (tsc + bundle) - biome lint clean Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> * refactor(extension)!: drop AO entirely; route through Solana (#247) * refactor(extension)!: drop AO entirely; route through Solana BREAKING change: AO support is removed from wayfinder-extension. The extension now talks to AR.IO exclusively through the Solana-backed @ar.io/sdk@4.x. Default network on fresh install is AR.IO Solana devnet; mainnet is reserved for when the AR.IO Solana mainnet deployment ships. Builds on the additive foundation landed in the previous commit (refactor(extension): add Solana network type/constant/default scaffolding). Code: - src/background.ts: drop AOProcess + @permaweb/aoconnect + AO process constant imports; add arioFromStorage() helper that constructs a read-only Solana ARIO from chrome.storage.local with EXTENSION_ DEFAULTS fallback; rewrite the four ARIO.init call sites to use it; add migrateStorageFromAOEra() that detects pre-existing AO-era storage keys, removes them, invalidates the cached gateway registry, and lets the next sync repopulate from Solana. - src/settings.ts: drop ARIO.mainnet() fallback in favor of a Solana-backed ARIO.init({backend: 'solana', ...}) built from current storage; replace handleProcessIdChange + handleAoCuUrlChange with a consolidated handleNetworkConfigChange covering all six new fields (network, rpcUrl, four program IDs); validate inputs via URL() for the RPC and @solana/kit `address()` for program IDs; preset selection auto-fills + disables the per-field inputs. - src/constants.ts: remove ARIO_MAINNET_PROCESS_ID and DEFAULT_AO_CU_URL. - src/config/defaults.ts: drop the AO `processId`/`aoCuUrl` entries from EXTENSION_DEFAULTS; replace with the Solana network defaults (`network`, `rpcUrl`, four program IDs). - src/settings.html: replace "AR.IO Process ID" + "AO Compute Unit URL" sections with a Network preset selector, a Solana RPC URL input, and a collapsible "Advanced: AR.IO Program IDs" panel exposing the per-program addresses. Mainnet preset is `disabled` until AR.IO Solana mainnet ships. Dependencies: - @ar.io/sdk: ^3.21.0 -> ^4.0.0-solana.8 - @solana/kit: added at ^2.1.0 (used by SDK's Solana backend and by the extension's address() validation in settings + the settings- side fallback ARIO instance) - @permaweb/aoconnect: removed Storage migration: - AO-era users had `processId` + `aoCuUrl` in chrome.storage.local. On first run after upgrade migrateStorageFromAOEra() removes them along with the cached `localGatewayAddressRegistry`, then the startup defaults block writes the new Solana keys. Background re-init then connects to AR.IO Solana devnet and the next sync repopulates the registry from a Solana gateway source. Users see the extension keep working with no settings prompt. Verified locally: - `npm run build -w @ar.io/wayfinder-extension` passes (tsc + vite) - `biome check` passes - Bundle size shrinks (vendor chunk: 5.3 MB -> 3.8 MB) thanks to dropping the AO compute stack and the aoconnect dependency. Out of scope (deferred): no automated tests exist in the extension package; validation is purely manual via a Chrome dev profile. The PR description includes a step-by-step smoke-test checklist. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(extension): clean up AO relics + wire reinitializeArIO Follow-up on the AO -> Solana migration: a self-review surfaced six remaining AO relics + one real bug. Bundled here as a single clean-up commit; the original 02a7660 stays as the readable migration commit. Real bugs: - gateways.ts: the gateway-ping health check probed `info.processId` on /ar-io/info, which AR.IO Solana gateways no longer emit (replaced by `programIds`). Without this fix, every modern AR.IO gateway would be marked Unhealthy by the extension's ping tool. Switched the check to `info.programIds` (typeof object). - background.ts (updateAdvancedSettings handler): handler was calling `chrome.storage.local.set(request.settings)`, but the settings page already writes storage directly and now sends the message with no `settings` field. The handler was effectively a no-op for storage and never rebuilt the ARIO instance — so a user changing the Solana RPC URL or program IDs wouldn't see the underlying SDK pick up the change until the next service-worker restart. Replaced the (dead) storage write with a call to `reinitializeArIO()` so the ARIO read instance rebuilds from the new storage on every settings change. Dead code removed: - background.ts: `setAoCuUrl` message handler (only reachable from the now-deleted AO CU URL form field). Plus its allowlist entry. Plus the orphan `setArIOProcessId` allowlist entry that never had a handler. - settings.ts: the "Reset all settings" button still removed the legacy `processId` / `aoCuUrl` storage keys instead of the new Solana keys, so pressing it left the user's storage untouched. Updated to remove the six new network keys; the startup defaults block then repopulates them with the devnet preset on next load. Build hygiene: - vite.config.js: the manualChunks `webIndex` chunk still listed `@permaweb/aoconnect` (now removed from dependencies). Replaced with `@solana/kit` to keep the chunk grouping useful. Docs: - README.md: "Network Configuration" section described the old "Process ID" + "AO CU URL" fields. Replaced with the new Network preset / Solana RPC URL / Advanced program IDs description. Note: `reinitializeArIO` (now wired into `updateAdvancedSettings`) was orphaned by the `setAoCuUrl` removal; lint would have flagged it. Pre-emptively re-wired before lint caught it. Verified locally: - `npm run build -w @ar.io/wayfinder-extension` passes (tsc + vite) - `biome check` passes - Final grep: no remaining unintentional AO references in the extension src/, README, vite config, or manifest. The remaining AO references in background.ts are all inside `migrateStorageFromAOEra()` (intentional — that function detects and removes AO-era storage keys). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * ci: re-trigger workflows after base retarget --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> * fix(extension): Solana migration follow-ups (fallback gate + startup robustness + dead code) (#248) Surfaced by a post-merge end-to-end scan of the extension's Solana migration. Three categories of cleanup: 1. Cross-network contamination via the mainnet fallback gateway FALLBACK_GATEWAY in constants.ts is hardcoded to turbo-gateway.com (mainnet). routing.ts uses it as a last-resort fallback when normal routing fails. After the migration the extension defaults to AR.IO Solana devnet, where the gateway registry is sparsely populated — so the fallback fires often and silently serves mainnet content under the user's devnet network. Now the fallback is gated on `network === 'mainnet'` in storage; on devnet or a custom network the original routing error is propagated instead, surfacing the empty-registry condition to the user rather than masking it with mainnet data. 2. Startup robustness against bad stored network config The boot IIFE in background.ts called `arIO = await arioFromStorage()` without a try/catch. arioFromStorage() invokes @solana/kit's address() on each stored program-ID, which throws on non-base58 input. If a user previously persisted a bad value via the custom-network preset, the IIFE would crash before reaching debouncedInitializeWayfinder(), leaving routing inoperable until manual reset. Now wrapped with a fallback to bundled EXTENSION_DEFAULTS that mirrors the existing reinitializeArIO() catch path. 3. Dead-code removal - `resetAdvancedSettings` message handler: had logic but no UI button calling it after the migration. The startup defaults block plus the existing `updateAdvancedSettings` flow cover the same surface. - `updateVerificationMode` allowlist entry: pure dead string, no handler ever existed in the post-migration tree. Both removed from the validMessages allowlist; the resetAdvanced Settings handler body removed too. Verified locally: - npm run build -w @ar.io/wayfinder-extension passes - npm run lint:check (biome + eslint, 121 files) passes - No new tests added (extension package has none; smoke test remains a manual Chrome dev-profile exercise). Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> * docs(core): rewrite README examples from AO mainnet to Solana syntax (#249) wayfinder-core itself is chain-agnostic — it consumes only the `AoARIORead` type and delegates instance construction to the caller. But the published README only showed `ARIO.mainnet()` (the AO-era AR.IO mainnet) examples, which is misleading in the post-Solana- migration ecosystem. Rewrite the four example blocks to use the SDK 4.x Solana backend: const ario = ARIO.init({ backend: 'solana', rpc: createSolanaRpc('https://api.devnet.solana.com'), coreProgramId: address('...'), garProgramId: address('...'), arnsProgramId: address('...'), antProgramId: address('...'), }); The first example carries a comment explaining how to switch to mainnet (drop the program-ID overrides; the SDK ships mainnet defaults) once AR.IO Solana mainnet deploys, and reaffirms that wayfinder-core is chain-agnostic — same APIs work for any backend the SDK supports. Sections updated: - Getting Started: Using with AR.IO Network - NetworkGatewaysProvider reference - CompositeGatewaysProvider example - CompositeRoutingStrategy examples 1 + 2 Docs-only. No code changes. wayfinder-core's `network.ts` already type-checked against SDK 4.x in the earlier compat-verification commit (991e450). Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> * feat!: migrate to @ar.io/sdk v4.0.2 stable (Solana-only) — v2.0.0 BREAKING CHANGE: Drop AO backend support entirely; Solana is now the only backend for the AR.IO on-chain registry. SDK migration: - Rename Ao-prefixed types: AoARIORead→ARIORead, AoGateway→Gateway, AoGatewayWithAddress→GatewayWithAddress across all packages - Remove `backend: 'solana'` from all ARIO.init() calls (Solana is the only backend, parameter no longer exists) - Bump @ar.io/sdk from ^4.0.0-solana.8 to ^4.0.2 - Bump @solana/kit from ^2.1.0 to ^6.8.0 - Bump wayfinder-core peer dep from @ar.io/sdk>=3.12.0 to >=4.0.0 Program IDs & mainnet: - Update devnet program IDs to match SDK v4.0.2 deployment - Populate mainnet program IDs (AR.IO Solana mainnet is now live) - Enable mainnet preset in extension settings UI - Add storage migration for users with stale devnet program IDs Build: - Fix Vite bundling for @solana/kit v6 (resolve.alias to deduplicate conflicting v5/v6 @solana/* sub-packages from x402-fetch) Version bumps: - wayfinder-core: 1.9.2 → 2.0.0 - wayfinder-extension: 1.0.23 → 2.0.0 - wayfinder-react: 1.0.29 → 2.0.0 - monorepo: 0.0.14 → 1.0.0 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(extension): use dynamic resolution for @solana/* Vite aliases The previous hardcoded paths to @solana/kit/node_modules/ only worked with yarn's nesting layout. CI uses npm, which hoists differently and the nested paths don't exist. Switch to createRequire anchored to @solana/kit's main entry, so each @solana/* sub-package resolves to the version kit was built against regardless of package manager hoisting strategy. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * perf(core,extension): add fetch timeouts, ping caching, periodic sync 1. Fetch timeouts — prevent indefinite hangs on slow/dead endpoints: - TrustedPeersGatewaysProvider: 10s timeout (configurable) - ContiguousDataRetrievalStrategy: 30s timeout (configurable) - ChunkDataRetrievalStrategy: 10s metadata, 30s per chunk (configurable) - Extension DNS lookup: 5s timeout 2. Ping result caching — avoid re-pinging all gateways on every request: - Wrap FastestPingRoutingStrategy with SimpleCacheRoutingStrategy (120s TTL) in the extension's routing setup - Stale cache is returned on ping failure (built into SimpleCacheRoutingStrategy) 3. Periodic gateway registry sync — recover from failed startup syncs: - chrome.alarms fires every 60 minutes - Skips sync if last sync was recent (staleness check via lastSyncTime) - Added "alarms" permission to manifest.json Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore(extension): change periodic gateway sync to every 24 hours Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(extension): default to mainnet, improve program IDs UI - Switch default network preset from devnet to mainnet - Restyle the Advanced: AR.IO Program IDs section: - Proper collapsible disclosure triangle - Stacked label+input layout with spacing - Monospace font for pubkey inputs - Description text with muted styling Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(extension): add retry with backoff for Solana RPC rate limits The public Solana RPC endpoints (mainnet-beta, devnet) aggressively rate-limit, returning HTTP 403 / SolanaError #8100002. Each getGateways() page fetch is now wrapped in retryWithBackoff() which: - Retries up to 5 times on 403, 429, 5xx, and network errors - Uses exponential backoff with jitter (2s base, 15s cap) - Lets application errors (bad address, deserialization) bubble immediately This makes the gateway sync work reliably with the free public RPC endpoints without requiring a premium QuickNode/Helius endpoint. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(extension): use QuickNode RPC for Solana mainnet The public api.mainnet-beta.solana.com actively rejects requests from Chrome extension service workers (HTTP 403). Switch the mainnet default to a QuickNode endpoint that works from browser contexts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs(extension): update README for v2.0.0 - Update Chrome Web Store section (no longer "coming soon") - Add yarn install + core build step to dev instructions - Update project structure with actual .ts filenames and new files - Add @ar.io/sdk v4.x and @solana/kit to key technologies - Clarify network preset defaults and RPC details Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(extension): rebrand UI to AR.IO 2026 design system Update the entire extension UI to match the AR.IO brand kit (v2026-03-30): Colors: - Primary accent: teal rgb(45, 211, 190) → purple #5427C8 - Secondary: dark teal → lavender #DFD6F7 - Dark backgrounds: neutral grays (#050505 scale) → purple-tinted darks (#0e0a1c scale) - Text on dark: gray #cacad6 → lavender #D4C6FF - Gradients: peach-to-purple (#f7c3a1→#df9be8) → purple spectrum (#5427C8→#DFD6F7) - Light theme: slate grays → Lavender Wash #f1ecff / Warm Neutral #F6F4EF Typography: - Headings: Rubik → Besley (weight 800, tight line-height 1.08) - Body: Rubik/Inter → Plus Jakarta Sans - Monospace: JetBrains Mono (kept) Layout: - Border radii increased: 4/8/12/16px → 8/12/20/24px - Strokes: neutral gray-blue rgba → purple-tinted rgba Files updated: - variables.css: Complete design token rewrite - popup.css, settings.css, gateways.css, gateways-enhanced.css, performance.css: All hardcoded colors replaced with new brand values - All 4 HTML files: Google Fonts updated to Besley + Plus Jakarta Sans Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(extension): pixel-perfect brand compliance pass - All Besley headings: font-weight 800, letter-spacing -0.025em, line-height 1.08 - Popup logo h1: switched from body font to heading font (Besley) - Nav card h3s: switched to Besley heading font - Toggle unchecked state: #0e0a1c → #26203a for visible contrast - Focus rings: added box-shadow glow on all text/url inputs - Filter buttons: border-radius 6px → var(--radius-sm, 8px) - Back buttons: border-radius 10px → var(--radius-md, 12px) - Fixed 4 remaining font-weight: 600 headings in settings.css Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(extension): enforce brand minimum 8px radius on interactive elements Tooltips, buttons, selects, close buttons, and list items had 4-6px radii. Brand spec minimum is 8px (--radius-sm). Updated 13 elements across popup.css, settings.css, gateways.css, and performance.css. Intentionally kept small radii on: scrollbar thumbs (3px), range slider tracks (3px), decorative accent bars (2px), tiny badges (3px), checkboxes (3px), and progress bars (3px) — these are sub-element details where 8px would look wrong. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(extension): add theme support to gateways/performance + fix card bg consistency Theme support: - gateways.ts and performance.ts had NO theme application — light mode was completely broken on these pages. Added applyTheme() + system preference listener to both, matching popup.ts/settings.ts pattern. Card background consistency: - Gateways container used L1 (#1a1527) instead of L0 (#0e0a1c) as page background — one shade off from popup/settings/performance. - Gateways back-button used L1 instead of L0 (inconsistent with settings/performance back buttons). - 8 hardcoded #26203a hover states replaced with var(--colors-container-containerL2) so light theme hovers work. - Toggle switch border/bg hardcoded values → CSS variables. All 4 pages now have identical theme detection, identical background hierarchy (L0 page → L1 cards → L2 hover → L3 inputs), and all container colors use CSS variables for correct light/dark theming. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(extension): update icon, fix theme flicker, tighten popup layout Extension icon: - Replace old icon with latest AR.IO brand icon from brand kit (ario-white-on-black-round) at 128/48/16px sizes Theme flicker fix: - Add inline <script> in <head> of all 4 HTML pages that sets data-theme synchronously before CSS paints — eliminates the flash of dark theme when navigating pages in light mode Popup layout tightening: - Reduce section gap from 18px to 12px - Reduce stat card height from 89.7px to 72px - Reduce nav card gap from 16px to 8px between cards - Reduce card padding from 16px to 12px vertically - Shrink strategy/feature icons from 32px to 28px - Remove transform/box-shadow from nav-card hover (was inconsistent with strategy-card hover behavior — now all cards hover identically) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(extension): normalize card backgrounds to containerL1 across all pages - Popup: replaced var(--bg-secondary) alias with explicit var(--colors-container-containerL1) on stat-card, strategy-card, nav-card — matches settings/gateways/performance convention - Fixed duplicate .strategy-card block (second override) that still used --bg-secondary with larger padding - Settings: network-option background was containerL0 (same as page bg, invisible) — changed to containerL1 to match other cards All cards across all 4 pages now use identical token: background: var(--colors-container-containerL1, #1a1527) hover: var(--colors-container-containerL2, #26203a) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(extension): fix container background hierarchy across all pages Apply consistent design token usage across all CSS: - Card/section elements use containerL1 (raised from page background) - Hover states use containerL2 - Input fields use containerL3 - Page background, headers, footers remain containerL0 Fixes: - popup.css: nav-cards gap 8px→12px to match parent section gap - settings.css: .theme-option, .advanced-option, .mode-option, .option-card, .provider-option, .verification-strategy-selector .strategy-option, .trusted-gateways-config .mode-option all changed from L0 to L1; hover states from L0 to L2 - performance.css: .filter-section, .usage-section, .action-card changed from L0 to L1 - gateways.css: .search-box input changed from L0 to L3 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(extension): fix advanced settings hover, toggle contrast, gateways light mode - Fix advanced settings section hover: .advanced-options → .advanced-config in the :not() exclusion list so hovering sub-items doesn't grey out the entire card - Improve toggle switch unchecked state: use containerL3 instead of L2 with visible border for better contrast against card backgrounds - Add light mode overrides for gateways page: header border, filter section, filter buttons, search input all now use proper light theme tokens instead of dark-mode rgba values Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(extension): comprehensive design system audit fixes across all pages Full pixel-level audit of popup, settings, gateways, and performance pages. Every element checked against the L0/L1/L2/L3 container hierarchy, font families, and text color tokens. Popup: - .stat-label: textHigh → textMid (secondary text should be muted) - .strategy-description: textHigh → textMid - .nav-content p: textHigh → textMid Settings: - .back-button:hover: L0 → L2 (was invisible hover state) - .input-with-button input: L0 → L3 (input fields must be L3) Performance: - .back-button:hover: L0 → L2 (no visual hover feedback) - .stat-card: --bg-secondary → containerL1 (undefined legacy var) - .stat-value: --text-high → neutrals-100 (undefined legacy var) - .stat-label: --text-high → textMid (secondary text muted) - Light mode: add missing overrides for filter-section, filter-btn, sort-select, stat-card, stat-value, stat-label, usage-section, section-header Gateways: - .stat-card: --bg-secondary → containerL1 (undefined legacy var) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(extension): cross-page consistency pass — borders, layout, focus rings Structural consistency: - Gateways page header/footer now fixed-position (was relative), matching popup/settings/performance — fixes inconsistent scroll behavior. Content padding updated to account for fixed elements. - Settings back-button radius 10px → var(--radius-md, 12px) to match gateways/performance pages. Border consistency: - Popup stat-cards now have 1px solid var(--border-subtle) border (was missing — strategy/nav cards had it, stat-cards didn't). - Normalized ALL border opacities from 0.08 to 0.10 across settings.css (14 occurrences — strategy options, theme options, advanced options, buttons, mode options, etc.). Focus accessibility: - Added purple focus ring (box-shadow glow) to network select dropdown in settings — was the only input without one. Light theme: - Added [data-theme="light"] block to gateways-enhanced.css for modal stat cards — was completely missing, causing dark styles in light mode. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(extension): fix light mode backgrounds on gateways and performance pages - Add explicit light mode background override for .gateways-container and .performance-container (CSS variable fallback was showing dark bg) - Add light mode overrides for gateways header, footer, stat cards - Add light mode overrides for performance container Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(extension): fix gateways page scroll clipping Remove overflow:hidden from .gateways-container — it was clipping the scrollable .gateways-content child, preventing scrolling to the top of the gateway list behind the fixed header. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(extension): reorder theme options — Dark first (default) Dark is the default theme, so it should appear first in the theme selector. Having Light first was confusing since it visually stood out with its white preview styling, making users think it was selected. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(extension): eliminate dark-to-light theme flash on page navigation Page was painting with dark defaults before the async chrome.storage.local.get() resolved with the user's theme preference. Fix: hide the page via `html:not([data-theme-ready]) { opacity: 0 }` inline style, then set `data-theme-ready` in the same callback that applies the theme. The browser only paints once the theme is set, eliminating the flash. Applied to all 4 HTML pages. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(extension): move theme init to external script for MV3 CSP compliance Chrome MV3 Content Security Policy blocks inline scripts. Move the theme initialization logic from inline <script> tags to an external theme-init.js file loaded via <script src="theme-init.js">. The opacity:0 → data-theme-ready technique still prevents the dark-to-light flash, now without violating CSP. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(extension): force white background on html/body in light mode Gateways and performance pages had dark fallback (#0e0a1c) on the html/body elements that was bleeding through as a grey hue at the top of the page in light mode. Override html, body, and the main container to #ffffff directly in the [data-theme="light"] block. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(extension): white primary text in dark mode, fix gateways scroll Text colors: - textHigh: #d4c6ff (lavender) → #ffffff (white) for primary text - textMid: #9b93b4 → #d4c6ff (lavender) for secondary/description text - iconHigh: #d4c6ff → #ffffff for primary icons - Muted text (#9b93b4) unchanged Gateways scroll: - Restore overflow:hidden on .gateways-container (needed for flex child scroll constraint) - Change min-height:100vh → height:100vh so the container is fixed size and .gateways-content overflow-y:auto actually activates Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(extension): add Top Staked routing strategy New routing strategy that round-robins across the top 20 gateways by total delegated stake, with ping health checks on each selection. - Add `limit` option to ChromeStorageGatewayProvider - Add `topStaked` case in routing.ts using RoundRobinRoutingStrategy with a stake-sorted, limited gateway provider wrapped in PingRoutingStrategy for health verification - Add strategy card in settings UI with star icon - Add label mapping in popup.ts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore(extension): default routing strategy to topStaked Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: update docs for topStaked default and mainnet - CLAUDE.md: fix default network to mainnet (was still saying devnet) - Extension CLAUDE.md: add topStaked strategy, update cache TTL - Extension README: add Top Staked to features list and routing config Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 054a5ae The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Warning Review limit reached
More reviews will be available in 19 minutes and 5 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (5)
📒 Files selected for processing (62)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
- Replace dead arnsProcessId (X-ArNS-Process-Id) with Solana-era arnsAntProgramId (X-ArNS-Ant-Program-Id) and arnsAntId (X-ArNS-Ant-Id) - Add new root data headers: rootPath, rootItemOffset, rootItemSize - Add HTTPSIG headers: Signature-Input, Signature (RFC 9421) - Add Arweave tx metadata headers: owner, ownerAddress, signature, signatureType, tagCount Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Release: Wayfinder v2.0.0
Production release merging the complete Solana migration and AR.IO rebrand from
alpha.Breaking Changes
@ar.io/sdkpeer dependency bumped from>=3.12.0to>=4.0.0AoARIORead→ARIORead,AoGateway→Gateway, etc.)Highlights
SDK & Network
@ar.io/sdkv4.0.2 stable (Solana-only)@solana/kitv6.8.0New Feature: Top Staked Routing
Resiliency
AR.IO 2026 Rebrand
Versions
@ar.io/wayfinder-core@ar.io/wayfinder-extension@ar.io/wayfinder-reactCI Status
All workflows passing: Core Library, Chrome Extension, React Components, Diff Check, CodeRabbit.
Test Results
Test plan
yarn build— all 5 packages clean🤖 Generated with Claude Code