Skip to content

feat: fix example and add local UI counter UI#39

Merged
GabrielePicco merged 1 commit into
mainfrom
feat/improve-example-and-add-local-ui
Oct 13, 2025
Merged

feat: fix example and add local UI counter UI#39
GabrielePicco merged 1 commit into
mainfrom
feat/improve-example-and-add-local-ui

Conversation

@GabrielePicco
Copy link
Copy Markdown
Contributor

@GabrielePicco GabrielePicco commented Oct 12, 2025

Summary

  • New Features
    • Introduces the Ephemeral Counter web app with Solana wallet integration, live counter updates, delegate/undelegate actions, and support for primary and ephemeral networks.
  • Documentation
    • Adds READMEs with setup, run instructions, and RPC endpoint configuration examples.
  • Style
    • Adds animated UI components, alerts, and comprehensive styling for the counter interface.
  • Chores
    • Adds licensing and build configuration for browser compatibility.
  • Tests
    • Updates tests to reflect streamlined account parameters and delegation flow.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Oct 12, 2025

Walkthrough

Adds a new React-based “Ephemeral Counter” app with Solana wallet integration, build configs, assets, styles, and entrypoint. Introduces program logic tweaks (counter.exit calls), updates the IDL (removes optional validator from delegate), and aligns tests with new account lists. Includes documentation and licensing files.

Changes

Cohort / File(s) Summary
Licenses & Docs
anchor-counter/app/LICENSE, anchor-counter/app/README.md, anchor-counter/app/app/LICENSE.md, anchor-counter/app/app/README.md
Adds MIT license files and READMEs covering app overview, setup, run instructions, env config, and OSS blurb.
Build & Configuration
anchor-counter/app/app/craco.config.js, anchor-counter/app/app/package.json, anchor-counter/app/app/tsconfig.json, anchor-counter/app/tsconfig.json
Introduces CRA+CRACO setup, dependencies (React, Solana adapters, polyfills), scripts, Webpack fallbacks, ProvidePlugin(Buffer), ignoreWarnings, publicPath, and TS configs.
Public Assets
anchor-counter/app/app/public/index.html, anchor-counter/app/app/public/manifest.json
Adds HTML shell and web app manifest (name, icons, colors, standalone display).
Frontend Entry & App
anchor-counter/app/app/src/index.tsx, anchor-counter/app/app/src/App.tsx
Creates app entry with StrictMode and Wallet wrapper; implements App component with Solana wallet, Program client, ephemeral provider, subscriptions, transactions, and UI logic.
UI Components
anchor-counter/app/app/src/components/Active.tsx, anchor-counter/app/app/src/components/Alert.tsx, anchor-counter/app/app/src/components/Button.tsx, anchor-counter/app/app/src/components/Square.tsx, anchor-counter/app/app/src/components/Wallet.tsx
Adds reusable components: activity indicator, auto-fading alert, styled button, animated square, and wallet/provider wrapper (plus SimpleProvider).
Styles
anchor-counter/app/app/src/index.css, anchor-counter/app/app/src/components/Active.scss, anchor-counter/app/app/src/components/Square.scss
Introduces global styles and component-specific SCSS for Active and Square visuals.
Program Logic
anchor-counter/programs/anchor-counter/src/lib.rs
Adds counter.exit calls in increment_and_commit and increment_and_undelegate; removes optional validator from DelegateInput.
IDL Update
anchor-counter/target/idl/anchor_counter.json
Removes optional validator account from delegate instruction definition.
Tests Alignment
anchor-counter/tests/advanced-magic.ts, anchor-counter/tests/anchor-counter.ts
Updates transactions to omit counter PDA/systemProgram where removed; renames validator constant; adjusts remainingAccounts and account lists accordingly.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant W as Wallet UI
  participant CP as ConnectionProvider
  participant EP as Ephemeral Provider
  participant P as Program (Anchor)
  participant RPC as RPC Endpoint(s)

  U->>W: Connect wallet
  W->>CP: Initialize Solana connection (env/default)
  CP->>P: Fetch IDL, init Program(client)
  Note over CP,P: Subscribe to counter PDA onAccountChange
  W->>EP: Init ephemeral connection (optional)
  EP-->>W: Subscribe to ephemeral PDA changes

  U->>W: Click Increment / Delegate / Undelegate
  W->>P: Build & send tx (wallet or temp keypair)
  P->>RPC: Submit and confirm
  RPC-->>W: Signature/confirmation
  CP-->>W: Account change event(s) → update UI
  W-->>U: Show updated counters / alerts
