-
Notifications
You must be signed in to change notification settings - Fork 24
Feat/add spl native example #52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
WalkthroughAdds 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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this 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
⛔ Files ignored due to path filters (9)
spl-tokens/Cargo.lockis excluded by!**/*.lockspl-tokens/app/app/public/favicon.icois excluded by!**/*.icospl-tokens/app/app/public/magicblock_white.pngis excluded by!**/*.pngspl-tokens/app/app/yarn.lockis excluded by!**/yarn.lock,!**/*.lockspl-tokens/app/yarn.lockis excluded by!**/yarn.lock,!**/*.lockspl-tokens/package-lock.jsonis excluded by!**/package-lock.jsonspl-tokens/tests/fixtures/dlp.sois excluded by!**/*.sospl-tokens/tests/fixtures/ephemeral_token_program.sois excluded by!**/*.sospl-tokens/yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (29)
spl-tokens/.gitignorespl-tokens/Anchor.tomlspl-tokens/Cargo.tomlspl-tokens/app/LICENSEspl-tokens/app/README.mdspl-tokens/app/app/LICENSE.mdspl-tokens/app/app/README.mdspl-tokens/app/app/craco.config.jsspl-tokens/app/app/package.jsonspl-tokens/app/app/public/index.htmlspl-tokens/app/app/public/manifest.jsonspl-tokens/app/app/src/App.tsxspl-tokens/app/app/src/components/Active.scssspl-tokens/app/app/src/components/Active.tsxspl-tokens/app/app/src/components/Alert.tsxspl-tokens/app/app/src/components/Button.tsxspl-tokens/app/app/src/components/Square.scssspl-tokens/app/app/src/components/Square.tsxspl-tokens/app/app/src/components/Wallet.tsxspl-tokens/app/app/src/index.cssspl-tokens/app/app/src/index.tsxspl-tokens/app/app/tsconfig.jsonspl-tokens/app/app/tsconfig.tsbuildinfospl-tokens/app/tsconfig.jsonspl-tokens/package.jsonspl-tokens/programs/spl-tokens/Cargo.tomlspl-tokens/programs/spl-tokens/src/lib.rsspl-tokens/tests/spl-tokens.tsspl-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/devnetandhttps://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 = truein 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
createRootAPI- Wraps the app in
StrictModefor 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. Thefullstack-test.shscript exists at the repository root and is executable, so the reference inpackage.jsonis 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 inanchor-counter/,anchor-minter/, andbolt-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-divutility class provides clean centering and styling for the container. The use offit-contentwidth 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
SquarePropsis well-structured with appropriate optional properties and flexible typing for theindparameter.
12-16: LGTM!The
handleClickimplementation 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. TheSimpleProviderimplementation is correct and complete.The Anchor
Providerinterface for version 0.32.1 (used in this codebase) requires only theconnectionandpublicKeyproperties, both of which are provided. Methods likesend,sendAndConfirm,sendAll, andsimulateare 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.
| [programs.devnet] | ||
| spl-tokens = "FgvEeit1djLPPjozq9zW9R8Ahu5JpijcdWQxqL4P887" | ||
|
|
||
| [programs.localnet] | ||
| spl-tokens= "FgvEeit1djLPPjozq9zW9R8Ahu5JpijcdWQxqL4P887" |
There was a problem hiding this comment.
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.
| [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.
| 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, | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check which buffer package is installed
cat spl-tokens/app/app/package.json | jq '.dependencies, .devDependencies' | grep -i bufferRepository: 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 2Repository: 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.
| 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
spl-tokens/app/app/package.json
Outdated
| "homepage": ".", | ||
| "name": "counter-ui-game", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| "@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", |
There was a problem hiding this comment.
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.
| "@coral-xyz/anchor": "0.31.1", | ||
| "@magicblock-labs/ephemeral-rollups-sdk": "0.7.1" | ||
| }, | ||
| "devDependencies": { | ||
| "@solana/spl-token": "^0.4.14", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 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 -20Repository: 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 jsxRepository: 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 -30Repository: 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>, |
There was a problem hiding this comment.
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.
| 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(), | ||
| ); |
There was a problem hiding this comment.
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.
| 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.
| // Get the validator identity | ||
| validator = new PublicKey((await (ephemeralConnection as any)._rpcRequest("getIdentity", []))!.result!.identity); | ||
| console.log("Validator: ", validator.toBase58()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| assert(acctA.amount == 1000n); | ||
| assert(acctB.amount == 1000n); |
There was a problem hiding this comment.
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.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this 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 rootspl-tokens/tsconfig.jsonuses"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/LICENSEandspl-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-colorto the transition property for smoother visual changes when toggling between.onand.offstates.spl-tokens/app/README.md (2)
29-49: Standardize npm script command in documentation for consistency.Both
npm run dev(line 34) andnpm 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
Examplesas 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 inSquare.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"withmodule: "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!disabledcheck 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-browserifyin the fallback config while theProvidePluginreferencesbufferwas already identified in a prior review. This should be consolidated to use the modernbufferpackage 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
accountsinensureAtawas already identified. The suggested fix to useaccountsRef.currentshould 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
handleTransferandperformQuickTransferwas 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: Missingtype="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
⛔ Files ignored due to path filters (9)
spl-tokens/Cargo.lockis excluded by!**/*.lockspl-tokens/app/app/public/favicon.icois excluded by!**/*.icospl-tokens/app/app/public/magicblock_white.pngis excluded by!**/*.pngspl-tokens/app/app/yarn.lockis excluded by!**/yarn.lock,!**/*.lockspl-tokens/app/yarn.lockis excluded by!**/yarn.lock,!**/*.lockspl-tokens/package-lock.jsonis excluded by!**/package-lock.jsonspl-tokens/tests/fixtures/dlp.sois excluded by!**/*.sospl-tokens/tests/fixtures/ephemeral_token_program.sois excluded by!**/*.sospl-tokens/yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (29)
spl-tokens/.gitignorespl-tokens/Anchor.tomlspl-tokens/Cargo.tomlspl-tokens/app/LICENSEspl-tokens/app/README.mdspl-tokens/app/app/LICENSE.mdspl-tokens/app/app/README.mdspl-tokens/app/app/craco.config.jsspl-tokens/app/app/package.jsonspl-tokens/app/app/public/index.htmlspl-tokens/app/app/public/manifest.jsonspl-tokens/app/app/src/App.tsxspl-tokens/app/app/src/components/Active.scssspl-tokens/app/app/src/components/Active.tsxspl-tokens/app/app/src/components/Alert.tsxspl-tokens/app/app/src/components/Button.tsxspl-tokens/app/app/src/components/Square.scssspl-tokens/app/app/src/components/Square.tsxspl-tokens/app/app/src/components/Wallet.tsxspl-tokens/app/app/src/index.cssspl-tokens/app/app/src/index.tsxspl-tokens/app/app/tsconfig.jsonspl-tokens/app/app/tsconfig.tsbuildinfospl-tokens/app/tsconfig.jsonspl-tokens/package.jsonspl-tokens/programs/spl-tokens/Cargo.tomlspl-tokens/programs/spl-tokens/src/lib.rsspl-tokens/tests/spl-tokens.tsspl-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
useMemowith 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 exportsSimpleProvider, but it's never instantiated anywhere in spl-tokens. The actual app (App.tsx) usesanchor.AnchorProviderdirectly for Anchor operations, making the completeness ofSimpleProvidernot a concern for this file. IfSimpleProvideris 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-langandanchor-splensure build reproducibility. Theinit-if-neededfeature 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
Bufferinjection viaProvidePluginis 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
beforehook 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
fmtfunction 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
setupAllfunction 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
fromaccount 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
toandtoken_programaccounts are correctly configured. Note that the previous review comment abouttoken_programbeing marked asmutappears 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.
| # 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 |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| "@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.
| ## 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| type ActiveProps = { | ||
| clsName: string; // Expected to be "on" or "off" | ||
| }; |
There was a problem hiding this comment.
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.
| # 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 | ||
|
|
There was a problem hiding this comment.
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.
| #[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(()) | ||
| } | ||
| } |
There was a problem hiding this comment.
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 ProgramAnd 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.
| #[account(mut)] | ||
| pub payer: Signer<'info>, |
There was a problem hiding this comment.
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.
| #[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 () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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).
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.