Skip to content

Store

Defined in: packages/store-kit/src/Store.ts:172

A specialized Store class extending from @tanstack/store, designed for managing and interacting with application-level state on the Algorand blockchain.

The class provides methods to deploy, initialize, save, and retrieve application state stored in Algorand application storage boxes. It leverages the AlgorandClient for blockchain interactions and a Deployer for deploying and signing transactions.

Get Started

import {Store} from '@awesome-algorand/store-kit'
const store = new Store({
foo: "bar",
baz: 123,
})
await store.setAlgorand(algorand).init("contract-name")

See the Store.constructor method for more information on how to instantiate the class.

Template

The type of the state managed by the store. This may be omitted in favor of type inference.

Extends

  • Store<TState>

Type Parameters

• TState extends object

Implements

Constructors

new Store()

new Store<TState>(initialState, options): Store<TState>

Defined in: packages/store-kit/src/Store.ts:412

A specialized Store class extending from @tanstack/store, designed for managing and interacting with application-level state on the Algorand blockchain.

Stores need both a valid Deployer and AlgorandClient to interact with the blockchain. This is done via the Store.setAccount and Store.setAlgorand methods respectively

Parameters

initialState

TState

initial data to populate the store with

options

StoreOptions = {}

Returns

Store<TState>

Examples

Create

import {Store} from '@awesome-algorand/store-kit'
const bearStore = new Store({
count: 5,
species: "Grizzly"
})

Configure

import {AlgorandClient} from '@algorandfoundation/algokit-utils'
bearStore
.setAlgorand(AlgorandClient.fromEnvironment())

Add Account

await bearStore
// Add a Deployer account to the store
.setAccount(await algorand.account.fromEnvironment('DEPLOYER'))

Deploy

await bearStore
// initialize the typed clients and deploy the contract by default
.init('grizzly-bears')
console.log(bearStore.appId)

Hydrate

[!WARNING] Only hydrate the store when it has been initialized

await bearStore
// Set the application id and rehydrate the store
.setAppId(1337n)

Overrides

BaseStore<TState>.constructor

Properties

appId

appId: null | bigint = null

Defined in: packages/store-kit/src/Store.ts:352


client

client: null | LodashClient = null

Defined in: packages/store-kit/src/Store.ts:345

Experimental: On-chain client for the Lodash application.


conflicts

conflicts: Map<string, Conflict>

Defined in: packages/store-kit/src/Store.ts:182

Active unresolved conflicts keyed by path (without PREFIX).


conflictsVersion

conflictsVersion: number = 0

Defined in: packages/store-kit/src/Store.ts:184

Monotonic counter bumped on every conflict mutation.


contractName

contractName: string = ""

Defined in: packages/store-kit/src/Store.ts:224

Local-only contract descriptor that mirrors the contract’s three global state slots (contract_name, contract_type, schema_app_id). Mutated via setName, setContractType, and setSchemaAppId.


contractType

contractType: ContractType = "object"

Defined in: packages/store-kit/src/Store.ts:225


deltas

deltas: Map<string, { t: number; v: any; }>

Defined in: packages/store-kit/src/Store.ts:178


deltasVersion

deltasVersion: number = 0

Defined in: packages/store-kit/src/Store.ts:180

Monotonic counter bumped on every delta mutation to drive React re-renders.


lastError

lastError: null | Error = null

Defined in: packages/store-kit/src/Store.ts:177


lastSubmittedTxIds

lastSubmittedTxIds: Map<string, number>

Defined in: packages/store-kit/src/Store.ts:199

TxIds submitted by the most recent save() invocations — used by adapters (notably ChainAdapter) to skip self-triggered sync churn.


listeners

listeners: Set<Listener<TState>>

Defined in: node_modules/@tanstack/store/dist/esm/store.d.ts:19

Inherited from

BaseStore.listeners


network

network: NetworkId = NetworkId.LOCALNET

Defined in: packages/store-kit/src/Store.ts:208


options?

optional options: StoreOptions<TState, (cb) => TState>

Defined in: node_modules/@tanstack/store/dist/esm/store.d.ts:22

Inherited from

BaseStore.options


pendingContractName

pendingContractName: null | string = null

Defined in: packages/store-kit/src/Store.ts:233

