Skip to content

fix: phone-mode deploy signing, slot key derivation, and session selection#276

Merged
UtkarshBhardwaj007 merged 1 commit into
mainfrom
fix/phone-deploy-storage-and-sessions
Jun 4, 2026
Merged

fix: phone-mode deploy signing, slot key derivation, and session selection#276
UtkarshBhardwaj007 merged 1 commit into
mainfrom
fix/phone-deploy-storage-and-sessions

Conversation

@UtkarshBhardwaj007
Copy link
Copy Markdown
Member

Problem

Phone-mode pg deploy failed in three stacked ways, and pg init allowance requests could silently never reach the phone:

  1. "Mobile transaction signing rejected: message too big" with no phone prompt. Since bulletin-deploy 0.8.x, passing signer routes Bulletin STORAGE through it too. Chunk txs carry up to 2 MiB of callData; the phone signing channel (statement store) rejects messages client-side far below that (4 KiB on the pinned host-papp 0.7.9; the Android app caps statements at 256 KiB regardless), so every chunk died before the phone was contacted.
  2. AncientBirthBlock chunk failures. The SDK's createSlotAccountSigner derives the wrong public key from phone-issued 64-byte slot keys (missing schnorrkel x8 scalar normalization). Verified on-chain: the phone's grant sits on the normalized address; the SDK-derived address has no authorization. bulletin-deploy therefore silently fell back to its shared testnet pool account, where other users' pending transactions create nonce gaps and mortal chunk txs (16-block era) expire while queued.
  3. Expired sessions hung for minutes. The statement-store allowance lapses ~2 days after login and cannot be renewed remotely (renewal requests ride the expired channel). The adapter logs NoAllowanceError without rejecting, so signing hung for the 180s SDK timeout under a misleading "transaction watcher silent" error.
  4. Stale session selection. The session repository appends on each pairing and the CLI used sessions[0] (the OLDEST) everywhere, so after a re-pair, requests (including init's allowance approval) were sent into a session the phone no longer serves, disappearing with no error.

Fixes

  • Bump bulletin-deploy to 0.8.3 (first release with storageSigner support) and thread the BulletInAllowance slot key as storageSigner/storageSignerAddress in phone mode (resolveStorageSignerOptions, wired into deploy and decentralise). DotNS and registry publish keep the phone signer.
  • New allowances/slotSigner.ts: correct schnorrkel-normalized derivation, frozen-vector tested, byte-exact mirror of bulletin-deploy's storage-signer. correctedSlotSigner swaps the SDK signer after every ensureSlotAccountSigner/createSlotAccountSigner call, reading the cache from the adapter's own storage namespace. Fixes the storage, metadata, and contract allowance paths at once.
  • New deploy/storageQuota.ts: pre-upload quota check against the estimated upload size with a one-tap Increase when short. Warn-and-proceed on residual shortfall (whether the chain enforces the extent is unconfirmed; per the bulletin-deploy author, the authorization is what counts), never blocks.
  • wrapSignerWithSssFastFail: detects NoAllowanceError during phone signing and rejects within ~200ms with a playground logout / playground init remedy. Re-entrant console interception, interval cleaned up on every path.
  • New loginStamp.ts: records login time (cleared by logout); deploy preflight warns when the session is older than 2 days. Warn-only, missing stamp produces no output.
  • newestSession() in auth.ts: all flows operate on the most recent pairing; waitForLogin best-effort disconnects stale older sessions after a successful login.
  • CLAUDE.md: new invariants for all of the above, plus an honest note that pnpm build (bun) does not typecheck and the tree carries a 13-error tsc --noEmit baseline (burn-down + CI step is an open follow-up).

Testing

  • 629/629 unit tests (24 new across slotSigner, loginStamp, storageQuota, signerMode, run, decentralize, auth, sessionSigner; every new behavior watched fail first).
  • pnpm format:check, pnpm lint:license, pnpm build green; tsc --noEmit error count unchanged from the pre-existing baseline (13).
  • On-chain verification on paseo-next-v2: the phone-issued grant sits on the normalized slot address (10 txs / 4 MiB, unused); the SDK-derived address has no authorization; pool account 9's nonce matched the failing chunk's nonce exactly.
  • Manual: phone-mode pg init allowance grant now arrives after re-pairing; chunk uploads sign locally with no phone prompts.

Upstream follow-ups (not in this PR)

  • product-sdk: createSlotAccountSigner must normalize 64-byte schnorrkel keys (root cause of the wrong-address derivation; this PR carries a local workaround to delete once fixed).
  • bulletin-deploy: pool-path chunk retries reuse the original nonce and cannot heal a permanent nonce gap; raw AncientBirthBlock JSON deserves a friendly message.

Changeset included (patch).

…ction

- Bump bulletin-deploy to 0.8.3 and pass the BulletInAllowance slot key as
  storageSigner so Bulletin chunk uploads never route through the phone.
  The statement-store channel caps messages far below the 2 MiB chunk size,
  which surfaced as 'Mobile transaction signing rejected: message too big'
  with no prompt ever reaching the phone.
- Derive the slot signer with schnorrkel x8 scalar normalization. The SDK's
  createSlotAccountSigner derives an address the chain never authorized
  (verified on-chain), which silently dropped storage onto the shared pool
  account where nonce races killed chunks with AncientBirthBlock.
- Check the slot's quota against the estimated upload size before starting,
  with a single Increase approval on the phone when short; warn and proceed
  on a residual shortfall rather than blocking.
- Fast-fail phone signing within ~200ms when the statement-store allowance
  has expired (it lapses ~2 days after login and cannot be renewed
  remotely), with a logout/init remedy, instead of hanging for minutes on
  a misleading 'transaction watcher silent' timeout.
- Record the login time and warn at deploy preflight when the session is
  older than 2 days.
- Select the newest paired session everywhere and prune stale sessions on
  login. Requests no longer disappear into dead sessions after re-pairing,
  which is what made 'pg init' allowance approvals never reach the phone.
- Document the bun-does-not-typecheck reality and the current tsc error
  baseline in CLAUDE.md.
@socket-security
Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​bulletin-deploy@​0.8.3721008996100

View full report

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 4, 2026

Dev build ready — try this branch:

curl -fsSL https://raw.githubusercontent.com/paritytech/playground-cli/main/install.sh | VERSION=dev/fix/phone-deploy-storage-and-sessions bash

@UtkarshBhardwaj007 UtkarshBhardwaj007 merged commit 47c0bd8 into main Jun 4, 2026
19 checks passed
@UtkarshBhardwaj007 UtkarshBhardwaj007 deleted the fix/phone-deploy-storage-and-sessions branch June 4, 2026 14:12
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 4, 2026

E2E Test Pass · ✅ PASS

Tag: e2e-ci-pr · Branch: fix/phone-deploy-storage-and-sessions · Commit: cddd98d · Run logs

Cell Result Time
pr-mod ✅ PASS 1m31s
pr-preflight ✅ PASS 2m30s
pr-init-session ✅ PASS 1m49s
pr-deploy-frontend ✅ PASS 7m09s
pr-deploy-cdm ✅ PASS 3m31s
pr-install ✅ PASS 0m45s
pr-deploy-foundry ✅ PASS 1m04s
${{ matrix.cell }} ⏭️ SKIP 0m00s
${{ matrix.cell }} ⏭️ SKIP 0m00s

Sentry traces: view spans for this run

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