feat(server,cli): auto-renew statement-store allowances#308
Draft
pgherveou wants to merge 174 commits into
Draft
feat(server,cli): auto-renew statement-store allowances#308pgherveou wants to merge 174 commits into
pgherveou wants to merge 174 commits into
Conversation
Adds the canonical testing module (api/testing.rs) and its v01/v02/versioned wiring used by the Rust host runtime and generated clients.
New crate defining the host syscall traits (storage, navigation, consent, permissions, ...) that host runtimes implement. Types are re-exported from truapi::versioned/v01 rather than redefined.
WASM host runtime that hosts implement: dispatcher, SCALE frames, subscription streams, chain runtime, host logic (sessions, SSO pairing, permissions, statement store, dotns) and the wasm bindings. Includes the committed generated dispatcher/wire-table under src/generated/.
…backs Extends the rustdoc-JSON code generator to emit the Rust dispatcher and wire table consumed by truapi-server, plus the TS host-callbacks adapter. Golden tests pin the emitted shapes.
New WASM-backed host runtime package embedding the Rust core, with web iframe and Web Worker entry points. Updates the @parity/truapi client (SCALE, sandbox, transport) and drops the obsolete explorer 0.3.2 codegen snapshot.
Updates CLAUDE.md/README, CI workflows, Makefile, deny.toml, changesets, and linguist attributes for generated code, and bumps the dotli submodule to the host integration that consumes the WASM runtime.
Adds the canonical testing module (api/testing.rs) and its v01/v02/versioned wiring used by the Rust host runtime and generated clients.
New crate defining the host syscall traits (storage, navigation, consent, permissions, ...) that host runtimes implement. Types are re-exported from truapi::versioned/v01 rather than redefined.
…backs Extends the rustdoc-JSON code generator to emit the Rust dispatcher and wire table consumed by truapi-server, plus the TS host-callbacks adapter. Golden tests pin the emitted shapes.
Decode ring revisions correctly for Bulletin allowance claims. Add CLI-managed signer accounts, network presets, and script-capable host modes. Regenerate headless signing and pairing diagnosis reports with zero failures.
Pin responder wire fixtures to @novasamatech/host-papp 0.8.11 and expose a global log-level flag for paired-host diagnostics.
BREAKING CHANGE: use bare /script for the editable getUserId template, or run whoami.ts explicitly by path.
Statement-store allowances are registered per UTC-day period and die at
the boundary (~12h average lifetime plus a 1h grace), after which product
statement submissions fail with "no allowance set for account". RFC-0010
assigns keeping them alive to the Account Holder; for the headless host
that is the signing host, which until now only registered allowances on
demand for the current period.
Core (truapi-server):
- statement_allowance/renewal: chain-pure pass that re-registers every
resolved target for the current period (AlreadyAllocated = fresh no-op,
chain state is the truth), continues past per-target failures, stops on
slot exhaustion, and computes the next tick delay
(min(1h, period boundary + 2min)).
- signing_host/allowance_renewal: durable target ledger persisted via
CoreStorage (new StatementRenewalTargets slot) storing derivation
recipes (//wallet//sso, //allowance//statement-store//{product}) so
entries survive root-entropy rotation, plus raw device keys; renew_now
driver and an idempotent Spawner-based loop holding only weak refs.
- A registration lock serializes the renewal pass (per target) with
on-demand allocation; allocate_statement_store_allowance now records
its product target in the ledger.
- SigningHostRuntime gains track_statement_renewal_targets,
renew_statement_allowances (primary one-pass API, FFI-friendly for
mobile OS schedulers), start_statement_allowance_renewal, and
next_statement_renewal_delay.
CLI (truapi-host):
- The signing host starts the renewal loop at runtime construction and
tracks the wallet-sso + peer device targets after pairing registration.
- New /renew command (interactive and `signing-host exec '/renew'`)
runs one pass, prints per-target outcomes, and marks auto-managed
accounts exhausted on slot exhaustion so the next pairing rotates.
Contributor
|
Note that mobile does that from a worker: doing so when app is running is not 100% reliable since the slot might expire when the app is not running |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Statement-store allowances are registered per UTC-day period (
period = unix_seconds / 86400) and die at the boundary, ~12h average lifetime plus a ~1h grace, after which product statement submissions fail with "no allowance set for account". Per RFC-0010, keeping an allowance alive is the Account Holder's job; in the headless world the signing host plays that role, but it only registered allowances on demand for the current period and never renewed. This ports the mobile app's auto-renewal model into the shared core.Design
Rule: core owns what to renew and how; the host owns only when.
statement_allowance/renewal.rs— chain-pure pass reusing the existingregister_statement_accountorchestrator. No persisted(period, seq): chain state is the truth via theAlreadyAllocatedfast path.signing_host/allowance_renewal.rs— target ledger persisted throughCoreStorage(newStatementRenewalTargetsslot). Entries are derivation recipes (WalletSso,ProductStatementAllowance{product_id}) so they survive the CLI's root-entropy rotation on slot exhaustion; only pairing peer device keys are raw account ids. Driver (renew_now) + idempotent loop spawned viaSpawner(weak refs only, dies with the runtime;futures/futures-timeronly, no tokio in core).allocate_statement_store_allowance, which now also records its product target in the ledger.SigningHostRuntime(native-only):renew_statement_allowances()(primary one-pass entry, what a mobile WorkManager/BGTaskScheduler shim would call over FFI),start_statement_allowance_renewal(),track_statement_renewal_targets(),next_statement_renewal_delay().CLI
build_signing_runtimestarts the renewal loop (covers startup and/sessionswitches, all modes).[WalletSso, device]in the ledger./renewcommand (interactive +signing-host exec '/renew') as the manual escape hatch: prints per-target outcomes and, on slot exhaustion, marks auto-managed accounts exhausted so the next pairing rotates.Tests
sso_responderderivations./renewparse accept/reject; codegen golden updated for the newCoreStorageKeyvariant.cargo +nightly fmt --check,clippy --workspace --all-targets --all-features -D warnings,cargo test --workspace,cargo check --target wasm32-unknown-unknown -p truapi-server(renewal is native-only; on web the paired mobile app is the Account Holder).Follow-ups (out of scope)
ProductBulletinAllowanceledger variant)./renew) can trigger account rotation.register_pairing_allowancesinto core to close the residual CLI-side registration race (benign: duplicate submits rescan).