Skip to content

ARC-87

ARC-87 (Draft, Standards Track) standardizes the key names used to store complex data (JSON, blobs) in application state, so any reader can address a single value directly on-chain. StoreKit is one of its reference implementations; the language-neutral vectors live in arc-87-reference.

Rules

All rules are about key names:

  • SHOULD be prefixed with o_ (for discovery/indexing).
  • MUST separate nested object keys with ..
  • SHOULD index collections with [N]; readers MUST also accept .N (o_blobs[1] and o_blobs.1 address the same value).
  • SHALL escape a segment that contains ., [, ], $ or { by wrapping the literal segment as ${literal}; readers MUST NOT interpret . or [N] inside an escaped span.

Objects

{
"alice": "APZK5I5UAURBDSGFBEHYK3B235CDGYGXG6BAGC34ZHGDPQOJTBM5OSG6IE",
"bob": "BX2RWWE77PA7JNNIPWUBQYX44LDHDE6EBRFEPLJUOMBNLT4ATQ3SA7UGEQ",
"metadata": { "rp": "algorand.co" }
}
keyvalue
o_aliceAPZK5I5UAURBDSGFBEHYK3B235CDGYGXG6BAGC34ZHGDPQOJTBM5OSG6IE
o_bobBX2RWWE77PA7JNNIPWUBQYX44LDHDE6EBRFEPLJUOMBNLT4ATQ3SA7UGEQ
o_metadata.rpalgorand.co

Collections and blobs

A value larger than one box is chunked into a collection:

{ "index": 2, "mime": "text/plain", "blobs": ["...", "..."] }
keyvalue
o_index2
o_mimetext/plain
o_blobs[0]...
o_blobs[1]...

Escaping

{ "a.b": "dotted", "c[0]": "indexed" }
keyvalue
o_${a.b}dotted
o_${c[0]}indexed

The ${literal} span is opaque to readers and is unwrapped to the original segment when the object is assembled.

Out of scope

  • Long keys. A box name is at most 64 bytes, prefix included. Templating longer paths is left to a future specification; the reference implementation rejects them.
  • Value encoding. Values that are ARC-4 encoded need knowledge of their types to decode; mapping ARC-4 containers to key paths is left to a future specification.
  • Private data is not addressed.

How StoreKit lays out a store

One store is one Lodash application; every leaf of the object is one box whose name is the prefix plus the leaf’s path. For example, the Quick Start store with a list added:

new Store({ count: 5, type: "Grizzly", tags: ["brown", "big"] })
box namevalue
orm_count5
orm_type"Grizzly"
orm_tags[0]"brown"
orm_tags[1]"big"
  • Nested keys are joined with . and array items written as [N]; on read both [N] and .N are accepted.
  • Without a schema each value is the UTF-8 JSON of the leaf. With a JSON Schema, covered paths hold raw ARC-4 bytes, and x-storekit-box: "whole" packs a subtree into one box.
  • Names are limited to 64 bytes and values to 32 KiB (MAX_KEY_SIZE, MAX_BOX_SIZE).

Because every value is directly addressable, reading a store needs nothing but the app’s boxes — and reading the boxes at a past round gives the store’s past state. See Time travel.