Ephemeral SPL Token program implementing MIMD 0013. It provides temporary (ephemeral) SPL balances that can be delegated to Data Layer Programs (DLPs), queued for delayed settlement, or routed through shuttle-based flows.
e-token— On-chain program (cdylib) implementing the Ephemeral SPL Token logic.e-token-api—no_stdrlib with the program ID, instruction discriminators, and shared types used by clients and tests.idl/ephemeral_spl_token.json— Machine-readable instruction/account summary aligned with the on-chain processors.
Public instructions currently handled by the program are:
Core balance management
0InitializeEphemeralAta— idempotently create the Ephemeral ATA PDA derived from[user, mint].1InitializeGlobalVault— create the per-mint global vault PDA derived from[mint], plus the vault-owned Ephemeral ATA and vault ATA.2DepositSplTokens— transfer tokens into the global vault and credit a standard or shuttle Ephemeral ATA.3WithdrawSplTokens— transfer tokens out of the global vault and debit the caller's Ephemeral ATA.10CloseEphemeralAta— close an empty Ephemeral ATA and refund its rent.
Delegation and permissions
4DelegateEphemeralAta— delegate an Ephemeral ATA to the delegation program. Raw data is empty or an appended 32-byte validator pubkey.5UndelegateEphemeralAta— commit and undelegate a user's delegated ATA flow.6CreateEphemeralAtaPermission— create the ACL permission PDA for an Ephemeral ATA. Raw data is a single permission-flags byte.7DelegateEphemeralAtaPermission— delegate the permission PDA associated with an Ephemeral ATA.8UndelegateEphemeralAtaPermission— commit and undelegate the permission PDA.9ResetEphemeralAtaPermission— reset permission members to the owner plus the requested ACL flags. Raw data is a single permission-flags byte.
Shuttle flows
11InitializeShuttleEphemeralAta— initialize shuttle metadata, its shuttle Ephemeral ATA, and the shuttle wallet ATA for[owner, mint, shuttle_id].13DelegateShuttleEphemeralAta— delegate a shuttle Ephemeral ATA. Raw data is empty or an appended 32-byte validator pubkey.14UndelegateShuttleEphemeralAta— commit and undelegate a shuttle wallet ATA, then schedule shuttle close/refund handling. Raw data is empty or a single escrow-index byte.15MergeShuttleIntoEphemeralAta— transfer the entire shuttle wallet ATA balance into a destination token account.24SetupAndDelegateShuttleEphemeralAtaWithMerge— initialize shuttle accounts if needed, deposit into the vault, sponsor delegation from the rent PDA, then schedule merge plus cleanup. Raw data isshuttle_id:u32,amount:u64, and an optional trailing 32-byte validator pubkey.25DepositAndDelegateShuttleEphemeralAtaWithMergeAndPrivateTransfer— same sponsored shuttle setup/deposit/delegate flow as24, but schedules a private queued transfer after merging back into the owner's source token account. Raw data starts withshuttle_id:u32andamount:u64, then carries three single-byte-length-prefixed buffers: validator bytes, encrypted destination bytes, and encrypted queue-suffix bytes.26WithdrawThroughDelegatedShuttleWithMerge— sponsor shuttle delegation, then schedule an owner-to-shuttle transfer followed by shuttle undelegation and cleanup. Raw data isshuttle_id:u32,amount:u64, and an optional trailing 32-byte validator pubkey.
Transfer queue and automation
12InitializeTransferQueue— create the per-mint transfer queue PDA derived from["queue", mint]. Raw data may be omitted, or may containsize_bytes:u32;0selects the default queue size.16DepositAndQueueTransfer— deposit into the vault and enqueue one or more delayed transfers. Raw data isamount:u64,min_delay_ms:u64,max_delay_ms:u64,split:u32, with an optional trailing flags byte.17EnsureTransferQueueCrank— ensure the recurring transfer-queue crank is scheduled.19DelegateTransferQueue— delegate the per-mint transfer queue PDA.20SponsoredLamportsTransfer— transfer lamports via the sponsored rent mechanism.
Rent PDA
23InitializeRentPda— initialize the global rent-sponsoring PDA derived from["rent"].
Internal automation instructions
196UndelegationCallback— delegation-program callback used to restore delegated account state.197CloseShuttleAtaIntent— internal close/refund handler for shuttle flows.198ExecuteReadyQueuedTransfer— internal settlement handler for a ready queued transfer.199ProcessTransferQueueTick— internal recurring crank callback that checks a queue and schedules settlement.201UndelegateWithdrawAndCloseShuttleEphemeralAta— internal post-delegation shuttle withdrawal and close/refund handler.
Discriminators 18, 21, and 22 are currently unused.
Program ID and external program
- The Ephemeral SPL Token program ID is declared in
e-token-api/src/lib.rsunderprogram::id_address(). - Delegation, undelegation, magic scheduling, and ACL flows are implemented through
ephemeral-rollups-pinocchio.
- Rust (toolchain pinned via
rust-toolchain.toml). - Solana CLI =
2.3.4(see[workspace.metadata.cli]inCargo.toml).
Build the on-chain program to SBF:
cargo build-sbfRun the test suite with program logs enabled:
cargo test-sbf --features loggingYou can run a single test by passing its name, for example:
cargo test-sbf --features logging delegate_ephemeral_ataTests live under e-token/tests/ and cover balance accounting, delegation/undelegation, shuttle flows, permissions, the rent PDA and lamports-PDA flows, and transfer-queue automation.
- The workspace depends on
ephemeral-rollups-pinocchioand several Solana crates; ensure your local environment matches the versions declared in the workspaceCargo.toml. - The program enables additional logs when compiled with the
loggingfeature, which is useful for debugging unit and integration tests.