Skip to content

feat: anchor ephemeral permission#84

Merged
Dodecahedr0x merged 15 commits into
mainfrom
dode/ephemeral-permission-rust
May 18, 2026
Merged

feat: anchor ephemeral permission#84
Dodecahedr0x merged 15 commits into
mainfrom
dode/ephemeral-permission-rust

Conversation

@Dodecahedr0x
Copy link
Copy Markdown
Contributor

@Dodecahedr0x Dodecahedr0x commented May 18, 2026

Summary by CodeRabbit

  • New Features

    • Added a complete example project demonstrating a private ephemeral permission counter with end-to-end flows between base-layer and ephemeral rollups.
  • Documentation

    • Added a comprehensive README with setup, environment variables, and usage examples for counter and ephemeral rollup operations.
  • Tests

    • Added end-to-end tests that exercise initialize, delegate, ER increments, permission lifecycle, commit, and undelegate flows.
  • Chores

    • Updated CI/toolchain and project configuration; refined ignore rules and package manifests.

Review Change Stack

@vercel
Copy link
Copy Markdown

vercel Bot commented May 18, 2026

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

Project Deployment Actions Updated (UTC)
er-rolldice Ready Ready Preview, Comment May 18, 2026 6:15pm
magicblock-counter-example Ready Ready Preview, Comment May 18, 2026 6:15pm
magicblock-engine-examples Ready Ready Preview, Comment May 18, 2026 6:15pm
magicblock-rewards-dashboard Ready Ready Preview, Comment May 18, 2026 6:15pm
spl-tokens Ready Ready Preview, Comment May 18, 2026 6:15pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 18, 2026

Warning

Rate limit exceeded

@Dodecahedr0x has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 38 minutes and 55 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: c87f23b9-595b-4a4b-90f0-d261372b0211

📥 Commits

Reviewing files that changed from the base of the PR and between 835bdd8 and 6cbb6b0.

📒 Files selected for processing (2)
  • .github/workflows/test-examples.yml
  • fullstack-test.sh

Walkthrough

This PR adds a new Anchor example project demonstrating a PDA-backed counter with Ephemeral Rollups private delegation/permission flows, updates CI/toolchain (Node/Rust/Solana/Anchor), provides project configuration (Cargo/Anchor/TS/package), implements the Anchor program, and adds an end-to-end TypeScript test suite and README.

Changes

Ephemeral Permissions Counter Example