Loading
sequenceDiagram
  autonumber
  participant C as Client
  participant Prog as anchor_counter Program

  rect rgba(200,230,255,0.3)
  Note over C,Prog: Updated on-chain flows
  C->>Prog: increment_and_commit
  Prog->>Prog: counter.exit(&ID)
  Prog-->>C: Success
  end

  rect rgba(220,255,220,0.3)
  C->>Prog: increment_and_undelegate
  Prog->>Prog: counter.exit(&ID)
  Prog-->>C: Success
  end

  rect rgba(255,240,200,0.3)
  Note over C,Prog: Delegate instruction (IDL)
  C->>Prog: delegate (no optional validator account)
  Prog-->>C: Success
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

I tap my paws on counting stone, click-click—hooray!
New wallets wink, PDAs blink, in sleek ballet.
Ephemeral winds push numbers higher,
While exits tidy up the wire.
I nibble docs, then ship with glee—
One hop, two hops: shipped UI! 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly captures the two primary changes—fixing the example code and adding a local counter UI—without listing files or using vague terms, giving reviewers a clear overview of the pull request’s purpose.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/improve-example-and-add-local-ui

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
anchor-counter/tests/advanced-magic.ts (1)

61-67: Critical: Remove validator from accounts and use remainingAccounts instead.

The validator field was removed from the DelegateInput struct in the Rust program (line 115-120 in lib.rs). The validator is now passed via ctx.remaining_accounts as shown in the program code at line 42. This test still passes validator in the accounts object, which will cause a runtime error since the IDL no longer includes this field.

Reference anchor-counter.ts lines 96-113 for the correct pattern using remainingAccounts.

