Skip to content

feat: Magic actions example#41

Merged
sporicle merged 13 commits into
mainfrom
magic-actions-example
Oct 14, 2025
Merged

feat: Magic actions example#41
sporicle merged 13 commits into
mainfrom
magic-actions-example

Conversation

@sporicle
Copy link
Copy Markdown
Contributor

@sporicle sporicle commented Oct 14, 2025

Summary by CodeRabbit

  • New Features

    • Adds Magic Actions workflows for initializing and updating on-chain counters and a leaderboard, including delegate/undelegate and cross-path commit actions.
  • Tests

    • Adds comprehensive end-to-end tests covering init, increments, delegation, leaderboard updates, cross-path commits, and undelegation.
  • Documentation

    • New example README with setup, install, build, deploy, and test instructions.
  • Chores

    • Adds project configs, manifest files, formatter/ignore rules, and a deploy script scaffold.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Oct 14, 2025

Walkthrough

Adds a new Anchor-based Solana example "magic-actions": workspace and crate configs, an on-chain program implementing counter/leaderboard and delegation flows, TypeScript E2E tests and migration script, plus repo tooling and ignore files. All changes are additive.

Changes

Cohort / File(s) Summary
Repo setup & tooling
magic-actions/.gitignore, magic-actions/.prettierignore, magic-actions/Anchor.toml, magic-actions/Cargo.toml, magic-actions/package.json, magic-actions/tsconfig.json, magic-actions/README.md, README.md
Adds ignore/prettier rules, Anchor project config, workspace Cargo.toml, Node manifest, TS config, example README, and updates top-level README to reference the example.
Program crate configuration
magic-actions/programs/magic-actions/Cargo.toml, magic-actions/programs/magic-actions/Xargo.toml
Adds Rust crate manifest with features, dependencies, and BPF target std config.
On-chain program logic
magic-actions/programs/magic-actions/src/lib.rs
New Anchor program magic_actions with PDAs, account structs and data types; instructions: initialize, increment, update_leaderboard, delegate, undelegate, and commit_and_update_leaderboard using ephemeral-rollups SDK and external-call discriminator.
Migration script
magic-actions/migrations/deploy.ts
Adds Anchor migration stub that sets provider; placeholder for deploy logic.
End-to-end tests
magic-actions/tests/magic-actions.ts
Adds comprehensive E2E tests exercising init/increment/leaderboard updates, delegation to edge router, ER-path increments, undelegation, and helper utilities for state inspection.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Test as Test Runner
  participant SDK as Router SDK
  participant Router as Magic Router
  participant Magic as Magic Program (router handler)
  participant Prog as magic_actions Program
  participant C as Counter PDA
  participant L as Leaderboard PDA

  Test->>SDK: build/sendMagicTransaction(initialize/increment)
  SDK->>Router: route action
  Router->>Magic: handle routed action
  Magic->>Prog: invoke corresponding ix
  Prog->>C: read/write counter
  Prog->>L: read/write leaderboard (when updating)
  Prog-->>Magic: return result
  Magic-->>SDK: return tx signature
  SDK-->>Test: deliver signature/result
Loading
sequenceDiagram
  autonumber
  actor Test as Test Runner
  participant Prog as magic_actions Program
  participant Magic as Magic Program
  participant C as Counter PDA
  participant L as Leaderboard PDA

  rect rgb(235,245,255)
  note right of Test: Delegation flow
  Test->>Prog: delegate(pda, config)
  Prog-->>Test: delegation committed
  end

  rect rgb(240,255,240)
  note right of Test: Commit + Update (via router)
  Test->>Prog: commit_and_update_leaderboard(...)
  Prog->>Magic: build MagicInstruction(ActionArgs, CallHandler)
  Magic->>Prog: external call -> update_leaderboard (discriminator)
  Prog->>C: read count
  Prog->>L: update high_score if needed
  Prog-->>Test: committed + updated
  end

  rect rgb(255,245,235)
  note right of Test: Undelegation
  Test->>Prog: undelegate(counter) <<commit>>
  Prog-->>Test: undelegated
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested reviewers

  • jonasXchen

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly describes the primary addition of a Magic Actions example and follows conventional commit style, directly reflecting the main change in the pull request without unnecessary detail.
✨ 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 magic-actions-example

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 13

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c7d6e88 and e6a3ce9.

⛔ Files ignored due to path filters (3)
  • magic-actions/Cargo.lock is excluded by !**/*.lock
  • magic-actions/package-lock.json is excluded by !**/package-lock.json
  • magic-actions/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (13)
  • magic-actions/.gitignore (1 hunks)
  • magic-actions/.prettierignore (1 hunks)
  • magic-actions/Anchor.toml (1 hunks)
  • magic-actions/Cargo.toml (1 hunks)
  • magic-actions/README.md (1 hunks)
  • magic-actions/debug-magic-router.js (1 hunks)
  • magic-actions/migrations/deploy.ts (1 hunks)
  • magic-actions/package.json (1 hunks)
  • magic-actions/programs/magic-actions/Cargo.toml (1 hunks)
  • magic-actions/programs/magic-actions/Xargo.toml (1 hunks)
  • magic-actions/programs/magic-actions/src/lib.rs (1 hunks)
  • magic-actions/tests/magic-actions.ts (1 hunks)
  • magic-actions/tsconfig.json (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
magic-actions/programs/magic-actions/src/lib.rs (1)
anchor-counter/programs/anchor-counter/src/lib.rs (1)
  • commit (64-72)
🪛 LanguageTool
magic-actions/README.md

[grammar] ~1-~1: Use correct spacing
Context: # ➕ Magic Actions Simple program to demonstrate magic acti...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~3-~3: Use correct spacing
Context: ...le program to demonstrate magic actions. ## Software Packages This program has util...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~5-~5: Use correct spacing
Context: ...ate magic actions. ## Software Packages This program has utilized the following ...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~7-~7: Ensure spelling is correct
Context: ...This program has utilized the following sofware packages. | Software | Version | Ins...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~7-~7: Use correct spacing
Context: ...utilized the following sofware packages. | Software | Version | Installation Gu...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~9-~9: There might be a mistake here.
Context: ... | | ---------- | ------- | ---------------...

(QB_NEW_EN)


[grammar] ~10-~10: There might be a mistake here.
Context: ...-------------------------------------- | | Solana | 2.1.21 | [Install Solana...

(QB_NEW_EN)


[grammar] ~11-~11: There might be a mistake here.
Context: ...docs.anza.xyz/cli/install) | | Rust | 1.82 | [Install Rust](...

(QB_NEW_EN)


[grammar] ~12-~12: There might be a mistake here.
Context: ...w.rust-lang.org/tools/install) | | Anchor | 0.31.1 | [Install Anchor...

(QB_NEW_EN)


[grammar] ~13-~13: There might be a mistake here.
Context: ...www.anchor-lang.com/docs/installation) | | Node | 22.17.0 | [Install Node](...

(QB_NEW_EN)


[grammar] ~14-~14: Use correct spacing
Context: ...dejs.org/en/download/current) | sh # Check and initialize your Solana version agave-install list agave-install init 2.1.21 # Check and initialize your Rust version rustup show rustup install 1.82 # Check and initialize your Anchor version avm list avm use 0.31.1

(QB_NEW_EN_OTHER_ERROR_IDS_5)

🔇 Additional comments (10)
magic-actions/.gitignore (1)

1-7: LGTM! Standard ignore patterns for an Anchor project.

The ignore entries appropriately cover Anchor build artifacts, Rust/Node dependencies, test artifacts, and platform-specific files.

magic-actions/programs/magic-actions/Xargo.toml (1)

1-2: Verify if Xargo is necessary for this project.

Modern Solana projects typically use cargo-build-sbf (or cargo-build-bpf for older versions) instead of Xargo. Anchor 0.31.1 with Solana 2.1.21 should have built-in BPF tooling support.

If Xargo is not explicitly required, consider removing this file and relying on the standard Anchor/Solana build toolchain.

Based on learnings: Anchor 0.31.1 is aligned with Solana v2/Agave tooling which includes native BPF compilation support.

magic-actions/.prettierignore (1)

1-7: LGTM! Appropriate Prettier ignore patterns.

The ignore list correctly excludes build artifacts, dependencies, and generated directories from formatting. The addition of dist and build (beyond what's in .gitignore) is appropriate for Prettier.

magic-actions/programs/magic-actions/Cargo.toml (1)

20-22: Deps look aligned; confirm cross-SDK compatibility

anchor-lang 0.31.1 and ephemeral-rollups-sdk 0.3.4 with feature "anchor" are reasonable. Ensure the TS SDK version used in tests is compatible with the on-chain integration flow.

magic-actions/tests/magic-actions.ts (2)

197-205: Validate ER counter layout before reading

Assumes discriminator + u64 at offset 8. Consider an assertion guard to avoid misleading output if layout changes.

Optionally:

if (!counterAccountER || counterAccountER.data.length < 16) {
  counterER = "<Unavailable>";
} else {
  const countValue = counterAccountER.data.readBigUInt64LE(8);
  counterER = countValue.toString();
}

14-18: Use AnchorProvider.env() wallet, correct workspace import, and align accounts with IDL

  • At top of tests:
    const provider = anchor.AnchorProvider.env();
    anchor.setProvider(provider);
    const program = anchor.workspace.MagicActions as Program<MagicActions>;
    const wallet = provider.wallet;
  • Replace every anchor.Wallet.local().publicKey with wallet.publicKey and [anchor.Wallet.local().payer] with [wallet.payer].
  • Ensure your generated IDL types file (target/types/magic_actions.ts) is present and that account keys in each .accounts({…}) call exactly match your IDL’s field names so you can safely remove the @ts-ignore.
magic-actions/package.json (1)

7-12: No SDK bump needed: @magicblock-labs/ephemeral-rollups-sdk@0.2.11 already exports sendMagicTransaction, getClosestValidator, and getDelegationStatus.

magic-actions/programs/magic-actions/src/lib.rs (3)

75-116: Double-check escrow_index and account ordering for the CallHandler

Ensure escrow_index: 1 matches the actual index that Magic expects for the escrow in this commit-with-handler flow, and that the account ordering resolves to [escrow, escrow_auth, leaderboard, counter] at the destination program. A mismatch will cause the CPI to fail at runtime.


53-63: Hardcoded validator pubkey — confirm environment

The validator is hardcoded. Confirm it’s correct for your target cluster/environment or consider wiring it via config.


10-10: Verified program ID consistency
The declare_id! in lib.rs matches the magic_actions entry in Anchor.toml.

Comment thread magic-actions/Anchor.toml
Comment thread magic-actions/Cargo.toml
Comment on lines +7 to +14
[profile.release]
overflow-checks = true
lto = "fat"
codegen-units = 1
[profile.release.build-override]
opt-level = 3
incremental = false
codegen-units = 1
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Size-optimize the on-chain program (opt-level "s")

BPF programs usually require opt-level="s" to meet size limits. Current setup leaves the program at default opt-level=3 (build-override only affects deps).

Add a per-package override:

 [profile.release]
 overflow-checks = true
 lto = "fat"
 codegen-units = 1
 [profile.release.build-override]
 opt-level = 3
 incremental = false
 codegen-units = 1
+[# Optimize the program crate for BPF size]
+[profile.release.package."magic-actions"]
+opt-level = "s"

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

🤖 Prompt for AI Agents
In magic-actions/Cargo.toml around lines 7–14, the release profile currently
sets opt-level = 3 only via build-override (which only affects dependencies) so
the package itself remains at opt-level=3; add a per-package profile override to
set opt-level = "s" for this crate (e.g. add a
[profile.release.package."<crate-name>"] section with opt-level = "s", and keep
overflow-checks/lto/codegen-units as needed) so the on-chain BPF program is
size-optimized.

Comment thread magic-actions/debug-magic-router.js Outdated
@@ -0,0 +1 @@

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Empty file added; remove or implement minimal debug wrapper.

As-is, this is dead code and can confuse contributors. Either delete it or implement a lightweight debug router.

Option A — remove if unused:

  • Delete magic-actions/debug-magic-router.js.

Option B — implement a minimal JS debug wrapper (safe, no SDK internals assumed):

+// Debug wrapper around MagicRouter with basic call logging.
+// If the project is TS-first, prefer converting this file to .ts.
+import { MagicRouter } from "@magicblock-labs/ephemeral-rollups-sdk";
+
+export function createDebugMagicRouter({ connection, ...opts } = {}) {
+  const router = new MagicRouter({ connection, validatorDiscovery: true, ...opts });
+  return new Proxy(router, {
+    get(target, prop, receiver) {
+      const val = Reflect.get(target, prop, receiver);
+      if (typeof val === "function") {
+        return async (...args) => {
+          console.debug(`[MagicRouter] ${String(prop)}()`, { argsCount: args.length });
+          try {
+            const res = await val.apply(target, args);
+            console.debug(`[MagicRouter] ${String(prop)} OK`);
+            return res;
+          } catch (e) {
+            console.error(`[MagicRouter] ${String(prop)} ERROR`, e);
+            throw e;
+          }
+        };
+      }
+      return val;
+    },
+  });
+}

If the repo is TS-first, consider renaming to debug-magic-router.ts and adding types. Based on learnings

To verify usage and module type:


🏁 Script executed:

#!/bin/bash
# Is this file referenced anywhere?
rg -n -C2 'debug-magic-router' || echo "No references to debug-magic-router found."

# Check package.json module type to pick ESM (import) vs CJS (require)
rg -n '"type"\s*:\s*"module"' magic-actions/package.json || echo "No \"type\": \"module\" in magic-actions/package.json"

Length of output: 92


Remove unused debug-magic-router.js
Delete magic-actions/debug-magic-router.js — it’s empty and unreferenced.

🤖 Prompt for AI Agents
In magic-actions/debug-magic-router.js at lines 1 to 1 the file is empty and
unreferenced; remove the file from the repository and any import/require
references if present (ensure no code elsewhere depends on it), update the
package or build manifests if they list the file, and commit the deletion with a
clear message like "chore: remove unused debug-magic-router.js".

// Configure client to use the provider.
anchor.setProvider(provider);

// Add your deploy script here.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider implementing the deployment logic.

This placeholder comment suggests that deployment logic is missing. For a complete "magic actions" example, consider adding actual deployment steps such as:

  • Deploying the program
  • Initializing program state
  • Setting up any required accounts

Would you like me to help generate the deployment logic based on the program's requirements, or is this placeholder intentional for the example?

🤖 Prompt for AI Agents
In magic-actions/migrations/deploy.ts around line 11, the file currently
contains only a placeholder comment and lacks actual deployment logic; replace
the comment with a deploy script that (1) builds and deploys the program
artifact (invoke the project build and on-chain deploy commands appropriate for
your stack), (2) initializes required on-chain state by sending the
initialization transaction(s) to the program, and (3) creates and funds any
required accounts/PDAs and sets initial configuration; ensure the script accepts
environment/config inputs (RPC URL, keypair, program id), awaits and checks
transaction confirmations, logs actions and errors, and exits non‑zero on
failure.

Comment on lines +1 to +6
{
"license": "ISC",
"scripts": {
"lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w",
"lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check"
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Document Node runtime requirement

Anchor TS and web3.js expect a modern Node. Add engines for clarity.

Apply:

 {
   "license": "ISC",
+  "engines": {
+    "node": ">=18.18"
+  },
   "scripts": {
📝 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
{
"license": "ISC",
"scripts": {
"lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w",
"lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check"
},
{
"license": "ISC",
"engines": {
"node": ">=18.18"
},
"scripts": {
"lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w",
"lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check"
},
🤖 Prompt for AI Agents
magic-actions/package.json lines 1-6: package.json should declare the required
Node runtime—add an "engines" field specifying a modern Node version (e.g.,
"node": ">=18") to communicate runtime requirements for Anchor TS and web3.js;
update the file by inserting the "engines" object at the top level (optionally
add "npm" or "pnpm" versions if needed) and ensure package.json remains valid
JSON.

Comment thread magic-actions/README.md Outdated
Comment thread magic-actions/tests/magic-actions.ts Outdated
Comment thread magic-actions/tests/magic-actions.ts Outdated
Comment thread magic-actions/tests/magic-actions.ts Outdated
Comment on lines +187 to +206
// Helper function to print the current value of the counter on base layer and ER.
async function printCounter(program: Program<MagicActions>, counter_pda: web3.PublicKey, leaderboard_pda: web3.PublicKey, routerConnection: web3.Connection, signature: string, message: string) {
console.log(message+" Signature: ", signature);
const delegationStatus = await getDelegationStatus(routerConnection, counter_pda);
const leaderboardAccount = await program.account.leaderboard.fetch(leaderboard_pda);

var counterER = "";
var counterBase = "";
var delegationStatusMsg = "";

if (delegationStatus.isDelegated) {
const counterAccountER = await routerConnection.getAccountInfo(counter_pda);
const countValue = counterAccountER?.data.readBigUInt64LE(8);
counterER = countValue?.toString() || "0";
counterBase = "<Delegated>";
delegationStatusMsg = "✅ Delegated";
} else {
counterER = "<Not Delegated>";
const counterAccount = await program.account.counter.fetch(counter_pda); // Fetchs on Devnet
counterBase = counterAccount.count.toNumber().toString();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Handle missing leaderboard gracefully in printCounter

If the leaderboard PDA isn’t initialized yet, fetch will throw and break the test (e.g., right after initialize). Add a safe fallback.

-  const leaderboardAccount = await program.account.leaderboard.fetch(leaderboard_pda);
+  let leaderboardAccount: any = null;
+  try {
+    leaderboardAccount = await program.account.leaderboard.fetch(leaderboard_pda);
+  } catch {
+    // Not initialized yet
+    leaderboardAccount = { highScore: new anchor.BN(0) };
+  }
🤖 Prompt for AI Agents
In magic-actions/tests/magic-actions.ts around lines 187 to 206, the call to
program.account.leaderboard.fetch(leaderboard_pda) will throw if the leaderboard
PDA is uninitialized and break the test; wrap the fetch in a try/catch (or use
program.account.leaderboard.fetchNullable if available) and provide a safe
fallback object (e.g., default values or null-checks) so printCounter can
continue when leaderboard is missing, logging or displaying a placeholder like
"<Uninitialized>" instead of crashing.

Comment on lines +3 to +8
"types": ["mocha", "chai"],
"typeRoots": ["./node_modules/@types"],
"lib": ["es2015"],
"module": "commonjs",
"target": "es6",
"esModuleInterop": true
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Update TS target/libs for BigInt + Node ergonomics

Tests use Buffer.readBigUInt64LE (BigInt). Bump target/libs and add module resolution to avoid type friction.

Apply:

   "compilerOptions": {
-    "types": ["mocha", "chai"],
-    "typeRoots": ["./node_modules/@types"],
-    "lib": ["es2015"],
-    "module": "commonjs",
-    "target": "es6",
-    "esModuleInterop": true
+    "types": ["mocha", "chai"],
+    "typeRoots": ["./node_modules/@types"],
+    "lib": ["es2020"],
+    "module": "commonjs",
+    "target": "es2020",
+    "moduleResolution": "node",
+    "skipLibCheck": true,
+    "esModuleInterop": true
   }
📝 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
"types": ["mocha", "chai"],
"typeRoots": ["./node_modules/@types"],
"lib": ["es2015"],
"module": "commonjs",
"target": "es6",
"esModuleInterop": true
"compilerOptions": {
"types": ["mocha", "chai"],
"typeRoots": ["./node_modules/@types"],
"lib": ["es2020"],
"module": "commonjs",
"target": "es2020",
"moduleResolution": "node",
"skipLibCheck": true,
"esModuleInterop": true
}
🤖 Prompt for AI Agents
In magic-actions/tsconfig.json around lines 3 to 8, TypeScript libs/target are
too old for BigInt and Node APIs and module resolution isn't set; update
"target" to at least "ES2020" (or ES2021), expand "lib" to include BigInt
support (e.g. "es2020.bigint" and "es2020"), and add "moduleResolution": "node"
to the compilerOptions to avoid type resolution friction with Node modules.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 8

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c7d6e88 and 955b8e8.

⛔ Files ignored due to path filters (3)
  • magic-actions/Cargo.lock is excluded by !**/*.lock
  • magic-actions/package-lock.json is excluded by !**/package-lock.json
  • magic-actions/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (12)
  • magic-actions/.gitignore (1 hunks)
  • magic-actions/.prettierignore (1 hunks)
  • magic-actions/Anchor.toml (1 hunks)
  • magic-actions/Cargo.toml (1 hunks)
  • magic-actions/README.md (1 hunks)
  • magic-actions/migrations/deploy.ts (1 hunks)
  • magic-actions/package.json (1 hunks)
  • magic-actions/programs/magic-actions/Cargo.toml (1 hunks)
  • magic-actions/programs/magic-actions/Xargo.toml (1 hunks)
  • magic-actions/programs/magic-actions/src/lib.rs (1 hunks)
  • magic-actions/tests/magic-actions.ts (1 hunks)
  • magic-actions/tsconfig.json (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
magic-actions/programs/magic-actions/src/lib.rs (1)
anchor-counter/programs/anchor-counter/src/lib.rs (1)
  • commit (64-72)
🪛 LanguageTool
magic-actions/README.md

[grammar] ~1-~1: Use correct spacing
Context: # ✨ Magic Actions Demonstrates using Magic Actions to exec...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~3-~3: Use correct spacing
Context: ...rom Ephemeral Rollups to the base layer. ## Software Packages This program has util...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~5-~5: Use correct spacing
Context: ...to the base layer. ## Software Packages This program has utilized the following ...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~7-~7: Ensure spelling is correct
Context: ...This program has utilized the following sofware packages. | Software | Version | Ins...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~7-~7: Use correct spacing
Context: ...utilized the following sofware packages. | Software | Version | Installation Gu...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~9-~9: There might be a mistake here.
Context: ... | | ---------- | ------- | ---------------...

(QB_NEW_EN)


[grammar] ~10-~10: There might be a mistake here.
Context: ...-------------------------------------- | | Solana | 2.1.21 | [Install Solana...

(QB_NEW_EN)


[grammar] ~11-~11: There might be a mistake here.
Context: ...docs.anza.xyz/cli/install) | | Rust | 1.82 | [Install Rust](...

(QB_NEW_EN)


[grammar] ~12-~12: There might be a mistake here.
Context: ...w.rust-lang.org/tools/install) | | Anchor | 0.31.1 | [Install Anchor...

(QB_NEW_EN)


[grammar] ~13-~13: There might be a mistake here.
Context: ...www.anchor-lang.com/docs/installation) | | Node | 22.17.0 | [Install Node](...

(QB_NEW_EN)


[grammar] ~14-~14: Use correct spacing
Context: ...dejs.org/en/download/current) | sh # Check and initialize your Solana version agave-install list agave-install init 2.1.21 # Check and initialize your Rust version rustup show rustup install 1.82 # Check and initialize your Anchor version avm list avm use 0.31.1 ## Build and Test Run the tests with exist...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~30-~30: Use correct spacing
Context: ...st avm use 0.31.1 ``` ## Build and Test Run the tests with existing program: ``...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~32-~32: There might be a mistake here.
Context: ...1 ## Build and Test Run the tests with existing program: bash anchor test ...

(QB_NEW_EN)


[grammar] ~32-~32: Use correct spacing
Context: ...st Run the tests with existing program: bash anchor test --skip-deploy --skip-build --skip-local-validator Build, deploy and run the tests with new...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~38-~38: There might be a mistake here.
Context: ...uild --skip-local-validator ``` Build, deploy and run the tests with new program (not...

(QB_NEW_EN_OTHER)


[grammar] ~38-~38: There might be a mistake here.
Context: ...or ``` Build, deploy and run the tests with new program (note: delete keypairs in `...

(QB_NEW_EN)


[grammar] ~38-~38: Use articles correctly
Context: ...with new program (note: delete keypairs in /target/deploy folder): ```bash # De...

(QB_NEW_EN_OTHER_ERROR_IDS_11)


[grammar] ~38-~38: Use correct spacing
Context: ...te keypairs in /target/deploy folder): bash # Delete keypairs in the deploy folder rm -rf /target/deploy/*.keypair # Build, deploy and test program anchor test

(QB_NEW_EN_OTHER_ERROR_IDS_5)

🔇 Additional comments (11)
magic-actions/programs/magic-actions/Xargo.toml (1)

1-2: LGTM!

Standard Xargo configuration for Solana BPF programs. The empty features list correctly ensures the program builds in a no-std environment.

magic-actions/.prettierignore (1)

1-7: LGTM!

Standard Prettier ignore patterns for an Anchor project. Appropriately excludes build artifacts, dependencies, and generated files from formatting.

magic-actions/.gitignore (1)

1-7: LGTM!

Standard ignore patterns for an Anchor/Rust project. Appropriately excludes build artifacts, dependencies, backup files, and generated test ledgers from version control.

magic-actions/Cargo.toml (1)

1-14: LGTM!

Standard Cargo workspace configuration for Solana programs with appropriate release profile optimizations:

  • LTO and single codegen unit maximize size optimization for BPF deployment
  • Overflow checks enabled for runtime safety
  • Resolver 2 is the current standard
magic-actions/tsconfig.json (1)

1-10: LGTM!

Standard TypeScript configuration for Mocha/Chai testing. The CommonJS module system with ES6 target and esModuleInterop is appropriate for the Node.js test environment.

magic-actions/Anchor.toml (3)

14-16: Verify the cluster configuration aligns with testing intentions.

The [provider] section specifies cluster = "devnet", but the program is defined under [programs.localnet]. This configuration will cause tests to execute against devnet rather than a local validator.

If local testing is intended, change line 15 to:

-cluster = "devnet"
+cluster = "localnet"

If devnet testing is intentional, consider renaming the program section to [programs.devnet] for clarity.


19-19: Verify the test timeout is intentional.

The test timeout is set to 1,000,000ms (approximately 16.7 minutes), which is unusually high. While this may be intentional for long-running integration tests, such a high timeout can mask hanging tests or performance issues.

Consider whether a lower timeout (e.g., 60000-300000ms) would be more appropriate, or document why such a long timeout is necessary.


8-9: Document or regenerate the hardcoded program ID.

The program ID 27bYc6G5sNWxKGwj7A9cgKwLp3kfkWbViKT9M4JZXCxw is hardcoded for localnet. Ensure this matches the keypair generated for local development, or document that developers should regenerate this with anchor keys list after running anchor build.

magic-actions/package.json (1)

7-12: LGTM! Version strategy aligns with best practices.

The dependency versions are up-to-date and the pinning strategy is appropriate:

  • @coral-xyz/anchor@^0.31.1: Latest stable Anchor release
  • @magicblock-labs/ephemeral-rollups-sdk@0.2.11: Correctly pinned without caret since the API surface can change between 0.2.x releases
  • @solana/web3.js@^1.98.2: Latest web3.js with Agave v2 RPC compatibility

Based on learnings.

magic-actions/migrations/deploy.ts (1)

1-12: LGTM!

Standard Anchor migration script template. The placeholder structure correctly configures the provider and includes clear guidance for adding deployment logic.

magic-actions/programs/magic-actions/src/lib.rs (1)

108-111: Field name: confirm SDK expects commited_accounts

Some SDKs use committed_accounts (double “t”). Verify to avoid a build-time error.

If needed:

-            magic_action: MagicAction::Commit(CommitType::WithHandler {
-                commited_accounts: vec![ctx.accounts.counter.to_account_info()],
+            magic_action: MagicAction::Commit(CommitType::WithHandler {
+                committed_accounts: vec![ctx.accounts.counter.to_account_info()],
                 call_handlers: vec![call_handler],
             }),

Comment on lines +1 to +2
{
"license": "ISC",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider adding package name and version fields.

While not critical for internal projects, adding name, version, and description fields would make this a more complete package manifest and avoid potential tooling warnings.

🤖 Prompt for AI Agents
In magic-actions/package.json around lines 1 to 2, the manifest is missing
standard fields; add "name" (a valid npm package name), "version" (semver, e.g.
"0.1.0"), and a short "description" to make the package.json complete and avoid
tooling warnings; keep the existing "license" field and, if this is not meant to
be published, consider adding "private": true instead of a publishable name.

Comment on lines +20 to +22
[dependencies]
anchor-lang = { version = "0.31.1", features = ["init-if-needed"] }
ephemeral-rollups-sdk = { version = "0.3.4", features = ["anchor"] } No newline at end of file
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Anchor pin looks good; verify ER SDK version alignment

Anchor 0.31.1 is correct. Ensure TS dependency @magicblock-labs/ephemeral-rollups-sdk matches Rust crate 0.3.x to avoid API drift.

Run to confirm TS package version:


🏁 Script executed:

#!/bin/bash
# Check all package.json files for the SDK version
fd -a package.json | while read -r f; do
  echo "==> $f"
  rg -n '@magicblock-labs/ephemeral-rollups-sdk' -n -C1 "$f"
done

Length of output: 988


Sync TS SDK version with Rust crate
Rust crate uses ephemeral-rollups-sdk 0.3.4; update all @magicblock-labs/ephemeral-rollups-sdk entries in your package.json files (currently ^0.2.x) to ^0.3.x to avoid API drift.

Comment on lines +1 to +9
use anchor_lang::prelude::*;
use ephemeral_rollups_sdk::anchor::{commit, delegate, ephemeral};
use ephemeral_rollups_sdk::cpi::DelegateConfig;
use ephemeral_rollups_sdk::ephem::commit_and_undelegate_accounts;
use ephemeral_rollups_sdk::ephem::{MagicInstructionBuilder, MagicAction, CallHandler, CommitType};
use ephemeral_rollups_sdk::{ActionArgs, ShortAccountMeta};
use anchor_lang::Discriminator;
use ephemeral_rollups_sdk::consts::EXTERNAL_CALL_HANDLER_DISCRIMINATOR;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Remove unused import

anchor_lang::Discriminator isn’t used.

-use anchor_lang::Discriminator;
📝 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
use anchor_lang::prelude::*;
use ephemeral_rollups_sdk::anchor::{commit, delegate, ephemeral};
use ephemeral_rollups_sdk::cpi::DelegateConfig;
use ephemeral_rollups_sdk::ephem::commit_and_undelegate_accounts;
use ephemeral_rollups_sdk::ephem::{MagicInstructionBuilder, MagicAction, CallHandler, CommitType};
use ephemeral_rollups_sdk::{ActionArgs, ShortAccountMeta};
use anchor_lang::Discriminator;
use ephemeral_rollups_sdk::consts::EXTERNAL_CALL_HANDLER_DISCRIMINATOR;
use anchor_lang::prelude::*;
use ephemeral_rollups_sdk::anchor::{commit, delegate, ephemeral};
use ephemeral_rollups_sdk::cpi::DelegateConfig;
use ephemeral_rollups_sdk::ephem::commit_and_undelegate_accounts;
use ephemeral_rollups_sdk::ephem::{MagicInstructionBuilder, MagicAction, CallHandler, CommitType};
use ephemeral_rollups_sdk::{ActionArgs, ShortAccountMeta};
use ephemeral_rollups_sdk::consts::EXTERNAL_CALL_HANDLER_DISCRIMINATOR;
🤖 Prompt for AI Agents
In magic-actions/programs/magic-actions/src/lib.rs around lines 1 to 9, the
import anchor_lang::Discriminator is unused; remove that import from the use
list to eliminate the unused import warning and keep imports minimal.

Comment on lines +53 to +63
pub fn delegate(ctx: Context<DelegateCounter>) -> Result<()> {
ctx.accounts.delegate_pda(
&ctx.accounts.payer,
&[TEST_PDA_SEED],
DelegateConfig {
commit_frequency_ms: 30_000,
validator: Some(pubkey!("MAS1Dt9qreoRMQ14YQuhg8UTZMMzDdKhmkZMECCzk57")),
},
)?;
Ok(())
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Avoid hard-coding validator

Hard-coding a validator can stale-break on different environments. Consider validator: None to auto-select or pass it via accounts/args.

-            DelegateConfig {
-                commit_frequency_ms: 30_000,
-                validator: Some(pubkey!("MAS1Dt9qreoRMQ14YQuhg8UTZMMzDdKhmkZMECCzk57")),
-            },
+            DelegateConfig {
+                commit_frequency_ms: 30_000,
+                validator: None,
+            },
📝 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
pub fn delegate(ctx: Context<DelegateCounter>) -> Result<()> {
ctx.accounts.delegate_pda(
&ctx.accounts.payer,
&[TEST_PDA_SEED],
DelegateConfig {
commit_frequency_ms: 30_000,
validator: Some(pubkey!("MAS1Dt9qreoRMQ14YQuhg8UTZMMzDdKhmkZMECCzk57")),
},
)?;
Ok(())
}
pub fn delegate(ctx: Context<DelegateCounter>) -> Result<()> {
ctx.accounts.delegate_pda(
&ctx.accounts.payer,
&[TEST_PDA_SEED],
DelegateConfig {
commit_frequency_ms: 30_000,
validator: None,
},
)?;
Ok(())
}
🤖 Prompt for AI Agents
In magic-actions/programs/magic-actions/src/lib.rs around lines 53 to 63, the
DelegateConfig currently hard-codes a validator pubkey which can break across
environments; change the delegate call to use validator: None to allow
auto-selection, or modify the function signature/accounts to accept a validator
Pubkey arg and pass that value through to DelegateConfig.validator, updating
callers/tests to supply the pubkey when needed and keeping existing behavior for
None.

Comment on lines +137 to +147
pub struct UpdateLeaderboard<'info> {
#[account(mut)]
/// CHECK: the correct pda - this will be moved to the end in the future, meaning you can omit this unless needed
pub escrow: UncheckedAccount<'info>,
/// CHECK: the correct pda - this will be moved to the end in the future, meaning you can omit this unless needed
pub escrow_auth: UncheckedAccount<'info>,
#[account(mut, seeds = [LEADERBOARD_SEED], bump)]
pub leaderboard: Account<'info, Leaderboard>,
/// CHECK: Your program ID
pub counter: UncheckedAccount<'info>,
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Harden UpdateLeaderboard: constrain the counter PDA

Counter is Unchecked without seeds; an attacker could pass a different account. Add seeds (and optionally owner) to bind it to your PDA.

 pub struct UpdateLeaderboard<'info> {
     #[account(mut)]
     /// CHECK: the correct pda - this will be moved to the end in the future, meaning you can omit this unless needed
     pub escrow: UncheckedAccount<'info>,
     /// CHECK: the correct pda - this will be moved to the end in the future, meaning you can omit this unless needed
     pub escrow_auth: UncheckedAccount<'info>,
     #[account(mut, seeds = [LEADERBOARD_SEED], bump)]
     pub leaderboard: Account<'info, Leaderboard>,
-    /// CHECK: Your program ID
-    pub counter: UncheckedAccount<'info>,
+    /// CHECK: Verified by seeds; binds to the expected PDA
+    #[account(seeds = [TEST_PDA_SEED], bump)]
+    pub counter: UncheckedAccount<'info>,
 }

Optional: switch to a typed account to drop manual deserialization:

-    pub counter: UncheckedAccount<'info>,
+    pub counter: Account<'info, Counter>,

…and then in update_leaderboard use &ctx.accounts.counter directly. Based on learnings

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

Comment thread magic-actions/README.md Outdated
Comment on lines +7 to +15
This program has utilized the following sofware packages.

| Software | Version | Installation Guide |
| ---------- | ------- | --------------------------------------------------------------- |
| **Solana** | 2.1.21 | [Install Solana](https://docs.anza.xyz/cli/install) |
| **Rust** | 1.82 | [Install Rust](https://www.rust-lang.org/tools/install) |
| **Anchor** | 0.31.1 | [Install Anchor](https://www.anchor-lang.com/docs/installation) |
| **Node** | 22.17.0 | [Install Node](https://nodejs.org/en/download/current) |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Typos and missing Anchor install step

Fix spelling and add avm install for first-time setup.

-This program has utilized the following sofware packages.
+This program uses the following software packages.
 # Check and initialize your Anchor version
 avm list
+avm install 0.31.1
 avm use 0.31.1

Also applies to: 25-28

🧰 Tools
🪛 LanguageTool

[grammar] ~7-~7: Ensure spelling is correct
Context: ...This program has utilized the following sofware packages. | Software | Version | Ins...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~7-~7: Use correct spacing
Context: ...utilized the following sofware packages. | Software | Version | Installation Gu...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~9-~9: There might be a mistake here.
Context: ... | | ---------- | ------- | ---------------...

(QB_NEW_EN)


[grammar] ~10-~10: There might be a mistake here.
Context: ...-------------------------------------- | | Solana | 2.1.21 | [Install Solana...

(QB_NEW_EN)


[grammar] ~11-~11: There might be a mistake here.
Context: ...docs.anza.xyz/cli/install) | | Rust | 1.82 | [Install Rust](...

(QB_NEW_EN)


[grammar] ~12-~12: There might be a mistake here.
Context: ...w.rust-lang.org/tools/install) | | Anchor | 0.31.1 | [Install Anchor...

(QB_NEW_EN)


[grammar] ~13-~13: There might be a mistake here.
Context: ...www.anchor-lang.com/docs/installation) | | Node | 22.17.0 | [Install Node](...

(QB_NEW_EN)


[grammar] ~14-~14: Use correct spacing
Context: ...dejs.org/en/download/current) | sh # Check and initialize your Solana version agave-install list agave-install init 2.1.21 # Check and initialize your Rust version rustup show rustup install 1.82 # Check and initialize your Anchor version avm list avm use 0.31.1 ## Build and Test Run the tests with exist...

(QB_NEW_EN_OTHER_ERROR_IDS_5)

🤖 Prompt for AI Agents
In magic-actions/README.md around lines 7 to 15 (and also apply same fix to
lines 25 to 28), correct the typo "sofware" to "software" and update the Anchor
installation guidance to include the first-time AVM setup step by instructing
users to run "avm install" (or equivalent AVM initialization) before installing
Anchor; keep the table formatting intact and ensure the Anchor Installation
Guide cell now mentions the additional "avm install" step for first-time setup.

Comment thread magic-actions/README.md
Comment on lines +41 to +46
# Delete keypairs in the deploy folder
rm -rf /target/deploy/*.keypair

# Build, deploy and test program
anchor test
```
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Dangerous absolute path and wrong keypair extension in rm command

Using /target/deploy/*.keypair can target the filesystem root; Anchor keys are .json. Fix to a safe, relative path.

Apply:

-# Delete keypairs in the deploy folder
-rm -rf /target/deploy/*.keypair
+# Delete local deploy keypairs (safe, relative)
+rm -f target/deploy/*.json
📝 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
# Delete keypairs in the deploy folder
rm -rf /target/deploy/*.keypair
# Build, deploy and test program
anchor test
```
# Delete local deploy keypairs (safe, relative)
rm -f target/deploy/*.json
# Build, deploy and test program
anchor test
🤖 Prompt for AI Agents
In magic-actions/README.md around lines 41 to 46, the remove command uses an
absolute path and the wrong extension; replace the dangerous
"/target/deploy/*.keypair" with a safe, relative path to the repo (e.g.
"./target/deploy") and the correct Anchor key extension ".json"; also avoid
using recursive "-r" on a file glob (use "-f" only) or, even safer, use a
targeted delete via find (e.g. find ./target/deploy -maxdepth 1 -name '*.json'
-delete) so only JSON keypair files in the local deploy folder are removed.

Comment on lines +17 to +18
const program = anchor.workspace.magicActions as Program<MagicActions>;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix program reference and missing accounts; tests will fail as written

  • Use workspace.MagicActions (case-sensitive).
  • Provide all required accounts per IDL:
    • initialize: add leaderboard
    • updateLeaderboard: add leaderboard
    • commitAndUpdateLeaderboard: add counter, leaderboard
    • undelegate: add counter

Apply:

-  const program = anchor.workspace.magicActions as Program<MagicActions>;
+  const program = anchor.workspace.MagicActions as Program<MagicActions>;
       .accounts({
-        // @ts-ignore
         counter: pda,
+        leaderboard: leaderboard_pda,
         user: anchor.Wallet.local().publicKey,
         systemProgram: anchor.web3.SystemProgram.programId,
       })
       .accounts({
-        escrow: leaderboard_pda, // unused - filler account
-        escrowAuth: leaderboard_pda, // unused - filler account
+        escrow: leaderboard_pda,      // filler
+        escrowAuth: leaderboard_pda,  // filler
+        leaderboard: leaderboard_pda,
         counter: pda,
       })
       .accounts({
         payer: anchor.Wallet.local().publicKey,
-        programId: program.programId,
+        programId: program.programId,
+        counter: pda,
+        leaderboard: leaderboard_pda,
       })
       .accounts({
         payer: anchor.Wallet.local().publicKey,
+        counter: pda,
       })

Also applies to: 51-66, 85-101, 144-167, 170-184

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

♻️ Duplicate comments (3)
magic-actions/README.md (1)

7-7: Fix typo: "sofware" → "software".

Apply this diff:

-This program has utilized the following sofware packages.
+This program has utilized the following software packages.
magic-actions/tests/magic-actions.ts (2)

5-7: Clean up unused imports.

The imports getLatestBlockhashForMagicTransaction and PublicKey are not used in the test file.

Apply this diff:

-import {
-  getDelegationStatus, DELEGATION_PROGRAM_ID, getClosestValidator, sendMagicTransaction, getLatestBlockhashForMagicTransaction
-} from "@magicblock-labs/ephemeral-rollups-sdk";
+import {
+  getDelegationStatus, DELEGATION_PROGRAM_ID, getClosestValidator, sendMagicTransaction
+} from "@magicblock-labs/ephemeral-rollups-sdk";
-import { PublicKey, Transaction } from "@solana/web3.js";
+import { Transaction } from "@solana/web3.js";

173-173: Handle missing leaderboard gracefully in printCounter.

If the leaderboard PDA isn't initialized yet, fetch will throw and break the test. Add error handling:

-  const leaderboardAccount = await program.account.leaderboard.fetch(leaderboard_pda);
+  let leaderboardAccount: any = null;
+  try {
+    leaderboardAccount = await program.account.leaderboard.fetch(leaderboard_pda);
+  } catch {
+    // Not initialized yet
+    leaderboardAccount = { highScore: new anchor.BN(0) };
+  }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e6a3ce9 and daa2df2.

📒 Files selected for processing (2)
  • magic-actions/README.md (1 hunks)
  • magic-actions/tests/magic-actions.ts (1 hunks)
🧰 Additional context used
🪛 LanguageTool
magic-actions/README.md

[grammar] ~1-~1: Use correct spacing
Context: # ✨ Magic Actions Demonstrates using Magic Actions to exec...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~3-~3: Use correct spacing
Context: ...rom Ephemeral Rollups to the base layer. ## Software Packages This program has util...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~5-~5: Use correct spacing
Context: ...to the base layer. ## Software Packages This program has utilized the following ...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~7-~7: Ensure spelling is correct
Context: ...This program has utilized the following sofware packages. | Software | Version | Ins...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~7-~7: Use correct spacing
Context: ...utilized the following sofware packages. | Software | Version | Installation Gu...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~9-~9: There might be a mistake here.
Context: ... | | ---------- | ------- | ---------------...

(QB_NEW_EN)


[grammar] ~10-~10: There might be a mistake here.
Context: ...-------------------------------------- | | Solana | 2.1.21 | [Install Solana...

(QB_NEW_EN)


[grammar] ~11-~11: There might be a mistake here.
Context: ...docs.anza.xyz/cli/install) | | Rust | 1.82 | [Install Rust](...

(QB_NEW_EN)


[grammar] ~12-~12: There might be a mistake here.
Context: ...w.rust-lang.org/tools/install) | | Anchor | 0.31.1 | [Install Anchor...

(QB_NEW_EN)


[grammar] ~13-~13: There might be a mistake here.
Context: ...www.anchor-lang.com/docs/installation) | | Node | 22.17.0 | [Install Node](...

(QB_NEW_EN)


[grammar] ~14-~14: Use correct spacing
Context: ...dejs.org/en/download/current) | sh # Check and initialize your Solana version agave-install list agave-install init 2.1.21 # Check and initialize your Rust version rustup show rustup install 1.82 # Check and initialize your Anchor version avm list avm use 0.31.1 ## Build and Test Run the tests with exist...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~30-~30: Use correct spacing
Context: ...st avm use 0.31.1 ``` ## Build and Test Run the tests with existing program: ``...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~32-~32: There might be a mistake here.
Context: ...1 ## Build and Test Run the tests with existing program: bash anchor test ...

(QB_NEW_EN)


[grammar] ~32-~32: Use correct spacing
Context: ...st Run the tests with existing program: bash anchor test --skip-deploy --skip-build --skip-local-validator Build, deploy and run the tests with new...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~38-~38: There might be a mistake here.
Context: ...uild --skip-local-validator ``` Build, deploy and run the tests with new program (not...

(QB_NEW_EN_OTHER)


[grammar] ~38-~38: There might be a mistake here.
Context: ...or ``` Build, deploy and run the tests with new program (note: delete keypairs in `...

(QB_NEW_EN)


[grammar] ~38-~38: Use articles correctly
Context: ...with new program (note: delete keypairs in /target/deploy folder): ```bash # De...

(QB_NEW_EN_OTHER_ERROR_IDS_11)


[grammar] ~38-~38: Use correct spacing
Context: ...te keypairs in /target/deploy folder): bash # Delete keypairs in the deploy folder rm -rf /target/deploy/*.keypair # Build, deploy and test program anchor test

(QB_NEW_EN_OTHER_ERROR_IDS_5)

🔇 Additional comments (1)
magic-actions/tests/magic-actions.ts (1)

78-79: No changes required for escrow accounts
escrow and escrow_auth are defined as UncheckedAccount fields in the UpdateLeaderboard context but aren’t referenced in the handler. Supplying leaderboard_pda as a dummy value in tests satisfies the Anchor context requirements.

Comment thread magic-actions/README.md

```bash
# Delete keypairs in the deploy folder
rm -rf /target/deploy/*.keypair
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Correct the path to be relative to the repository root.

The path /target/deploy/*.keypair uses an absolute path starting with /, but should be relative to the project root. This will fail on most systems since /target would refer to the filesystem root.

Apply this diff:

-rm -rf /target/deploy/*.keypair
+rm -rf target/deploy/*.keypair
📝 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
rm -rf /target/deploy/*.keypair
rm -rf target/deploy/*.keypair
🤖 Prompt for AI Agents
In magic-actions/README.md around line 42, the cleanup command uses an absolute
path (/target/deploy/*.keypair) which should be relative to the repository root;
change it to target/deploy/*.keypair (remove the leading slash) so the command
operates on the repo's target directory rather than the filesystem root, and
update any surrounding instructions/examples in the README to match this
relative path.

Comment on lines +40 to +167
it("Initialize Counter!", async () => {
const tx = await program.methods
.initialize()
.accounts({
// @ts-ignore
counter: pda,
user: anchor.Wallet.local().publicKey,
systemProgram: anchor.web3.SystemProgram.programId,
})
.transaction() as Transaction;
const signature = await sendMagicTransaction(
routerConnection,
tx,
[anchor.Wallet.local().payer]
);
await printCounter(program, pda, leaderboard_pda, routerConnection, signature, "✅ Initialized Counter PDA!");
});

it("Increment Counter!", async () => {
const tx = await program.methods
.increment()
.accounts({
counter: pda,
})
.transaction() as Transaction;

const signature = await sendMagicTransaction(
routerConnection,
tx,
[anchor.Wallet.local().payer]
);
console.log("✅ Incremented Counter PDA! Signature:", signature);
});

it("Update Leaderboard!", async () => {
const tx = await program.methods
.updateLeaderboard()
.accounts({
escrow: leaderboard_pda, // unused - filler account
escrowAuth: leaderboard_pda, // unused - filler account
counter: pda,
})
.transaction();

const signature = await sendMagicTransaction(
routerConnection,
tx,
[anchor.Wallet.local().payer]
);

await printCounter(program, pda, leaderboard_pda, routerConnection, signature, "✅ Updated Leaderboard!");
});

it("Delegate Counter to ER!", async () => {
const validatorKey = await getClosestValidator(routerConnection);
console.log("Delegating to closest validator: ", validatorKey.toString());

const tx = await program.methods
.delegate()
.accounts({
payer: anchor.Wallet.local().publicKey,
pda: pda,
})
.transaction();

const signature = await sendMagicTransaction(
routerConnection,
tx,
[anchor.Wallet.local().payer]
);

await sleepWithAnimation(10); // ensure the delegation is processed
console.log("✅ Delegated Counter PDA! Signature:", signature);
});


it("Increment Counter on ER!", async () => {
const tx = await program.methods
.increment()
.accounts({
counter: pda,
})
.transaction();

const signature = await sendMagicTransaction(
routerConnection,
tx,
[anchor.Wallet.local().payer]
);

await printCounter(program, pda, leaderboard_pda, routerConnection, signature, "✅ Incremented Counter PDA!");
});

it("Update Leaderboard While Delegated!", async () => {
const tx = await program.methods
.commitAndUpdateLeaderboard()
.accounts({
payer: anchor.Wallet.local().publicKey,
programId: program.programId,
})
.transaction();

const signature = await sendMagicTransaction(
routerConnection,
tx,
[anchor.Wallet.local().payer]
);

await sleepWithAnimation(5);
await printCounter(program, pda, leaderboard_pda, routerConnection, signature, "✅ Updated Leaderboard While Delegated!");
});

it("Undelegate Counter!", async () => {
const tx = await program.methods
.undelegate()
.accounts({
payer: anchor.Wallet.local().publicKey,
})
.transaction();

const signature = await sendMagicTransaction(
routerConnection,
tx,
[anchor.Wallet.local().payer]
);
await sleepWithAnimation(5);
await printCounter(program, pda, leaderboard_pda, routerConnection, signature, "✅ Undelegated Counter PDA!");
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Add actual assertions to verify test outcomes.

The test suite only logs output without asserting expected behavior. This means tests will pass even if the program logic is incorrect.

Add assertions to verify the expected state after each operation. For example:

it("Increment Counter!", async () => {
  // Get initial count
  const beforeAccount = await program.account.counter.fetch(pda);
  const beforeCount = beforeAccount.count.toNumber();
  
  const tx = await program.methods
    .increment()
    .accounts({ counter: pda })
    .transaction() as Transaction;

  const signature = await sendMagicTransaction(
    routerConnection,
    tx,
    [anchor.Wallet.local().payer]
  );
  
  // Verify count increased
  const afterAccount = await program.account.counter.fetch(pda);
  const afterCount = afterAccount.count.toNumber();
  assert.equal(afterCount, beforeCount + 1, "Counter should increment by 1");
  
  console.log("✅ Incremented Counter PDA! Signature:", signature);
});

Apply similar patterns to other test cases to validate:

  • Initialize sets count to 0
  • Update Leaderboard correctly updates the high score
  • Delegation status changes as expected
  • Counter values persist across delegation/undelegation
🤖 Prompt for AI Agents
magic-actions/tests/magic-actions.ts lines 40-167: tests only log results and
lack assertions—add explicit checks after each operation using
program.account.counter.fetch(pda) (and leaderboard account fetch) to read
on-chain state and assert expected values: for Initialize assert count === 0,
for Increment assert count increased by 1 vs a captured before value, for Update
Leaderboard assert leaderboard/high-score fields updated accordingly, for
Delegate/Undelegate assert delegation-related account/state flags change as
expected, and across delegation verify counter value persisted; use a stable
assertion helper (e.g., assert.equal or expect) and fetch accounts after
sendMagicTransaction (and after any sleep) to validate results rather than just
logging.

const tx = await program.methods
.initialize()
.accounts({
// @ts-ignore
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Remove type suppression and fix the underlying type issue.

The @ts-ignore comment suppresses TypeScript's type checking. This is hiding a type mismatch that should be resolved properly. Anchor's .accounts() method expects properly typed account objects.

Apply this diff to remove the suppression:

       .accounts({
-        // @ts-ignore
         counter: pda,
         user: anchor.Wallet.local().publicKey,
         systemProgram: anchor.web3.SystemProgram.programId,
       })

If TypeScript reports an error after removing this, investigate the root cause. The accounts object should match the IDL-generated type for the initialize instruction. If there's a mismatch, verify that the IDL is up to date with the on-chain program or adjust the account keys accordingly.

📝 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
// @ts-ignore
.accounts({
counter: pda,
user: anchor.Wallet.local().publicKey,
systemProgram: anchor.web3.SystemProgram.programId,
})
🤖 Prompt for AI Agents
In magic-actions/tests/magic-actions.ts around line 44, remove the "//
@ts-ignore" and fix the underlying type mismatch by making the object passed to
the Anchor program's .accounts() call conform to the IDL-generated Initialize
instruction type: import and use the generated program types (or the
program.types namespace), ensure each property name and type matches the IDL
(e.g., PublicKey values for accounts, SystemProgram.programId where required),
or update the IDL if it is out of sync with on-chain; after removing the ignore,
adjust property names/types or add a narrow, safe cast using the generated
InitializeAccounts type only if the runtime shape is guaranteed to match.

[anchor.Wallet.local().payer]
);

await sleepWithAnimation(10); // ensure the delegation is processed
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Replace arbitrary sleep times with polling for deterministic tests.

Using fixed sleep durations (5 and 10 seconds) makes tests slower and potentially flaky. If the operation completes faster, tests wait unnecessarily. If it takes longer, tests may fail intermittently.

Replace sleepWithAnimation with polling that checks for the expected state:

async function waitForDelegation(
  connection: web3.Connection, 
  pda: web3.PublicKey, 
  expectedDelegated: boolean,
  maxAttempts = 20,
  delayMs = 500
): Promise<void> {
  for (let i = 0; i < maxAttempts; i++) {
    const status = await getDelegationStatus(connection, pda);
    if (status.isDelegated === expectedDelegated) {
      return;
    }
    await new Promise(resolve => setTimeout(resolve, delayMs));
  }
  throw new Error(`Delegation status did not reach expected state: ${expectedDelegated}`);
}

Then replace the sleep calls:

-  await sleepWithAnimation(10); // ensure the delegation is processed
+  await waitForDelegation(routerConnection, pda, true);

Also applies to: 148-148, 165-165

🤖 Prompt for AI Agents
In magic-actions/tests/magic-actions.ts around lines 111, 148 and 165, replace
the fixed sleepWithAnimation calls with a polling helper that queries the
on-chain delegation state until it matches the expected value (with sensible
maxAttempts and delayMs) to avoid flakiness and speed up tests; implement a
waitForDelegation(connection, pda, expectedDelegated, maxAttempts=20,
delayMs=500) that loops calling getDelegationStatus (or equivalent), returns
when status.isDelegated === expectedDelegated, and throws if it times out, then
call that helper in place of sleepWithAnimation at the three locations.


if (delegationStatus.isDelegated) {
const counterAccountER = await routerConnection.getAccountInfo(counter_pda);
const countValue = counterAccountER?.data.readBigUInt64LE(8);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Manual account data parsing is fragile and error-prone.

Using readBigUInt64LE(8) assumes a specific account layout with an 8-byte discriminator. This is fragile because:

  1. The offset could change if the account structure is modified
  2. It bypasses Anchor's type-safe deserialization
  3. It could read incorrect data if the discriminator size differs

Instead of manually parsing the account data, use the program's typed account fetch:

   if (delegationStatus.isDelegated) {
-    const counterAccountER = await routerConnection.getAccountInfo(counter_pda);
-    const countValue = counterAccountER?.data.readBigUInt64LE(8);
-    counterER = countValue?.toString() || "0";
+    try {
+      const counterAccountER = await program.account.counter.fetch(counter_pda);
+      counterER = counterAccountER.count.toNumber().toString();
+    } catch {
+      counterER = "0";
+    }
     counterBase = "<Delegated>";
     delegationStatusMsg = "✅ Delegated";

Note: This assumes program.account.counter.fetch() works with the router connection for delegated accounts. If not, you may need to create a separate program instance with the ER connection, or keep the manual parsing but add comments explaining the layout assumptions.

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

🤖 Prompt for AI Agents
In magic-actions/tests/magic-actions.ts around line 181 the code manually reads
the counter value via counterAccountER?.data.readBigUInt64LE(8), which is
brittle and bypasses Anchor's typed deserialization; replace this manual parsing
with the Anchor account fetch (e.g., program.account.counter.fetch(...) using
the program instance bound to the ER connection) so you get a typed object and
correct offsets, or if the router/ER connection prevents direct fetch,
instantiate a program tied to the ER connection and call its
account.counter.fetch, and only if neither is feasible keep manual parsing but
add a clear comment documenting the exact layout (discriminator size and field
offsets) and validate buffer length before reading.

@sporicle sporicle merged commit afdb8e8 into main Oct 14, 2025
1 of 2 checks passed
@sporicle sporicle deleted the magic-actions-example branch October 14, 2025 13:25
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (11)
magic-actions/README.md (2)

41-46: Fix dangerous absolute path and wrong key extension in cleanup.

Use a safe, relative path and correct .json extension; avoid -r on files.

-# Delete keypairs in the deploy folder
-rm -rf /target/deploy/*.keypair
+# Delete local deploy keypairs (safe, relative)
+rm -f target/deploy/*.json

Optionally even safer:

find target/deploy -maxdepth 1 -type f -name '*.json' -delete

25-28: Add first-time Anchor install step (avm install).

Running only avm use 0.31.1 fails if that version isn’t installed. Insert avm install 0.31.1 before avm use.

Based on learnings

 # Check and initialize your Anchor version
 avm list
+avm install 0.31.1
 avm use 0.31.1
magic-actions/tests/magic-actions.ts (9)

41-49: Remove @ts-ignore and pass all required accounts for initialize.

Type suppression hides a mismatch. Also include leaderboard if required by the IDL.

   const tx = await program.methods
     .initialize()
     .accounts({
-      // @ts-ignore
       counter: pda,
+      leaderboard: leaderboard_pda,
       user: anchor.Wallet.local().publicKey,
       systemProgram: anchor.web3.SystemProgram.programId,
     })
#!/bin/bash
# Print Initialize accounts from the generated IDL (if built)
jq -r '.instructions[] | select(.name=="initialize") | .accounts[].name' magic-actions/target/idl/magic_actions.json

75-83: Provide leaderboard in Update Leaderboard accounts.

Current call passes filler escrow/escrowAuth and omits leaderboard, likely failing at runtime.

   const tx = await program.methods
     .updateLeaderboard()
     .accounts({
-      escrow: leaderboard_pda, // unused - filler account
-      escrowAuth: leaderboard_pda, // unused - filler account
+      escrow: leaderboard_pda,      // if truly required
+      escrowAuth: leaderboard_pda,  // if truly required
+      leaderboard: leaderboard_pda,
       counter: pda,
     })
#!/bin/bash
# Verify required accounts for updateLeaderboard
jq -r '.instructions[] | select(.name=="updateLeaderboard") | .accounts[].name' magic-actions/target/idl/magic_actions.json

134-141: Missing PDAs for commitAndUpdateLeaderboard.

Add counter and leaderboard per IDL; otherwise the instruction will fail.

   const tx = await program.methods
     .commitAndUpdateLeaderboard()
     .accounts({
       payer: anchor.Wallet.local().publicKey,
       programId: program.programId,
+      counter: pda,
+      leaderboard: leaderboard_pda,
     })
     .transaction();
#!/bin/bash
jq -r '.instructions[] | select(.name=="commitAndUpdateLeaderboard") | .accounts[].name' magic-actions/target/idl/magic_actions.json

152-158: Undelegate likely needs the counter PDA.

Provide counter: pda to match the IDL.

   const tx = await program.methods
     .undelegate()
     .accounts({
       payer: anchor.Wallet.local().publicKey,
+      counter: pda,
     })
     .transaction();
#!/bin/bash
jq -r '.instructions[] | select(.name=="undelegate") | .accounts[].name' magic-actions/target/idl/magic_actions.json

111-111: Replace fixed sleeps with deterministic polling.

Sleeping is flaky and slow. Poll delegation status until it matches the expected state.

-    await sleepWithAnimation(10); // ensure the delegation is processed
+    await waitForDelegation(routerConnection, pda, true);
-      await sleepWithAnimation(5);
+      await waitForDelegation(routerConnection, pda, true);
-    await sleepWithAnimation(5);
+    await waitForDelegation(routerConnection, pda, false);

Add helper:

+async function waitForDelegation(
+  connection: web3.Connection,
+  pda: web3.PublicKey,
+  expectedDelegated: boolean,
+  maxAttempts = 20,
+  delayMs = 500
+): Promise<void> {
+  for (let i = 0; i < maxAttempts; i++) {
+    const status = await getDelegationStatus(connection, pda);
+    if (status.isDelegated === expectedDelegated) return;
+    await new Promise(r => setTimeout(r, delayMs));
+  }
+  throw new Error(`Delegation state did not reach ${expectedDelegated}`);
+}

Also applies to: 148-148, 165-165


58-72: Add assertions; logs alone won’t catch regressions.

Verify on-chain state after increment (and similar for other cases).

 it("Increment Counter!", async () => {
-  const tx = await program.methods
+  const before = (await program.account.counter.fetch(pda)).count.toNumber();
+  const tx = await program.methods
     .increment()
     .accounts({
       counter: pda,
     })
     .transaction() as Transaction;
 
   const signature = await sendMagicTransaction(
     routerConnection,
     tx,
     [anchor.Wallet.local().payer]
   );
-  console.log("✅ Incremented Counter PDA! Signature:", signature);
+  const after = (await program.account.counter.fetch(pda)).count.toNumber();
+  if (after !== before + 1) {
+    throw new Error(`Counter did not increment: before=${before}, after=${after}`);
+  }
+  console.log("✅ Incremented Counter PDA! Signature:", signature);
 });

Apply similar assertions to initialize, leaderboard updates, delegate/undelegate flows.


173-173: Handle missing leaderboard gracefully.

Fetch will throw if the account isn’t initialized; use fetchNullable or try/catch.

-  const leaderboardAccount = await program.account.leaderboard.fetch(leaderboard_pda);
+  const leaderboardAccount =
+    (await program.account.leaderboard.fetchNullable?.(leaderboard_pda)) ??
+    (await (async () => { try { return await program.account.leaderboard.fetch(leaderboard_pda); } catch { return { highScore: new anchor.BN(0) }; } })());

179-185: Avoid manual buffer parsing; use typed fetch or guard carefully.

Manual readBigUInt64LE(8) is brittle. Prefer Anchor deserialization against the ER connection, or at least validate buffer length.

-  if (delegationStatus.isDelegated) {
-    const counterAccountER = await routerConnection.getAccountInfo(counter_pda);
-    const countValue = counterAccountER?.data.readBigUInt64LE(8);
-    counterER = countValue?.toString() || "0";
+  if (delegationStatus.isDelegated) {
+    try {
+      // Option A: instantiate a Program bound to the ER connection and fetch typed account
+      const erProvider = new anchor.AnchorProvider(routerConnection, anchor.Wallet.local(), { commitment: "confirmed" });
+      const erProgram = new Program<MagicActions>(program.idl as any, program.programId, erProvider);
+      const erCounter = await erProgram.account.counter.fetch(counter_pda);
+      counterER = erCounter.count.toNumber().toString();
+    } catch {
+      // Fallback: raw buffer with checks
+      const info = await routerConnection.getAccountInfo(counter_pda);
+      const buf = info?.data;
+      counterER = buf && buf.length >= 16 ? buf.readBigUInt64LE(8).toString() : "0";
+    }
     counterBase = "<Delegated>";
     delegationStatusMsg = "✅ Delegated";

16-16: Fix program workspace identifier (case-sensitive).

Anchor exposes programs in workspace by PascalCase of the IDL name. Use MagicActions.

-  const program = anchor.workspace.magicActions as Program<MagicActions>;
+  const program = anchor.workspace.MagicActions as Program<MagicActions>;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between daa2df2 and 0434eb5.

📒 Files selected for processing (4)
  • README.md (1 hunks)
  • magic-actions/Anchor.toml (1 hunks)
  • magic-actions/README.md (1 hunks)
  • magic-actions/tests/magic-actions.ts (1 hunks)
🧰 Additional context used
🪛 LanguageTool
magic-actions/README.md

[grammar] ~1-~1: Use correct spacing
Context: # ✨ Magic Actions Demonstrates using Magic Actions to exec...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~3-~3: Use correct spacing
Context: ...rom Ephemeral Rollups to the base layer. ## Software Packages This program has util...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~5-~5: Use correct spacing
Context: ...to the base layer. ## Software Packages This program has utilized the following ...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~7-~7: Use correct spacing
Context: ...tilized the following software packages. | Software | Version | Installation Gu...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~9-~9: There might be a mistake here.
Context: ... | | ---------- | ------- | ---------------...

(QB_NEW_EN)


[grammar] ~10-~10: There might be a mistake here.
Context: ...-------------------------------------- | | Solana | 2.1.21 | [Install Solana...

(QB_NEW_EN)


[grammar] ~11-~11: There might be a mistake here.
Context: ...docs.anza.xyz/cli/install) | | Rust | 1.82 | [Install Rust](...

(QB_NEW_EN)


[grammar] ~12-~12: There might be a mistake here.
Context: ...w.rust-lang.org/tools/install) | | Anchor | 0.31.1 | [Install Anchor...

(QB_NEW_EN)


[grammar] ~13-~13: There might be a mistake here.
Context: ...www.anchor-lang.com/docs/installation) | | Node | 22.17.0 | [Install Node](...

(QB_NEW_EN)


[grammar] ~14-~14: Use correct spacing
Context: ...dejs.org/en/download/current) | sh # Check and initialize your Solana version agave-install list agave-install init 2.1.21 # Check and initialize your Rust version rustup show rustup install 1.82 # Check and initialize your Anchor version avm list avm use 0.31.1 ## Build and Test Run the tests with exist...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~30-~30: Use correct spacing
Context: ...st avm use 0.31.1 ``` ## Build and Test Run the tests with existing program: ``...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~32-~32: There might be a mistake here.
Context: ...1 ## Build and Test Run the tests with existing program: bash anchor test ...

(QB_NEW_EN)


[grammar] ~32-~32: Use correct spacing
Context: ...st Run the tests with existing program: bash anchor test --skip-deploy --skip-build --skip-local-validator Build, deploy and run the tests with new...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~38-~38: There might be a mistake here.
Context: ...uild --skip-local-validator ``` Build, deploy and run the tests with new program (not...

(QB_NEW_EN_OTHER)


[grammar] ~38-~38: There might be a mistake here.
Context: ...or ``` Build, deploy and run the tests with new program (note: delete keypairs in `...

(QB_NEW_EN)


[grammar] ~38-~38: Use articles correctly
Context: ...with new program (note: delete keypairs in /target/deploy folder): ```bash # De...

(QB_NEW_EN_OTHER_ERROR_IDS_11)


[grammar] ~38-~38: Use correct spacing
Context: ...te keypairs in /target/deploy folder): bash # Delete keypairs in the deploy folder rm -rf /target/deploy/*.keypair # Build, deploy and test program anchor test

(QB_NEW_EN_OTHER_ERROR_IDS_5)

README.md

[grammar] ~18-~18: Use correct spacing
Context: ... chain actions from an ephemeral rollup. ## 🚧 Under Testing 🚧 The Ephemeral Rollu...

(QB_NEW_EN_OTHER_ERROR_IDS_5)

🔇 Additional comments (3)
magic-actions/Anchor.toml (1)

1-22: Anchor config looks consistent (devnet mapping present).

Programs mapped for localnet and devnet; provider points to devnet; yarn set as package manager. LGTM.

magic-actions/tests/magic-actions.ts (2)

25-33: PDA seeds match on-chain definitions
Test constants SEED_TEST_PDA ("test-pda") and SEED_LEADERBOARD ("leaderboard") exactly mirror the program’s TEST_PDA_SEED and LEADERBOARD_SEED. No changes needed.


97-104: Confirm IDL account key for delegate
Unable to locate the IDL at magic-actions/target/idl. Please verify that your IDL’s delegate instruction expects an account named counter (not pda), and if so update the call to:

 .accounts({
   payer: anchor.Wallet.local().publicKey,
-  pda: pda,
+  counter: pda,
 })

Comment thread README.md
- [Rust Counter](./rust-counter/README.md) - A simple counter that can be incremented. Tests natively to delegate/undelegate accounts and run transactions.
- [Bolt Counter](./bolt-counter/README.md) - A simple counter that can be incremented. Tests use the bolt sdk to delegate/undelegate accounts and run transactions.
- [Dummy Token Transfer](./dummy-token-transfer/README.md) - A token transferer that can delegate and execute both on-chain and in the ephemeral rollup.
- [Magic Actions](./magic-actions/README.md) - Demonstrates using Magic Actions to execute base chain actions from an ephemeral rollup.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Trim trailing spaces; ensure a blank line before the next heading.

Minor formatting: remove any end-of-line double spaces after this list item to avoid Markdown spacing glitches; keep a single empty line before the following "Under Testing" section.

🧰 Tools
🪛 LanguageTool

[grammar] ~18-~18: Use correct spacing
Context: ... chain actions from an ephemeral rollup. ## 🚧 Under Testing 🚧 The Ephemeral Rollu...

(QB_NEW_EN_OTHER_ERROR_IDS_5)

🤖 Prompt for AI Agents
In README.md around line 18, the list item contains trailing double spaces and
is immediately followed by the next heading; remove the trailing spaces at the
end of the Magic Actions line and ensure there is exactly one blank line between
this list and the following "Under Testing" heading so the Markdown renders
correctly.

@coderabbitai coderabbitai Bot mentioned this pull request Jan 19, 2026
jonasXchen pushed a commit that referenced this pull request Apr 16, 2026
* wip

* working state pre actions

* wip

* wip

* wip

* wip

* wip

* wip

* v1

* update README

* cleanup

* nits

* update top level readme
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant