Skip to content

refactor: statement submit core#217

Merged
johnthecat merged 12 commits into
release/0.8.7from
refactor/statement-submit-core
Jun 11, 2026
Merged

refactor: statement submit core#217
johnthecat merged 12 commits into
release/0.8.7from
refactor/statement-submit-core

Conversation

@johnthecat

Copy link
Copy Markdown
Contributor

statement-store: standalone sign-and-submit primitives over a shared expiry allocator

What

This branch extracts the statement signing and submission logic out of the session into a small set of standalone primitives in @novasamatech/statement-store, exports them from the package index, and rewires the session to consume them. External writers (e.g. a desktop V2 SSO session) can now submit statements with the same expiry/priority and retry behaviour the session uses, instead of duplicating it.

New exports

  • createExpiryAllocator() — hands out strictly increasing statement expiries for one signing account. When the chain rejects a submission with a higher minimum, the allocator adopts that minimum so the next submit clears it. All writers signing with the same account should share one allocator — independent counters can tie on same-second priorities, which the store rejects.
  • submitStatementOnce(params) — a single attempt: allocate the next expiry, prove and submit the statement, and on a priority rejection raise the allocator floor to the chain-reported minimum.
  • signAndSubmitStatement(params) / submitWithRetry(submit, options) — the same with a retry policy on top: separate budgets for transient failures and priority rejections, a per-retry delay schedule, and a liveness gate.
  • isPriorityTooLow(error) — narrows an error to ExpiryTooLowError / AccountFullError.
  • PRIORITY_EPOCH_OFFSET — the spec's priority epoch base (see below).
const allocator = createExpiryAllocator(); // one per signing account

await signAndSubmitStatement({
  statementStore,
  prover,
  allocator,
  channel,
  topics,
  data,
  retry: { attempts: 0, priorityAttempts: 3, delaysMs: [500, 1500, 3000] },
});

Behaviour changes

  • host-papp: the SSO request size limit was raised from 254 KiB to 500 KiB, tracking the mobile statement allowance.
  • Priority epoch aligned with mobile. The statement priority (the expiry's low word) is now counted from the spec's priority epoch, matching iOS and Android. Previously it was the raw Unix timestamp, so a TS-written statement always outranked a mobile-written one in cross-client priority comparisons.
  • AccountFullError is handled like ExpiryTooLowError. Both are priority rejections: while a submission is still live the session resyncs its expiry above the chain-reported minimum and keeps retrying past the transient-failure cap; once the submission has been superseded on its channel, the rejection is absorbed as success (it lost the race to a newer statement — re-answering would clobber it). Priority rejections never surface to session callers.
  • createSession accepts an optional shared allocator. Defaults to a private one, identical to the previous behaviour.
  • Disposed sessions fail fast. submitRequestMessage / submitResponseMessage reject immediately after dispose(), and a session disposed while initialization is in flight no longer re-activates or submits queued work.

@johnthecat johnthecat merged commit b1b428d into release/0.8.7 Jun 11, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant