Getting Started with Storage Programs
This guide walks you through creating a Storage Program, writing data to it, and reading it back over RPC.Prerequisites
- Bun (latest) installed
- The Demos SDK:
bun add @kynesyslabs/demosdk@latest - A Demos wallet with enough balance to cover storage fees (1 DEM per 10 KB chunk, minimum 1 DEM)
- Access to a Demos Network RPC node
The mental model
Every Storage Program operation follows the same four-step shape:- Build a typed payload with one of the
StorageProgram.*static helpers (createStorageProgram,writeStorage,updateAccessControl,deleteStorageProgram, plus the granularsetField/setItem/appendItem/deleteField/deleteItem). - Sign it with
demos.storagePrograms.sign(payload)— this returns a signedTransaction. - Confirm gas with
demos.confirm(tx). - Broadcast with
demos.broadcast(validityData)(ordemos.broadcastAndWaitfor deterministic inclusion).
demos.storagePrograms.read(address) directly, no transaction required.
Step 1: Connect
demos.getAddress() is synchronous and returns the connected wallet’s address as a string. It does not return a Promise.Step 2: Build the create payload
StorageProgram.createStorageProgram(deployer, programName, data, encoding, acl?, options) builds the payload for the create transaction. The deterministic storage address is derived inside the helper — you don’t compute it separately.
Step 3: Sign, confirm, broadcast
broadcast and broadcastAndWait and the error types each can throw.
Step 4: Write data
writeStorage replaces the entire data field of the program. For surgical updates use the granular operations below.
Step 5: Read data
Reads are served directly over RPC — no transaction, no fee.StorageProgramResponse from @kynesyslabs/demosdk/storage. Notable fields: owner, programName, encoding, data, metadata, storageLocation, sizeBytes, createdAt, updatedAt. See RPC Queries for queries beyond the address-based lookup.
Granular updates
For JSON-encoded programs, you can change individual fields and array elements without rewriting the whole document:StorageProgramPayload you sign + confirm + broadcast like any other write. Granular operations are JSON-only — they are rejected for binary-encoded programs.
Updating access control and deleting
Fees
Storage Programs are billed at 1 DEM per 10 KB chunk, minimum 1 DEM per write. Calculate the fee for a payload before sending it:bigint in OS (1 DEM = 10⁹ OS). See Amounts & Denominations for the conversion helpers.
Resource limits
| Limit | Value | Constant |
|---|---|---|
| Max payload size | 1 MB (1,048,576 bytes) | STORAGE_PROGRAM_CONSTANTS.MAX_SIZE_BYTES |
| Max JSON nesting depth | 64 | STORAGE_PROGRAM_CONSTANTS.MAX_JSON_NESTING_DEPTH |
| Pricing chunk | 10 KB (10,240 bytes) | STORAGE_PROGRAM_CONSTANTS.PRICING_CHUNK_BYTES |
| Fee per chunk | 1 DEM (= 10⁹ OS) | STORAGE_PROGRAM_CONSTANTS.FEE_PER_CHUNK |
Where to go next
- Operations — when to use create vs. write vs. granular ops, and the full lifecycle.
- Access Control —
owner/public/restrictedmodes, allowlists, blacklists, and group permissions. - RPC Queries — full read-side surface, including the node-level RPC endpoints for listing, searching, and field-level lookups.
- API Reference — every
StorageProgramstatic helper, payload shape, and response interface. - Cookbook — end-to-end recipes (public profile, team workspace, binary attachments).