Layer / File(s) Summary
CI Toolchain and Infrastructure Updates
.github/workflows/test-examples.yml, .gitignore
Updated GitHub Actions to Node 20 and Rust 1.94.0, added apt native deps, updated Solana installer and Anchor install path; adjusted root .gitignore to ignore anchor-counter deploy artifacts.
Project Configuration and Build Setup
anchor-ephemeral-permission-counter/.env.example, anchor-ephemeral-permission-counter/.gitignore, anchor-ephemeral-permission-counter/Anchor.toml, anchor-ephemeral-permission-counter/Cargo.toml, anchor-ephemeral-permission-counter/package.json, anchor-ephemeral-permission-counter/tsconfig.json, anchor-ephemeral-permission-counter/programs/private-counter/Cargo.toml
Adds example env vars, project .gitignore, Anchor config (toolchain 0.32.1), Cargo workspace and release profile, npm scripts and deps, tsconfig, and the private-counter Cargo manifest with pinned anchor-lang and ephemeral-rollups-sdk.
Counter Program Instruction Handlers and Account Schema
anchor-ephemeral-permission-counter/programs/private-counter/src/lib.rs
Implements Counter { count: u64, authority: Pubkey }, COUNTER_SEED, and instruction handlers: initialize, increment (wrap at >1000), delegate, permission CPIs (initialize_permission, update_permission, close_permission), and Magic/ER flows (commit, undelegate) with all Anchor account contexts.
Documentation and End-to-End Test Suite
anchor-ephemeral-permission-counter/README.md, anchor-ephemeral-permission-counter/tests/private-counter.ts
Adds comprehensive README and tests that set up base and ER providers (including TEE auth token flow), derive PDAs, exercise initialize/increment/delegate, manage ER permissions (init/update/close), perform ER increments and commits, and undelegate with base-layer confirmation polling.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • GabrielePicco
  • jonasXchen
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'feat: anchor ephemeral permission' is vague and does not clearly describe the changeset. It lacks specificity about what is being added (e.g., a new counter program, ephemeral rollups integration, or example project). Consider a more descriptive title such as 'feat: add ephemeral rollups counter example with private permissions' to better reflect the main changes.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dode/ephemeral-permission-rust

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
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: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/test-examples.yml:
- Around line 26-29: Replace the archived actions-rs/toolchain@v1 usage with a
maintained action: swap the step that currently uses actions-rs/toolchain@v1
(and its inputs toolchain: "1.94.0" and override: true) to a supported
alternative such as dtolnay/rust-toolchain (or
actions-rust-lang/setup-rust-toolchain) and map the existing inputs accordingly
(preserve the rust version "1.94.0" and equivalent override behavior using the
chosen action's inputs); update the step's uses value to dtolnay/rust-toolchain
(or actions-rust-lang/setup-rust-toolchain) and adjust inputs to the target
action's expected fields.

In `@anchor-ephemeral-permission-counter/programs/private-counter/Cargo.toml`:
- Around line 24-28: The Cargo.toml dependency for ephemeral-rollups-sdk pins
rev to an abbreviated SHA; replace the short commit hash in the rev field for
the dependency declaration named ephemeral-rollups-sdk with the full
40-character commit SHA to ensure reproducible pinning (update the rev value in
the dependency block that includes features "anchor", "disable-realloc",
"access-control").

In `@anchor-ephemeral-permission-counter/programs/private-counter/src/lib.rs`:
- Around line 32-48: The initialize flow is currently re-runnable because the
transfer(...) and state assignments always execute; guard them so they only run
on first initialization: in the Initialize handler (the transfer(...) call,
counter.count and counter.authority assignments), check whether the counter is
uninitialized (e.g., counter.authority == Pubkey::default() or add an explicit
is_initialized flag) and only perform the ephemeral_accounts::rent transfer and
set counter.count = 0 and counter.authority = ctx.accounts.authority.key() when
that check passes; alternatively change the account constraint from
init_if_needed to a strict init so Anchor enforces single creation—apply this
guard to the same logic referenced by Initialize, transfer, and counter.* so
repeated calls no longer reset state or re-transfer lamports.
- Around line 60-65: The increment handler uses wrap logic (if counter.count >
1000 then reset to 0) but other handlers that also increment the account do not,
causing inconsistent semantics; make the behavior consistent by centralizing the
wrap logic into a single helper (e.g., implement a method on the account like
impl Counter { fn increment_wrapped(&mut self) { self.count += 1; if self.count
> 1000 { self.count = 0 } } }) and replace the inline increments in pub fn
increment(...) and all other handlers that mutate counter.count with a call to
that helper so every path uses identical wrap behavior.
- Around line 90-163: Permission lifecycle functions (initialize_permission,
update_permission, close_permission) lack an authority signer check in
PermissionContext, letting anyone call them; update the PermissionContext to
include an explicit authority Signer account and enforce that this signer equals
the counter.authority (so only the counter owner can call these instructions),
then adjust the CPI calls: pass the authority signer account as the authority
argument and set authority_is_signer = true for the CPIs that use an authority
(e.g., in UpdateEphemeralPermissionCpi and CloseEphemeralPermissionCpi) so the
external program sees the caller as a real signer.

In `@anchor-ephemeral-permission-counter/tests/private-counter.ts`:
- Around line 176-177: Several tests use fixed sleeps like await new
Promise((resolve) => setTimeout(resolve, 3000)); which makes E2E flaky; replace
each fixed delay with a bounded polling helper (e.g., implement a
pollForCondition or waitFor helper) that repeatedly checks the concrete
condition (owner change, account exists/absent, or whatever state the subsequent
assertions expect) until success or a max timeout, and use that helper in place
of the three setTimeout occurrences so tests wait deterministically for the
actual condition rather than a fixed interval.
- Around line 73-88: The provider recreation uses hardcoded teeUrl/teeWsUrl
which ignores a custom ephemeralRpcEndpoint; after obtaining authToken via
getAuthToken (called with ephemeralRpcEndpoint, payer.publicKey, ...), rebuild
providerEphemeralRollup using ephemeralRpcEndpoint (and its corresponding ws
endpoint) with the token appended instead of teeUrl/teeWsUrl so the configured
TEE_PROVIDER_ENDPOINT is honored; update the Connection instantiation in
providerEphemeralRollup to derive the RPC URL from ephemeralRpcEndpoint and the
wsEndpoint from the matching ws URL (or construct by replacing protocol/host as
needed) and append ?token=${authToken.token}.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: fb513a75-13a6-429f-964d-9ef7ae561d95

📥 Commits

Reviewing files that changed from the base of the PR and between d6ec56d and ae64180.

⛔ Files ignored due to path filters (2)
  • anchor-ephemeral-permission-counter/Cargo.lock is excluded by !**/*.lock
  • anchor-ephemeral-permission-counter/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (12)
  • .github/workflows/test-examples.yml
  • .gitignore
  • anchor-ephemeral-permission-counter/.env.example
  • anchor-ephemeral-permission-counter/.gitignore
  • anchor-ephemeral-permission-counter/Anchor.toml
  • anchor-ephemeral-permission-counter/Cargo.toml
  • anchor-ephemeral-permission-counter/README.md
  • anchor-ephemeral-permission-counter/package.json
  • anchor-ephemeral-permission-counter/programs/private-counter/Cargo.toml
  • anchor-ephemeral-permission-counter/programs/private-counter/src/lib.rs
  • anchor-ephemeral-permission-counter/tests/private-counter.ts
  • anchor-ephemeral-permission-counter/tsconfig.json
💤 Files with no reviewable changes (1)
  • .gitignore

Comment thread .github/workflows/test-examples.yml Outdated
Comment thread anchor-ephemeral-permission-counter/programs/private-counter/Cargo.toml Outdated
Comment thread anchor-ephemeral-permission-counter/tests/private-counter.ts
Comment thread anchor-ephemeral-permission-counter/tests/private-counter.ts Outdated
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

Caution

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

⚠️ Outside diff range comments (1)
.github/workflows/test-examples.yml (1)

58-68: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Missing CI test step for anchor-ephemeral-permission-counter.

The PR adds a new example project but no corresponding test step in CI. This means regressions in the new example won't be caught automatically.

🧪 Suggested test step
       - name: Test anchor-counter
         env:
           PROVIDER_ENDPOINT: http://127.0.0.1:8899
           WS_ENDPOINT: ws://127.0.0.1:8900
           EPHEMERAL_PROVIDER_ENDPOINT: http://127.0.0.1:7799
           EPHEMERAL_WS_ENDPOINT: ws://127.0.0.1:7800
         run: |
           sudo prlimit --pid $$ --nofile=1048576:1048576
           cd anchor-counter
           yarn install
           anchor test --provider.cluster localnet
+
+      - name: Test anchor-ephemeral-permission-counter
+        env:
+          PROVIDER_ENDPOINT: http://127.0.0.1:8899
+          WS_ENDPOINT: ws://127.0.0.1:8900
+          TEE_PROVIDER_ENDPOINT: http://127.0.0.1:7799
+          TEE_WS_ENDPOINT: ws://127.0.0.1:7800
+        run: |
+          sudo prlimit --pid $$ --nofile=1048576:1048576
+          cd anchor-ephemeral-permission-counter
+          yarn install
+          anchor test --provider.cluster localnet
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/test-examples.yml around lines 58 - 68, Add a new CI test
step mirroring the existing "Test anchor-counter" job for the new example:
create a step named "Test anchor-ephemeral-permission-counter" that sets the
same environment variables (PROVIDER_ENDPOINT, WS_ENDPOINT,
EPHEMERAL_PROVIDER_ENDPOINT, EPHEMERAL_WS_ENDPOINT), runs the same setup
commands (sudo prlimit --pid $$ --nofile=1048576:1048576), changes into the
anchor-ephemeral-permission-counter directory, runs yarn install, and executes
anchor test --provider.cluster localnet so the new example is exercised in CI.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/test-examples.yml:
- Around line 25-28: The GitHub Actions step that uses the
dtolnay/rust-toolchain action ("Setup Rust") is pinned to `@master` which is
unsafe; update the action reference in that step (the uses field currently
`dtolnay/rust-toolchain@master`) to a stable ref such as `@stable`, `@v1`, or a
full commit SHA to ensure reproducible builds while keeping the existing
toolchain input ("toolchain": "1.94.0") unchanged.

---

Outside diff comments:
In @.github/workflows/test-examples.yml:
- Around line 58-68: Add a new CI test step mirroring the existing "Test
anchor-counter" job for the new example: create a step named "Test
anchor-ephemeral-permission-counter" that sets the same environment variables
(PROVIDER_ENDPOINT, WS_ENDPOINT, EPHEMERAL_PROVIDER_ENDPOINT,
EPHEMERAL_WS_ENDPOINT), runs the same setup commands (sudo prlimit --pid $$
--nofile=1048576:1048576), changes into the anchor-ephemeral-permission-counter
directory, runs yarn install, and executes anchor test --provider.cluster
localnet so the new example is exercised in CI.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2d7ca9a8-e734-4273-9eab-edcb1f746bbd

📥 Commits

Reviewing files that changed from the base of the PR and between ae64180 and 835bdd8.

⛔ Files ignored due to path filters (1)
  • anchor-ephemeral-permission-counter/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • .github/workflows/test-examples.yml
  • anchor-ephemeral-permission-counter/programs/private-counter/Cargo.toml
  • anchor-ephemeral-permission-counter/programs/private-counter/src/lib.rs
  • anchor-ephemeral-permission-counter/tests/private-counter.ts

Comment thread .github/workflows/test-examples.yml
@Dodecahedr0x Dodecahedr0x self-assigned this May 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant