Migrate to paseo-next-v2 (Asset Hub Next + RFC-0010 allowances)#157
Merged
Conversation
`dot init` now requests RFC-0010 resource allowances (Bulletin + Statement
Store + smart-contract gas) from the user's mobile wallet before mapping
the account; PAS funding from a dedicated funder account is gone. Grants
are cached at `~/.polkadot/allowances.json` (per env, per address, per
resource) so repeat `dot init` runs don't re-prompt. `dot mod` no longer
requires login or account-mapping to browse moddable apps.
Endpoints, contracts, and feature flags for paseo-next-v2 (Asset Hub Next
1500, Bulletin Next 1501, People Next System 1502) live in src/config.ts
under an env model that mirrors bulletin-deploy's `environments.json`.
`getNetworkLabel()` drives the Header bread-crumb off the active env.
Key fixes for paseo-next-v2's signing surface:
- Custom session signer (src/utils/sessionSigner.ts) routes tx signing
through `session.signPayload` instead of `session.signRaw({tag:"Payload"})`.
Android v1198's signRaw applies the `<Bytes>` anti-phishing wrap
unconditionally, which produces a signature over `<Bytes>${hex}</Bytes>`
instead of the bare payload — chain rejects as BadProof. The new path
forwards the structured PJS payload to `session.signPayload`, letting
the host reconstruct the full payload (including AsPgas sponsoring)
natively. Wraps PJS adapter with the "relaxed signed extensions" pattern
from polkadot-app-android-v2's sample to bypass PJS's
"PJS does not support this signed-extension" throw on AsPgas.
- `checkMapping` queries `Revive.OriginalAccount[H160]` via
`ReviveApi.address` (canonical bulletin-deploy pattern) and falls
through on the stale-descriptor "Incompatible runtime entry" error so
init doesn't crash.
- `ensureMapped` swallows `InvalidTransaction::Stale` /
`AccountAlreadyMapped` errors so re-running `dot init` against an
already-mapped account is a clean no-op. On AutoMap=true chains
map_account is a dispatch-side no-op anyway; the chain rejects
redundant submissions at signed-extension validation.
Logging hygiene for Bun's SEA runtime:
- `process.stderr.write` filter in bootstrap.ts drops Bun's unhandled-
rejection block when the payload contains `DestroyedError: Client
destroyed` — polkadot-api's chain-head subscriptions emit those as
detached microtasks during teardown that no `process.on('unhandledRejection')`
handler can suppress in compiled SEA binaries.
- product-sdk-logger handler suppresses
`tx / Transaction subscription error / Client destroyed` so the post-
destroy noise can't corrupt Ink's cursor anchor mid-render.
- `isBenignUnsubscriptionError` re-suppresses `DestroyedError` for
Node-runtime tests.
Package bumps (all to latest published versions):
- bulletin-deploy 0.7.14 → 0.7.19 (ships paseo-next-v2 env with
autoAccountMapping + bulletinAuthorizeV2 + skipDotnsCli flags)
- @parity/product-sdk-* to the 0.5.0 workspace facade
(terminal 0.2.1 = PAPI-native signer / PR #81 AsPgas fix;
contracts 0.5.0 = QueryResult discriminated union;
new product-sdk-host 0.3.0 for type reference)
- @dotdm/contracts ^2.0.3 (drops dev-tag pin)
- @novasamatech/* overrides 0.7.8-2 → 0.7.9-4
- @parity/product-sdk-logger ^0.1.1 (new dep for the suppression handler)
Other structural changes:
- Registry split into `getRegistryContract` (signed) for `dot deploy`
and `getReadOnlyRegistryContract` (Alice-origin dry-run) for `dot mod`.
- Metadata-upload (`publishToPlayground`) signs `TransactionStorage.store`
with the user's session signer instead of Alice — v2's bulletinAuthorizeV2
ring grants the user direct submission.
- `AppBrowser` and `SetupScreen` narrow on `res.success` before reading
`res.value` (required by contracts 0.5.0 discriminated union).
- `dot deploy` accepts both legacy `testnet|mainnet` and new env IDs via
`resolveLegacyEnv`.
- `PLAYGROUND_PRODUCT_ID` updated to `playground42.dot`.
- Diagnostic tool: `tools/diagnose-mapping.ts` queries AutoMap +
`Revive.OriginalAccount` for a given SS58.
CLAUDE.md updated for all of the above.
Contributor
|
Dev build ready — try this branch: |
Contributor
E2E Test Pass · ❌ FAILTag:
Sentry traces: view spans for this run |
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.
Summary
~/.polkadot/allowances.json.Revive.map_accountby routing tx signing throughsession.signPayloadinstead ofsession.signRaw(the SDK's PR [BUG] While CLI is waiting get overwhelmed by chain errros #81 fix sent opaque bytes through android's<Bytes>-wrapping handler — wrong signed bytes → BadProof).product-sdk@0.5.0workspace facade.dot modno longer requires login or mapping; uses a read-only registry handle with Alice-derived dry-run origin.Closes the work on the stale draft #156.
Test plan
CI gates (all green locally)
pnpm format:checkpnpm lint:licensepnpm test— 499 passed, 1 skipped (flaky vitest fs-isolation case, documented)pnpm buildpr-install,pr-preflight,pr-init-session,pr-mod,pr-deploy-{frontend,foundry}) — may need fixture republish on paseo-next-v2 before deploy legs passManual smoke (verified by author)
dot initagainst android nightly v1198 + desktop experimental v0.3.17 — allowances prompt → grant → map → setup complete. No stray DestroyedError stderr.dot initon an already-mapped account → mapping step shows ✓ (Stale rejection swallowed as known-benign).Manual smoke (still to do — runtime / mobile required)
dot deployof a small site end-to-end on paseo-next-v2dot modlisting + cloning a moddable app withoutdot initdot logout→ re-dot initflowKey changes
Allowances (RFC-0010)
src/utils/allowances/host.tswrapssession.requestResourceAllocation()on theUserSessionfrom@novasamatech/host-papp(product-sdk-terminal doesn't re-export this yet; CLI-local shim until it does).src/utils/allowances/marker.tspersists grants at~/.polkadot/allowances.json(mode 0600), keyedenv → ss58 → resourceTag.Signing
src/utils/sessionSigner.tsbuilds a PolkadotSigner viagetPolkadotSignerFromPjswith a customsignPayloadthat forwards PJS's structured payload tosession.signPayload. The "relaxed signed extensions" wrapper (mirrored from polkadot-app-android-v2's sample) zeros out value/additionalSigned forAsPgasandAsRingAliasso PJS doesn't throw on unknown extensions; the host fills in the real encoding from its own runtime.product-sdk-terminal@0.2.1'screateSessionSignerForAccountno longer used directly — itssignRaw({tag:"Payload"})path hits android v1198's unconditional<Bytes>wrap and produces BadProof.Mapping
checkMappingmirrorsbulletin-deploy/src/dotns.ts::checkIfAccountMapped:ReviveApi.address(ss58) → H160 → Revive.OriginalAccount[H160]. SwallowsIncompatible runtime entryerrors (the bundledpaseo-asset-hubdescriptor is stale vs. live runtime) so init falls through cleanly.ensureMappedswallowsInvalidTransaction::StaleandAccountAlreadyMapped— on AutoMap=true chains map_account is a dispatch no-op; re-submissions are rejected at validate.Env model
src/config.tsmirrors bulletin-deploy'senvironments.jsonkeys (paseo-next, paseo-next-v2, paseo-review, preview, polkadot, kusama). Only paseo-next-v2 is populated; others throw--env <X> is not yet supported.--env testnet|mainnetstill accepted viaresolveLegacyEnv.getNetworkLabel()drives the Header bread-crumb off the active env.Registry split
getRegistryContract(signed) fordot deploy.getReadOnlyRegistryContract(Alice-derived dry-run origin) fordot mod— no login or mapping required.--suriretained as deprecated no-op ondot mod.Bun-runtime hygiene
process.stderr.writefilter inbootstrap.tsdrops Bun's unhandled-rejection formatter block when it's reportingDestroyedError: Client destroyed. polkadot-api's chain-head teardown emits those from detached microtasks that noprocess.on('unhandledRejection')handler can suppress in compiled SEA binaries.product-sdk-loggerhandler suppressestx / Transaction subscription error / Client destroyedpost-destroy noise.DOT_DEPLOY_VERBOSE=1reveals every suppression for debugging.Open follow-ups
@parity/product-sdk-descriptors/paseo-asset-hubis generated against an older runtime than what's live atwss://paseo-asset-hub-next-rpc.polkadot.io. PAPI's typed queries forRevive.OriginalAccountandSystem.Account.noncedecode incorrectly. Mitigated end-to-end here (storage swallows the error, mapping is idempotent), but the proper fix is upstream regen.dot deploy, parked until manual smoke confirms.product-sdk-terminalexposing RFC-0010requestResourceAllocationnatively — when it does, drop the CLI-local shim insrc/utils/allowances/host.ts.Out of scope
dot init's old "preview-net" duality from point CLI to preview-net instead of paseo #156 — not adding a second env profile until we genuinely need one.checkMappingskip cleanly.