Documentation Index Fetch the complete documentation index at: https://mintlify.com/magicblock-labs/magicblock-engine-examples/llms.txt
Use this file to discover all available pages before exploring further.
Quickstart
Get started with Ephemeral Rollups by running the Anchor Counter example. This guide will have you delegating accounts, executing low-latency transactions, and committing state back to Solana in under 10 minutes.
Prerequisites
Before you begin, ensure you have the following tools installed:
Software Version Installation Guide Solana 2.3.13 Install Solana Rust 1.85.0 Install Rust Anchor 0.32.1 Install Anchor Node 24.10.0 Install Node
Use version managers like agave-install for Solana, rustup for Rust, and avm for Anchor to easily switch between versions.
Verify your installations
# Check and initialize your Solana version
agave-install list
agave-install init 2.3.13
# Check and initialize your Rust version
rustup show
rustup install 1.85.0
# Check and initialize your Anchor version
avm list
avm use 0.32.1
Run the Anchor Counter example
Clone the repository
Clone the MagicBlock Engine examples repository: git clone https://github.com/magicblock-labs/magicblock-engine-examples.git
cd magicblock-engine-examples/anchor-counter
Install dependencies
Install the required Node.js packages: The project uses:
@coral-xyz/anchor (0.32.1) - Anchor framework
@magicblock-labs/ephemeral-rollups-sdk (0.6.5) - Ephemeral Rollups SDK
Build and deploy
Build the program and deploy it to the configured cluster: anchor build
anchor deploy
If you want to deploy with a fresh program ID, delete the keypair first: rm -rf target/deploy/ * .keypair
anchor build
Run the tests
Execute the test suite to see delegation, execution, and commits in action: anchor test --skip-deploy --skip-build --skip-local-validator
You’ll see output showing:
Counter initialization on Solana base layer
Account delegation to Ephemeral Rollup
Fast increment transactions on the ER
State commits back to Solana
Account undelegation
Understanding the code
The Counter program
The Anchor Counter program demonstrates the core Ephemeral Rollup pattern:
anchor-counter/programs/anchor-counter/src/lib.rs
use ephemeral_rollups_sdk :: anchor :: {commit, delegate, ephemeral};
#[ephemeral]
#[program]
pub mod anchor_counter {
use super ::* ;
/// Initialize the counter
pub fn initialize ( ctx : Context < Initialize >) -> Result <()> {
let counter = & mut ctx . accounts . counter;
counter . count = 0 ;
Ok (())
}
/// Increment the counter
pub fn increment ( ctx : Context < Increment >) -> Result <()> {
let counter = & mut ctx . accounts . counter;
counter . count += 1 ;
Ok (())
}
/// Delegate account to Ephemeral Rollup
pub fn delegate ( ctx : Context < DelegateInput >) -> Result <()> {
ctx . accounts . delegate_pda (
& ctx . accounts . payer,
& [ COUNTER_SEED ],
DelegateConfig :: default (),
) ? ;
Ok (())
}
}
The #[ephemeral] attribute on the program enables Ephemeral Rollup support. The #[delegate] attribute on the context generates delegation boilerplate.
Delegating an account
Delegation transfers account ownership to the delegation program, making it available in the Ephemeral Rollup:
anchor-counter/tests/anchor-counter.ts
const [ counterPDA ] = anchor . web3 . PublicKey . findProgramAddressSync (
[ Buffer . from ( "counter" )],
program . programId
);
// Delegate the counter to Ephemeral Rollup
let tx = await program . methods
. delegate ()
. accounts ({
payer: provider . wallet . publicKey ,
pda: counterPDA ,
})
. transaction ();
const txHash = await provider . sendAndConfirm ( tx , [ provider . wallet . payer ]);
console . log ( "Delegate txHash:" , txHash );
Executing on Ephemeral Rollup
Once delegated, transactions execute with millisecond latency:
// Create provider for Ephemeral Rollup
const providerEphemeralRollup = new anchor . AnchorProvider (
new anchor . web3 . Connection (
process . env . EPHEMERAL_PROVIDER_ENDPOINT || "https://devnet-as.magicblock.app/" ,
{
wsEndpoint: process . env . EPHEMERAL_WS_ENDPOINT || "wss://devnet-as.magicblock.app/"
}
),
anchor . Wallet . local ()
);
// Execute increment on ER - notice the fast execution!
let tx = await program . methods
. increment ()
. accounts ({ counter: counterPDA })
. transaction ();
tx . feePayer = providerEphemeralRollup . wallet . publicKey ;
tx . recentBlockhash = (
await providerEphemeralRollup . connection . getLatestBlockhash ()
). blockhash ;
tx = await providerEphemeralRollup . wallet . signTransaction ( tx );
const txHash = await providerEphemeralRollup . sendAndConfirm ( tx );
console . log ( "ER Increment txHash:" , txHash );
Committing state
Commit account state back to Solana:
use ephemeral_rollups_sdk :: ephem :: commit_accounts;
pub fn commit ( ctx : Context < CommitAccounts >) -> Result <()> {
commit_accounts (
& ctx . accounts . payer,
vec! [ & ctx . accounts . counter . to_account_info ()],
& ctx . accounts . magic_context,
& ctx . accounts . magic_program,
) ? ;
Ok (())
}
Test output explained
When you run the tests, you’ll see timing comparisons:
2000ms (Base Layer) Initialize txHash: abc123...
1800ms (Base Layer) Increment txHash: def456...
1500ms (Base Layer) Delegate txHash: ghi789...
45ms (ER) Increment txHash: jkl012... ← Notice the speed!
50ms (ER) Increment and Commit txHash: mno345...
Ephemeral Rollup transactions execute 40-50x faster than base layer transactions.
Next steps
Core Concepts Learn how delegation, commits, and transaction routing work
Framework Examples Explore examples for different Solana frameworks
Local Development Set up a local Ephemeral Rollup validator
Advanced Examples Try cranks, Magic Actions, and session keys
Troubleshooting
Transaction fails with 'Account not found'
Wait a few seconds after delegation before executing transactions on the ER. Account propagation takes 2-3 seconds: await provider . sendAndConfirm ( delegateTx );
await new Promise ( resolve => setTimeout ( resolve , 3000 )); // Wait 3s
'Program not deployed' error
Make sure you’ve deployed to the correct cluster. Check your Anchor.toml: [ provider ]
cluster = "localnet" # or "devnet"
Then deploy: anchor deploy --provider.cluster localnet
Ensure all tools match the required versions: solana --version # Should be 2.3.13
rustc --version # Should be 1.85.0
anchor --version # Should be 0.32.1
node --version # Should be 24.x
Use version managers to switch versions as needed.
Insufficient SOL for transactions
Make sure your wallet has SOL on the target cluster: # For localnet
solana airdrop 2
# For devnet
solana airdrop 2 --url devnet
The Ephemeral Rollups are currently in testing. Contact the MagicBlock team on Discord to get access to the testing endpoint.