Skip to content

Conversation

@GabrielePicco
Copy link
Contributor

@GabrielePicco GabrielePicco commented Jan 2, 2026

Summary by CodeRabbit

  • New Features
    • SPL token transfer support with validation and error handling
    • React UI for ephemeral token accounts: minting, balances, delegation, transfers, drag-and-drop quick transfers, and alerts
    • Wallet integration and real-time balance syncing across networks
  • Tests
    • End-to-end test suite exercising minting, delegation, ephemeral transfers, undelegation, and withdrawals
  • Documentation
    • Added READMEs and MIT licenses
  • Chores
    • Project manifests, build/tooling config, and ignore rules added

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 2, 2026

Walkthrough

Adds a complete spl-tokens workspace: React frontend (UI, wallet, build), Anchor Solana program implementing SPL token transfer via CPI, integration tests, and project/packaging manifests and ignore rules.

Changes

Cohort / File(s) Summary
Workspace & Ignore
spl-tokens/.gitignore, spl-tokens/Cargo.toml
Adds comprehensive gitignore and a Cargo workspace manifest with release profile and resolver settings.
Anchor & Program Manifests
spl-tokens/Anchor.toml, spl-tokens/programs/spl-tokens/Cargo.toml
Adds Anchor workspace config (toolchain, program IDs, test genesis entries) and crate manifest for spl-tokens with features and dependencies.
On-chain Program
spl-tokens/programs/spl-tokens/src/lib.rs
New Anchor Rust program exposing transfer instruction, TransferTokens accounts struct with owner/mint constraints, and ErrorCode enum.
Integration Tests
spl-tokens/tests/spl-tokens.ts
New end-to-end test exercising mint creation, delegation/undelegation, ephemeral rollup flows, transfers, withdrawals, and assertions.
Package Manifests & TS Configs
spl-tokens/package.json, spl-tokens/tsconfig.json, spl-tokens/app/tsconfig.json, spl-tokens/app/package.json
Adds npm/Yarn manifests and TypeScript configs for project and app (Mocha/Chai types, build/test scripts, dependencies).
React App: Entry & Public Assets
spl-tokens/app/app/public/..., spl-tokens/app/app/src/index.tsx, spl-tokens/app/app/public/manifest.json, spl-tokens/app/app/public/index.html
Adds React entry point and static public assets (HTML, manifest) for the frontend.
React App: Core UI & Logic
spl-tokens/app/app/src/App.tsx, spl-tokens/app/app/src/index.css
Adds main App component implementing ephemeral account handling, minting, balances, transfers, delegation flows, and global styles.
React App: Components
spl-tokens/app/app/src/components/Wallet.tsx, .../Active.tsx, .../Alert.tsx, .../Button.tsx, .../Square.tsx
New UI components: Wallet provider + SimpleProvider class, Active, Alert (with AlertProps type), Button, and Square (framer-motion).
React App: Component Styles
spl-tokens/app/app/src/components/Active.scss, .../Square.scss
SCSS for Active and Square components.
React Build Configuration
spl-tokens/app/app/craco.config.js
Adds Craco webpack customization (module fallbacks, Buffer ProvidePlugin, publicPath, ignoreWarnings).
Docs & Licenses
spl-tokens/app/README.md, spl-tokens/app/LICENSE, spl-tokens/app/app/README.md, spl-tokens/app/app/LICENSE.md
Adds README and MIT license files for app and subdirectory.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • jonasXchen

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 'Feat/add spl native example' accurately describes the main change: adding a comprehensive SPL tokens example with both on-chain program and React UI components for ephemeral rollups.
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/add-spl-native-example

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.

❤️ Share

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

Copy link

@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: 39

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5919bcc and a320bfc.

⛔ Files ignored due to path filters (9)
  • spl-tokens/Cargo.lock is excluded by !**/*.lock
  • spl-tokens/app/app/public/favicon.ico is excluded by !**/*.ico
  • spl-tokens/app/app/public/magicblock_white.png is excluded by !**/*.png
  • spl-tokens/app/app/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • spl-tokens/app/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • spl-tokens/package-lock.json is excluded by !**/package-lock.json
  • spl-tokens/tests/fixtures/dlp.so is excluded by !**/*.so
  • spl-tokens/tests/fixtures/ephemeral_token_program.so is excluded by !**/*.so
  • spl-tokens/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (29)
  • spl-tokens/.gitignore
  • spl-tokens/Anchor.toml
  • spl-tokens/Cargo.toml
  • spl-tokens/app/LICENSE
  • spl-tokens/app/README.md
  • spl-tokens/app/app/LICENSE.md
  • spl-tokens/app/app/README.md
  • spl-tokens/app/app/craco.config.js
  • spl-tokens/app/app/package.json
  • spl-tokens/app/app/public/index.html
  • spl-tokens/app/app/public/manifest.json
  • spl-tokens/app/app/src/App.tsx
  • spl-tokens/app/app/src/components/Active.scss
  • spl-tokens/app/app/src/components/Active.tsx
  • spl-tokens/app/app/src/components/Alert.tsx
  • spl-tokens/app/app/src/components/Button.tsx
  • spl-tokens/app/app/src/components/Square.scss
  • spl-tokens/app/app/src/components/Square.tsx
  • spl-tokens/app/app/src/components/Wallet.tsx
  • spl-tokens/app/app/src/index.css
  • spl-tokens/app/app/src/index.tsx
  • spl-tokens/app/app/tsconfig.json
  • spl-tokens/app/app/tsconfig.tsbuildinfo
  • spl-tokens/app/tsconfig.json
  • spl-tokens/package.json
  • spl-tokens/programs/spl-tokens/Cargo.toml
  • spl-tokens/programs/spl-tokens/src/lib.rs
  • spl-tokens/tests/spl-tokens.ts
  • spl-tokens/tsconfig.json
🧰 Additional context used
🧬 Code graph analysis (3)
spl-tokens/app/app/src/components/Alert.tsx (1)
roll-dice/app/components/ui/alert.tsx (1)
  • Alert (59-59)
spl-tokens/app/app/src/components/Button.tsx (1)
roll-dice/app/components/ui/button.tsx (2)
  • ButtonProps (36-40)
  • Button (56-56)
spl-tokens/app/app/src/index.tsx (1)
spl-tokens/app/app/src/components/Wallet.tsx (1)
  • Wallet (27-44)
🪛 Biome (2.1.2)
spl-tokens/app/app/src/App.tsx

[error] 697-699: Provide screen reader accessible content when using heading elements.

All headings on a page should have content that is accessible to screen readers.

(lint/a11y/useHeadingContent)


[error] 701-729: Static Elements should not be interactive.

To add interactivity such as a mouse or key event listener to a static element, give the element an appropriate role value.

(lint/a11y/noStaticElementInteractions)


[error] 735-755: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)


[error] 793-833: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)


[error] 883-968: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)


[error] 1008-1084: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)


[error] 1162-1175: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)


[error] 1209-1219: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)


[error] 1221-1231: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)


[error] 1236-1248: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)

spl-tokens/app/app/src/components/Button.tsx

[error] 11-20: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)

🪛 Gitleaks (8.30.0)
spl-tokens/Anchor.toml

[high] 9-9: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 12-12: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🪛 markdownlint-cli2 (0.18.1)
spl-tokens/app/app/README.md