Pending contract-descriptor changes awaiting an on-chain push. null slot means “no change pending” for that field; non-null is the value to write.


pendingContractType

pendingContractType: null | ContractType = null

Defined in: packages/store-kit/src/Store.ts:234


pendingSchemaAppId

pendingSchemaAppId: null | bigint = null

Defined in: packages/store-kit/src/Store.ts:235


prevState

prevState: TState

Defined in: node_modules/@tanstack/store/dist/esm/store.d.ts:21

Inherited from

BaseStore.prevState


schema

schema: null | CompiledSchema

Defined in: packages/store-kit/src/Store.ts:216

Compiled JSON-Schema bound to this store, or null when no schema was configured. When set, all pack/unpack/toPaths/getStorageMBR/ fromBoxes(Raw) calls thread the schema through so matching subtrees use ARC4 packing instead of JSON.


schemaAppId

schemaAppId: bigint = 0n

Defined in: packages/store-kit/src/Store.ts:226


schemaVersion

schemaVersion: number = 0

Defined in: packages/store-kit/src/Store.ts:238

Monotonic counter bumped whenever schema or any pending contract field mutates.


setState()

setState: (updater) => void

Defined in: node_modules/@tanstack/store/dist/esm/store.d.ts:25

Parameters

updater

(cb) => TState

Returns

void

Inherited from

BaseStore.setState


state

state: TState

Defined in: node_modules/@tanstack/store/dist/esm/store.d.ts:20

Inherited from

BaseStore.state


status

status: StoreStatus = "unknown"

Defined in: packages/store-kit/src/Store.ts:176


subscribe()

subscribe: (listener) => () => void

Defined in: node_modules/@tanstack/store/dist/esm/store.d.ts:24

Parameters

listener

Listener<TState>

Returns

Function

Returns

void

Inherited from

BaseStore.subscribe

Accessors

adapters

Get Signature

get adapters(): readonly RemoteAdapter[]

Defined in: packages/store-kit/src/Store.ts:261

Returns

readonly RemoteAdapter[]


dirty

Get Signature

get dirty(): boolean

Defined in: packages/store-kit/src/Store.ts:240

Returns

boolean


hasConflicts

Get Signature

get hasConflicts(): boolean

Defined in: packages/store-kit/src/Store.ts:257

Returns

boolean


schemaDirty

Get Signature

get schemaDirty(): boolean

Defined in: packages/store-kit/src/Store.ts:249

True when any contract-descriptor field (name / type / schemaAppId) has a pending on-chain push. Surfaced in the UI so the user can Save/Deploy schema-app rebinds without needing a data delta.

Returns

boolean

Methods

addAdapter()

addAdapter(adapter): this

Defined in: packages/store-kit/src/Store.ts:1108

Parameters

adapter

RemoteAdapter

Returns

this


applyRemote()

applyRemote(remoteData, meta): void

Defined in: packages/store-kit/src/Store.ts:948

Merge a remote snapshot into local state honoring pending deltas and the configured per-path ConflictStrategy. This is the single funnel through which all remote update sources (init, sync, ChainAdapter, and any third-party RemoteAdapter via onRemoteChange) reconcile state.

Per-path rules:

  1. No pending delta ⇒ remote wins (including deletions).
  2. Pending delta + remote matches baseline ⇒ local wins silently.
  3. Pending delta + remote diverged from baseline ⇒ resolved by strategy: manual (default) records a Conflict; local-wins keeps the delta; remote-wins discards the delta; last-write-wins picks the newer timestamp.

Baseline is updated unconditionally so subsequent collisions are judged against the most recently observed remote value.

Parameters

remoteData

Record<string, any>

meta
source?

string

txIds?

string[]

Returns

void


assemble()

assemble(): Promise<TState>

Defined in: packages/store-kit/src/Store.ts:1709

Assembles and retrieves data stored in the storage boxes of an application, decodes the content, and formats it into a structured object.

Returns

Promise<TState>

Returns a Promise that resolves to an object of type T, containing the decoded and processed data from the application storage boxes.

Throws

Throws an error if the client is undefined, indicating that initialization has not been completed.

Implementation of

StoreInterface.assemble


balance()

balance(): Promise<bigint>

Defined in: packages/store-kit/src/Store.ts:543

Returns

Promise<bigint>


clearError()

clearError(): void