Apply this diff to fix the delegation flow:

  it("Delegate counter to ER", async () => {
    const start = Date.now();
+   // Add validator to remaining accounts
+   const remainingAccounts = [
+     {
+       pubkey: ER_VALIDATOR,
+       isSigner: false,
+       isWritable: false,
+     },
+   ];
    let tx = await program.methods
      .delegate()
      .accounts({
        payer: providerMagic.wallet.publicKey,
-       validator: ER_VALIDATOR,
        pda: pda,
      })
+     .remainingAccounts(remainingAccounts)
      .transaction();
🧹 Nitpick comments (4)
anchor-counter/app/app/tsconfig.json (1)

4-13: Keep TS output as ES modules and use the modern JSX runtime.

For a browser React app that bundles via CRACO/CRA, forcing "module": "commonjs" will downlevel all import/export syntax to require/module.exports, which conflicts with the bundler’s ESM pipeline and can break tree-shaking. Also, "jsx": "react" reverts to the legacy JSX transform, making every component import React manually even though React 17+ tooling (including CRA) expects "react-jsx".

Switch these options to stay aligned with the default CRA tooling:

-    "module": "commonjs",
+    "module": "esnext",
@@
-    "jsx": "react"
+    "jsx": "react-jsx"
anchor-counter/app/app/LICENSE.md (1)

1-21: LGTM!

Standard MIT License text is correctly formatted. Note that there's another LICENSE file at anchor-counter/app/LICENSE with identical content. Having license files at both the app root and app/app directory may be intentional for different distribution contexts, but consider if both are necessary.

anchor-counter/app/app/public/manifest.json (1)

2-3: Update the app names to match the actual application.

The short_name and name fields still contain generic Create React App defaults. Consider updating them to reflect the actual application name ("Ephemeral Counter") for consistency with the HTML title and better PWA branding.

Apply this diff to update the names:

-    "short_name": "React App",
-    "name": "Create React App Sample",
+    "short_name": "Ephemeral Counter",
+    "name": "Ephemeral Counter App",
anchor-counter/app/app/package.json (1)

7-7: Update @coral-xyz/anchor to ^0.31.1
Includes critical proc-macro2 build fixes, TypeScript Provider enhancements, and compatibility with Solana 2.1.0. No known vulnerabilities in 0.30.1, but upgrading ensures these improvements.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ef006b0 and 58fbc39.

⛔ Files ignored due to path filters (5)
  • anchor-counter/app/app/package-lock.json is excluded by !**/package-lock.json
  • anchor-counter/app/app/public/favicon.ico is excluded by !**/*.ico
  • anchor-counter/app/app/public/magicblock_white.png is excluded by !**/*.png
  • anchor-counter/app/app/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • anchor-counter/app/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (24)
  • anchor-counter/app/LICENSE (1 hunks)
  • anchor-counter/app/README.md (1 hunks)
  • anchor-counter/app/app/LICENSE.md (1 hunks)
  • anchor-counter/app/app/README.md (1 hunks)
  • anchor-counter/app/app/craco.config.js (1 hunks)
  • anchor-counter/app/app/package.json (1 hunks)
  • anchor-counter/app/app/public/index.html (1 hunks)
  • anchor-counter/app/app/public/manifest.json (1 hunks)
  • anchor-counter/app/app/src/App.tsx (1 hunks)
  • anchor-counter/app/app/src/components/Active.scss (1 hunks)
  • anchor-counter/app/app/src/components/Active.tsx (1 hunks)
  • anchor-counter/app/app/src/components/Alert.tsx (1 hunks)
  • anchor-counter/app/app/src/components/Button.tsx (1 hunks)
  • anchor-counter/app/app/src/components/Square.scss (1 hunks)
  • anchor-counter/app/app/src/components/Square.tsx (1 hunks)
  • anchor-counter/app/app/src/components/Wallet.tsx (1 hunks)
  • anchor-counter/app/app/src/index.css (1 hunks)
  • anchor-counter/app/app/src/index.tsx (1 hunks)
  • anchor-counter/app/app/tsconfig.json (1 hunks)
  • anchor-counter/app/tsconfig.json (1 hunks)
  • anchor-counter/programs/anchor-counter/src/lib.rs (1 hunks)
  • anchor-counter/target/idl/anchor_counter.json (0 hunks)
  • anchor-counter/tests/advanced-magic.ts (1 hunks)
  • anchor-counter/tests/anchor-counter.ts (2 hunks)
💤 Files with no reviewable changes (1)
  • anchor-counter/target/idl/anchor_counter.json
🧰 Additional context used
🧬 Code graph analysis (3)
anchor-counter/app/app/src/index.tsx (1)
anchor-counter/app/app/src/components/Wallet.tsx (1)
  • Wallet (27-44)
anchor-counter/app/app/src/components/Button.tsx (1)
roll-dice/app/components/ui/button.tsx (2)
  • ButtonProps (36-40)
  • Button (56-56)
anchor-counter/app/app/src/App.tsx (1)
anchor-counter/app/app/src/components/Wallet.tsx (1)
  • SimpleProvider (17-25)
🔇 Additional comments (16)
anchor-counter/app/LICENSE (1)

1-21: LGTM!

Standard MIT License text is correctly formatted with appropriate copyright notice for Magicblock Pte. Ltd.

anchor-counter/app/app/public/index.html (1)

1-22: LGTM!

The HTML structure is well-formed with proper meta tags, favicon/manifest references, and a root element for React mounting. The external Google Fonts link for Roboto is appropriately included.

anchor-counter/app/README.md (1)

1-54: LGTM!

The README provides clear documentation for the Ephemeral Counter UI, including prerequisites, installation steps, and environment variable configuration. The structure and content are well-organized and informative.

anchor-counter/app/app/package.json (1)

22-28: LGTM!

The scripts section is correctly configured to use CRACO for CRA customization. The dev and start scripts both map to craco start, which is appropriate for the development workflow.

anchor-counter/app/app/src/index.tsx (2)

7-8: LGTM!

Excellent error handling for the missing root element. This prevents silent failures and provides a clear error message if the DOM structure is incorrect.


10-15: LGTM!

The React 18 root creation and rendering is correctly implemented. Using StrictMode and the Wallet wrapper component follows best practices for wallet-enabled Solana applications.

anchor-counter/tests/advanced-magic.ts (3)

5-7: LGTM!

The import formatting change improves readability.


79-84: Verify that Anchor correctly infers the counter account.

The counter account is no longer explicitly passed to incrementAndCommit and incrementAndUndelegate, relying on Anchor's automatic account inference. With the addition of counter.exit() calls in the Rust program, ensure the PDA is correctly resolved from the seeds at runtime.

Also applies to: 106-111


45-50: Counter PDA auto-derivation confirmed. Initialize in anchor-counter/src/lib.rs defines the counter account with seeds = [TEST_PDA_SEED] and the module is annotated with #[ephemeral], so Anchor will infer the PDA automatically.

anchor-counter/programs/anchor-counter/src/lib.rs (3)

76-76: LGTM: Proper serialization before commit.

The counter.exit() call ensures the Anchor account is properly serialized before the CPI to commit_accounts. This is the correct pattern when using mutable Anchor accounts with CPI operations in the ephemeral rollups SDK.


92-92: LGTM: Proper serialization before commit and undelegate.

The counter.exit() call ensures the Anchor account is properly serialized before the CPI to commit_and_undelegate_accounts, following the same pattern as increment_and_commit.


36-46: LGTM: Correct use of remaining_accounts for validator.

The validator is correctly retrieved from ctx.remaining_accounts instead of a dedicated struct field, providing more flexibility for optional validator specification. This aligns with the test changes in anchor-counter.ts.

anchor-counter/tests/anchor-counter.ts (4)

8-8: LGTM: Descriptive constant name.

Renaming to LOCAL_ER_VALIDATOR better indicates this validator is used for local development environments.


96-113: LGTM: Correct validator handling via remainingAccounts.

The validator is correctly passed via remainingAccounts instead of a dedicated account field, aligning with the Rust program changes. The conditional logic properly handles local vs. remote environments.


53-57: Verify that Anchor correctly infers the counter PDA.

The counter account is no longer explicitly passed, relying on Anchor's automatic PDA derivation from the Initialize struct's seeds. Ensure this works correctly with the program's initialization logic.


181-184: Verify empty accounts object with Anchor's account inference.

The incrementAndCommit call passes an empty accounts object {}, relying entirely on Anchor's automatic account resolution. Confirm that the #[commit] macro and PDA seeds enable Anchor to correctly infer both the payer and counter accounts at runtime.

Comment on lines +8 to +17
webpackConfig.resolve.fallback = {
http: require.resolve('stream-http'),
https: require.resolve('https-browserify'),
crypto: require.resolve('crypto-browserify'),
stream: require.resolve('stream-browserify'),
buffer: require.resolve('buffer-browserify'),
zlib: false,
url: false,
vm: false,
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Preserve existing fallbacks instead of overwriting them.

webpackConfig.resolve.fallback may already contain framework-provided entries (e.g., CRA polyfills). Replacing the object wholesale drops those defaults, which can reintroduce missing module errors elsewhere in the app. Merge with the existing fallback instead of clobbering it.

🤖 Prompt for AI Agents
In anchor-counter/app/app/craco.config.js around lines 8 to 17, the code
replaces webpackConfig.resolve.fallback wholesale which discards any existing
framework-provided fallbacks; instead, preserve and extend the existing object
by merging your custom entries into webpackConfig.resolve.fallback (ensure the
property exists first), so that you add
http/https/crypto/stream/buffer/zlib/url/vm entries without clobbering defaults.

Comment on lines +5 to +7
```bash
npm run install
```
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix the npm install command.

The command npm run install is incorrect. The standard npm command is npm install without the run prefix.

Apply this diff to fix the command:

 ```bash
-npm run install
+npm install

<details>
<summary>🤖 Prompt for AI Agents</summary>

In anchor-counter/app/app/README.md around lines 5 to 7, the README shows the
incorrect command "npm run install"; replace it with the standard "npm install"
command so users run the proper installer command (update the fenced code block
to contain "npm install" instead of "npm run install").


</details>

<!-- This is an auto-generated comment by CodeRabbit -->

Comment on lines +100 to +107
if (!publicKey) return;
if (!publicKey || Keypair.fromSeed(publicKey.toBytes()).publicKey.equals(tempKeypair.current?.publicKey || PublicKey.default)) return;
console.log("Wallet connected with publicKey:", publicKey.toBase58());
// Derive the temp keypair from the publicKey
const newTempKeypair = Keypair.fromSeed(publicKey.toBytes());
tempKeypair.current = newTempKeypair;
console.log("Temp Keypair", newTempKeypair.publicKey.toBase58());
}, [connection, publicKey]);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Stop deriving private keys from public data

Keypair.fromSeed(publicKey.toBytes()) creates the temp private key from the wallet’s public key. Anyone who knows that public key can reproduce the same seed and steal the lamports or impersonate the user in delegated flows. Generate the temp keypair from a secret (e.g., a wallet-signed message or fresh randomness) and persist it securely if you need determinism.

Comment on lines +152 to +160
const submitTransaction = useCallback(async (transaction: Transaction, useTempKeypair: boolean = false, ephemeral: boolean = false, confirmCommitment : Commitment = "processed"): Promise<string | null> => {
if (!tempKeypair.current) return null;
if (!publicKey) return null;
if (!ephemeralConnection.current) return null;
//if (isSubmitting) return null;
setIsSubmitting(true);
setTransactionError(null);
setTransactionSuccess(null);
let connection = ephemeral ? ephemeralConnection.current : provider.current.connection;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Don’t gate every transaction on the ephemeral connection

submitTransaction returns early when ephemeralConnection.current is missing, even when ephemeral is false. If the auxiliary endpoint is down or still initializing, all actions (delegate, increment) silently fail. Only require the ephemeral connection in the ephemeral === true path.

🤖 Prompt for AI Agents
In anchor-counter/app/app/src/App.tsx around lines 152 to 160, the function
currently bail outs when ephemeralConnection.current is missing even for
non-ephemeral transactions; update the guard so the ephemeral connection is only
required when ephemeral === true. Replace the unconditional check "if
(!ephemeralConnection.current) return null" with a conditional that returns null
only when ephemeral is true and ephemeralConnection.current is falsy, leaving
other early returns (tempKeypair/publicKey) intact.

Comment on lines +12 to +27
useEffect(() => {
setOpacity(1);

const fadeOutTimer = setTimeout(() => {
setOpacity(0);
}, 3000);

const removeTimer = setTimeout(() => {
onClose();
}, 3500);

return () => {
clearTimeout(fadeOutTimer);
clearTimeout(removeTimer);
};
}, [onClose]);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Reset fade timers when the alert content changes

Line 12’s effect only depends on onClose, so if the parent shows a new message while the component stays mounted, the old timer keeps running and the new alert can disappear almost immediately. Add type and message to the dependency list (and restart the timers when either changes) so every alert gets its full display duration.

🤖 Prompt for AI Agents
In anchor-counter/app/app/src/components/Alert.tsx around lines 12 to 27, the
useEffect only lists onClose as a dependency so timers aren't reset when the
alert's message or type changes; update the effect to include type and message
in the dependency array and ensure the timers are created/cleared inside the
effect so they restart whenever either prop changes, giving each new alert its
full display duration.

Comment on lines +17 to +25
export class SimpleProvider implements Provider {
readonly connection: Connection;
readonly publicKey?: PublicKey;

constructor(connection: Connection, publicKey?: PublicKey) {
this.connection = connection;
this.publicKey = publicKey;
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

SimpleProvider doesn’t satisfy Anchor’s Provider contract

Line 17 claims to implement Provider, but the class only exposes connection and publicKey. The Anchor Provider type also requires methods like send/sendAndConfirm (and opts/wallet depending on the exact version). TypeScript will reject this implementation, and any code that relies on it will break at runtime. Either drop implements Provider or supply the full Provider surface (or simply extend AnchorProvider instead of re‑implementing it).

🤖 Prompt for AI Agents
In anchor-counter/app/app/src/components/Wallet.tsx around lines 17 to 25,
SimpleProvider is declared as implementing Anchor's Provider but only exposes
connection and publicKey; implement the full Provider surface or stop claiming
to implement it. Fix by either (A) remove "implements Provider" if you only need
those two fields, or (B) extend AnchorProvider (or construct an AnchorProvider)
and delegate all required members (send, sendAndConfirm, wallet, opts, etc.) to
that implementation, or (C) add the missing methods and properties with
signatures matching the Provider type and forward calls to an underlying
AnchorProvider/Connection/wallet instance. Ensure the chosen approach satisfies
the Provider interface types so TypeScript compiles.

Comment on lines +220 to +227
.join-game input[type="text"] ::placeholder {
color: rgba(255, 255, 255, 0.7);
}

.join-game input[type="text"] :focus {
outline: none;
border-color: #62fffc;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix the placeholder/focus selectors

Line 220 and Line 224 include a space before ::placeholder and :focus, so the browser interprets them as descendant selectors and the styling never applies. Remove the space to target the input itself.

-.join-game input[type="text"] ::placeholder {
+.join-game input[type="text"]::placeholder {
     color: rgba(255, 255, 255, 0.7);
 }
 
-.join-game input[type="text"] :focus {
+.join-game input[type="text"]:focus {
     outline: none;
     border-color: #62fffc;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.join-game input[type="text"] ::placeholder {
color: rgba(255, 255, 255, 0.7);
}
.join-game input[type="text"] :focus {
outline: none;
border-color: #62fffc;
}
.join-game input[type="text"]::placeholder {
color: rgba(255, 255, 255, 0.7);
}
.join-game input[type="text"]:focus {
outline: none;
border-color: #62fffc;
}
🤖 Prompt for AI Agents
In anchor-counter/app/app/src/index.css around lines 220 to 227, the selectors
have an extra space before ::placeholder and :focus so they act as descendant
selectors and never target the input; remove the space so the selectors directly
target the input element (i.e., change ".join-game input[type=\"text\"]
::placeholder" to ".join-game input[type=\"text\"]::placeholder" and ".join-game
input[type=\"text\"] :focus" to ".join-game input[type=\"text\"]:focus") and
keep the same declarations.

{
"compilerOptions": {
"types": ["mocha", "chai"],
"typeRoots": ["./node_modules/@types"],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Don’t override typeRoots to a possibly nonexistent folder.

Pointing typeRoots to ./node_modules/@types makes TS ignore ancestor node_modules/@types. In this repo the dependencies (including @types/node, React, etc.) live at the workspace root, so the compiler will stop seeing them. Drop the override (let the defaults apply) or include the ancestor paths explicitly.

🤖 Prompt for AI Agents
In anchor-counter/app/tsconfig.json around line 4, the tsconfig overrides
"typeRoots" to ["./node_modules/@types"], which prevents TypeScript from picking
up ancestor workspace type packages (e.g. @types/node, React) and causes
resolution failures; remove the "typeRoots" setting entirely so TS uses its
defaults, or if you must keep it, expand it to include the workspace
root/ancestor node_modules/@types paths (e.g. "../../node_modules/@types" or the
appropriate relative paths) so all required @types packages remain visible to
the compiler.

@GabrielePicco GabrielePicco merged commit e8606cf into main Oct 13, 2025
2 checks passed
@GabrielePicco GabrielePicco deleted the feat/improve-example-and-add-local-ui branch October 13, 2025 00:48
This was referenced Jan 2, 2026
@coderabbitai coderabbitai Bot mentioned this pull request Apr 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant