commit_and_update_leaderboard コミット命令は ER 上で実行されます。MagicIntentBundleBuilder を使用してコミットとコミット後アクションの両方を magic_context に予約します — ER トランザクションがベースレイヤーへ確定されるとき、両者は同時に適用されます。
// commit action instruction on ERpub fn commit_and_update_leaderboard(ctx: Context<CommitAndUpdateLeaderboard>) -> Result<()> { // Build the post-commit action that updates the leaderboard on base layer let instruction_data = anchor_lang::InstructionData::data(&crate::instruction::UpdateLeaderboard {}); let action_args = ActionArgs::new(instruction_data); let action_accounts = vec![ ShortAccountMeta { pubkey: ctx.accounts.leaderboard.key(), is_writable: true, }, ShortAccountMeta { pubkey: ctx.accounts.counter.key(), is_writable: false, }, ]; let action = CallHandler { destination_program: crate::ID, accounts: action_accounts, args: action_args, // Signer that pays transaction fees for the action from its escrow PDA escrow_authority: ctx.accounts.payer.to_account_info(), compute_units: 200_000, }; // Schedule commit + post-commit action on magic_context MagicIntentBundleBuilder::new( ctx.accounts.payer.to_account_info(), ctx.accounts.magic_context.to_account_info(), ctx.accounts.magic_program.to_account_info(), ) .commit(&[ctx.accounts.counter.to_account_info()]) .add_post_commit_actions([action]) .build_and_invoke()?; Ok(())}// commit action context on ER#[commit]#[derive(Accounts)]pub struct CommitAndUpdateLeaderboard<'info> { #[account(mut)] pub payer: Signer<'info>, #[account(mut, seeds = [COUNTER_SEED], bump)] pub counter: Account<'info, Counter>, /// CHECK: Leaderboard PDA - not mut here, writable set in handler #[account(seeds = [LEADERBOARD_SEED], bump)] pub leaderboard: UncheckedAccount<'info>, /// CHECK: Your program ID pub program_id: AccountInfo<'info>,}
// Chain several actions — they execute sequentially on base layer after the commit lands.MagicIntentBundleBuilder::new( ctx.accounts.payer.to_account_info(), ctx.accounts.magic_context.to_account_info(), ctx.accounts.magic_program.to_account_info(),).commit(&[ ctx.accounts.counter.to_account_info(), // ... additional committed accounts]).add_post_commit_actions([action_1, action_2, action_3]).build_and_invoke()?;
アクションは委任解除にも連鎖できます — counter のコミット、委任解除、アクションすべてが同一の ER トランザクション内でアトミックに実行されます。
// Commit, undelegate, AND execute actions — all atomically on base layer after the ER transaction seals.MagicIntentBundleBuilder::new( ctx.accounts.payer.to_account_info(), ctx.accounts.magic_context.to_account_info(), ctx.accounts.magic_program.to_account_info(),).commit_and_undelegate(&[ctx.accounts.counter.to_account_info()]).add_post_commit_actions([action]).build_and_invoke()?;