24-24: Trailing spaces
Expected: 0 or 2; Actual: 3

(MD009, no-trailing-spaces)

spl-tokens/app/app/LICENSE.md

1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)


21-21: Files should end with a single newline character

(MD047, single-trailing-newline)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test-examples
🔇 Additional comments (20)
spl-tokens/app/README.md (1)

37-54: Verify RPC endpoint configuration and defaults.

The documentation specifies fallback endpoints to MagicBlock public services. Please verify that:

  • The endpoint URLs are correct and currently active: https://rpc.magicblock.app/devnet and https://devnet.magicblock.app
  • The environment variable names are correctly referenced in the React app code
  • The documented port 7799 for the ephemeral provider is the expected standard
spl-tokens/Cargo.toml (1)

7-10: Verify overflow-checks in release mode is intentional.

Enabling overflow-checks = true in release builds adds runtime performance overhead. While this is generally disabled in release mode for performance, it may be intentional for Solana programs where security and correctness are prioritized over performance.

Please confirm this is the desired configuration for your use case.

spl-tokens/tsconfig.json (1)

1-10: LGTM!

The TypeScript configuration is well-formatted and uses appropriate modern ECMAScript targets (es2020) for the test environment. The inclusion of Mocha and Chai type definitions properly supports the test suite.

spl-tokens/app/app/src/index.tsx (1)

7-15: LGTM! Clean React 18 bootstrap with proper error handling.

The entry point correctly:

  • Validates the root element exists before attempting to render
  • Uses React 18's createRoot API
  • Wraps the app in StrictMode for development checks
  • Integrates wallet functionality through the Wallet wrapper component

The implementation follows React best practices and provides good error handling.

spl-tokens/package.json (1)

5-5: Test script path is valid. The fullstack-test.sh script exists at the repository root and is executable, so the reference in package.json is correct.

spl-tokens/.gitignore (1)

4-4: Verify gitignore line reference and non-existent directory pattern.

