Skip to content

Sealed Storage policies — on-chain API reference ​

Package sealed_storage (Move 2024), testnet 0x0c8f7349…773d. Depends on access_gate 0xd7ddaa94… (git dependency pinned to a commit SHA). config::init shares one PolicyConfig and gives the PolicyAdminCap to the publisher; every entry below takes policy: &PolicyConfig and checks its version first.

sealed_storage::nft_gate (policy) ​

FunctionSignatureChecks, in order
seal_approveentry fun seal_approve(id: vector<u8>, policy: &PolicyConfig, gate: &Gate, nft: &AccessNFT)in this order: version (else config 1); id ≥ 32 bytes and id[0..32] == object::id_bytes(gate) (else 1); not (paused and policy pause_blocks_decryption) (else 4); access_gate::is_valid_for(nft, gate) (else 2); single-use pass has uses > 0 (else 3). So a paused policy gate presented with a foreign pass aborts 4, not 2.
seal_approve_soulboundentry fun seal_approve_soulbound(id: vector<u8>, policy: &PolicyConfig, gate: &Gate, nft: &SoulboundAccessNFT)same, via is_valid_for_soulbound / uses_remaining_soulbound

Side-effect free: immutable references only; no mutation, transfer, object creation or events. Pausing a gate blocks decryption only if the gate was created with the access_gate policy flag pause_blocks_decryption; decryption resumes when the gate is unpaused. frozen is never checked. Keys already released stay usable — pausing stops new key releases, not past ones.

CodeConstantMeaning
1E_ID_NOT_NAMESPACEDIdentity shorter than 32 bytes or not prefixed with this gate's id
2E_WRONG_GATEThe NFT was not minted from this gate
3E_EXHAUSTEDSingle-use pass with zero uses remaining
4E_GATE_PAUSEDGate is paused and its policy has pause_blocks_decryption (not in the superseded 0x9f0563…)

sealed_storage::timelock (policy) ​

FunctionSignatureChecks
seal_approveentry fun seal_approve(id: vector<u8>, policy: &PolicyConfig, clock: &Clock)version (else config 1); id ≥ 8 bytes (else 1); clock.timestamp_ms() >= u64_be(id[0..8]) (else 2). Suffix bytes ignored.

Side-effect free. Clock is the system object 0x6.

CodeConstantMeaning
1E_BAD_IDIdentity shorter than 8 bytes
2E_TOO_EARLYUnlock time not yet reached

sealed_storage::sealed_content (registry — not a policy) ​

ItemDefinition
SealedContenthas key, store (shared on publish): gate_id: ID, blob_id: String, seal_id: String, label: String, publisher: address
publishentry fun publish(policy: &PolicyConfig, gate_id: ID, blob_id: String, seal_id: String, label: String, ctx) — version (else config 1); permissionless; creates and shares a SealedContent; emits SealedContentPublished. No validation of gate_id; no update/delete.
SealedContentPublishedevent (copy, drop): content_id, gate_id, blob_id, seal_id, label, publisher
Viewsgate_id, blob_id, seal_id, label, publisher
CodeConstantMeaning
1E_LABEL_TOO_LONGlabel longer than 256 bytes
2E_BLOB_ID_TOO_LONGblob_id longer than 128 bytes
3E_SEAL_ID_TOO_LONGseal_id longer than 256 bytes

sealed_storage::config (version gate — not a policy) ​

ItemDefinition
PolicyConfighas key (shared by init): version: u64
PolicyAdminCaphas key, store (to the publisher; custody per CUSTODY.md)
migratepublic fun migrate(_cap: &PolicyAdminCap, config: &mut PolicyConfig) — sets version to this package's VERSION; forward only; emits PolicyConfigMigratedEvent { from_version, to_version }
check_versionpublic(package) — aborts unless config.version == VERSION
Viewsversion(config), package_version()
CodeConstantMeaning
1E_WRONG_VERSIONPolicyConfig names another package version (this code is retired, or not yet migrated to)
2E_NOT_UPGRADEmigrate called when the config is already at or past this version

Abort codes are per module: a client distinguishes config 1 from nft_gate 1 by the abort location.

Identity layouts (conformance) ​

PolicyLayoutVector (shared with sealed-storage-client)
nft_gate[32-byte gate id][nonce]gate 0x123 → prefix 00…0123 (32 bytes)
timelock[8-byte BE unlock_ms][nonce]1704067200000 → 00 00 01 8c c2 51 f4 00

Invariants ​

  • seal_approve* never has side effects and aborts (never grants) on malformed identities.
  • Every entry aborts under any package version other than the one PolicyConfig names; migrate only moves forward.
  • An nft_gate identity for gate A can never be approved with gate B's pass.
  • timelock never approves before unlock_ms; unlock_ms = 0 always approves; u64::MAX decodes without overflow.

Canonical source: @meddleware/sealed-storage-sui → docs/onchain/api-reference.md — maintained with the Move package; edit it there, not on this site.

2026 Meddleware. All jams preserved.