Skip to content
ENBANKDesk

Enbank docs

Preview ledger

The local JSON record behind the desk, including keys, types, and reset.

On this page

Storage keys

Two keys, both on localStorage, both versioned so a breaking shape can be ignored rather than migrated.

KeyWriterContents
enbank.wallet.v1saveWallet{ address, privateKey }
enbank.preview.v1BankProviderThe full Desk JSON

On load, the provider reads the preview key once. parseDesk either replaces the seed or is ignored. After ready flips true, every desk change is written back. The wallet key is independent. Setting an address on the desk does not rewrite the wallet, and clearing the wallet does not rewrite the desk.

A separate sessionStorage flag, enbank.intro, only hides the homepage loader. It is not part of the ledger.

Desk shape

type Desk = {
  address: string;
  custom: boolean;     // true when address !== PREVIEW_ADDRESS
  revealed: boolean;
  balances: Balance[]; // one row per asset
  positions: Position[];
  activity: ActivityItem[];
  transit: Transit;
};

Position carries id, name, desk, movesToday, total, status (Ongoing | Settled | Queued), roundTrip, and span (month | year). Activity fields are listed on Markets. Transit fields are listed on Sealed transfers.

Identifiers for new positions, sends, and allocations come from crypto.randomUUID(). Seed rows use stable ids: aureum, harbor, northline, cinder, shield, inbound, aureum-alloc, harbor-sweep.

Parse rules

parseDesk returns null on any failed check, and the provider keeps createDesk(). The checks are structural, not semantic:

  • JSON parses, and the value is an object.
  • address passes isAddress. custom and revealed are booleans. A mismatch between custom and the address is stored as written.
  • Balances are non-negative numbers on the three known assets, with each asset present once.
  • Every position and activity row matches its enum and string fields. Amounts may be null only on activity.
  • Transit has an asset, a destination string, an eta string, and numeric done and total with total >= 0.

Unknown extra keys are dropped, because the return value is rebuilt field by field. There is no version field inside the JSON. The version is the storage key.

Amounts

Storage uses JavaScript numbers, rounded to 8 decimal places on write via roundAmount. Display uses Intl.NumberFormat with 2 fraction digits for dollars and up to 4 for SOL. The form is stricter than storage: it rejects more than 2 or 4 decimal places before send is called.

illustrativeUsd is not stored. It is derived when the vault renders. Changing SOL_USD would change the headline without a ledger migration.

Export

downloadLedger builds a CSV named enbank-preview-ledger.csv with columns time, title, detail, amount, asset, status. An empty activity list downloads nothing and returns false. Cells containing quotes, commas, or newlines are escaped. When reveal is off, the amount cell is the literal sealed rather than a blank, so a later reader can tell a hidden figure from a row that never had one.

Reset calls createDesk(), clears the desk search query, and toasts "Preview desk restored." The wallet key survives a reset. Account operations that do touch the key are on Accounts and keys.