The unignore patterns do work correctly with the **/target/* ignore rule—verified by tracked files in anchor-counter/, anchor-minter/, and bolt-counter/ target directories. However, the file has only 19 lines, not 20 as referenced. Additionally, line 19 references !programs/spl-tokens/target/idl/, which does not exist in the repository. Consider removing this unignore pattern if the directory is not needed, or verify whether it should be added to the codebase.

spl-tokens/app/app/src/components/Active.scss (1)

27-34: LGTM!

The .active-div utility class provides clean centering and styling for the container. The use of fit-content width and auto margins for centering is appropriate.

spl-tokens/Anchor.toml (2)

22-30: LGTM!

The test genesis configuration is properly structured with appropriate program addresses and upgrade settings for test fixtures.


32-33: Verify the test timeout duration.

The test timeout is set to 1,000,000ms (~16.67 minutes), which is exceptionally long. While Solana integration tests with ephemeral rollups may require extended timeouts, please confirm this duration is necessary and not a placeholder value.

spl-tokens/app/app/src/components/Square.scss (1)

1-38: LGTM!

The SCSS styling is well-structured and uses modern CSS techniques effectively. The use of pseudo-elements for the X visual and border-color for the O is a clean, performant approach.

spl-tokens/app/app/src/components/Square.tsx (2)

5-9: LGTM!

The type definition for SquareProps is well-structured with appropriate optional properties and flexible typing for the ind parameter.


12-16: LGTM!

The handleClick implementation correctly guards against undefined values before invoking the callback, preventing potential runtime errors.

spl-tokens/app/app/src/components/Active.tsx (2)

9-23: LGTM!

The component structure is clean and the animation pattern is consistent with other components in the codebase (e.g., Square.tsx).


2-2: > Likely an incorrect or invalid review comment.

spl-tokens/app/app/src/components/Wallet.tsx (2)

30-33: LGTM!

Wallet adapters are correctly memoized with an empty dependency array since they don't depend on any reactive values.


17-25: No changes needed. The SimpleProvider implementation is correct and complete.

The Anchor Provider interface for version 0.32.1 (used in this codebase) requires only the connection and publicKey properties, both of which are provided. Methods like send, sendAndConfirm, sendAll, and simulate are optional, not required. The implementation will not cause runtime errors.

Likely an incorrect or invalid review comment.

spl-tokens/programs/spl-tokens/Cargo.toml (1)

1-25: LGTM!

The Cargo manifest is well-structured with properly pinned Anchor dependencies and appropriate feature flags for the SPL token program.

spl-tokens/programs/spl-tokens/src/lib.rs (2)

14-28: LGTM!

The transfer function correctly validates the amount, constructs the CPI context, and invokes the SPL Token program. The error handling with custom error codes is well-implemented.


31-47: LGTM!

The account constraints properly validate token ownership and mint consistency. The constraint error annotations provide clear error messages for debugging.

spl-tokens/app/app/src/App.tsx (1)

134-172: Security consideration: Storing private keys in localStorage.

Storing keypair secret keys in localStorage exposes them to XSS attacks. While acceptable for a demo/example application, ensure this is documented and never used for real funds.

Consider adding a warning comment:

// ⚠️ WARNING: This stores private keys in localStorage for demo purposes only.
// Never use this approach with real funds or in production applications.

Comment on lines +8 to +12
[programs.devnet]
spl-tokens = "FgvEeit1djLPPjozq9zW9R8Ahu5JpijcdWQxqL4P887"

[programs.localnet]
spl-tokens= "FgvEeit1djLPPjozq9zW9R8Ahu5JpijcdWQxqL4P887"
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Fix formatting inconsistency and verify program ID usage.

Line 12 is missing a space after the = operator, which is inconsistent with line 9. Additionally, both devnet and localnet use the same program ID. While this may be intentional for local development and testing, please verify this is the desired configuration.

🔎 Proposed fix for formatting
-spl-tokens= "FgvEeit1djLPPjozq9zW9R8Ahu5JpijcdWQxqL4P887"
+spl-tokens = "FgvEeit1djLPPjozq9zW9R8Ahu5JpijcdWQxqL4P887"
📝 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
[programs.devnet]
spl-tokens = "FgvEeit1djLPPjozq9zW9R8Ahu5JpijcdWQxqL4P887"
[programs.localnet]
spl-tokens= "FgvEeit1djLPPjozq9zW9R8Ahu5JpijcdWQxqL4P887"
[programs.devnet]
spl-tokens = "FgvEeit1djLPPjozq9zW9R8Ahu5JpijcdWQxqL4P887"
[programs.localnet]
spl-tokens = "FgvEeit1djLPPjozq9zW9R8Ahu5JpijcdWQxqL4P887"
🧰 Tools
🪛 Gitleaks (8.30.0)

[high] 9-9: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 12-12: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🤖 Prompt for AI Agents
In spl-tokens/Anchor.toml around lines 8 to 12, fix the formatting inconsistency
by adding a space after the `=` on line 12 so it matches line 9 (change
`spl-tokens= "..."` to `spl-tokens = "..."`), and verify whether localnet should
reuse the same program ID as devnet—if localnet needs a different ID replace the
value on line 12 with the correct localnet program ID; otherwise keep the same
value but ensure formatting consistency.

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

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check which buffer package is installed
cat spl-tokens/app/app/package.json | jq '.dependencies, .devDependencies' | grep -i buffer

Repository: magicblock-labs/magicblock-engine-examples

Length of output: 140


🏁 Script executed:

#!/bin/bash
# Search for references to buffer-browserify and buffer in the codebase
echo "=== References to buffer-browserify ==="
rg "buffer-browserify" spl-tokens/app/app/ --type js --type json

echo -e "\n=== References to buffer (excluding node_modules) ==="
rg "require\(['\"]buffer['\"]" spl-tokens/app/app/ --type js

# Check if buffer-browserify is actually needed or redundant
echo -e "\n=== Import/require statements for buffer modules ==="
rg "from ['\"]buffer" spl-tokens/app/app/ --type js -A 2

Repository: magicblock-labs/magicblock-engine-examples

Length of output: 402


Use the modern buffer package instead of the legacy buffer-browserify.

The webpack fallback config uses buffer-browserify (v0.2.5), but the project also has the modern buffer package (v6.0.3) installed. Replace require.resolve('buffer-browserify') with require.resolve('buffer') and remove buffer-browserify from package.json since it's no longer needed.

🤖 Prompt for AI Agents
In spl-tokens/app/app/craco.config.js around lines 8 to 17, the webpack fallback
uses the legacy buffer-browserify; replace require.resolve('buffer-browserify')
with require.resolve('buffer') so the modern installed buffer package (v6.x) is
used, then update package.json to remove the now-unnecessary buffer-browserify
dependency and run install to ensure lockfile is updated.

Comment on lines +1 to +21
MIT License

Copyright (c) 2023 Magicblock Pte. Ltd.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. No newline at end of file
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add trailing newline to license file.

The file is missing a trailing newline character at the end, which is a standard convention for text files.

As per static analysis hints, this helps ensure better cross-platform compatibility and follows POSIX standards.

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)


21-21: Files should end with a single newline character

(MD047, single-trailing-newline)

🤖 Prompt for AI Agents
In spl-tokens/app/app/LICENSE.md around lines 1 to 21, the file is missing a
trailing newline character; open the LICENSE.md and add a single newline (line
break) at the end of the file so the file ends with a '\n' character, then save
and commit the change.

Comment on lines 2 to 3
"homepage": ".",
"name": "counter-ui-game",
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Align project naming across all files.

The project name "counter-ui-game" doesn't match references elsewhere:

  • HTML title (index.html): "Ephemeral Counter"
  • PWA manifest (manifest.json): "React App" / "Create React App Sample"
  • README references: implied SPL token operations

Choose a consistent name that reflects the SPL token functionality and update all files accordingly.

🤖 Prompt for AI Agents
In spl-tokens/app/app/package.json around lines 2 to 3, the "name" field is set
to "counter-ui-game" which is inconsistent with other project references; update
the project name here to the chosen canonical name that reflects the SPL token
functionality (for example "spl-token-app" or your agreed name) and then
propagate that same name across index.html title, manifest.json (name and
short_name), README, and any other metadata files so all project identifiers
match; ensure the package.json name is a valid npm package name (lowercase, no
spaces) and run a quick search/replace across the repo to keep all references
consistent.

Comment on lines 7 to 15
"@coral-xyz/anchor": "^0.32.1",
"@craco/craco": "^7.1.0",
"@magicblock-labs/ephemeral-rollups-sdk": "file:/Users/gabrielepicco/Documents/Solana/ephemeral-rollups-sdk/ts/web3js",
"@solana/spl-token": "^0.4.9",
"@solana/wallet-adapter-base": "^0.9.23",
"@solana/wallet-adapter-react": "^0.15.35",
"@solana/wallet-adapter-react-ui": "^0.9.35",
"@solana/wallet-adapter-wallets": "^0.19.37",
"@solana/web3.js": "^1.98.0",
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check for the latest versions of critical Solana dependencies
echo "=== Checking @solana/web3.js ==="
npm view @solana/web3.js version 2>/dev/null || echo "npm registry unreachable"

echo -e "\n=== Checking @coral-xyz/anchor ==="
npm view @coral-xyz/anchor version 2>/dev/null || echo "npm registry unreachable"

echo -e "\n=== Checking @solana/spl-token ==="
npm view @solana/spl-token version 2>/dev/null || echo "npm registry unreachable"

echo -e "\n=== Checking wallet adapters ==="
npm view @solana/wallet-adapter-base version 2>/dev/null || echo "npm registry unreachable"
npm view @solana/wallet-adapter-react version 2>/dev/null || echo "npm registry unreachable"

# Check advisory information if available
echo -e "\n=== Checking vulnerability database ==="
npm view @solana/web3.js --json 2>/dev/null | grep -i "deprecated\|security" || echo "No public advisories found in basic check"

Repository: magicblock-labs/magicblock-engine-examples

Length of output: 343


Consider updating wallet adapter dependencies to latest patch versions.

The Solana Web3.js (1.98.0) and Anchor (0.32.1) versions are compatible and at acceptable versions. However, several dependencies have available patch updates: @solana/spl-token (0.4.14), @solana/wallet-adapter-base (0.9.27), and @solana/wallet-adapter-react (0.15.39). No security vulnerabilities were detected. These updates are optional but recommended for stability and bug fixes.

🤖 Prompt for AI Agents
In spl-tokens/app/app/package.json around lines 7 to 15, several Solana wallet
adapter deps are behind patch releases; update the versions for stability by
changing @solana/spl-token to ^0.4.14, @solana/wallet-adapter-base to ^0.9.27,
and @solana/wallet-adapter-react to ^0.15.39 in package.json, then run your
package manager install (npm/yarn/pnpm) to regenerate the lockfile and
node_modules, and run the app build/tests to confirm no regressions.

Comment on lines +8 to +12
"@coral-xyz/anchor": "0.31.1",
"@magicblock-labs/ephemeral-rollups-sdk": "0.7.1"
},
"devDependencies": {
"@solana/spl-token": "^0.4.14",
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

@coral-xyz/anchor latest version npm

💡 Result:

Latest published npm version of @coral-xyz/anchor is 0.31.1 (checked Jan 2, 2026).

Install: npm i @coral-xyz/anchor@0.31.1. [1][2]

Sources:
[1] npm package page for @coral-xyz/anchor.
[2] Package summary (Socket.dev) showing 0.31.1.


🌐 Web query:

@magicblock-labs/ephemeral-rollups-sdk latest version npm

💡 Result:

The latest version on the npm registry is 0.2.10 (published 3 days ago). [1]

Note: a third-party tracker (Socket) lists 0.3.4 as the latest; verify on the npm package page if you need absolute certainty. [2]

Sources:

  • npm package page for @magicblock-labs/ephemeral-rollups-sdk. [1]
  • Socket.dev package listing. [2]

🌐 Web query:

@solana/spl-token latest version npm

💡 Result:

Latest published version of @solana/spl-token (as of Jan 2, 2026) is 0.4.14. [1][2]

Sources:

  • Yarn/npm package listing showing v0.4.14 (published Sep 2, 2025). [1]
  • @Solana package docs / registry listing. [2]

🏁 Script executed:

# Check the project structure and see if @solana/spl-token is used in production code
find . -type f \( -name "*.ts" -o -name "*.js" -o -name "*.tsx" -o -name "*.jsx" \) ! -path "*/node_modules/*" ! -path "*/.next/*" ! -path "*/dist/*" ! -path "*/build/*" | head -20

Repository: magicblock-labs/magicblock-engine-examples

Length of output: 228


🏁 Script executed:

# Search for @solana/spl-token imports in production code
rg "@solana/spl-token" --type ts --type js --type tsx --type jsx

Repository: magicblock-labs/magicblock-engine-examples

Length of output: 113


🏁 Script executed:

# Find TypeScript/JavaScript files in the repository
find . -type f \( -name "*.ts" -o -name "*.js" \) ! -path "*/node_modules/*" ! -path "*/.next/*" ! -path "*/dist/*" ! -path "*/build/*" 2>/dev/null | head -30

Repository: magicblock-labs/magicblock-engine-examples

Length of output: 1304


🏁 Script executed:

# Search for @solana/spl-token imports across all source files
rg "@solana/spl-token" --no-heading -B 2 -A 2 2>/dev/null || echo "No matches found"

Repository: magicblock-labs/magicblock-engine-examples

Length of output: 50399


🏁 Script executed:

# Check if there are test files and how they import the package
rg "@solana/spl-token" . 2>/dev/null || echo "No matches found"

Repository: magicblock-labs/magicblock-engine-examples

Length of output: 50399


Move @solana/spl-token to production dependencies.

The package is imported in production code (spl-tokens/app/app/src/App.tsx) and should not be a devDependency. The versions for @coral-xyz/anchor (0.31.1) and @solana/spl-token (^0.4.14) are current.

🤖 Prompt for AI Agents
In spl-tokens/package.json around lines 8 to 12, @solana/spl-token is currently
listed under devDependencies but is imported by production code
(spl-tokens/app/app/src/App.tsx); move the "@solana/spl-token": "^0.4.14" entry
from devDependencies into the top-level dependencies section (keeping the same
version), remove it from devDependencies, save the updated package.json, and run
your package manager (npm install or yarn install) to update the lockfile so
production installs include the package.

#[account(mut)]
pub to: Account<'info, TokenAccount>,

pub token_program: Program<'info, Token>,
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Remove mut from token_program account.

Program accounts are executable and read-only; marking them as mutable is unnecessary and may cause confusion. The Program<'info, Token> type already handles the correct account constraints.

🔎 Proposed fix
-    pub token_program: Program<'info, Token>,
+    pub token_program: Program<'info, Token>,

Note: If there's currently a #[account(mut)] attribute on line 46 that isn't shown in the snippet, remove it:

// Remove any #[account(mut)] from token_program
pub token_program: Program<'info, Token>,

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In spl-tokens/programs/spl-tokens/src/lib.rs around line 46, the token_program
account is marked mutable but program accounts are executable/read-only; remove
the mut flag/#[account(mut)] attribute (if present) so the field is declared
simply as pub token_program: Program<'info, Token>, ensuring no mutable
constraint is applied.

Comment on lines +32 to +50
const providerEphemeralRollup = new anchor.AnchorProvider(
// new anchor.web3.Connection(
// process.env.EPHEMERAL_PROVIDER_ENDPOINT ||
// "https://devnet-as.magicblock.app/",
// {
// wsEndpoint:
// process.env.EPHEMERAL_WS_ENDPOINT || "wss://devnet-as.magicblock.app/",
// },
// ),
new anchor.web3.Connection(
process.env.EPHEMERAL_PROVIDER_ENDPOINT ||
"http://localhost:7799",
{
wsEndpoint:
process.env.EPHEMERAL_WS_ENDPOINT || "ws://localhost:7800",
},
),
anchor.Wallet.local(),
);
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Remove or document commented-out code.

The commented-out production endpoint configuration creates confusion about which endpoint should be used. Either remove it or add a clear comment explaining when to use each configuration.

🔎 Proposed cleanup
     const providerEphemeralRollup = new anchor.AnchorProvider(
-      // new anchor.web3.Connection(
-      //   process.env.EPHEMERAL_PROVIDER_ENDPOINT ||
-      //     "https://devnet-as.magicblock.app/",
-      //     {
-      //         wsEndpoint:
-      //             process.env.EPHEMERAL_WS_ENDPOINT || "wss://devnet-as.magicblock.app/",
-      //     },
-      // ),
+        // Use environment variables for production, localhost for local testing
         new anchor.web3.Connection(
             process.env.EPHEMERAL_PROVIDER_ENDPOINT ||
             "http://localhost:7799",
📝 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
const providerEphemeralRollup = new anchor.AnchorProvider(
// new anchor.web3.Connection(
// process.env.EPHEMERAL_PROVIDER_ENDPOINT ||
// "https://devnet-as.magicblock.app/",
// {
// wsEndpoint:
// process.env.EPHEMERAL_WS_ENDPOINT || "wss://devnet-as.magicblock.app/",
// },
// ),
new anchor.web3.Connection(
process.env.EPHEMERAL_PROVIDER_ENDPOINT ||
"http://localhost:7799",
{
wsEndpoint:
process.env.EPHEMERAL_WS_ENDPOINT || "ws://localhost:7800",
},
),
anchor.Wallet.local(),
);
const providerEphemeralRollup = new anchor.AnchorProvider(
// Use environment variables for production, localhost for local testing
new anchor.web3.Connection(
process.env.EPHEMERAL_PROVIDER_ENDPOINT ||
"http://localhost:7799",
{
wsEndpoint:
process.env.EPHEMERAL_WS_ENDPOINT || "ws://localhost:7800",
},
),
anchor.Wallet.local(),
);
🤖 Prompt for AI Agents
In spl-tokens/tests/spl-tokens.ts around lines 32 to 50, there is commented-out
production endpoint configuration left inline which causes confusion; either
delete the commented block or replace it with a short, explicit comment that
documents when to use the production/devnet endpoints and which environment
variables control each (e.g.,
EPHEMERAL_PROVIDER_ENDPOINT/EPHEMERAL_WS_ENDPOINT), and ensure the active code
clearly selects between local and production via those env vars so only one
configuration path is present and understandable.

Comment on lines +156 to +158
// Get the validator identity
validator = new PublicKey((await (ephemeralConnection as any)._rpcRequest("getIdentity", []))!.result!.identity);
console.log("Validator: ", validator.toBase58());
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Avoid using private RPC methods.

_rpcRequest is a private/internal method that may change without notice. Consider using a public API or the official getIdentity method if available.

🔎 Suggested alternative
-        validator = new PublicKey((await (ephemeralConnection as any)._rpcRequest("getIdentity", []))!.result!.identity);
+        // Use a more stable approach if the RPC supports it
+        const identityResponse = await (ephemeralConnection as any).getIdentity?.() 
+            ?? await fetch(ephemeralConnection.rpcEndpoint, {
+                method: 'POST',
+                headers: { 'Content-Type': 'application/json' },
+                body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'getIdentity', params: [] })
+            }).then(r => r.json());
+        validator = new PublicKey(identityResponse.result?.identity);

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In spl-tokens/tests/spl-tokens.ts around lines 156 to 158, the code calls the
private method _rpcRequest to get the validator identity; replace that with a
public RPC call such as await ephemeralConnection.getClusterNodes(), locate the
desired node entry (e.g., nodes[0] or by matching IP/port) and construct the
PublicKey from node.pubkey, then log validator.toBase58(); this removes use of
the internal _rpcRequest and uses the supported public API.

Comment on lines +177 to +178
assert(acctA.amount == 1000n);
assert(acctB.amount == 1000n);
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Add descriptive messages to assertions.

Bare assert() calls without messages make debugging test failures difficult. Adding context helps identify which specific check failed.

🔎 Example improvement
-        assert(acctA.amount == 1000n);
-        assert(acctB.amount == 1000n);
+        assert(acctA.amount === 1000n, `Expected acctA to have 1000 tokens, got ${acctA.amount}`);
+        assert(acctB.amount === 1000n, `Expected acctB to have 1000 tokens, got ${acctB.amount}`);

Also applies to: 210-211, 233-234

🤖 Prompt for AI Agents
In spl-tokens/tests/spl-tokens.ts around lines 177-178 (and also update lines
210-211 and 233-234), the assertions use bare assert() calls which lack context;
replace them with assertions that include descriptive failure messages (e.g.,
assert(acctA.amount == 1000n, "acctA amount expected 1000n but was " +
acctA.amount)) so each test failure identifies which account and expected value
failed; update all listed assertion calls to include concise, specific messages
that show the expected vs actual values.

@vercel
Copy link

vercel bot commented Jan 2, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
er-rolldice Ready Ready Preview, Comment Jan 2, 2026 6:33pm

Copy link

@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

♻️ Duplicate comments (29)
spl-tokens/app/tsconfig.json (1)

1-11: Fix formatting issues in tsconfig.

This file has multiple formatting problems that were previously flagged:

  • Lines 2-9: Inconsistent and excessive indentation (12+ spaces instead of standard 2-4)
  • Line 11: Contains trailing whitespace
  • Lines 5, 7: Uses outdated "lib": ["es2015"] and "target": "es6" while the root spl-tokens/tsconfig.json uses "es2020"

Please address these issues by normalizing indentation, removing trailing whitespace, and aligning ECMAScript versions with the root configuration.

spl-tokens/app/LICENSE (1)

1-21: Consider consolidating duplicate license files.

As previously noted, an identical MIT license file exists at both spl-tokens/app/LICENSE and spl-tokens/app/app/LICENSE.md. Additionally, this file is missing a trailing newline character. Consider maintaining a single canonical license file to avoid synchronization issues.

spl-tokens/app/app/src/components/Active.scss (1)

13-13: LGTM with optional enhancement for smoother transitions.

The styles are well-structured. As previously suggested, consider adding background-color to the transition property for smoother visual changes when toggling between .on and .off states.

spl-tokens/app/README.md (2)

29-49: Standardize npm script command in documentation for consistency.

Both npm run dev (line 34) and npm run start (line 49) are used interchangeably, which may create confusion. As previously noted, pick one command and use it consistently throughout the documentation.


45-45: Format "Examples" as a markdown heading.

Line 45 shows Examples as plain text but should be formatted as a markdown heading (e.g., #### Examples) to maintain consistent document structure and improve readability.

spl-tokens/app/app/public/manifest.json (1)

2-3: Customize PWA manifest names to match the SPL tokens branding.

The manifest still uses generic Create React App placeholders. These should be updated to reflect the actual application name and purpose.

spl-tokens/package.json (2)

3-4: Simplify lint glob patterns for consistency.

The lint patterns are overly complex and may not match files as intended. Consider using simpler standard glob patterns like **/*.{js,ts}.


