From 10e907045b8e6e8dfcce6f66dca8edfeb8f4b0ad Mon Sep 17 00:00:00 2001 From: pgherveou Date: Mon, 31 Aug 2026 14:23:50 +0200 Subject: [PATCH] revert: remove raw proof context escape hatch Restore product-scoped ring-VRF contexts after the temporary Humanity workaround served its purpose. Reverts #457. --- js/packages/truapi/README.md | 7 --- js/packages/truapi/src/development.test.ts | 51 ---------------- js/packages/truapi/src/development.ts | 60 ------------------- js/packages/truapi/src/index.ts | 1 - rust/crates/truapi-host-cli/README.md | 7 --- .../truapi-server/src/runtime/pairing_host.rs | 8 +-- .../truapi-server/src/runtime/signing_host.rs | 8 +-- .../src/runtime/signing_host/ring_vrf.rs | 21 ------- 8 files changed, 8 insertions(+), 155 deletions(-) delete mode 100644 js/packages/truapi/src/development.test.ts delete mode 100644 js/packages/truapi/src/development.ts diff --git a/js/packages/truapi/README.md b/js/packages/truapi/README.md index 9a456eb04..46d47676d 100644 --- a/js/packages/truapi/README.md +++ b/js/packages/truapi/README.md @@ -72,13 +72,6 @@ sub.unsubscribe(); - **Sandbox bootstrap** (`@parity/truapi/sandbox`) that detects the host environment, builds the matching provider, and exposes a cached client — see below. -## Development escape hatches - -- **`development_createAccountProof(client, request)`** — `account.createAccountProof` - with `context` given as the exact 32-byte hex the proof is bound to, instead of a - product-namespaced `ProductProofContext`. Yet to be removed before a production - release; it lives entirely in `src/development.ts`. - ## Sandbox bootstrap `@parity/truapi/sandbox` wires up a client for browser-embedded hosts: it detects whether the app diff --git a/js/packages/truapi/src/development.test.ts b/js/packages/truapi/src/development.test.ts deleted file mode 100644 index 92a30514a..000000000 --- a/js/packages/truapi/src/development.test.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { describe, expect, test } from "bun:test"; -import { okAsync } from "neverthrow"; -import { development_createAccountProof } from "./development.js"; -import type { HostAccountCreateProofRequest } from "./generated/index.js"; - -const context = `0x${"ab".repeat(32)}` as const; -const base = { - keyHandle: { dotNsIdentifier: "dim2.dot", derivationIndex: { tag: "Index", value: 0 } }, - ringLocation: { chainId: `0x${"00".repeat(32)}`, junctions: [] }, - message: "0x01", -} as const; - -function stub() { - const seen: HostAccountCreateProofRequest[] = []; - const client = { - account: { - createAccountProof(request: HostAccountCreateProofRequest) { - seen.push(request); - return okAsync({ - proof: "0x", - contextualAlias: { context, alias: "0x" }, - ringIndex: 0, - ringRevision: 0, - }); - }, - }, - }; - return { - seen, - client: client as unknown as Parameters[0], - }; -} - -describe("development_createAccountProof", () => { - test("forwards the request with the raw context marker", async () => { - const { seen, client } = stub(); - await development_createAccountProof(client, { ...base, context }); - expect(seen).toEqual([ - { ...base, context: { productId: "raw:", suffix: { tag: "Raw", value: context } } }, - ]); - }); - - test("rejects contexts that are not 32 bytes of hex", () => { - const { client } = stub(); - for (const bad of ["0x00", "ab".repeat(32), `0x${"zz".repeat(32)}`]) { - expect(() => - development_createAccountProof(client, { ...base, context: bad as `0x${string}` }), - ).toThrow(TypeError); - } - }); -}); diff --git a/js/packages/truapi/src/development.ts b/js/packages/truapi/src/development.ts deleted file mode 100644 index 41aec66af..000000000 --- a/js/packages/truapi/src/development.ts +++ /dev/null @@ -1,60 +0,0 @@ -// TODO(development_createAccountProof): dev-only escape hatch, yet to be -// removed before a production release. Everything for it lives in this file, -// its test and one re-export in `index.ts`; delete those to remove it. -import type { - HostAccountCreateProofRequest, - HostAccountCreateProofResponse, - ProductProofContext, - TrUApiClient, - VersionedHostAccountCreateProofError, -} from "./generated/index.js"; -import type { ResultAsync } from "./generated/client.js"; -import type { CallErrorValue, HexString } from "./scale.js"; - -/** `productId` the signing host reads as "use the suffix bytes verbatim". */ -const RAW_PROOF_CONTEXT_PRODUCT_ID = "raw:"; - -/** Same as `HostAccountCreateProofRequest`, with the 32-byte context given raw. */ -export interface DevelopmentCreateProofRequest extends Omit< - HostAccountCreateProofRequest, - "context" -> { - /** The exact 32 bytes the proof is bound to, as `0x`-prefixed hex. */ - context: HexString; -} - -/** - * `account.createAccountProof` with a verbatim 32-byte proof context instead of - * a product-namespaced one. - * - */ -export function development_createAccountProof( - client: Pick, - request: DevelopmentCreateProofRequest, -): ResultAsync< - HostAccountCreateProofResponse, - CallErrorValue -> { - const { context, ...rest } = request; - return client.account.createAccountProof({ - ...rest, - context: rawProofContext(context), - }); -} - -function rawProofContext(context: HexString): ProductProofContext { - const digits = context.startsWith("0x") ? context.slice(2) : null; - if ( - digits === null || - digits.length !== 64 || - !/^[0-9a-fA-F]*$/.test(digits) - ) { - throw new TypeError( - `development_createAccountProof: context must be 32 bytes of 0x-prefixed hex, got ${JSON.stringify(context)}`, - ); - } - return { - productId: RAW_PROOF_CONTEXT_PRODUCT_ID, - suffix: { tag: "Raw", value: context }, - }; -} diff --git a/js/packages/truapi/src/index.ts b/js/packages/truapi/src/index.ts index 726ddd851..2648df85b 100644 --- a/js/packages/truapi/src/index.ts +++ b/js/packages/truapi/src/index.ts @@ -30,4 +30,3 @@ export * as scale from "./scale.js"; export type { Codec, HexString } from "./scale.js"; export * from "./generated/index.js"; export * from "./well-known-chains.js"; -export * from "./development.js"; diff --git a/rust/crates/truapi-host-cli/README.md b/rust/crates/truapi-host-cli/README.md index 86f67920e..60e18db2c 100644 --- a/rust/crates/truapi-host-cli/README.md +++ b/rust/crates/truapi-host-cli/README.md @@ -105,13 +105,6 @@ make headless install # build dependencies and install truapi-host once truapi-host signing-host ``` -### Raw proof contexts (development only) - -A product can bind a ring-VRF proof to 32 bytes of its choosing instead of a -product-namespaced context by calling `development_createAccountProof` from -`@parity/truapi`; the signing host honours it as is. Yet to be removed before a -production release. - ### Browser products `truapi-host dev` is one command for "run this product as if it were inside a diff --git a/rust/crates/truapi-server/src/runtime/pairing_host.rs b/rust/crates/truapi-server/src/runtime/pairing_host.rs index d68e5f231..be64b953b 100644 --- a/rust/crates/truapi-server/src/runtime/pairing_host.rs +++ b/rust/crates/truapi-server/src/runtime/pairing_host.rs @@ -56,8 +56,8 @@ use zeroize::Zeroizing; use super::ring_vrf_registry::{RingVrfRegistryStore, validate_owner_listing}; use super::signing_host::ring_vrf::{ - ChainRingResolver, MemberCandidate, RingResolver, alias_from_entropy, create_proof, - development_context_bytes, member_from_entropy, sign_from_entropy, + ChainRingResolver, MemberCandidate, RingResolver, alias_from_entropy, context_bytes, + create_proof, member_from_entropy, sign_from_entropy, }; /// Distinguishes all remote authority request entrypoints by wire label. @@ -2127,7 +2127,7 @@ impl PairingHost { { self.ring_resolver.validate(&request.ring_location).await?; self.current_private_session(session)?; - let context = development_context_bytes(&request.context); + let context = context_bytes(&request.context); let alias = alias_from_entropy(&entropy, &context)?; return Ok(v01::ContextualAlias { context, @@ -2160,7 +2160,7 @@ impl PairingHost { .resolve(&request.ring_location, &[MemberCandidate { member }]) .await?; self.current_private_session(session)?; - let context = development_context_bytes(&request.context); + let context = context_bytes(&request.context); let (proof, alias) = create_proof(&entropy, &resolved, &context, &request.message)?; return Ok(v01::HostAccountCreateProofResponse { proof, diff --git a/rust/crates/truapi-server/src/runtime/signing_host.rs b/rust/crates/truapi-server/src/runtime/signing_host.rs index d2f0c82d2..3469cef32 100644 --- a/rust/crates/truapi-server/src/runtime/signing_host.rs +++ b/rust/crates/truapi-server/src/runtime/signing_host.rs @@ -65,8 +65,8 @@ use crate::runtime::statement_allowance::CollectionCandidate; #[cfg(not(target_arch = "wasm32"))] use crate::runtime::statement_allowance::collection::PersonhoodCollection; use ring_vrf::{ - ChainRingResolver, MemberCandidate, RingResolver, alias_from_entropy, create_proof, - development_context_bytes, member_from_entropy, sign_from_entropy, + ChainRingResolver, MemberCandidate, RingResolver, alias_from_entropy, context_bytes, + create_proof, member_from_entropy, sign_from_entropy, }; use sso_replay::SsoReplayLocks; @@ -839,7 +839,7 @@ impl ProductAuthority for SigningHost { .resolve_ring_vrf_key_for_ring(session, &request.key_handle, &request.ring_location) .await?; self.ring_resolver.validate(&request.ring_location).await?; - let context = development_context_bytes(&request.context); + let context = context_bytes(&request.context); let alias = alias_from_entropy(&entropy, &context)?; Ok(v01::ContextualAlias { context, @@ -866,7 +866,7 @@ impl ProductAuthority for SigningHost { // Reject a stale request if the local session disconnected or changed // while its chain snapshot was being resolved. self.require_current_session(session)?; - let context = development_context_bytes(&request.context); + let context = context_bytes(&request.context); let (proof, alias) = create_proof(&entropy, &resolved, &context, &request.message)?; Ok(v01::HostAccountCreateProofResponse { proof, diff --git a/rust/crates/truapi-server/src/runtime/signing_host/ring_vrf.rs b/rust/crates/truapi-server/src/runtime/signing_host/ring_vrf.rs index 11a49ab92..7e6e51b8e 100644 --- a/rust/crates/truapi-server/src/runtime/signing_host/ring_vrf.rs +++ b/rust/crates/truapi-server/src/runtime/signing_host/ring_vrf.rs @@ -212,27 +212,6 @@ impl RingResolver for ChainRingResolver { } } -// TODO(development_createAccountProof): dev-only escape hatch, yet to be -// removed before a production release. Delete this module and point its -// callers in `signing_host.rs` and `pairing_host.rs` back at `context_bytes`. -mod development { - use truapi::v01::{DerivationIndex, ProductProofContext}; - - const RAW_CONTEXT_PRODUCT_ID: &str = "raw:"; - - /// [`super::context_bytes`], except that the `raw:` product id (which - /// dotNS cannot issue) makes the `Raw` suffix the context, verbatim. - pub(in crate::runtime) fn development_context_bytes(context: &ProductProofContext) -> [u8; 32] { - if context.product_id == RAW_CONTEXT_PRODUCT_ID - && let DerivationIndex::Raw(bytes) = context.suffix - { - return bytes; - } - super::context_bytes(context) - } -} -pub(in crate::runtime) use development::development_context_bytes; - pub(in crate::runtime) fn context_bytes(context: &ProductProofContext) -> [u8; 32] { let suffix = derivation_index_bytes(&context.suffix); let mut input = Vec::with_capacity(9 + context.product_id.len() + suffix.len());