Defined in: packages/store-kit/src/Store.ts:1098

Clear the latest lastError and reset status to ready if currently error.

Returns

void


converge()

converge(state): Promise<LodashComposer<[]>>

Defined in: packages/store-kit/src/Store.ts:1668

Parameters

state

any

Returns

Promise<LodashComposer<[]>>


destroy()

destroy(state): Promise<void>

Defined in: packages/store-kit/src/Store.ts:1739

Deletes the deployed application from-chain, closing out the app account’s remaining balance to the creator (the current deployer), and resets local state.

The flow is:

  1. Enumerate every box on the app and remove them in chunked groups — this is required to release the per-box MBR back to the app account so the full balance can be reclaimed.
  2. Re-read the app account balance and, if above ACCOUNT_MIN_BALANCE, reclaim(balance - MIN) drains the recoverable balance back to the creator via inner payment.
  3. delete.bare() issues the DeleteApplication call in the same group as the final reclaim.
  4. Local Store fields (appId, client, deltas, etc.) are reset and the supplied state (typically the user’s current local state) is re-emitted so reactive consumers settle to a clean baseline.

Parameters

state

TState

Returns

Promise<void>


dispose()

dispose(): Promise<void>

Defined in: packages/store-kit/src/Store.ts:1250

Returns

Promise<void>


findExistingClient()

findExistingClient(name?): Promise<null | LodashClient>

Defined in: packages/store-kit/src/Store.ts:737

Parameters

name?

string

Returns

Promise<null | LodashClient>


getAlgorand()

getAlgorand(): null | AlgorandClient

Defined in: packages/store-kit/src/Store.ts:713

Returns the AlgorandClient bound to the current instance.

Returns

null | AlgorandClient

Implementation of

StoreInterface.getAlgorand


init()

init(name?, sync?): Promise<Store<TState>>

Defined in: packages/store-kit/src/Store.ts:788

Initializes the store with the provided configurations. This method sets up a client instance, handles deployment if necessary, and syncs the state as required.

Parameters

name?

string = "Lodash"

The identifier or name of the app/client to be initialized.

sync?

boolean = true

Indicates whether to synchronize the state after initialization.

Returns

Promise<Store<TState>>

Throws

Error Will throw an error if a client already exists, if the Algorand client is missing, or if required prerequisites for initialization or deployment are not met.


isSelfSubmittedGroup()

isSelfSubmittedGroup(txIds): boolean

Defined in: packages/store-kit/src/Store.ts:309

Returns true if every supplied txId was submitted by a recent local save() (i.e. the adapter should ignore this block to avoid racing with delta-clear).

Parameters

txIds

string[]

Returns

boolean


noteRound()

noteRound(round): void

Defined in: packages/store-kit/src/Store.ts:317

Parameters

round

number

Returns

void


onRemoteChange()

onRemoteChange(remoteData, meta): void

Defined in: packages/store-kit/src/Store.ts:1063

Public alias for third-party adapter integrations. Funnels remote snapshots through applyRemote so all merge / conflict rules apply.

Parameters

remoteData

Record<string, any>

meta
source?

string

txIds?

string[]

Returns

void


removeAdapter()

removeAdapter(adapter): Promise<Store<TState>>

Defined in: packages/store-kit/src/Store.ts:1120

Parameters

adapter

RemoteAdapter

Returns

Promise<Store<TState>>


resolveConflict()

resolveConflict(path, choice): void

Defined in: packages/store-kit/src/Store.ts:1075

Resolve an unresolved manual conflict for path. choice:

  • "local" — keep the pending delta, clear the conflict.
  • "remote" — discard the delta, apply the remote value, clear the conflict.

Parameters

path

string

choice

"remote" | "local"

Returns

void


save()

save(): Promise<void>

Defined in: packages/store-kit/src/Store.ts:1298

Saves the current state to the network. This method ensures that the app is initialized and a deployer is provided before attempting to save. It synchronizes the state by mapping paths to their respective values and storing them on-chain.

Returns

Promise<void>

Resolves when the state has been successfully saved to the network.

Throws

Throws an error if the app has not been initialized with a client or if a deployer is not provided.

Example

Basic Usage

// Import a custom Store instance
import {exampleStore} from "./exampleStore"
// Save the state to the network
await exampleStore.save()