12-12: Move @solana/spl-token to production dependencies.

The package is used in production code and should not be listed as a devDependency.

spl-tokens/app/app/public/index.html (2)

8-8: Make the meta description more specific.

The current description is generic. Consider making it more descriptive of the SPL token operations and Ephemeral Rollups functionality for better SEO.


11-11: Consider font loading strategy.

The external Google Fonts link may impact privacy, performance, and reliability. Consider self-hosting fonts, using system fonts, or adding a font-display strategy.

spl-tokens/Anchor.toml (1)

12-12: Fix formatting inconsistency.

Line 12 is missing a space after the = operator, which is inconsistent with line 9's formatting.

🔎 Proposed fix
-spl-tokens= "FgvEeit1djLPPjozq9zW9R8Ahu5JpijcdWQxqL4P887"
+spl-tokens = "FgvEeit1djLPPjozq9zW9R8Ahu5JpijcdWQxqL4P887"
spl-tokens/app/app/src/components/Square.tsx (1)

24-31: Remove redundant text content from span.

Line 30 renders {clsName} as text content, but the visual X and O symbols are rendered entirely by CSS pseudo-elements and border styling in Square.scss. The span should be empty.

🔎 Proposed fix
             {clsName && (
                 <motion.span
                     initial={{ scale: 0 }}
                     animate={{ scale: 1 }}
                     className={`counter ${clsName}`}
-                >
-                    {clsName}
-                </motion.span>
+                />
             )}
spl-tokens/app/app/tsconfig.json (2)

3-4: Consider aligning module system with target.

The configuration uses target: "ES2020" with module: "commonjs". For modern React apps targeting ES2020, consider using "module": "esnext" or "module": "es2020" for better tree-shaking and modern module support, unless CommonJS is specifically required for compatibility.


13-13: Consider using the modern JSX transform.

The configuration uses "jsx": "react", which requires importing React in every file that uses JSX. Modern React (17+) supports "jsx": "react-jsx", which eliminates the need for these imports.

🔎 Proposed fix
-    "jsx": "react"
+    "jsx": "react-jsx"

Note: After this change, you can remove import React from 'react'; from files that only use JSX.

spl-tokens/app/app/README.md (1)

1-47: Consider enhancing documentation.

While the README provides basic setup instructions, consider adding:

  • Links to Solana and MagicBlock documentation
  • Troubleshooting section for common issues
  • Architecture overview or diagram showing how the UI interacts with on-chain and ephemeral components
  • Example workflows or screenshots
spl-tokens/app/app/src/index.css (1)

1-233: No additional concerns beyond past reviews.

The CSS file has been previously reviewed. The concerns about Google Fonts CDN usage (line 1) and orphaned tic-tac-toe styling (lines 52-169) were already raised in prior reviews. These should be addressed as noted in the existing comments.

spl-tokens/app/app/src/components/Button.tsx (1)

11-22: Issues previously identified.

The missing type="button" attribute and redundant !disabled check in the onClick handler were already flagged in prior reviews. These should be addressed as noted.

spl-tokens/app/app/craco.config.js (1)

8-17: Buffer package inconsistency was previously flagged.

The use of buffer-browserify in the fallback config while the ProvidePlugin references buffer was already identified in a prior review. This should be consolidated to use the modern buffer package consistently.

spl-tokens/tests/spl-tokens.ts (3)

32-50: Commented-out code was previously flagged.

The commented-out production endpoint configuration was already identified in a prior review. It should be removed or documented.


156-158: Private RPC method usage was previously flagged.

The use of _rpcRequest("getIdentity", []) was already identified as using a private/internal method that may change without notice.


177-178: Assertion messages were previously flagged.

The bare assert() calls without descriptive messages were already identified in a prior review.

spl-tokens/app/app/src/App.tsx (8)

200-208: Private RPC method usage was previously flagged.

The use of _rpcRequest("getIdentity", []) was already identified in a prior review.


235-254: Stale closure concern was previously flagged.

The potential stale closure issue with accounts in ensureAta was already identified. The suggested fix to use accountsRef.current should be applied.


291-291: Debug console.log was previously flagged.


313-313: Debug console.log was previously flagged.


433-511: Code duplication between transfer functions was previously flagged.

The significant overlap between handleTransfer and performQuickTransfer was already identified. Extracting shared logic into a helper would improve maintainability.


697-699: Empty heading accessibility issue was previously flagged.

The <h1> with only whitespace was already identified via static analysis.


701-728: Interactive div missing ARIA attributes was previously flagged.

The drag-and-drop target div lacking proper accessibility attributes was already identified.


735-755: Missing type="button" was previously flagged.

This and all other button elements missing explicit type attributes were already identified in prior reviews.

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5919bcc and 5d50368.

⛔ Files ignored due to path filters (9)
  • spl-tokens/Cargo.lock is excluded by !**/*.lock
  • spl-tokens/app/app/public/favicon.ico is excluded by !**/*.ico
  • spl-tokens/app/app/public/magicblock_white.png is excluded by !**/*.png
  • spl-tokens/app/app/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • spl-tokens/app/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • spl-tokens/package-lock.json is excluded by !**/package-lock.json
  • spl-tokens/tests/fixtures/dlp.so is excluded by !**/*.so
  • spl-tokens/tests/fixtures/ephemeral_token_program.so is excluded by !**/*.so
  • spl-tokens/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (29)
  • spl-tokens/.gitignore
  • spl-tokens/Anchor.toml
  • spl-tokens/Cargo.toml
  • spl-tokens/app/LICENSE
  • spl-tokens/app/README.md
  • spl-tokens/app/app/LICENSE.md
  • spl-tokens/app/app/README.md
  • spl-tokens/app/app/craco.config.js
  • spl-tokens/app/app/package.json
  • spl-tokens/app/app/public/index.html
  • spl-tokens/app/app/public/manifest.json
  • spl-tokens/app/app/src/App.tsx
  • spl-tokens/app/app/src/components/Active.scss
  • spl-tokens/app/app/src/components/Active.tsx
  • spl-tokens/app/app/src/components/Alert.tsx
  • spl-tokens/app/app/src/components/Button.tsx
  • spl-tokens/app/app/src/components/Square.scss
  • spl-tokens/app/app/src/components/Square.tsx
  • spl-tokens/app/app/src/components/Wallet.tsx
  • spl-tokens/app/app/src/index.css
  • spl-tokens/app/app/src/index.tsx
  • spl-tokens/app/app/tsconfig.json
  • spl-tokens/app/app/tsconfig.tsbuildinfo
  • spl-tokens/app/tsconfig.json
  • spl-tokens/package.json
  • spl-tokens/programs/spl-tokens/Cargo.toml
  • spl-tokens/programs/spl-tokens/src/lib.rs
  • spl-tokens/tests/spl-tokens.ts
  • spl-tokens/tsconfig.json
🧰 Additional context used
🧬 Code graph analysis (3)
spl-tokens/app/app/src/components/Button.tsx (1)
roll-dice/app/components/ui/button.tsx (2)
  • ButtonProps (36-40)
  • Button (56-56)
spl-tokens/app/app/src/index.tsx (1)
spl-tokens/app/app/src/components/Wallet.tsx (1)
  • Wallet (27-44)
spl-tokens/app/app/src/App.tsx (2)
spl-tokens/app/app/src/components/Wallet.tsx (1)
  • Wallet (27-44)
roll-dice/app/components/ui/alert.tsx (1)
  • Alert (59-59)
🪛 Biome (2.1.2)
spl-tokens/app/app/package.json

[error] 9-9: Missing closing quote

The closing quote must be on the same line.

(parse)


[error] 10-10: expected , but instead found "@solana/spl-token"

Remove "@solana/spl-token"

(parse)

spl-tokens/app/app/src/components/Button.tsx

[error] 11-20: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)

spl-tokens/app/app/src/App.tsx

[error] 697-699: Provide screen reader accessible content when using heading elements.

All headings on a page should have content that is accessible to screen readers.

(lint/a11y/useHeadingContent)


[error] 701-729: Static Elements should not be interactive.

To add interactivity such as a mouse or key event listener to a static element, give the element an appropriate role value.

(lint/a11y/noStaticElementInteractions)


[error] 735-755: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)


[error] 793-833: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)


[error] 883-968: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)


[error] 1008-1084: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)


[error] 1162-1175: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)


[error] 1209-1219: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)


[error] 1221-1231: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)


[error] 1236-1248: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)

🪛 Gitleaks (8.30.0)
spl-tokens/Anchor.toml

[high] 9-9: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 12-12: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🪛 markdownlint-cli2 (0.18.1)
spl-tokens/app/app/LICENSE.md

1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)


21-21: Files should end with a single newline character

(MD047, single-trailing-newline)

spl-tokens/app/README.md

1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)


21-21: Files should end with a single newline character

(MD047, single-trailing-newline)

spl-tokens/app/app/README.md

1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)


5-5: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


17-17: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


21-21: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


25-25: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


25-25: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


31-31: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


31-31: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


36-36: Bare URL used

(MD034, no-bare-urls)


40-40: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


46-46: Bare URL used

(MD034, no-bare-urls)


47-47: Bare URL used

(MD034, no-bare-urls)


47-47: Files should end with a single newline character

(MD047, single-trailing-newline)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test-examples
🔇 Additional comments (15)
spl-tokens/tsconfig.json (1)

1-10: LGTM!

The TypeScript configuration is clean and properly formatted with appropriate settings for the spl-tokens workspace, including ES2020 support and mocha/chai types for testing.

spl-tokens/Cargo.toml (1)

1-14: LGTM! Solid Rust workspace configuration.

The workspace setup follows Solana/Anchor best practices with appropriate release optimizations (overflow checks for safety, fat LTO and single codegen unit for binary size optimization).

spl-tokens/app/app/src/components/Square.scss (1)

1-38: LGTM!

The SCSS styling is well-structured and effectively uses pseudo-elements (::before and ::after) to render the X symbol and border styling for the O symbol. The visual design is clean and the grid layout centers content appropriately.

spl-tokens/app/app/src/components/Wallet.tsx (2)

27-43: Wallet component structure looks good.

The wallet integration correctly wraps the app with the necessary Solana wallet adapter providers, uses useMemo with stable dependencies for adapter instances, and provides a sensible default RPC endpoint.


17-25: SimpleProvider is exported but not used in this file. The Wallet.tsx component exports SimpleProvider, but it's never instantiated anywhere in spl-tokens. The actual app (App.tsx) uses anchor.AnchorProvider directly for Anchor operations, making the completeness of SimpleProvider not a concern for this file. If SimpleProvider is intended only as a utility for other projects in this monorepo (like session-keys), consider moving it to a shared utilities module or removing it if unused.

Likely an incorrect or invalid review comment.

spl-tokens/programs/spl-tokens/Cargo.toml (1)

22-25: Dependency versions and features look appropriate.

The pinned versions for anchor-lang and anchor-spl ensure build reproducibility. The init-if-needed feature is enabled—be mindful that this allows accounts to be initialized during instruction execution, which requires careful validation to prevent reinitialization attacks in your program logic.

spl-tokens/app/app/craco.config.js (1)

24-29: ProvidePlugin Buffer injection is correctly configured.

The global Buffer injection via ProvidePlugin is necessary for Solana libraries that rely on Node.js Buffer in browser environments.

spl-tokens/tests/spl-tokens.ts (1)

64-159: Test setup and initialization logic is well-structured.

The before hook properly creates a mint, ATAs for both recipients, funds accounts, and mints initial tokens. The assertions verify the setup succeeded before tests run.

spl-tokens/app/app/src/App.tsx (4)

45-53: Formatting helper handles edge cases correctly.

The fmt function properly handles undefined values, negative numbers, and removes trailing zeros from fractional parts.


134-172: LocalStorage persistence for keypairs is appropriate for a demo app.

Storing generated keypairs in localStorage is acceptable for this example/demo application. For production use, this approach would need proper key management.


592-672: Mint setup flow is well-implemented.

The setupAll function correctly creates a mint, ATAs for all accounts, and mints initial tokens in a single transaction. The mint metadata is persisted to localStorage for session continuity.


913-928: Delegation flow handles re-delegation correctly.

The code properly checks if already delegated and performs undelegation first before re-delegating, including waiting for the commitment signature confirmation on L1.

spl-tokens/programs/spl-tokens/src/lib.rs (3)

1-6: LGTM! Imports and program ID are correctly configured.

The imports include all necessary types for SPL token CPI operations, and the program ID declaration follows standard Anchor conventions.


36-46: Account constraints and structure are well-designed.

The constraints on the from account correctly enforce:

  • Ownership validation (line 38): ensures payer owns the token account
  • Mint consistency (line 39): prevents transferring between accounts of different token types

The to and token_program accounts are correctly configured. Note that the previous review comment about token_program being marked as mut appears to have been addressed—line 46 correctly omits any mutability modifier.


49-57: LGTM! Error codes are well-defined and descriptive.

Each error code corresponds to a specific validation check in the program and includes clear, user-friendly messages.

Comment on lines +17 to +20
# But don't ignore the target/idl/ directory
!**/anchor-minter/target/idl/
!programs/spl-tokens/target/idl/
!**/anchor-minter/target/deploy/ No newline at end of file
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Inconsistent path pattern in un-ignore rule.

Line 19 uses a path pattern without the **/ prefix (programs/spl-tokens/target/idl/), while lines 18 and 20 use **/ prefixes. This inconsistency may cause the un-ignore rule to not work as intended if the directory structure differs from expectations.

🔎 Proposed fix for consistency
 # But don't ignore the target/idl/ directory
 !**/anchor-minter/target/idl/
-!programs/spl-tokens/target/idl/
+!**/programs/spl-tokens/target/idl/
 !**/anchor-minter/target/deploy/
🤖 Prompt for AI Agents
In spl-tokens/.gitignore around lines 17 to 20, the un-ignore rule on line 19
uses an inconsistent path pattern (programs/spl-tokens/target/idl/) compared to
the other lines that use the **/ prefix; update line 19 to use the same glob
prefix (e.g., !**/programs/spl-tokens/target/idl/) so all un-ignore rules are
consistent and will match regardless of nested directory layout.

"dependencies": {
"@coral-xyz/anchor": "^0.32.1",
"@craco/craco": "^7.1.0",
"@magicblock-labs/ephemeral-rollups-sdk": "0.7.2,
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: Fix JSON syntax error - missing closing quote.

Line 9 has a syntax error: the version string "0.7.2, is missing the closing quote. This will prevent the package.json from being parsed by npm/yarn.

🔎 Proposed fix
-        "@magicblock-labs/ephemeral-rollups-sdk": "0.7.2,
+        "@magicblock-labs/ephemeral-rollups-sdk": "0.7.2",
📝 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
"@magicblock-labs/ephemeral-rollups-sdk": "0.7.2,
"@magicblock-labs/ephemeral-rollups-sdk": "0.7.2",
🧰 Tools
🪛 Biome (2.1.2)

[error] 9-9: Missing closing quote

The closing quote must be on the same line.

(parse)

🤖 Prompt for AI Agents
In spl-tokens/app/app/package.json around line 9, the dependency version entry
"@magicblock-labs/ephemeral-rollups-sdk": "0.7.2, has a missing closing quote
which breaks JSON parsing; fix it by adding the closing double-quote after 0.7.2
and ensure the trailing comma is correct for the JSON object (e.g.,
"@magicblock-labs/ephemeral-rollups-sdk": "0.7.2",) so package.json remains
valid.

Comment on lines +1 to +47
## SPL Tokens Example UI (Ephemeral Rollups)

A React UI that demonstrates SPL Token flows across Solana and MagicBlock Ephemeral Rollups. It pairs with the programs/spl-tokens on-chain program in this repository.

### What this UI shows
- Create or load a temporary SPL token mint (for demo purposes)
- Create Associated Token Accounts (ATAs) for users
- Mint demo tokens to accounts
- Delegate tokens to the Ephemeral Rollup chain
- Perform token transfers on the Ephemeral chain
- Undelegate and withdraw tokens back to Solana

---

## 🚀 Getting Started

### Prerequisites
- Node.js (18+ recommended)
- npm or yarn

### Install & run
From this folder (app/app):

Using npm
```
npm install
npm run start
```

Using yarn
```
yarn install
yarn start
```

The dev server will start on http://localhost:3000.

---

## ⚙️ Configure RPC endpoints
This UI talks to two RPC endpoints:
- REACT_APP_PROVIDER_ENDPOINT: Solana RPC (e.g., local validator or a public devnet RPC)
- REACT_APP_EPHEMERAL_PROVIDER_ENDPOINT: Ephemeral Rollup RPC

You can set them via environment variables when starting the app. If not provided, the app defaults to MagicBlock public endpoints:
- REACT_APP_PROVIDER_ENDPOINT → https://rpc.magicblock.app/devnet
- REACT_APP_EPHEMERAL_PROVIDER_ENDPOINT → https://devnet.magicblock.app No newline at end of file
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Address markdown formatting issues.

The markdown linter flags multiple formatting issues that should be addressed for consistency:

  • Headings should be surrounded by blank lines (lines 5, 17, 21, 40)
  • Fenced code blocks should be surrounded by blank lines and specify a language (lines 25, 31)
  • Bare URLs should be wrapped in angle brackets or markdown links (lines 36, 46, 47)
  • File should end with a single newline character
🔎 Example fixes

For headings, add blank lines before and after:

 
 ### What this UI shows
+
 - Create or load a temporary SPL token mint (for demo purposes)

For code blocks, add language identifier and blank lines:

+
-```
+```bash
 npm install
 npm run start

For URLs, use angle brackets or markdown links:
```diff
-The dev server will start on http://localhost:3000.
+The dev server will start on <http://localhost:3000>.

Based on static analysis hints.

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)


5-5: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


17-17: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


21-21: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


25-25: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


25-25: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


31-31: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


31-31: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


36-36: Bare URL used

(MD034, no-bare-urls)


40-40: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


46-46: Bare URL used

(MD034, no-bare-urls)


47-47: Bare URL used

(MD034, no-bare-urls)


47-47: Files should end with a single newline character

(MD047, single-trailing-newline)

🤖 Prompt for AI Agents
In spl-tokens/app/app/README.md around lines 1 to 47, the markdown has
formatting lint issues: add a blank line before and after each heading (around
lines 5, 17, 21, 40), ensure fenced code blocks are surrounded by blank lines
and include a language identifier (e.g., ```bash) for the npm/yarn blocks
(around lines 25 and 31), wrap bare URLs in angle brackets or convert them to
markdown links (lines ~36, 46, 47), and ensure the file ends with exactly one
trailing newline; apply these edits to satisfy the linter.

