> ## Documentation Index
> Fetch the complete documentation index at: https://docs.magicblock.gg/llms.txt
> Use this file to discover all available pages before exploring further.

# Ephemeral SPL Token 快速入门

> 使用 ephemeral-rollups-sdk 将 SPL token account 委托给 Ephemeral Rollup，在 ER 上转账，并提取回 base layer。

***

<Tip>
  **正在使用 AI 编程助手开发？** 安装 MagicBlock Dev Skill，为你的助手提供 MagicBlock 专属开发模式——委托流程、Magic Actions、Crank、VRF 等。

  Claude Code 快速安装：

  ```bash theme={null}
  npx add-skill https://github.com/magicblock-labs/magicblock-dev-skill
  ```

  使用 Cursor、Codex、Windsurf、Cline 或其他助手？请参阅 [AI Dev Skill](/cn/pages/overview/additional-information/ai-dev-skill) 页面了解所有安装方式。
</Tip>

### 快速访问

查看示例：

<CardGroup cols={2}>
  <Card title="GitHub" icon="github" href="https://github.com/magicblock-labs/magicblock-engine-examples/tree/main/spl-tokens" iconType="duotone">
    SPL Token Anchor 实现
  </Card>

  <Card title="在线示例应用" icon="coins" href="https://one.magicblock.app/" iconType="duotone">
    体验私密支付
  </Card>
</CardGroup>

<Note>
  这些代码片段面向使用 legacy-vault 路径的 `@magicblock-labs/ephemeral-rollups-sdk`
  **v0.14.3**。idempotent-shuttle 路径面向 v0.15.3；在同一个生命周期内，请为
  `delegateSpl` / `undelegateIx` / `withdrawSpl` 使用同一路径。
</Note>

***

## 分步指南

通过 Ephemeral SPL Token 程序 `SPLxh1LVZzEkX99H6rqYizhytLWPZVV296zyYDPagv2`
完成 SPL token 的完整生命周期：[委托](/cn/pages/ephemeral-rollups-ers/introduction/ephemeral-accounts)、
在 [ER](/cn/pages/ephemeral-rollups-ers/introduction/ephemeral-rollup) 上交易，然后结算回 Solana：

<Steps>
  <Step title={<a href="#1-delegate">委托 token account</a>}>
    在 base layer 上将所有者的余额委托给 validator。首次委托某个 mint 时会创建共享的
    Global Vault。
  </Step>

  <Step title={<a href="#2-transfer">在 ER 上转账</a>}>
    在 rollup 内的 eATA 之间转移 token，可以公开也可以私密。
  </Step>

  <Step title={<a href="#3-undelegate">取消委托并提交</a>}>
    在 ER 上取消委托，并等待状态提交回 base layer。
  </Step>

  <Step title={<a href="#4-withdraw">提取到 base layer</a>}>
    将余额从 Global Vault 转入 base-layer token account。
  </Step>
</Steps>

***

## Ephemeral SPL Token 示例

你可能需要以下软件包，其他版本也可能兼容：

