feat: Studio UX improvements - config validation, error messages, and safer defaults#74
feat: Studio UX improvements - config validation, error messages, and safer defaults#740xSoju2 wants to merge 10 commits intoMeteoraAg:mainfrom
Conversation
…t spurious errors
…ddresses to README
|
/bot review |
|
Bot Agent progress:
Progress:
|
There was a problem hiding this comment.
Summary
Keep all seven comments. They are mutually consistent, non-duplicative, and align with the stated merge-blocking concerns: global --help short-circuiting command help, overly broad and incomplete placeholder validation, incorrect explorer cluster mapping, pnpm version mismatch in README, null-guard ordering causing potential TypeError in damm_v1, and createCheckedConnection not being wired into active execution paths.
Inline comments
See inline comments on the diff.
Claude (API) review
Rounds: 2 (min=1, max=10).
First look: Codex + Claude (Claude first-look failed; fell back to Codex).
Agreement: yes (no new findings/questions).
Debate transcript
First look comparison
Codex (first look):
Summary:
Great UX-focused improvements overall, but I found a few actionable issues before merge: --help currently bypasses command-specific help, placeholder validation is both over-broad (/^XXX/) and incomplete for non-address TOKEN_* fields, success explorer links assume devnet for all non-mainnet networks, README has a pnpm version mismatch, and config-validation.ts still has prettier violations (currently failing lint).
Inline comment highlights:
- studio/src/helpers/cli.ts:42: This early-exit
--helpbranch will trigger for normal command invocations like... --help(whererawArgsis typically just['--help']), so command-specificdisplayHelp()logic later never runs. Consider not exiting here for per-co - studio/src/helpers/config-validation.ts:17: The placeholder regex
/^XXX/iis too broad and can reject legitimate base58 public keys that happen to start withXXX. IfXXXis meant as a literal placeholder token, this should be an exact/specific match (e.g./^XXX$/i) instead of - studio/src/helpers/config-validation.ts:65:
isPlaceholder()is only used fromvalidateAddress(). That means non-address placeholders likeTOKEN_NAME,TOKEN_SYMBOL, andTOKEN_DESCRIPTIONare not actually validated anywhere yet. Please add a generic string-field placeholder v - studio/src/helpers/output-formatter.ts:72: Explorer URL generation currently treats every non-mainnet network as devnet (
?cluster=devnet). This will produce incorrect links fortestnetand especiallylocalnet/custom RPC. Suggest explicit cluster mapping (mainnet-beta, `devne - studio/README.md:80: The checklist says
pnpm ≥ 9, but the repo declarespackageManager: pnpm@10.27.0and enginespnpm >=10. Please align this to prevent onboarding users onto an unsupported pnpm version. - studio/src/helpers/config-validation.ts:264: This file is currently failing prettier/lint (including this signature area and
validateBaseConfigsignature formatting). Please run prettier on this file to unblock CI.
Codex (first look fallback):
Summary:
Solid UX-focused improvements, but I found a few actionable issues before merge: --help handling now short-circuits command-specific help, one validation call is ordered before its null guard, and there are a couple of edge-case correctness/UX problems (placeholder regex breadth and explorer cluster mapping). I also noticed a docs version mismatch and that the new RPC helper appears not to be wired into execution paths yet.
Inline comment highlights:
- studio/src/helpers/cli.ts:46: This early-exit path for
--helpwill trigger for action scripts that are invoked aspnpm studio <action> --help, because the action name is not part of the script's argv. That means command-specific help handlers never run and users onl - studio/src/lib/damm_v1/index.ts:51:
validateBaseConfig(config)now runs before theif (!config)guard. If config loading ever returnsnull/undefined, this will throw a TypeError inside validation instead of the intended clear error. Please move the null guard above va - studio/src/helpers/config-validation.ts:17: Using
/^XXX/ias a placeholder detector is very broad and can reject legitimate base58 public keys that happen to start withXXX(rare but valid). Suggest narrowing this to explicit placeholder tokens (e.g., exactXXXorXXX_...) to - studio/src/helpers/output-formatter.ts:72: Explorer URL selection defaults to
devnetfor any non-mainnet network. For localnet (or unknown/testnet), this prints an incorrect link and can mislead users. Consider explicit cluster mapping (mainnet,devnet,testnet) and skipping - studio/README.md:80: The checklist says
pnpm ≥ 9, but repo root engines requirepnpm >=10. This mismatch can send users down a bad setup path; please align the README version requirement withpackage.json. - studio/src/helpers/connection.ts:18: I don’t see this helper wired into the updated action/lib execution paths in this diff. Without replacing existing
new Connection(...)call sites, the health-check and improved RPC errors won’t actually be observed by users.
Comparison notes:
PR Review Synthesis
- No true disagreements — both reviews align on key issues:
--helpshort-circuiting command help, placeholder regex too broad, explorer cluster mapping, and README pnpm mismatch. - Differences in emphasis:
- Review A only: calls out missing placeholder validation for non-address
TOKEN_*fields and explicit Prettier/lint failures inconfig-validation.ts. - Review B only: highlights a potential runtime bug where
validateBaseConfig(config)is called beforeconfignull-check. - Review B only: questions whether
connection.tsis actually wired into execution paths, so RPC/health-check improvements may be inactive.
- Review A only: calls out missing placeholder validation for non-address
Most important follow-up action:
Prioritize the runtime safety fix: move the null guard above validateBaseConfig(config) (with a regression test), then handle the shared UX/docs issues.
Round 1
Codex (primary):
Summary:
Great UX-focused improvements overall, but I found a few actionable issues before merge: --help currently bypasses command-specific help, placeholder validation is both over-broad (/^XXX/) and incomplete for non-address TOKEN_* fields, success explorer links assume devnet for all non-mainnet networks, README has a pnpm version mismatch, and config-validation.ts still has prettier violations (currently failing lint).
Inline comment highlights:
- studio/src/helpers/cli.ts:42: This early-exit
--helpbranch will trigger for normal command invocations like... --help(whererawArgsis typically just['--help']), so command-specificdisplayHelp()logic later never runs. Consider not exiting here for per-co - studio/src/helpers/config-validation.ts:17: The placeholder regex
/^XXX/iis too broad and can reject legitimate base58 public keys that happen to start withXXX. IfXXXis meant as a literal placeholder token, this should be an exact/specific match (e.g./^XXX$/i) instead of - studio/src/helpers/config-validation.ts:65:
isPlaceholder()is only used fromvalidateAddress(). That means non-address placeholders likeTOKEN_NAME,TOKEN_SYMBOL, andTOKEN_DESCRIPTIONare not actually validated anywhere yet. Please add a generic string-field placeholder v - studio/src/helpers/output-formatter.ts:72: Explorer URL generation currently treats every non-mainnet network as devnet (
?cluster=devnet). This will produce incorrect links fortestnetand especiallylocalnet/custom RPC. Suggest explicit cluster mapping (mainnet-beta, `devne - studio/README.md:80: The checklist says
pnpm ≥ 9, but the repo declarespackageManager: pnpm@10.27.0and enginespnpm >=10. Please align this to prevent onboarding users onto an unsupported pnpm version. - studio/src/helpers/config-validation.ts:264: This file is currently failing prettier/lint (including this signature area and
validateBaseConfigsignature formatting). Please run prettier on this file to unblock CI.
Claude (API):
Critique of Primary Review
The primary review is solid and covers the main UX/correctness issues well. However, it has two notable gaps:
-
Missed runtime bug (damm_v1/index.ts:52): The primary review doesn't flag that
validateBaseConfig(config)is called before the existingif (!config)null guard. This is a real crash-path bug — if config loading ever returnsnull, the user gets a crypticTypeError: Cannot read properties of null (reading 'rpcUrl')instead of the intended clear error. My round-0 review caught this; the primary review did not. -
Missed dead code (connection.ts): The new
createCheckedConnectionhelper is exported but never called from any modified execution path. The primary review doesn't mention this, meaning the headline feature of "RPC health-check with clear error messages" is actually inert in this PR. -
Over-emphasis on lint formatting: The primary review spends a full inline comment on prettier violations in
config-validation.ts. While the CI failure is real, this is aprettier --writeauto-fix — it's not a review-worthy finding at the same priority level as the runtime bugs above. It would be better as a brief note rather than a numbered inline comment. -
Incomplete
--helpanalysis: The primary review correctly flags the--helpearly-exit issue but doesn't fully trace through howprocess.argvlooks when invoked viapnpm studio <script> --help(i.e., via tsx). The actual argv seen by the script may vary depending on the pnpm/tsx invocation pattern, and this deserves a concrete test recommendation.
Overall the primary review catches ~70% of the important issues. The runtime null-guard ordering and dead-code module are the highest-value additions.
Codex (response):
- New findings applied: 2/2
- False positives addressed: 1/1
- Open questions kept for author: 2/2
Round 2
Codex (primary):
Summary:
Nice UX-focused progress overall, but there are still several merge-blocking items: global --help handling may preempt command-specific help, placeholder validation is both over-broad (/^XXX/) and incomplete for non-address TOKEN_* fields, explorer links incorrectly assume devnet for every non-mainnet network, and README’s pnpm requirement is inconsistent with the repo config. In addition, two important issues were added: a null-guard ordering bug in damm_v1 can throw an unhandled TypeError, and createCheckedConnection is currently dead code because execution paths still use new Connection(...) directly. I removed the prior inline lint/prettier-only comment as non-critical review noise.
Inline comment highlights:
- studio/src/helpers/cli.ts:42: This early
--helpexit can still preempt command-level help handling. In common invocations likepnpm studio <command> --help, scripts often receiverawArgsas just['--help'], so later command-specificdisplayHelp()/ parsed-help - studio/src/helpers/config-validation.ts:17: The placeholder regex
/^XXX/iis too broad and can reject legitimate base58 public keys that happen to start withXXX. IfXXXis meant as a literal placeholder token, this should be an exact/specific match (e.g./^XXX$/i) instead of - studio/src/helpers/config-validation.ts:65:
isPlaceholder()is only used fromvalidateAddress(). That means non-address placeholders likeTOKEN_NAME,TOKEN_SYMBOL, andTOKEN_DESCRIPTIONare not actually validated anywhere yet. Please add a generic string-field placeholder v - studio/src/helpers/output-formatter.ts:72: Explorer URL generation currently treats every non-mainnet network as devnet (
?cluster=devnet). This produces incorrect links fortestnetand especiallylocalnet/custom RPC. Suggest explicit cluster mapping (mainnet-beta,devnet, - studio/README.md:80: The checklist says
pnpm ≥ 9, but the repo declarespackageManager: pnpm@10.27.0and enginespnpm >=10. Please align this to avoid onboarding users onto an unsupported pnpm version. - studio/src/lib/damm_v1/index.ts:52: Bug:
validateBaseConfig(config)is called before the null guard (if (!config)). Ifconfigis nullish, validation will throw an unhandled TypeError (e.g., readingconfig.rpcUrl) instead of your intended clear error. Move the null che - studio/src/helpers/connection.ts:18:
createCheckedConnectionis exported/re-exported but not used in the modified execution paths, which still instantiatenew Connection(...)directly. As written, the RPC health-check and clearer connection errors are dead code. Please wir
Claude (API):
Critique of Primary Review (Round 2)
The primary review has incorporated all findings from the prior critique round and now covers the key issues comprehensively:
- Null-guard ordering bug (damm_v1/index.ts:52) — correctly flagged
- Dead code (connection.ts) — correctly flagged
- Placeholder regex breadth — correctly flagged
- Missing placeholder validation for non-address fields — correctly flagged
- Explorer URL cluster mapping — correctly flagged
- README pnpm version mismatch — correctly flagged
--helpearly exit preemption — correctly flagged- Lint/prettier downgraded — appropriately handled
I don't see additional high-signal issues that the primary review missed, nor do I see false positives to retract. The same null-guard bug pattern exists in damm_v2/index.ts (lines 51-53 and 252-254) and dlmm/index.ts (lines 36-38) and dbc/index.ts (lines 53-54, 165-166), but in those files the null check is on a sub-field (config.dammV2Config, config.dlmmConfig, config.dbcConfig) rather than on config itself — and validateBaseConfig only accesses config.rpcUrl and config.keypairFilePath, which would exist on the outer config object even when sub-fields are missing. So the damm_v1 case is the only one where config itself can be nullish before validation. The primary review correctly identified this specific case.
The review is thorough and well-prioritized. No additional action needed from me.
Codex (response):
Agreement reached. No further changes.
Synthesis
PR Review Synthesis
- No true disagreements — both reviews align on key issues:
--helpshort-circuiting command help, placeholder regex too broad, explorer cluster mapping, and README pnpm mismatch. - Differences in emphasis:
- Review A only: calls out missing placeholder validation for non-address
TOKEN_*fields and explicit Prettier/lint failures inconfig-validation.ts. - Review B only: highlights a potential runtime bug where
validateBaseConfig(config)is called beforeconfignull-check. - Review B only: questions whether
connection.tsis actually wired into execution paths, so RPC/health-check improvements may be inactive.
- Review A only: calls out missing placeholder validation for non-address
Most important follow-up action:
Prioritize the runtime safety fix: move the null guard above validateBaseConfig(config) (with a regression test), then handle the shared UX/docs issues.
Repo checks
Repo Checks
-
LLM checks planner: added package install step before running JS commands.
-
pnpm install --frozen-lockfile: ok
rogress: resolved 1, reused 0, downloaded 0, added 0
Packages: +1925
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Progress: resolved 1925, reused 407, downloaded 0, added 0
Progress: resolved 1925, reused 1102, downloaded 0, added 0
Progress: resolved 1925, reused 1595, downloaded 49, added 387
Progress: resolved 1925, reused 1595, downloaded 126, added 737
Progress: resolved 1925, reused 1595, downloaded 189, added 1018
Progress: resolved 1925, reused 1595, downloaded 303, added 1201
Progress: resolved 1925, reused 1595, downloaded 307, added 1920
Progress: resolved 1925, reused 1595, downloaded 308, added 1925, done
devDependencies:
+ @types/node 24.5.2
+ eslint 9.36.0
+ husky 9.1.7
+ lint-staged 16.2.0
+ prettier 3.6.2
+ syncpack 13.0.4
+ turbo 2.5.8
+ typescript 5.9.2
. prepare$ husky install
. prepare: husky - install command is DEPRECATED
. prepare: Done
╭ Warning ─────────────────────────────────────────────────────────────────────╮
│ │
│ Ignored build scripts: @parcel/watcher@2.5.1, @reown/appkit@1.7.12, │
│ @tailwindcss/oxide@4.1.11, aws-sdk@2.1692.0, bigint-buffer@1.1.5, │
│ blake-hash@2.0.0, bufferutil@4.0.9, esbuild@0.25.10, keccak@3.0.4, │
│ protobufjs@7.4.0, protobufjs@7.5.4, secp256k1@5.0.1, sharp@0.33.5, │
│ tiny-secp256k1@1.1.7, unrs-resolver@1.11.0, unrs-resolver@1.11.1, │
│ usb@2.15.0, utf-8-validate@5.0.10. │
│ Run "pnpm approve-builds" to pick which dependencies should be allowed │
│ to run scripts. │
│ │
╰──────────────────────────────────────────────────────────────────────────────╯
Done in 10.9s using pnpm v10.27.0
! Corepack is about to download https://registry.npmjs.org/pnpm/-/pnpm-10.27.0.tgz
- pnpm run lint: failed
teora-invent/studio:lint: 264:48 error Insert `⏎··` prettier/prettier
@meteora-invent/studio:lint: 265:1 error Insert `··` prettier/prettier
@meteora-invent/studio:lint: 266:3 error Insert `··` prettier/prettier
@meteora-invent/studio:lint: 267:1 error Replace `}·|·null` with `··}·|·null⏎` prettier/prettier
@meteora-invent/studio:lint: 285:45 error Replace `⏎··rpcUrl?:·string;⏎··keypairFilePath?:·string;⏎` with `·rpcUrl?:·string;·keypairFilePath?:·string·` prettier/prettier
@meteora-invent/studio:lint:
@meteora-invent/studio:lint: ✖ 7 problems (7 errors, 0 warnings)
@meteora-invent/studio:lint: 7 errors and 0 warnings potentially fixable with the `--fix` option.
@meteora-invent/studio:lint:
@meteora-invent/studio:lint: ELIFECYCLE Command failed with exit code 1.
Tasks: 2 successful, 3 total
Cached: 0 cached, 3 total
Time: 27.604s
Failed: @meteora-invent/studio#lint
ELIFECYCLE Command failed with exit code 1.
@meteora-invent/studio:lint: ERROR: command finished with error: command (/data/workdir/MeteoraAg/meteora-invent/studio) /usr/bin/pnpm run lint exited (1)
@meteora-invent/studio#lint: command (/data/workdir/MeteoraAg/meteora-invent/studio) /usr/bin/pnpm run lint exited (1)
ERROR run failed: command exited (1)
- pnpm run build: ok
e optimization ...
@meteora-invent/scaffold/fun-launch:build: Collecting build traces ...
@meteora-invent/scaffold/fun-launch:build:
@meteora-invent/scaffold/fun-launch:build: Route (pages) Size First Load JS
@meteora-invent/scaffold/fun-launch:build: ┌ ○ / (1791 ms) 6.82 kB 414 kB
@meteora-invent/scaffold/fun-launch:build: ├ └ css/9f3b6b2ca5b1fa79.css 156 B
@meteora-invent/scaffold/fun-launch:build: ├ /_app 0 B 297 kB
@meteora-invent/scaffold/fun-launch:build: ├ ○ /404 190 B 297 kB
@meteora-invent/scaffold/fun-launch:build: ├ ƒ /api/send-transaction 0 B 297 kB
@meteora-invent/scaffold/fun-launch:build: ├ ƒ /api/upload 0 B 297 kB
@meteora-invent/scaffold/fun-launch:build: ├ ○ /create-pool (1684 ms) 25.1 kB 332 kB
@meteora-invent/scaffold/fun-launch:build: └ ○ /token/[tokenId] (1794 ms) 35.5 kB 443 kB
@meteora-invent/scaffold/fun-launch:build: └ css/3c2f07303407c553.css 217 B
@meteora-invent/scaffold/fun-launch:build: + First Load JS shared by all 305 kB
@meteora-invent/scaffold/fun-launch:build: ├ chunks/framework-f33e45afded06d93.js 59.6 kB
@meteora-invent/scaffold/fun-launch:build: ├ chunks/main-e44d0f48ed3240dd.js 33.7 kB
@meteora-invent/scaffold/fun-launch:build: ├ chunks/pages/_app-080c42b0d51e1550.js 202 kB
@meteora-invent/scaffold/fun-launch:build: └ other shared chunks (total) 10 kB
@meteora-invent/scaffold/fun-launch:build:
@meteora-invent/scaffold/fun-launch:build: ○ (Static) prerendered as static content
@meteora-invent/scaffold/fun-launch:build: ƒ (Dynamic) server-rendered on demand
@meteora-invent/scaffold/fun-launch:build:
Tasks: 1 successful, 1 total
Cached: 0 cached, 1 total
Time: 1m33.096s
studio/src/helpers/cli.ts
Outdated
| // --help is handled per-command via displayHelp(), but if it appears with NO | ||
| // other meaningful arguments we print a generic usage hint and exit early so | ||
| // the user doesn't hit config errors. | ||
| if (rawArgs.includes('--help') || rawArgs.includes('-h')) { |
There was a problem hiding this comment.
This early --help exit can still preempt command-level help handling. In common invocations like pnpm studio <command> --help, scripts often receive rawArgs as just ['--help'], so later command-specific displayHelp() / parsed-help logic may never run. Please handle help within each action (or gate this global exit more narrowly).
| const PLACEHOLDER_PATTERNS = [ | ||
| /^YOUR_/i, | ||
| /^PLACEHOLDER/i, | ||
| /^XXX/i, |
There was a problem hiding this comment.
The placeholder regex /^XXX/i is too broad and can reject legitimate base58 public keys that happen to start with XXX. If XXX is meant as a literal placeholder token, this should be an exact/specific match (e.g. /^XXX$/i) instead of any prefix.
| fix: `Set a valid Solana address in ${configFile} for the "${field}" field.`, | ||
| }; | ||
| } | ||
| if (isPlaceholder(value)) { |
There was a problem hiding this comment.
isPlaceholder() is only used from validateAddress(). That means non-address placeholders like TOKEN_NAME, TOKEN_SYMBOL, and TOKEN_DESCRIPTION are not actually validated anywhere yet. Please add a generic string-field placeholder validator for token metadata fields (or remove those patterns to avoid false confidence).
| console.log(' 3. Re-run the same command to execute on-chain.'); | ||
| } else { | ||
| if (info.txHash) { | ||
| const explorer = info.network?.toLowerCase().includes('mainnet') |
There was a problem hiding this comment.
Explorer URL generation currently treats every non-mainnet network as devnet (?cluster=devnet). This produces incorrect links for testnet and especially localnet/custom RPC. Suggest explicit cluster mapping (mainnet-beta, devnet, testnet) and skipping explorer links for localnet.
| Before running any action, verify each item: | ||
|
|
||
| - [ ] **Node.js ≥ 18** installed (`node --version`) | ||
| - [ ] **pnpm ≥ 9** installed (`pnpm --version`) |
There was a problem hiding this comment.
The checklist says pnpm ≥ 9, but the repo declares packageManager: pnpm@10.27.0 and engines pnpm >=10. Please align this to avoid onboarding users onto an unsupported pnpm version.
| } | ||
| ) { | ||
| // Validate config before executing any actions | ||
| validateBaseConfig(config); |
There was a problem hiding this comment.
Bug: validateBaseConfig(config) is called before the null guard (if (!config)). If config is nullish, validation will throw an unhandled TypeError (e.g., reading config.rpcUrl) instead of your intended clear error. Move the null check above both validation calls.
| * @param commitment - Commitment level (default: 'confirmed') | ||
| * @param skipHealthCheck - Set true to skip the health-check (useful in tests) | ||
| */ | ||
| export async function createCheckedConnection( |
There was a problem hiding this comment.
createCheckedConnection is exported/re-exported but not used in the modified execution paths, which still instantiate new Connection(...) directly. As written, the RPC health-check and clearer connection errors are dead code. Please wire this helper into action/lib call sites (or defer/remove it from this PR).
- fix(cli): remove global --help exit from checkEarlyExitFlags() Each command script receives rawArgs=['--help'] with no command prefix, so the global exit always fired before command-specific displayHelp() could run. --help is now handled exclusively per-command via args.help. --version early-exit is retained (safe — version is not command-specific). - fix(config-validation): narrow XXX placeholder regex from prefix to exact /^XXX/i matched any base58 public key starting with 'XXX', causing false positives. Changed to /^XXX$/i (exact match) to only catch the literal placeholder string.
|
/bot review |
|
You do not have permission to request a review. |
Overview
This PR improves the Studio onboarding experience and error handling across all pool types (DBC, DAMM v1/v2, DLMM, Alpha Vault, Presale Vault).
Changes
🔴 Critical Fixes (Phase 1)
1. Config Validation Module (NEW)
studio/src/helpers/config-validation.ts2. Validation in All Pool Type Libraries
src/lib/{dbc,damm_v1,damm_v2,dlmm,alpha_vault,presale_vault}/index.ts3. CLI Argument Parsing Fix
🟡 Important Improvements (Phase 2)
4. Safer Default: dryRun = true
config/*.jsoncfiles default to"dryRun": true5. RPC Connection Helper (NEW)
studio/src/helpers/connection.tscreateCheckedConnection()validates RPC connectivity earlygetLatestBlockhash()6. Better Error Messages
🟢 Polish (Phase 3)
7. Success Summary Output (NEW)
studio/src/helpers/output-formatter.tsformatPoolCreationSuccess()displays formatted table8. Documentation Updates
studio/README.md.env.exampledocuments dry-run behaviorFiles Changed (19 files, +644 / -13)
New Files
studio/src/helpers/config-validation.ts- Config validation modulestudio/src/helpers/connection.ts- RPC connection helperstudio/src/helpers/output-formatter.ts- Output formatting utilitiesUpdated Library Files (All with validation)
src/lib/dbc/index.tssrc/lib/damm_v1/index.tssrc/lib/damm_v2/index.tssrc/lib/dlmm/index.tssrc/lib/alpha_vault/index.tssrc/lib/presale_vault/index.tsConfiguration & Documentation
config/*.jsoncfiles (dryRun default)studio/.env.example(documentation)studio/README.md(setup guide & troubleshooting)studio/src/helpers/cli.ts(early exit flags)Impact
User Experience
Before: Users see "Non-base58 character" error with no idea what field is wrong
After: "feeClaimer contains placeholder. Update config/dbc_config.jsonc with your Solana address"
Before: dryRun defaults to false, risking accidental live transactions
After: dryRun defaults to true, safer for learning
Before: RPC errors are cryptic
After: Clear message: "Failed to connect to {rpcUrl}. Make sure it's correct and network is accessible"
Testing
npx tsc --noEmit→ 0 errors)Related Issues
This fixes the onboarding friction identified in devnet testing.
Commits (8)
Reviewers
@dannweeeee - General review for UX improvement and integration testing