Comment on lines +5 to +7
type ActiveProps = {
clsName: string; // Expected to be "on" or "off"
};
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Enforce type constraint for clsName prop.

The comment indicates clsName should be "on" or "off", but the type is declared as string, allowing any string value. Use a string literal union type to enforce this constraint at compile time.

🔎 Proposed fix
 type ActiveProps = {
-    clsName: string; // Expected to be "on" or "off"
+    clsName: 'on' | 'off';
 };
🤖 Prompt for AI Agents
In spl-tokens/app/app/src/components/Active.tsx around lines 5 to 7, the
ActiveProps type declares clsName as a plain string but the comment says it must
be "on" or "off"; change the type to a string-literal union (clsName: "on" |
"off") to enforce the constraint at compile time, update any component usages or
default props to pass only "on" or "off" (or adjust callers to satisfy the new
type), and run TypeScript to fix any resulting type errors.

Comment on lines +1 to +54
# Ephemeral Counter UI

This is a React-based UI for the Ephemeral Counter program, which is part of the documentation for integrating with the Ephemeral Rollups.

## Overview

The UI demonstrates the use of Solana's ephemeral rollups with a simple counter program. It showcases an `increment` instruction that can run both on the main network and ephemeral rollup.

## Documentation

For more information, visit: [Ephemeral Rollups Documentation](https://docs.magicblock.gg/Accelerate/ephemeral_rollups).

## Getting Started

### Prerequisites

- Node.js
- npm

### Installation

1. Navigate to the `app` directory
2. Install the dependencies:


npm install


### Running the Application

To start the application, run:


npm run dev


### Configure RPC endpoints

This UI talks to two RPC endpoints:
- REACT_APP_PROVIDER_ENDPOINT: the Solana RPC used by the wallet and on-chain counter (e.g., your local validator or a public RPC).
- REACT_APP_EPHEMERAL_PROVIDER_ENDPOINT: the Ephemeral Rollup RPC used for the ephemeral counter.

You can set them via environment variables when starting the app.

Examples
- Using localhost (same machine):
REACT_APP_PROVIDER_ENDPOINT=http://localhost:8899 \
REACT_APP_EPHEMERAL_PROVIDER_ENDPOINT=http://localhost:7799 \
npm run start

If these variables are not provided, the app will default to MagicBlock’s public endpoints:
- REACT_APP_PROVIDER_ENDPOINT → https://rpc.magicblock.app/devnet
- REACT_APP_EPHEMERAL_PROVIDER_ENDPOINT → https://devnet.magicblock.app

Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Add trailing newline at end of file.

The file is missing a trailing newline character, which is a minor formatting convention. Consider adding one for consistency with standard markdown formatting practices.

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

1-1: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)


21-21: Files should end with a single newline character

(MD047, single-trailing-newline)

🤖 Prompt for AI Agents
In spl-tokens/app/README.md around lines 1 to 54, the file is missing a trailing
newline at EOF; add a single newline character at the end of the file so the
file ends with a blank line (ensure the editor saves with a trailing newline) to
conform to standard file formatting conventions.

Comment on lines +8 to +29
#[ephemeral]
#[program]
pub mod spl_tokens {
use super::*;

/// Transfer `amount` of SPL tokens from `from` to `to`.
pub fn transfer(ctx: Context<TransferTokens>, amount: u64) -> Result<()> {
require!(amount > 0, ErrorCode::InvalidAmount);

// CPI into the SPL Token Program
let cpi_accounts = SplTransfer {
from: ctx.accounts.from.to_account_info(),
to: ctx.accounts.to.to_account_info(),
authority: ctx.accounts.payer.to_account_info(),
};
let cpi_ctx = CpiContext::new(ctx.accounts.token_program.to_account_info(), cpi_accounts);

token::transfer(cpi_ctx, amount)?;

Ok(())
}
}
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Transfer implementation is correct.

The function properly validates input, sets up CPI accounts, and delegates to the SPL Token Program. The authority is correctly set to payer, which matches the ownership constraint validated in the accounts struct.

💡 Optional: Consider adding a self-transfer check

You could add a check to prevent no-op transfers where from and to are the same account:

 pub fn transfer(ctx: Context<TransferTokens>, amount: u64) -> Result<()> {
     require!(amount > 0, ErrorCode::InvalidAmount);
+    require!(ctx.accounts.from.key() != ctx.accounts.to.key(), ErrorCode::SelfTransfer);

     // CPI into the SPL Token Program

And add a corresponding error:

#[msg("cannot transfer to the same account")]
SelfTransfer,

This would save compute units by failing early, though the SPL Token Program handles this gracefully.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In spl-tokens/programs/spl-tokens/src/lib.rs around lines 8 to 29, add an early
self-transfer validation and corresponding error variant: check that
ctx.accounts.from.key() != ctx.accounts.to.key() and return an
ErrorCode::SelfTransfer (or similar) when they are equal; also add a new error
enum variant like #[msg("cannot transfer to the same account")] SelfTransfer to
the program's error definitions. This will fail fast on no-op transfers and save
compute by avoiding the CPI when from == to.

Comment on lines +33 to +34
#[account(mut)]
pub payer: Signer<'info>,
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider removing mut from payer account.

The payer acts as a signer and authority but doesn't have its lamport balance or data modified in this instruction. Marking it as mut is unnecessary, though it doesn't cause security issues.

🔎 Proposed refinement
-    #[account(mut)]
     pub payer: Signer<'info>,
📝 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
#[account(mut)]
pub payer: Signer<'info>,
pub payer: Signer<'info>,
🤖 Prompt for AI Agents
In spl-tokens/programs/spl-tokens/src/lib.rs around lines 33 to 34, the payer
account is annotated with #[account(mut)] but its lamports/data are not modified
in this instruction; remove the mut flag so it reads pub payer: Signer<'info>,
update any comments if necessary, and recompile to ensure no other code relies
on the mutable annotation.


const program = anchor.workspace.SplTokens as Program<SplTokens>;

it("Delegate SPL tokens and do a transfer trough a program", async () => {
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Minor typo in test description.

"trough" should be "through".

-    it("Delegate SPL tokens and do a transfer trough a program", async () => {
+    it("Delegate SPL tokens and do a transfer through a program", async () => {
📝 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
it("Delegate SPL tokens and do a transfer trough a program", async () => {
it("Delegate SPL tokens and do a transfer through a program", async () => {
🤖 Prompt for AI Agents
In spl-tokens/tests/spl-tokens.ts around line 239, the test title contains a
typo: "trough" should be "through"; update the it(...) description string to
read "Delegate SPL tokens and do a transfer through a program" (keep the rest of
the test unchanged).

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.

2 participants