| 软件         | 版本      | 安装指南                                                       |
| ---------- | ------- | ---------------------------------------------------------- |
| **Solana** | 3.1.9   | [安装 Solana](https://docs.anza.xyz/cli/install)             |
| **Rust**   | 1.89.0  | [安装 Rust](https://www.rust-lang.org/tools/install)         |
| **Anchor** | 1.0.2   | [安装 Anchor](https://www.anchor-lang.com/docs/installation) |
| **Node**   | 24.10.0 | [安装 Node](https://nodejs.org/en/download/current)          |

安装 SDK：

```bash theme={null}
yarn add @magicblock-labs/ephemeral-rollups-sdk@0.14.3
```

### 代码片段

<Tabs>
  <Tab title="1. 委托">
    `delegateSpl` 将所有者的余额委托给 validator。首次委托某个 mint 时会创建共享的
    Global Vault（`initVaultIfMissing: true`），后续委托则复用它。请在 **base layer**
    上发送，并在委托前为 rent sponsor（`deriveRentPda()`）提供资金。

    ```typescript theme={null}
    // Legacy vault flow — keep the same idempotent setting across
    // delegateSpl / undelegateIx / withdrawSpl within one lifecycle.
    const delegateOpts = { validator, idempotent: false as const, payer: admin.publicKey };

    const ixs = await delegateSpl(owner.publicKey, mint.publicKey, amount, {
      ...delegateOpts,
      initVaultIfMissing, // true for the first owner of this mint, false after
    });

    await provider.sendAndConfirm(
      new anchor.web3.Transaction().add(...ixs),
      [owner, admin],
      { commitment: "confirmed", skipPreflight: true },
    );
    ```

    [⬆️ 返回顶部](#code-snippets)
  </Tab>

  <Tab title="2. 转账">
    `transferSpl` 在 rollup 内的 eATA 之间转移 token。请通过 **ephemeral** provider 发送。
    私密支付应设置 `visibility: "private"`，普通快速转账则设置 `"public"`。

    ```typescript theme={null}
    // Delegation confirms on base before the ER clones the account —
    // poll the ER view before transferring.
    await waitForErTokenAccount(ata, expectedAmount);

    const transferIxs = await transferSpl(
      recipientA.publicKey,
      recipientB.publicKey,
      mint.publicKey,
      2n,
      { visibility: "public", fromBalance: "ephemeral", toBalance: "ephemeral" },
    );

    await providerEphemeralRollup.sendAndConfirm(
      new anchor.web3.Transaction().add(...transferIxs),
      [recipientA],
      { commitment: "confirmed", skipPreflight: true },
    );
    ```

    [⬆️ 返回顶部](#code-snippets)
  </Tab>

  <Tab title="3. 取消委托">
    在 ER 上逐个取消每位所有者的委托（每笔交易一个），然后使用
    `GetCommitmentSignature` 等待提交回 base layer，再执行提取。

    ```typescript theme={null}
    const sgn = await providerEphemeralRollup.sendAndConfirm(
      new anchor.web3.Transaction().add(undelegateIx(owner.publicKey, mint.publicKey)),
      [owner],
      { commitment: "confirmed", skipPreflight: true },
    );

    // Wait for the commit back to base before withdrawing, or the withdraw
    // races the commit and fails with InvalidAccountOwner.
    const commit = await GetCommitmentSignature(sgn, providerEphemeralRollup.connection);
    await connection.confirmTransaction(commit, "confirmed");
    ```

    [⬆️ 返回顶部](#code-snippets)
  </Tab>

  <Tab title="4. 提取">
    `withdrawSpl` 将余额从 Global Vault 转回所有者的 base-layer ATA。

    ```typescript theme={null}
    const withdrawIxs = await withdrawSpl(owner.publicKey, mint.publicKey, amount, {
      idempotent: false,
    });

    await provider.sendAndConfirm(
      new anchor.web3.Transaction().add(...withdrawIxs),
      [owner],
      { commitment: "confirmed" },
    );
    ```

    [⬆️ 返回顶部](#code-snippets)
  </Tab>

  <Tab title="支持 ER 的程序">
    如果要通过自己的程序而不是 SDK helper 来处理 ER 端转账，请添加 `#[ephemeral]`
    属性；该指令就是普通的 SPL Token CPI。有关托管与 PDA 签名转账，请参阅
    [智能合约集成](/cn/pages/ephemeral-spl-token/smart-contract-integration)。

    ```rust theme={null}
    use anchor_lang::prelude::*;
    use anchor_spl::token::{self, Token, TokenAccount, Transfer as SplTransfer};
    use ephemeral_rollups_sdk::anchor::ephemeral;

    #[ephemeral]
    #[program]
    pub mod spl_tokens {
        use super::*;

        /// Transfer `amount` of SPL tokens from `from` to `to`.
        pub fn transfer(ctx: Context<TransferTokens>, amount: u64) -> Result<()> {
            require!(amount > 0, ErrorCode::InvalidAmount);
            let cpi_accounts = SplTransfer {
                from: ctx.accounts.from.to_account_info(),
                to: ctx.accounts.to.to_account_info(),
                authority: ctx.accounts.payer.to_account_info(),
            };
            let cpi_ctx = CpiContext::new(ctx.accounts.token_program.to_account_info(), cpi_accounts);
            token::transfer(cpi_ctx, amount)?;
            Ok(())
        }
    }
    ```

    [⬆️ 返回顶部](#code-snippets)
  </Tab>
</Tabs>

<Note>
  **本地运行：** `yarn` → `yarn build` → `yarn setup`（启动本地 base + ER 集群并保持运行）
  → 在第二个终端中执行 `yarn test:local`。
</Note>

***

## Solana 浏览器

查看你在 Solana 上的交易和账户详情：

<CardGroup cols={2}>
  <Card title="Solana 浏览器" icon="search" href="https://explorer.solana.com/" iconType="duotone">
    官方 Solana 浏览器
  </Card>

  <Card title="Solscan" icon="searchengin" href="https://solscan.io/" iconType="duotone">
    浏览 Solana 区块链
  </Card>
</CardGroup>

## Solana RPC 提供商

通过现有 RPC 提供商发送交易和请求：

<CardGroup cols={2}>
  <Card title="Solana" icon="star" href="https://solana.com/docs/references/clusters#on-a-high-level" iconType="duotone">
    Free Public Nodes
  </Card>

  <Card title="Helius" icon="sun" href="https://www.helius.dev/solana-rpc-nodes" iconType="duotone">
    Free Shared Nodes
  </Card>

  <Card title="Triton" icon="crystal-ball" href="https://triton.one/solana" iconType="duotone">
    Dedicated High-Performance Nodes
  </Card>
</CardGroup>

## Solana 验证器仪表盘

查看 Solana 验证器基础设施的实时更新：

<CardGroup cols={2}>
  <Card title="Solana Beach" icon="wave" href="https://solanabeach.io/" iconType="duotone">
    Get Validator Insights
  </Card>

  <Card title="Validators App" icon="cloud-binary" href="https://www.validators.app/" iconType="duotone">
    Discover Validator Metrics
  </Card>
</CardGroup>

## 服务状态

订阅 Solana 与 MagicBlock 的服务状态：

<CardGroup cols={2}>
  <Card title="Solana Status" icon="server" href="https://status.solana.com/" iconType="duotone">
    Subscribe to Solana Server Updates
  </Card>

  <Card title="MagicBlock Status" icon="heart-pulse" href="/cn/pages/overview/additional-information/system-status" iconType="duotone">
    Subscribe to MagicBlock Server Status
  </Card>
</CardGroup>

***

## MagicBlock 产品

<CardGroup cols={2}>
  <Card title="Ephemeral Rollup（ER）" icon="bolt" href="/cn/pages/ephemeral-rollups-ers/how-to-guide/quickstart" iconType="duotone">
    在 Solana 上安全执行实时、零手续费交易。
  </Card>

  <Card title="Private Ephemeral Rollup（PER）" icon="shield-check" href="/cn/pages/private-ephemeral-rollups-pers/how-to-guide/quickstart" iconType="duotone">
    在合规的前提下保护敏感数据——基于 Ephemeral Rollups 构建。
  </Card>

  <Card title="Ephemeral SPL Token" icon="coins" href="/cn/pages/ephemeral-spl-token/overview" iconType="duotone">
    以 rollup 速度转移 SPL token——支持公开或私密转账、swap，以及面向交易和 DeFi 应用的私密支付。
  </Card>

  <Card title="预测市场与交易" icon="chart-line" href="/pages/solutions/prediction-markets" iconType="duotone">
    结合实时执行、session key、token 托管、价格数据、自动化与结算能力。
  </Card>

  <Card title="Solana VRF" icon="dice" href="/cn/pages/verifiable-randomness-functions-vrfs/introduction/solana-vrf" iconType="duotone">
    为游戏、抽奖和实时应用添加可证明公平的链上随机数。
  </Card>

  <Card title="价格预言机" icon="waveform" href="/cn/pages/tools/oracle/introduction" iconType="duotone">
    获取适用于交易和 DeFi 的低延迟链上价格数据。
  </Card>
</CardGroup>

***