Custom Deployer

Deployer can be passed as an argument to the save method

// Import a custom Store instance
import {exampleStore} from "./exampleStore"
// Define a deployer
const deployer = await algorand.account.fromMnemonic("example deployer mnemonic")
// Save the state to the network
await exampleStore.save(deployer)

setAccount()

setAccount(deployer, sync): Store<TState>

Defined in: packages/store-kit/src/Store.ts:553

Sets the account for the given deployer and determines synchronization behavior.

This will override any TransactionSigners associated with the WalletManager.

Parameters

deployer

The deployer instance to set, or null to clear the account.

null | TransactionSignerAccount

sync

boolean

A boolean indicating whether the account should be synchronized.

Returns

Store<TState>

Implementation of

StoreInterface.setAccount


setAlgorand()

setAlgorand(algorand): Store<TState>

Defined in: packages/store-kit/src/Store.ts:704

Binds the provided AlgorandClient to the current instance.

Parameters

algorand

AlgorandClient

Returns

Store<TState>

Implementation of

StoreInterface.setAlgorand


setAppId()

setAppId(appId, sync): Promise<Store<TState>>

Defined in: packages/store-kit/src/Store.ts:559

Sets the application ID for the store.

Parameters

appId

bigint

The application ID to associate with the store.

sync

boolean

Optionally trigger all lifecycle events, defaults to false

Returns

Promise<Store<TState>>

Implementation of

StoreInterface.setAppId


setClient()

setClient(client, sync): Promise<Store<TState>>

Defined in: packages/store-kit/src/Store.ts:722

Binds the provided LodashClient to the current instance.

Parameters

client

LodashClient

sync

boolean = true

Returns

Promise<Store<TState>>


setContractType()

setContractType(type): this

Defined in: packages/store-kit/src/Store.ts:519

Set the contract type discriminator ("object" or "schema"). Queues an on-chain set_contract_type call for the next save/deploy.

Parameters

type

ContractType

Returns

this


setManager()

setManager(manager): Store<TState>

Defined in: packages/store-kit/src/Store.ts:607

Binds the provided WalletManager to the current instance. If the WalletManager has an active address, it initializes the deployer object using the active address and transaction signer. Additionally, sets up a subscription to handle state changes in the WalletManager.

Parameters

manager

The wallet manager instance to be bound.

null | WalletManager

Returns

Store<TState>

Implementation of

StoreInterface.setManager


setName()

setName(name): this

Defined in: packages/store-kit/src/Store.ts:504

Set the human-readable contract name. Queues an on-chain set_contract_name call for the next save/deploy if the value differs from what is currently bound.

Parameters

name

string

Returns

this


setSchema()

setSchema(config): this

Defined in: packages/store-kit/src/Store.ts:484

Replace (or clear) the JSON-Schema bound to this store at runtime.

The schema document is a pure CLIENT-SIDE concern — nothing about it is persisted on-chain. Callers that want a discoverable pointer to where the schema lives should deploy a sibling Lodash app of type === "schema" and use setSchemaAppId.

Pass null to clear. After a rotation, callers should await assemble() since existing boxes packed under the previous schema may decode differently.

Parameters

config

null | JSONSchema | SchemaConfig

Returns

this


setSchemaAppId()

setSchemaAppId(appId): this

Defined in: packages/store-kit/src/Store.ts:533

Set (or clear with 0n) the schema-app pointer. Queues an on-chain set_schema_app_id call for the next save/deploy.

Parameters

appId

bigint

Returns

this


sync()

sync(): Promise<void>

Defined in: packages/store-kit/src/Store.ts:919

Synchronizes the local state with the on-chain box state. If a path has a pending local delta, it is preserved; otherwise, the remote value wins.

Returns

Promise<void>

Implementation of

StoreInterface.sync


toChunks()

toChunks(): (undefined | string)[][]

Defined in: packages/store-kit/src/Store.ts:1269

Returns

(undefined | string)[][]


toMBR()

toMBR(): bigint

Defined in: packages/store-kit/src/Store.ts:571

Returns

bigint


toMBRDelta()

toMBRDelta(): Promise<bigint | 0>

Defined in: packages/store-kit/src/Store.ts:1264

TODO: get delta and update MBR

Returns

Promise<bigint | 0>