Core concepts · Explanation
Universal assets and identity
Shared state lets different execution environments refer to the same asset and authority records. Singularity uses a Universal Token Header (UTH) for a common token representation and a Universal Identity Header (UIH) with delegated capabilities for controlled actions. The first answers “what balance does this account represent?” The second helps answer “who may perform this action, under which budget and restrictions?”
Neither a familiar byte layout nor a recognizable address is sufficient authorization. Applications must verify the account's owning program, the record's identity and the authority required by the operation.
This explanation follows representation into an authorized spend and revocation. For the surrounding signed-message model, read protocol primitives; for a broader security review, use trust boundaries.
The token header is a common representation
A UTH occupies the first 84 bytes of account data:
| Offset | Bytes | Field |
|---|---|---|
| 0 | 8 | Magic: 55 54 48 00 01 e7 0f a5 |
| 8 | 1 | Header version, currently 1 |
| 9 | 1 | Origin environment |
| 10 | 32 | Mint identity |
| 42 | 32 | Token holder identity |
| 74 | 8 | Amount, unsigned little-endian integer |
| 82 | 1 | Decimals |
| 83 | 1 | Frozen flag |
A balance is an integer in that asset's base units. Decimals tell a client how to display it; they do not change transfer arithmetic. The fixed offsets let a compatible reader decode the record without knowing a VM-specific serialization language. Canonical header.
The origin values recognized by current typed readers are SVM 0, EVM 1, WASM 2, Move 3 and ZK 4. Unknown values round-trip as an unknown byte. Bombil is the sixth VM-level environment in the architecture; its design reserves origin 5, but the current typed header enum has not added a named Bombil variant. An unknown origin is therefore not evidence of a corrupt header or an executing Bombil integration. Origin decoding, Bombil architecture, current Bombil identifiers and admission.
The magic prevents unrelated account data from accidentally being interpreted as a token. It does not prove authenticity: another program can write the same bytes into its own account. Before trusting a balance, validate the expected program owner and application-specific mint/holder relationship. The universal-token sentinel ends in 06; the separate SING_TOKEN_PROGRAM_ID appears in other token-related helpers. Which owner is accepted depends on the actual consuming path. Structural versus authority checks.
Shared representation does not collapse every token system
The native universal-token handler is UniversalTokenProgram under UNIVERSAL_TOKEN_PROGRAM_ID. Its instruction bytes differ from both classic SPL Token and the introductory opcode list in programs/singularity_token.rs.
| Universal-token opcode | Payload after opcode | Required account relationship |
|---|---|---|
| 0 — Transfer | amount: u64 LE | Source and destination UTH accounts; source header owner must sign |
| 1 — MintTo | mint: 32 bytes, amount: u64 LE | Destination and matching mint record; mint's recorded authority must sign |
| 2 — Freeze | None | Target and mint record; mint authority |
| 3 — Unfreeze | None | Target and mint record; mint authority |
| 4 — CreateAccount | mint[32], owner[32], decimals:u8, vm_origin:u8 | New token account, subject to creation validation |
For a nonzero transfer between different accounts, the implementation checks both accounts are owned by the universal-token program, both headers decode, mints match, neither account is frozen, the source holder signed and integer subtraction/addition fit. Zero amounts and self-transfers return without changing balances. The enclosing executor separately enforces writable declarations and consistent aliases. Instruction processing, native dispatch.
The helper derive_token_account(owner, mint) hashes sing:token: followed by the two 32-byte identities. EVM-owner mapping hashes evm: plus the 20-byte address; the WASM helper hashes wasm: plus supplied address bytes. These mappings are domain-specific hashes, not reversible padding. A helper's deterministic address is also distinct from a Solana PDA with an off-curve bump search. Address helpers.
SING account lamports, classic SPL balances, universal-token headers, EVM storage and bridge asset metadata remain distinct representations and paths. Comments describing “one token program for all VMs” express a broader goal; they do not establish that arbitrary ERC-20, SPL and VM calls are automatically intercepted and converted. Check the VM compatibility boundaries before selecting an interface.
For foreign-origin assets, authenticity also depends on the bridge's source attribution and deposit verification. A valid UTH says nothing by itself about remote collateral or redeemability.
Identity connects a holder to a delegation lineage
The UIH is a fixed 224-byte record with identity, parent and root IDs; holder key; capability-root commitment; generation; cached root generation; optional attestation hash; status; custody mode; remaining delegation depth; and reserved bytes. The identity program owns UIH accounts. Capability-owned PDAs separately store epoch anchors, budget counters, nonce ledgers, funding vaults and audit receipts. Identity layout and account domains.
Registering a root creates its UIH and epoch anchor. Registering a child derives lineage from the parent's account, rather than accepting a caller-invented root. Registration requires the funding signer and controlling authority. The current instruction enum also includes CreateFundingVault, ExerciseDraw, Revoke and Invoke; older comments saying only registration exists are superseded by those handlers. Identity instruction contract.
A SidCap is a signed capability chain. Delegation can narrow the effective scope, budget or validity window; it cannot widen the parent's permissions. The maximum delegation depth constant is 9. The capability verifier reads every ancestor's live anchor, so a cached root-generation hint cannot replace checking the chain's actual authority state.
One authorized spend path
Consider a purchasing agent allowed to pay a particular merchant within a shared budget. The application submits the action, canonical SidCap bytes, proof of possession and nonce together with all token-derived accounts.
The pure cap_check_core checks the consensus slot, canonical encoding, signature chain, narrowing of permissions, live ancestor status and generations, intersected validity interval, action scope, proof of possession, replay protection and budget conditions. It returns either the first deterministic rejection or an allowed debit description. It does not itself change a balance. Capability verification.
ExerciseDraw derives the account keys from the token and applies the permitted transition: update the shared budget counter, advance the nonce ledger and move the authorized amount from the program-owned vault to the recipient. A budget counter is keyed by budget lineage; a nonce ledger is keyed by the individual capability ID. Separate delegated tokens therefore do not automatically receive separate copies of a shared budget. Derived state lookup.
Invoke reuses that spend path for a cross-party request and appends an audit receipt containing the originator, executor, slot, nonce and debit. It requires the receipt account before proceeding. A presenter equal to the executor must use ExerciseDraw instead. The receipt establishes this authorized on-chain transition; it does not prove an external tool returned correct work. Invoke handler.
Revocation and failure are part of the contract
Revocation increments the identity's epoch-anchor generation and marks it revoked. Subsequent draws check every ancestor, so revoking a root invalidates capabilities below it without rewriting each descendant token. An unrelated branch remains independent. The source tests cover ancestor revocation, unauthorized revocation, generation monotonicity and unrelated branches. Revocation and tests.
Typical capability failures include a broken signature chain, a dropped restrictive facet, a revoked ancestor, an expired interval, replayed nonce, missing/wrongly classified state or exceeded budget. These are explicit reasons in the verifier, not permission to retry the same action with broader credentials automatically. The tests were inspected, not executed during this run.
Start an integration by separating the token amount you want to use from the capability that authorizes its use. Then follow native application protocols for the surrounding workflow and trust boundaries for the checks that must survive every entrypoint.