@parity/product-sdk 0.21.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,5 +4,6 @@ import '@parity/product-sdk-chain-client';
4
4
  import '@parity/product-sdk-contracts';
5
5
  import '@parity/product-sdk-crypto';
6
6
  import '@parity/product-sdk-host';
7
+ import '@parity/product-sdk-individuality';
7
8
  import '@parity/product-sdk-local-storage';
8
9
  import '@parity/product-sdk-signer';
@@ -1,6 +1,6 @@
1
1
  export { createApp } from '../index.js';
2
2
  export { LogEntry, LogHandler, LogLevel, Logger, LoggerConfig, configure, createLogger } from '@parity/product-sdk-logger';
3
- export { A as Account, b as App, c as AppConfig, C as ChainApi, a as CloudStorageApi, d as CloudStorageConfig, D as DotNsIdentitySignature, L as LocalStorageApi, S as SignMessageWithDotNsIdentityArgs, W as WalletApi } from '../types-CztPAgZT.js';
3
+ export { A as Account, b as App, c as AppConfig, C as ChainApi, a as CloudStorageApi, d as CloudStorageConfig, D as DotNsIdentitySignature, L as LocalStorageApi, S as SignMessageWithDotNsIdentityArgs, W as WalletApi } from '../types-DTgyMIi0.js';
4
4
  export { ChainClient } from '@parity/product-sdk-chain-client';
5
5
  export { ChainDefinition, PolkadotClient, TypedApi } from 'polkadot-api';
6
6
  import '@parity/result';
@@ -9,4 +9,4 @@ import '@parity/product-sdk-host';
9
9
  import '@parity/product-sdk-signer';
10
10
  import '@parity/product-sdk-local-storage';
11
11
  import '@parity/product-sdk-cloud-storage';
12
- import '../dotns-hLSvmo6u.js';
12
+ import '../dotns-DIaptENj.js';
@@ -16,7 +16,12 @@ interface DotNsRecord {
16
16
  /** Expiration timestamp (if applicable) */
17
17
  expiresAt?: number;
18
18
  }
19
- /** Context alias info: a deterministic, context-bound alias derived from a parent account */
19
+ /**
20
+ * Context alias info: a deterministic, context-bound alias derived from a parent account
21
+ *
22
+ * @deprecated Returned by `deriveContextAlias`, whose addresses no key can spend.
23
+ * Removal: `@parity/product-sdk` 0.23.0.
24
+ */
20
25
  interface ContextAliasInfo {
21
26
  /** Alias SS58 address */
22
27
  address: string;
@@ -27,22 +32,6 @@ interface ContextAliasInfo {
27
32
  /** Context string used for derivation */
28
33
  context: string;
29
34
  }
30
- /** Ring VRF alias info */
31
- interface AnonymousAliasInfo {
32
- /** Anonymous alias identifier */
33
- alias: string;
34
- /** Ring location for proof generation */
35
- ringLocation: RingLocation;
36
- /** Context used for alias derivation */
37
- context: string;
38
- }
39
- /** Ring location for VRF proofs */
40
- interface RingLocation {
41
- /** Ring index */
42
- ringIndex: number;
43
- /** Member index within ring */
44
- memberIndex: number;
45
- }
46
35
  /** Identity verification result */
47
36
  interface VerificationResult {
48
37
  /** Whether identity is verified */
@@ -175,4 +164,4 @@ declare function isDotNsAvailable(name: string): Promise<boolean>;
175
164
  declare function resolvePeopleUsernameOwner(username: string, peopleApi: PeopleUsernameQueryApi): Promise<`0x${string}` | null>;
176
165
  declare function accountIdHexToBytes(accountId: `0x${string}`): Uint8Array;
177
166
 
178
- export { type AnonymousAliasInfo as A, type ContextAliasInfo as C, type DotNsRecord as D, type OnChainIdentity as O, type PeopleUsernameChain as P, type RingLocation as R, type VerificationResult as V, type PeopleUsernameQueryApi as a, accountIdHexToBytes as b, isValidDotNsName as c, resolvePeopleUsernameOwner as d, reverseDotNs as e, isDotNsAvailable as i, normalizeDotNsName as n, resolveDotNs as r };
167
+ export { type ContextAliasInfo as C, type DotNsRecord as D, type OnChainIdentity as O, type PeopleUsernameChain as P, type VerificationResult as V, type PeopleUsernameQueryApi as a, accountIdHexToBytes as b, isValidDotNsName as c, resolvePeopleUsernameOwner as d, reverseDotNs as e, isDotNsAvailable as i, normalizeDotNsName as n, resolveDotNs as r };
@@ -1,12 +1,15 @@
1
- import { R as RingLocation, A as AnonymousAliasInfo, C as ContextAliasInfo } from '../dotns-hLSvmo6u.js';
2
- export { D as DotNsRecord, O as OnChainIdentity, P as PeopleUsernameChain, a as PeopleUsernameQueryApi, V as VerificationResult, b as accountIdHexToBytes, i as isDotNsAvailable, c as isValidDotNsName, n as normalizeDotNsName, r as resolveDotNs, d as resolvePeopleUsernameOwner, e as reverseDotNs } from '../dotns-hLSvmo6u.js';
1
+ import { C as ContextAliasInfo } from '../dotns-DIaptENj.js';
2
+ export { D as DotNsRecord, O as OnChainIdentity, P as PeopleUsernameChain, a as PeopleUsernameQueryApi, V as VerificationResult, b as accountIdHexToBytes, i as isDotNsAvailable, c as isValidDotNsName, n as normalizeDotNsName, r as resolveDotNs, d as resolvePeopleUsernameOwner, e as reverseDotNs } from '../dotns-DIaptENj.js';
3
3
  import 'polkadot-api';
4
4
 
5
5
  /**
6
- * Context alias derivation
6
+ * Context alias derivation (deprecated, removal in 0.23.0)
7
7
  *
8
8
  * Derives a deterministic, context-bound alias from a parent account using blake2b-256.
9
9
  *
10
+ * The output is a hash, not a key, so no signing key exists for the addresses
11
+ * returned here. See the notes on each function for what to use instead.
12
+ *
10
13
  * NOTE: this is NOT the canonical sr25519 product-account derivation used by
11
14
  * mobile, desktop, and dotli hosts. For that, use
12
15
  * `@parity/product-sdk-keys::deriveProductAccountPublicKey`.
@@ -18,57 +21,43 @@ import 'polkadot-api';
18
21
  * The alias is deterministically derived using:
19
22
  * aliasPublicKey = blake2b256(parentPublicKey || context)
20
23
  *
24
+ * @deprecated Returns addresses that no key can spend. The alias public key is a
25
+ * blake2b-256 hash rather than a derived key, so no secret corresponds to the
26
+ * SS58 address or to the H160: both can receive value and neither can ever
27
+ * send it. Removal: `@parity/product-sdk` 0.23.0. Replace by intent:
28
+ *
29
+ * - An account that holds or spends value:
30
+ * `SignerManager.getProductAccount(dotNsIdentifier, index)` from
31
+ * `@parity/product-sdk-signer`. Host-backed and actually signable.
32
+ * - The address offline, with no host: `deriveProductAccountPublicKey` from
33
+ * `@parity/product-sdk-keys`, the canonical sr25519 soft derivation.
34
+ * - An unlinkable per-context alias: select a registered ring-VRF key, then call
35
+ * `SignerManager.getProductAccountAlias(keyHandle, context, location)` or
36
+ * `createRingVRFProof(keyHandle, context, location, message)`.
37
+ * - A context-scoped identifier, never used as an account: `blake2b256` from
38
+ * `@parity/product-sdk/crypto`. Same bytes, without address packaging that
39
+ * invites the mistake.
40
+ *
21
41
  * @param parentAddress - Parent account SS58 address
22
42
  * @param context - Context string for derivation (e.g. an app id or scope label)
23
43
  * @param ss58Prefix - SS58 prefix (default: 42)
24
44
  * @returns Context alias info
25
- *
26
- * @example
27
- * ```ts
28
- * const alias = deriveContextAlias(
29
- * '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',
30
- * 'voting-round-1'
31
- * );
32
- * console.log('Alias address:', alias.address);
33
- * ```
34
45
  */
35
46
  declare function deriveContextAlias(parentAddress: string, context: string, ss58Prefix?: number): ContextAliasInfo;
36
47
  /**
37
48
  * Verify that a context alias was derived from a parent account.
38
49
  *
50
+ * @deprecated Recomputes {@link deriveContextAlias} from two public values and
51
+ * compares the result, so it confirms a derivation relationship and nothing
52
+ * more. No secret enters the operation at any point, which means there is
53
+ * nothing here to authenticate: a passing result does not show that anyone
54
+ * controls either account. Removal: `@parity/product-sdk` 0.23.0.
55
+ *
39
56
  * @param aliasAddress - Context alias SS58 address
40
57
  * @param parentAddress - Claimed parent address
41
58
  * @param context - Context string used for derivation
42
59
  * @returns True if derivation is valid
43
60
  */
44
61
  declare function verifyContextAlias(aliasAddress: string, parentAddress: string, context: string): boolean;
45
- /**
46
- * Derive an anonymous alias using Ring VRF
47
- *
48
- * This creates a context-specific alias that cannot be linked
49
- * back to the original identity without the ring proof.
50
- *
51
- * @param context - Context for alias derivation (e.g., "voting-round-1")
52
- * @param ringLocation - Ring location for proof generation
53
- * @returns Anonymous alias info
54
- */
55
- declare function deriveAnonymousAlias(context: string, ringLocation: RingLocation): AnonymousAliasInfo;
56
- /**
57
- * Create a Ring VRF proof for a message
58
- *
59
- * @param message - Message to prove
60
- * @param ringLocation - Ring location
61
- * @returns Proof bytes
62
- */
63
- declare function createRingProof(message: Uint8Array, ringLocation: RingLocation): Promise<Uint8Array>;
64
- /**
65
- * Verify a Ring VRF proof
66
- *
67
- * @param message - Original message
68
- * @param proof - Proof bytes
69
- * @param alias - Expected alias
70
- * @returns True if proof is valid
71
- */
72
- declare function verifyRingProof(message: Uint8Array, proof: Uint8Array, alias: string): Promise<boolean>;
73
62
 
74
- export { AnonymousAliasInfo, ContextAliasInfo, RingLocation, createRingProof, deriveAnonymousAlias, deriveContextAlias, verifyContextAlias, verifyRingProof };
63
+ export { ContextAliasInfo, deriveContextAlias, verifyContextAlias };
@@ -39,25 +39,7 @@ function verifyContextAlias(aliasAddress, parentAddress, context) {
39
39
  return false;
40
40
  }
41
41
  }
42
- function deriveAnonymousAlias(context, ringLocation) {
43
- log.debug("Deriving anonymous alias", { context, ringLocation });
44
- throw new Error(
45
- "deriveAnonymousAlias() is not yet implemented. This requires container mode with Ring VRF support."
46
- );
47
- }
48
- async function createRingProof(message, ringLocation) {
49
- log.debug("Creating ring proof", { ringLocation });
50
- throw new Error(
51
- "createRingProof() is not yet implemented. This requires container mode with Ring VRF support."
52
- );
53
- }
54
- async function verifyRingProof(message, proof, alias) {
55
- log.debug("Verifying ring proof");
56
- throw new Error(
57
- "verifyRingProof() is not yet implemented. This requires container mode with Ring VRF support."
58
- );
59
- }
60
42
 
61
- export { createRingProof, deriveAnonymousAlias, deriveContextAlias, verifyContextAlias, verifyRingProof };
43
+ export { deriveContextAlias, verifyContextAlias };
62
44
  //# sourceMappingURL=index.js.map
63
45
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/identity/product-account.ts"],"names":[],"mappings":";;;;;AAiBA,IAAM,GAAA,GAAM,aAAa,UAAU,CAAA;AAsB5B,SAAS,kBAAA,CACZ,aAAA,EACA,OAAA,EACA,UAAA,GAAa,EAAA,EACG;AAChB,EAAA,MAAM,EAAE,SAAA,EAAW,eAAA,EAAgB,GAAI,WAAW,aAAa,CAAA;AAG/D,EAAA,MAAM,YAAA,GAAe,IAAI,WAAA,EAAY,CAAE,OAAO,OAAO,CAAA;AACrD,EAAA,MAAM,WAAW,IAAI,UAAA,CAAW,eAAA,CAAgB,MAAA,GAAS,aAAa,MAAM,CAAA;AAC5E,EAAA,QAAA,CAAS,GAAA,CAAI,iBAAiB,CAAC,CAAA;AAC/B,EAAA,QAAA,CAAS,GAAA,CAAI,YAAA,EAAc,eAAA,CAAgB,MAAM,CAAA;AAEjD,EAAA,MAAM,cAAA,GAAiB,WAAW,QAAQ,CAAA;AAC1C,EAAA,MAAM,OAAA,GAAU,UAAA,CAAW,cAAA,EAAgB,UAAU,CAAA;AACrD,EAAA,MAAM,WAAA,GAAc,WAAW,cAAc,CAAA;AAE7C,EAAA,GAAA,CAAI,MAAM,uBAAA,EAAyB;AAAA,IAC/B,aAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GACH,CAAA;AAED,EAAA,OAAO;AAAA,IACH,OAAA;AAAA,IACA,WAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACJ;AACJ;AAUO,SAAS,kBAAA,CACZ,YAAA,EACA,aAAA,EACA,OAAA,EACO;AACP,EAAA,IAAI;AACA,IAAA,MAAM,OAAA,GAAU,kBAAA,CAAmB,aAAA,EAAe,OAAO,CAAA;AACzD,IAAA,MAAM,EAAE,SAAA,EAAW,QAAA,EAAS,GAAI,WAAW,YAAY,CAAA;AACvD,IAAA,MAAM,EAAE,SAAA,EAAW,UAAA,EAAW,GAAI,UAAA,CAAW,QAAQ,OAAO,CAAA;AAG5D,IAAA,IAAI,QAAA,CAAS,MAAA,KAAW,UAAA,CAAW,MAAA,EAAQ,OAAO,KAAA;AAClD,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AACtC,MAAA,IAAI,SAAS,CAAC,CAAA,KAAM,UAAA,CAAW,CAAC,GAAG,OAAO,KAAA;AAAA,IAC9C;AACA,IAAA,OAAO,IAAA;AAAA,EACX,CAAA,CAAA,MAAQ;AACJ,IAAA,OAAO,KAAA;AAAA,EACX;AACJ;AAYO,SAAS,oBAAA,CACZ,SACA,YAAA,EACkB;AAClB,EAAA,GAAA,CAAI,KAAA,CAAM,0BAAA,EAA4B,EAAE,OAAA,EAAS,cAAc,CAAA;AAI/D,EAAA,MAAM,IAAI,KAAA;AAAA,IACN;AAAA,GAEJ;AACJ;AASA,eAAsB,eAAA,CAClB,SACA,YAAA,EACmB;AACnB,EAAA,GAAA,CAAI,KAAA,CAAM,qBAAA,EAAuB,EAAE,YAAA,EAAc,CAAA;AAGjD,EAAA,MAAM,IAAI,KAAA;AAAA,IACN;AAAA,GAEJ;AACJ;AAUA,eAAsB,eAAA,CAClB,OAAA,EACA,KAAA,EACA,KAAA,EACgB;AAChB,EAAA,GAAA,CAAI,MAAM,sBAAsB,CAAA;AAGhC,EAAA,MAAM,IAAI,KAAA;AAAA,IACN;AAAA,GAEJ;AACJ","file":"index.js","sourcesContent":["// Copyright 2026 Parity Technologies (UK) Ltd.\n// SPDX-License-Identifier: Apache-2.0\n/**\n * Context alias derivation\n *\n * Derives a deterministic, context-bound alias from a parent account using blake2b-256.\n *\n * NOTE: this is NOT the canonical sr25519 product-account derivation used by\n * mobile, desktop, and dotli hosts. For that, use\n * `@parity/product-sdk-keys::deriveProductAccountPublicKey`.\n */\n\nimport { createLogger } from \"@parity/product-sdk-logger\";\nimport { blake2b256 } from \"@parity/product-sdk-crypto\";\nimport { ss58Encode, ss58Decode, deriveH160 } from \"@parity/product-sdk-address\";\nimport type { ContextAliasInfo, AnonymousAliasInfo, RingLocation } from \"./types.js\";\n\nconst log = createLogger(\"identity\");\n\n/**\n * Derive a context-bound alias from a parent account.\n *\n * The alias is deterministically derived using:\n * aliasPublicKey = blake2b256(parentPublicKey || context)\n *\n * @param parentAddress - Parent account SS58 address\n * @param context - Context string for derivation (e.g. an app id or scope label)\n * @param ss58Prefix - SS58 prefix (default: 42)\n * @returns Context alias info\n *\n * @example\n * ```ts\n * const alias = deriveContextAlias(\n * '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',\n * 'voting-round-1'\n * );\n * console.log('Alias address:', alias.address);\n * ```\n */\nexport function deriveContextAlias(\n parentAddress: string,\n context: string,\n ss58Prefix = 42,\n): ContextAliasInfo {\n const { publicKey: parentPublicKey } = ss58Decode(parentAddress);\n\n // Derive alias public key: blake2b-256(parentPublicKey || context)\n const contextBytes = new TextEncoder().encode(context);\n const combined = new Uint8Array(parentPublicKey.length + contextBytes.length);\n combined.set(parentPublicKey, 0);\n combined.set(contextBytes, parentPublicKey.length);\n\n const aliasPublicKey = blake2b256(combined);\n const address = ss58Encode(aliasPublicKey, ss58Prefix);\n const h160Address = deriveH160(aliasPublicKey);\n\n log.debug(\"Derived context alias\", {\n parentAddress,\n context,\n address,\n });\n\n return {\n address,\n h160Address,\n parentAddress,\n context,\n };\n}\n\n/**\n * Verify that a context alias was derived from a parent account.\n *\n * @param aliasAddress - Context alias SS58 address\n * @param parentAddress - Claimed parent address\n * @param context - Context string used for derivation\n * @returns True if derivation is valid\n */\nexport function verifyContextAlias(\n aliasAddress: string,\n parentAddress: string,\n context: string,\n): boolean {\n try {\n const derived = deriveContextAlias(parentAddress, context);\n const { publicKey: aliasKey } = ss58Decode(aliasAddress);\n const { publicKey: derivedKey } = ss58Decode(derived.address);\n\n // Compare public keys\n if (aliasKey.length !== derivedKey.length) return false;\n for (let i = 0; i < aliasKey.length; i++) {\n if (aliasKey[i] !== derivedKey[i]) return false;\n }\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Derive an anonymous alias using Ring VRF\n *\n * This creates a context-specific alias that cannot be linked\n * back to the original identity without the ring proof.\n *\n * @param context - Context for alias derivation (e.g., \"voting-round-1\")\n * @param ringLocation - Ring location for proof generation\n * @returns Anonymous alias info\n */\nexport function deriveAnonymousAlias(\n context: string,\n ringLocation: RingLocation,\n): AnonymousAliasInfo {\n log.debug(\"Deriving anonymous alias\", { context, ringLocation });\n\n // TODO: Implement Ring VRF alias derivation\n // This requires the Ring VRF implementation from TruAPI\n throw new Error(\n \"deriveAnonymousAlias() is not yet implemented. \" +\n \"This requires container mode with Ring VRF support.\",\n );\n}\n\n/**\n * Create a Ring VRF proof for a message\n *\n * @param message - Message to prove\n * @param ringLocation - Ring location\n * @returns Proof bytes\n */\nexport async function createRingProof(\n message: Uint8Array,\n ringLocation: RingLocation,\n): Promise<Uint8Array> {\n log.debug(\"Creating ring proof\", { ringLocation });\n\n // TODO: Implement Ring VRF proof creation via TruAPI\n throw new Error(\n \"createRingProof() is not yet implemented. \" +\n \"This requires container mode with Ring VRF support.\",\n );\n}\n\n/**\n * Verify a Ring VRF proof\n *\n * @param message - Original message\n * @param proof - Proof bytes\n * @param alias - Expected alias\n * @returns True if proof is valid\n */\nexport async function verifyRingProof(\n message: Uint8Array,\n proof: Uint8Array,\n alias: string,\n): Promise<boolean> {\n log.debug(\"Verifying ring proof\");\n\n // TODO: Implement Ring VRF proof verification\n throw new Error(\n \"verifyRingProof() is not yet implemented. \" +\n \"This requires container mode with Ring VRF support.\",\n );\n}\n"]}
1
+ {"version":3,"sources":["../../src/identity/product-account.ts"],"names":[],"mappings":";;;;;AAoBA,IAAM,GAAA,GAAM,aAAa,UAAU,CAAA;AA8B5B,SAAS,kBAAA,CACZ,aAAA,EACA,OAAA,EACA,UAAA,GAAa,EAAA,EACG;AAChB,EAAA,MAAM,EAAE,SAAA,EAAW,eAAA,EAAgB,GAAI,WAAW,aAAa,CAAA;AAG/D,EAAA,MAAM,YAAA,GAAe,IAAI,WAAA,EAAY,CAAE,OAAO,OAAO,CAAA;AACrD,EAAA,MAAM,WAAW,IAAI,UAAA,CAAW,eAAA,CAAgB,MAAA,GAAS,aAAa,MAAM,CAAA;AAC5E,EAAA,QAAA,CAAS,GAAA,CAAI,iBAAiB,CAAC,CAAA;AAC/B,EAAA,QAAA,CAAS,GAAA,CAAI,YAAA,EAAc,eAAA,CAAgB,MAAM,CAAA;AAEjD,EAAA,MAAM,cAAA,GAAiB,WAAW,QAAQ,CAAA;AAC1C,EAAA,MAAM,OAAA,GAAU,UAAA,CAAW,cAAA,EAAgB,UAAU,CAAA;AACrD,EAAA,MAAM,WAAA,GAAc,WAAW,cAAc,CAAA;AAE7C,EAAA,GAAA,CAAI,MAAM,uBAAA,EAAyB;AAAA,IAC/B,aAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GACH,CAAA;AAED,EAAA,OAAO;AAAA,IACH,OAAA;AAAA,IACA,WAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACJ;AACJ;AAgBO,SAAS,kBAAA,CACZ,YAAA,EACA,aAAA,EACA,OAAA,EACO;AACP,EAAA,IAAI;AACA,IAAA,MAAM,OAAA,GAAU,kBAAA,CAAmB,aAAA,EAAe,OAAO,CAAA;AACzD,IAAA,MAAM,EAAE,SAAA,EAAW,QAAA,EAAS,GAAI,WAAW,YAAY,CAAA;AACvD,IAAA,MAAM,EAAE,SAAA,EAAW,UAAA,EAAW,GAAI,UAAA,CAAW,QAAQ,OAAO,CAAA;AAG5D,IAAA,IAAI,QAAA,CAAS,MAAA,KAAW,UAAA,CAAW,MAAA,EAAQ,OAAO,KAAA;AAClD,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,CAAS,QAAQ,CAAA,EAAA,EAAK;AACtC,MAAA,IAAI,SAAS,CAAC,CAAA,KAAM,UAAA,CAAW,CAAC,GAAG,OAAO,KAAA;AAAA,IAC9C;AACA,IAAA,OAAO,IAAA;AAAA,EACX,CAAA,CAAA,MAAQ;AACJ,IAAA,OAAO,KAAA;AAAA,EACX;AACJ","file":"index.js","sourcesContent":["// Copyright 2026 Parity Technologies (UK) Ltd.\n// SPDX-License-Identifier: Apache-2.0\n/**\n * Context alias derivation (deprecated, removal in 0.23.0)\n *\n * Derives a deterministic, context-bound alias from a parent account using blake2b-256.\n *\n * The output is a hash, not a key, so no signing key exists for the addresses\n * returned here. See the notes on each function for what to use instead.\n *\n * NOTE: this is NOT the canonical sr25519 product-account derivation used by\n * mobile, desktop, and dotli hosts. For that, use\n * `@parity/product-sdk-keys::deriveProductAccountPublicKey`.\n */\n\nimport { createLogger } from \"@parity/product-sdk-logger\";\nimport { blake2b256 } from \"@parity/product-sdk-crypto\";\nimport { ss58Encode, ss58Decode, deriveH160 } from \"@parity/product-sdk-address\";\nimport type { ContextAliasInfo } from \"./types.js\";\n\nconst log = createLogger(\"identity\");\n\n/**\n * Derive a context-bound alias from a parent account.\n *\n * The alias is deterministically derived using:\n * aliasPublicKey = blake2b256(parentPublicKey || context)\n *\n * @deprecated Returns addresses that no key can spend. The alias public key is a\n * blake2b-256 hash rather than a derived key, so no secret corresponds to the\n * SS58 address or to the H160: both can receive value and neither can ever\n * send it. Removal: `@parity/product-sdk` 0.23.0. Replace by intent:\n *\n * - An account that holds or spends value:\n * `SignerManager.getProductAccount(dotNsIdentifier, index)` from\n * `@parity/product-sdk-signer`. Host-backed and actually signable.\n * - The address offline, with no host: `deriveProductAccountPublicKey` from\n * `@parity/product-sdk-keys`, the canonical sr25519 soft derivation.\n * - An unlinkable per-context alias: select a registered ring-VRF key, then call\n * `SignerManager.getProductAccountAlias(keyHandle, context, location)` or\n * `createRingVRFProof(keyHandle, context, location, message)`.\n * - A context-scoped identifier, never used as an account: `blake2b256` from\n * `@parity/product-sdk/crypto`. Same bytes, without address packaging that\n * invites the mistake.\n *\n * @param parentAddress - Parent account SS58 address\n * @param context - Context string for derivation (e.g. an app id or scope label)\n * @param ss58Prefix - SS58 prefix (default: 42)\n * @returns Context alias info\n */\nexport function deriveContextAlias(\n parentAddress: string,\n context: string,\n ss58Prefix = 42,\n): ContextAliasInfo {\n const { publicKey: parentPublicKey } = ss58Decode(parentAddress);\n\n // Derive alias public key: blake2b-256(parentPublicKey || context)\n const contextBytes = new TextEncoder().encode(context);\n const combined = new Uint8Array(parentPublicKey.length + contextBytes.length);\n combined.set(parentPublicKey, 0);\n combined.set(contextBytes, parentPublicKey.length);\n\n const aliasPublicKey = blake2b256(combined);\n const address = ss58Encode(aliasPublicKey, ss58Prefix);\n const h160Address = deriveH160(aliasPublicKey);\n\n log.debug(\"Derived context alias\", {\n parentAddress,\n context,\n address,\n });\n\n return {\n address,\n h160Address,\n parentAddress,\n context,\n };\n}\n\n/**\n * Verify that a context alias was derived from a parent account.\n *\n * @deprecated Recomputes {@link deriveContextAlias} from two public values and\n * compares the result, so it confirms a derivation relationship and nothing\n * more. No secret enters the operation at any point, which means there is\n * nothing here to authenticate: a passing result does not show that anyone\n * controls either account. Removal: `@parity/product-sdk` 0.23.0.\n *\n * @param aliasAddress - Context alias SS58 address\n * @param parentAddress - Claimed parent address\n * @param context - Context string used for derivation\n * @returns True if derivation is valid\n */\nexport function verifyContextAlias(\n aliasAddress: string,\n parentAddress: string,\n context: string,\n): boolean {\n try {\n const derived = deriveContextAlias(parentAddress, context);\n const { publicKey: aliasKey } = ss58Decode(aliasAddress);\n const { publicKey: derivedKey } = ss58Decode(derived.address);\n\n // Compare public keys\n if (aliasKey.length !== derivedKey.length) return false;\n for (let i = 0; i < aliasKey.length; i++) {\n if (aliasKey[i] !== derivedKey[i]) return false;\n }\n return true;\n } catch {\n return false;\n }\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { LogEntry, LogHandler, LogLevel, Logger, LoggerConfig, configure, createLogger } from '@parity/product-sdk-logger';
2
- import { c as AppConfig, b as App } from './types-CztPAgZT.js';
3
- export { A as Account, C as ChainApi, a as CloudStorageApi, D as DotNsIdentitySignature, L as LocalStorageApi, S as SignMessageWithDotNsIdentityArgs, W as WalletApi } from './types-CztPAgZT.js';
2
+ import { c as AppConfig, b as App } from './types-DTgyMIi0.js';
3
+ export { A as Account, C as ChainApi, a as CloudStorageApi, D as DotNsIdentitySignature, L as LocalStorageApi, S as SignMessageWithDotNsIdentityArgs, W as WalletApi } from './types-DTgyMIi0.js';
4
4
  export { Result, err, isErrorOf, ok } from '@parity/result';
5
5
  export { SdkError, isSdkError } from '@parity/product-sdk-errors';
6
6
  export { isInsideContainer, isInsideContainerSync } from '@parity/product-sdk-host';
@@ -9,7 +9,7 @@ export { SignerManager } from '@parity/product-sdk-signer';
9
9
  export { createLocalKvStore } from '@parity/product-sdk-local-storage';
10
10
  export { CloudStorageClient, calculateCid } from '@parity/product-sdk-cloud-storage';
11
11
  export { ChainDefinition, PolkadotClient, TypedApi } from 'polkadot-api';
12
- import './dotns-hLSvmo6u.js';
12
+ import './dotns-DIaptENj.js';
13
13
 
14
14
  /**
15
15
  * createApp - Main entry point for the Product SDK
@@ -0,0 +1 @@
1
+ export * from '@parity/product-sdk-individuality';
@@ -0,0 +1,3 @@
1
+ export * from '@parity/product-sdk-individuality';
2
+ //# sourceMappingURL=index.js.map
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
@@ -2,12 +2,12 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
3
  import { ReactNode } from 'react';
4
4
  import { LogLevel } from '@parity/product-sdk-logger';
5
- import { b as App, S as SignMessageWithDotNsIdentityArgs, D as DotNsIdentitySignature, A as Account } from '../types-CztPAgZT.js';
5
+ import { b as App, S as SignMessageWithDotNsIdentityArgs, D as DotNsIdentitySignature, A as Account } from '../types-DTgyMIi0.js';
6
6
  import { ChainDefinition, TypedApi } from 'polkadot-api';
7
7
  import '@parity/product-sdk-cloud-storage';
8
8
  import '@parity/result';
9
9
  import '@parity/product-sdk-chain-client';
10
- import '../dotns-hLSvmo6u.js';
10
+ import '../dotns-DIaptENj.js';
11
11
 
12
12
  /** Props for ProductSDKProvider */
13
13
  interface ProductSDKProviderProps {
@@ -1,4 +1,4 @@
1
- import { A as Account, L as LocalStorageApi, C as ChainApi, a as CloudStorageApi, b as App } from '../types-CztPAgZT.js';
1
+ import { A as Account, L as LocalStorageApi, C as ChainApi, a as CloudStorageApi, b as App } from '../types-DTgyMIi0.js';
2
2
  export * from '@parity/product-sdk-local-storage/testing';
3
3
  export * from '@parity/product-sdk-signer/testing';
4
4
  export * from '@parity/product-sdk-contracts/testing';
@@ -7,7 +7,7 @@ import '@parity/product-sdk-logger';
7
7
  import '@parity/product-sdk-cloud-storage';
8
8
  import '@parity/result';
9
9
  import '@parity/product-sdk-chain-client';
10
- import '../dotns-hLSvmo6u.js';
10
+ import '../dotns-DIaptENj.js';
11
11
  import 'polkadot-api';
12
12
 
13
13
  /** Configurable behavior for the fake {@link WalletApi}. */
@@ -2,7 +2,7 @@ import { LogLevel } from '@parity/product-sdk-logger';
2
2
  import { ProductCloudStorageError, CloudStorageEnvironment } from '@parity/product-sdk-cloud-storage';
3
3
  import { Result } from '@parity/result';
4
4
  import { ChainClient } from '@parity/product-sdk-chain-client';
5
- import { P as PeopleUsernameChain } from './dotns-hLSvmo6u.js';
5
+ import { P as PeopleUsernameChain } from './dotns-DIaptENj.js';
6
6
  import { ChainDefinition, TypedApi, PolkadotClient } from 'polkadot-api';
7
7
 
8
8
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parity/product-sdk",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "description": "Unified SDK for building products in the Polkadot ecosystem - umbrella package",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -44,6 +44,10 @@
44
44
  "import": "./dist/identity/index.js",
45
45
  "types": "./dist/identity/index.d.ts"
46
46
  },
47
+ "./individuality": {
48
+ "import": "./dist/individuality/index.js",
49
+ "types": "./dist/individuality/index.d.ts"
50
+ },
47
51
  "./react": {
48
52
  "import": "./dist/react/index.js",
49
53
  "types": "./dist/react/index.d.ts"
@@ -68,18 +72,19 @@
68
72
  "dependencies": {
69
73
  "polkadot-api": "^2.1.6",
70
74
  "@parity/product-sdk-address": "0.1.1",
71
- "@parity/product-sdk-cloud-storage": "0.10.0",
72
- "@parity/product-sdk-chain-client": "0.10.0",
75
+ "@parity/product-sdk-cloud-storage": "0.10.1",
76
+ "@parity/product-sdk-contracts": "0.10.2",
77
+ "@parity/product-sdk-chain-client": "0.11.0",
73
78
  "@parity/product-sdk-crypto": "0.1.1",
74
- "@parity/product-sdk-host": "0.15.1",
75
- "@parity/product-sdk-contracts": "0.10.1",
76
- "@parity/product-sdk-keys": "0.3.18",
79
+ "@parity/product-sdk-host": "0.16.0",
80
+ "@parity/product-sdk-individuality": "0.1.0",
81
+ "@parity/product-sdk-keys": "0.3.19",
82
+ "@parity/product-sdk-logger": "0.1.1",
77
83
  "@parity/product-sdk-errors": "0.2.0",
78
84
  "@parity/result": "0.2.0",
79
- "@parity/product-sdk-logger": "0.1.1",
80
- "@parity/product-sdk-signer": "0.12.1",
81
- "@parity/product-sdk-tx": "0.4.1",
82
- "@parity/product-sdk-local-storage": "0.3.4"
85
+ "@parity/product-sdk-signer": "0.13.0",
86
+ "@parity/product-sdk-tx": "0.4.2",
87
+ "@parity/product-sdk-local-storage": "0.3.5"
83
88
  },
84
89
  "peerDependencies": {
85
90
  "react": "^18.0.0 || ^19.0.0"
@@ -3,8 +3,12 @@
3
3
  /**
4
4
  * @parity/product-sdk/identity
5
5
  *
6
- * Identity utilities: DotNS name resolution, context-alias derivation,
7
- * and Ring VRF anonymous aliases.
6
+ * Identity utilities: DotNS name resolution, plus the deprecated context-alias
7
+ * helpers.
8
+ *
9
+ * For real Ring VRF aliases and proofs, use `SignerManager`'s
10
+ * `getProductAccountAlias` and `createRingVRFProof` from
11
+ * `@parity/product-sdk-signer`.
8
12
  */
9
13
 
10
14
  // DotNS utilities
@@ -19,21 +23,13 @@ export {
19
23
  } from "./dotns.js";
20
24
  export type { PeopleUsernameChain, PeopleUsernameQueryApi } from "./dotns.js";
21
25
 
22
- // Context alias utilities
23
- export {
24
- deriveContextAlias,
25
- verifyContextAlias,
26
- deriveAnonymousAlias,
27
- createRingProof,
28
- verifyRingProof,
29
- } from "./product-account.js";
26
+ // Context alias utilities (deprecated)
27
+ export { deriveContextAlias, verifyContextAlias } from "./product-account.js";
30
28
 
31
29
  // Types
32
30
  export type {
33
31
  DotNsRecord,
34
32
  ContextAliasInfo,
35
- AnonymousAliasInfo,
36
- RingLocation,
37
33
  VerificationResult,
38
34
  OnChainIdentity,
39
35
  } from "./types.js";
@@ -0,0 +1,129 @@
1
+ // Copyright 2026 Parity Technologies (UK) Ltd.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * Frozen vectors for the deprecated context-alias helpers.
5
+ *
6
+ * These pin current behaviour so the deprecation cannot silently alter the
7
+ * derivation. Never re-derive: a caller may use the value as a plain
8
+ * identifier, where different output bytes would be a silent break.
9
+ */
10
+ import { ss58Decode, ss58Encode } from "@parity/product-sdk-address";
11
+ import { blake2b256 } from "@parity/product-sdk-crypto";
12
+ import { describe, expect, it } from "vitest";
13
+ import * as identity from "./index.js";
14
+ import { deriveContextAlias, verifyContextAlias } from "./product-account.js";
15
+
16
+ const ALICE = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY";
17
+ const CONTEXT = "voting-round-1";
18
+
19
+ /** Recomputes the documented formula from primitives, independent of the implementation. */
20
+ function expectedAliasPublicKey(parentAddress: string, context: string): Uint8Array {
21
+ const { publicKey } = ss58Decode(parentAddress);
22
+ const contextBytes = new TextEncoder().encode(context);
23
+ const combined = new Uint8Array(publicKey.length + contextBytes.length);
24
+ combined.set(publicKey, 0);
25
+ combined.set(contextBytes, publicKey.length);
26
+ return blake2b256(combined);
27
+ }
28
+
29
+ describe("deriveContextAlias", () => {
30
+ it("returns blake2b256(parentPublicKey || context), encoded at the given prefix", () => {
31
+ const alias = deriveContextAlias(ALICE, CONTEXT);
32
+ const expected = expectedAliasPublicKey(ALICE, CONTEXT);
33
+
34
+ expect(alias.address).toBe(ss58Encode(expected, 42));
35
+ });
36
+
37
+ it("matches a frozen vector for a known parent and context", () => {
38
+ const alias = deriveContextAlias(ALICE, CONTEXT);
39
+
40
+ expect(alias.address).toBe("5GPTdhxkG9wNKhCSN1vZrCwrf3fwvAf4j487vqrkVzvRMH6F");
41
+ expect(alias.h160Address).toBe("0x93d10a91de267ba79b27fbec373e5a3b2e86a283");
42
+ expect(alias.parentAddress).toBe(ALICE);
43
+ expect(alias.context).toBe(CONTEXT);
44
+ });
45
+
46
+ it("defaults to ss58 prefix 42", () => {
47
+ expect(deriveContextAlias(ALICE, CONTEXT).address).toBe(
48
+ deriveContextAlias(ALICE, CONTEXT, 42).address,
49
+ );
50
+ });
51
+
52
+ it("changes only the encoding when the ss58 prefix changes, not the key", () => {
53
+ const at42 = deriveContextAlias(ALICE, CONTEXT, 42);
54
+ const at0 = deriveContextAlias(ALICE, CONTEXT, 0);
55
+
56
+ expect(at0.address).not.toBe(at42.address);
57
+ expect(Array.from(ss58Decode(at0.address).publicKey)).toEqual(
58
+ Array.from(ss58Decode(at42.address).publicKey),
59
+ );
60
+ });
61
+
62
+ it("derives a different alias for a different context", () => {
63
+ expect(deriveContextAlias(ALICE, "round-1").address).not.toBe(
64
+ deriveContextAlias(ALICE, "round-2").address,
65
+ );
66
+ });
67
+ });
68
+
69
+ describe("verifyContextAlias", () => {
70
+ it("accepts an alias derived from the same parent and context", () => {
71
+ const alias = deriveContextAlias(ALICE, CONTEXT);
72
+
73
+ expect(verifyContextAlias(alias.address, ALICE, CONTEXT)).toBe(true);
74
+ });
75
+
76
+ it("rejects a different context", () => {
77
+ const alias = deriveContextAlias(ALICE, CONTEXT);
78
+
79
+ expect(verifyContextAlias(alias.address, ALICE, "voting-round-2")).toBe(false);
80
+ });
81
+
82
+ it("rejects a different parent", () => {
83
+ const alias = deriveContextAlias(ALICE, CONTEXT);
84
+ const bob = "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty";
85
+
86
+ expect(verifyContextAlias(alias.address, bob, CONTEXT)).toBe(false);
87
+ });
88
+
89
+ it("returns false rather than throwing on an undecodable address", () => {
90
+ expect(verifyContextAlias("not-an-address", ALICE, CONTEXT)).toBe(false);
91
+ });
92
+
93
+ // Guards the byte-level comparison: `addressesEqual` from
94
+ // @parity/product-sdk-address compares SS58 strings exactly and would
95
+ // return false here, silently narrowing behaviour.
96
+ it("compares public keys, so it accepts an alias encoded at another prefix", () => {
97
+ const alias = deriveContextAlias(ALICE, CONTEXT, 42);
98
+ const reencoded = ss58Encode(ss58Decode(alias.address).publicKey, 0);
99
+
100
+ expect(reencoded).not.toBe(alias.address);
101
+ expect(verifyContextAlias(reencoded, ALICE, CONTEXT)).toBe(true);
102
+ });
103
+ });
104
+
105
+ describe("the identity export surface", () => {
106
+ // These threw on every call, so no working consumer could exist. Deleting
107
+ // turns a guaranteed runtime throw into a compile error.
108
+ it("no longer exports the unimplemented ring helpers", () => {
109
+ for (const name of ["deriveAnonymousAlias", "createRingProof", "verifyRingProof"]) {
110
+ expect(name in identity).toBe(false);
111
+ }
112
+ });
113
+
114
+ it("still exports the DotNS helpers and the deprecated context-alias pair", () => {
115
+ for (const name of [
116
+ "resolveDotNs",
117
+ "reverseDotNs",
118
+ "isDotNsAvailable",
119
+ "resolvePeopleUsernameOwner",
120
+ "isValidDotNsName",
121
+ "normalizeDotNsName",
122
+ "accountIdHexToBytes",
123
+ "deriveContextAlias",
124
+ "verifyContextAlias",
125
+ ]) {
126
+ expect(name in identity).toBe(true);
127
+ }
128
+ });
129
+ });
@@ -1,10 +1,13 @@
1
1
  // Copyright 2026 Parity Technologies (UK) Ltd.
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
  /**
4
- * Context alias derivation
4
+ * Context alias derivation (deprecated, removal in 0.23.0)
5
5
  *
6
6
  * Derives a deterministic, context-bound alias from a parent account using blake2b-256.
7
7
  *
8
+ * The output is a hash, not a key, so no signing key exists for the addresses
9
+ * returned here. See the notes on each function for what to use instead.
10
+ *
8
11
  * NOTE: this is NOT the canonical sr25519 product-account derivation used by
9
12
  * mobile, desktop, and dotli hosts. For that, use
10
13
  * `@parity/product-sdk-keys::deriveProductAccountPublicKey`.
@@ -13,7 +16,7 @@
13
16
  import { createLogger } from "@parity/product-sdk-logger";
14
17
  import { blake2b256 } from "@parity/product-sdk-crypto";
15
18
  import { ss58Encode, ss58Decode, deriveH160 } from "@parity/product-sdk-address";
16
- import type { ContextAliasInfo, AnonymousAliasInfo, RingLocation } from "./types.js";
19
+ import type { ContextAliasInfo } from "./types.js";
17
20
 
18
21
  const log = createLogger("identity");
19
22
 
@@ -23,19 +26,27 @@ const log = createLogger("identity");
23
26
  * The alias is deterministically derived using:
24
27
  * aliasPublicKey = blake2b256(parentPublicKey || context)
25
28
  *
29
+ * @deprecated Returns addresses that no key can spend. The alias public key is a
30
+ * blake2b-256 hash rather than a derived key, so no secret corresponds to the
31
+ * SS58 address or to the H160: both can receive value and neither can ever
32
+ * send it. Removal: `@parity/product-sdk` 0.23.0. Replace by intent:
33
+ *
34
+ * - An account that holds or spends value:
35
+ * `SignerManager.getProductAccount(dotNsIdentifier, index)` from
36
+ * `@parity/product-sdk-signer`. Host-backed and actually signable.
37
+ * - The address offline, with no host: `deriveProductAccountPublicKey` from
38
+ * `@parity/product-sdk-keys`, the canonical sr25519 soft derivation.
39
+ * - An unlinkable per-context alias: select a registered ring-VRF key, then call
40
+ * `SignerManager.getProductAccountAlias(keyHandle, context, location)` or
41
+ * `createRingVRFProof(keyHandle, context, location, message)`.
42
+ * - A context-scoped identifier, never used as an account: `blake2b256` from
43
+ * `@parity/product-sdk/crypto`. Same bytes, without address packaging that
44
+ * invites the mistake.
45
+ *
26
46
  * @param parentAddress - Parent account SS58 address
27
47
  * @param context - Context string for derivation (e.g. an app id or scope label)
28
48
  * @param ss58Prefix - SS58 prefix (default: 42)
29
49
  * @returns Context alias info
30
- *
31
- * @example
32
- * ```ts
33
- * const alias = deriveContextAlias(
34
- * '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',
35
- * 'voting-round-1'
36
- * );
37
- * console.log('Alias address:', alias.address);
38
- * ```
39
50
  */
40
51
  export function deriveContextAlias(
41
52
  parentAddress: string,
@@ -71,6 +82,12 @@ export function deriveContextAlias(
71
82
  /**
72
83
  * Verify that a context alias was derived from a parent account.
73
84
  *
85
+ * @deprecated Recomputes {@link deriveContextAlias} from two public values and
86
+ * compares the result, so it confirms a derivation relationship and nothing
87
+ * more. No secret enters the operation at any point, which means there is
88
+ * nothing here to authenticate: a passing result does not show that anyone
89
+ * controls either account. Removal: `@parity/product-sdk` 0.23.0.
90
+ *
74
91
  * @param aliasAddress - Context alias SS58 address
75
92
  * @param parentAddress - Claimed parent address
76
93
  * @param context - Context string used for derivation
@@ -96,69 +113,3 @@ export function verifyContextAlias(
96
113
  return false;
97
114
  }
98
115
  }
99
-
100
- /**
101
- * Derive an anonymous alias using Ring VRF
102
- *
103
- * This creates a context-specific alias that cannot be linked
104
- * back to the original identity without the ring proof.
105
- *
106
- * @param context - Context for alias derivation (e.g., "voting-round-1")
107
- * @param ringLocation - Ring location for proof generation
108
- * @returns Anonymous alias info
109
- */
110
- export function deriveAnonymousAlias(
111
- context: string,
112
- ringLocation: RingLocation,
113
- ): AnonymousAliasInfo {
114
- log.debug("Deriving anonymous alias", { context, ringLocation });
115
-
116
- // TODO: Implement Ring VRF alias derivation
117
- // This requires the Ring VRF implementation from TruAPI
118
- throw new Error(
119
- "deriveAnonymousAlias() is not yet implemented. " +
120
- "This requires container mode with Ring VRF support.",
121
- );
122
- }
123
-
124
- /**
125
- * Create a Ring VRF proof for a message
126
- *
127
- * @param message - Message to prove
128
- * @param ringLocation - Ring location
129
- * @returns Proof bytes
130
- */
131
- export async function createRingProof(
132
- message: Uint8Array,
133
- ringLocation: RingLocation,
134
- ): Promise<Uint8Array> {
135
- log.debug("Creating ring proof", { ringLocation });
136
-
137
- // TODO: Implement Ring VRF proof creation via TruAPI
138
- throw new Error(
139
- "createRingProof() is not yet implemented. " +
140
- "This requires container mode with Ring VRF support.",
141
- );
142
- }
143
-
144
- /**
145
- * Verify a Ring VRF proof
146
- *
147
- * @param message - Original message
148
- * @param proof - Proof bytes
149
- * @param alias - Expected alias
150
- * @returns True if proof is valid
151
- */
152
- export async function verifyRingProof(
153
- message: Uint8Array,
154
- proof: Uint8Array,
155
- alias: string,
156
- ): Promise<boolean> {
157
- log.debug("Verifying ring proof");
158
-
159
- // TODO: Implement Ring VRF proof verification
160
- throw new Error(
161
- "verifyRingProof() is not yet implemented. " +
162
- "This requires container mode with Ring VRF support.",
163
- );
164
- }
@@ -18,7 +18,12 @@ export interface DotNsRecord {
18
18
  expiresAt?: number;
19
19
  }
20
20
 
21
- /** Context alias info: a deterministic, context-bound alias derived from a parent account */
21
+ /**
22
+ * Context alias info: a deterministic, context-bound alias derived from a parent account
23
+ *
24
+ * @deprecated Returned by `deriveContextAlias`, whose addresses no key can spend.
25
+ * Removal: `@parity/product-sdk` 0.23.0.
26
+ */
22
27
  export interface ContextAliasInfo {
23
28
  /** Alias SS58 address */
24
29
  address: string;
@@ -30,24 +35,6 @@ export interface ContextAliasInfo {
30
35
  context: string;
31
36
  }
32
37
 
33
- /** Ring VRF alias info */
34
- export interface AnonymousAliasInfo {
35
- /** Anonymous alias identifier */
36
- alias: string;
37
- /** Ring location for proof generation */
38
- ringLocation: RingLocation;
39
- /** Context used for alias derivation */
40
- context: string;
41
- }
42
-
43
- /** Ring location for VRF proofs */
44
- export interface RingLocation {
45
- /** Ring index */
46
- ringIndex: number;
47
- /** Member index within ring */
48
- memberIndex: number;
49
- }
50
-
51
38
  /** Identity verification result */
52
39
  export interface VerificationResult {
53
40
  /** Whether identity is verified */
@@ -0,0 +1,56 @@
1
+ // Copyright 2026 Parity Technologies (UK) Ltd.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * Compile-time guard for the chain contract in `@parity/product-sdk-individuality`.
5
+ *
6
+ * That package types its chain parameter structurally, listing the storage
7
+ * entries it needs rather than naming a descriptor. That keeps it free of a
8
+ * chain-client dependency and lets its tests use a plain double, at the cost that
9
+ * the contract can drift from the real chain silently, since the double satisfies
10
+ * it by construction.
11
+ *
12
+ * This file closes that gap: if a descriptor regeneration changes a key or a
13
+ * value type, `pnpm typecheck` fails here.
14
+ *
15
+ * **It lives in the umbrella package deliberately.** Inside the individuality
16
+ * package the same assertion is vacuous, passing even against a contract that
17
+ * demands a pallet the chain does not have, because the descriptor types do not
18
+ * fully resolve through that package's dependency graph. Here, where both
19
+ * `chain-client` and the individuality package are direct dependencies, it
20
+ * correctly rejects a bogus contract. The negative control below keeps that
21
+ * property honest: if `IndividualityChain` ever stopped constraining, the
22
+ * `@ts-expect-error` would report as unused and this file would fail.
23
+ */
24
+ import type { getChainAPI } from "@parity/product-sdk-chain-client";
25
+ import type { IndividualityChain } from "@parity/product-sdk-individuality";
26
+ import { expect, test } from "vitest";
27
+
28
+ // The false branch must be `false`, not `never`. `never` is assignable to
29
+ // `true`, so a `never` branch would make the assertion unfalsifiable.
30
+ type Assert<T extends true> = T;
31
+
32
+ type PaseoClient = Awaited<ReturnType<typeof getChainAPI<"paseo">>>;
33
+ type DevnetClient = Awaited<ReturnType<typeof getChainAPI<"devnet">>>;
34
+
35
+ // These four aliases are the test. Each fails to typecheck if its condition
36
+ // breaks, so they need no export and no runtime reference.
37
+ type PaseoSatisfiesContract = Assert<PaseoClient extends IndividualityChain ? true : false>;
38
+ type DevnetSatisfiesContract = Assert<DevnetClient extends IndividualityChain ? true : false>;
39
+
40
+ // Negative control, kept type-only so it emits no runtime code. If
41
+ // `IndividualityChain` ever stopped constraining, this flips to `false` and the
42
+ // file fails to typecheck, which is what keeps the assertions above honest.
43
+ type ClientWithoutIndividuality = {
44
+ assetHub: unknown;
45
+ raw: { assetHub: unknown };
46
+ destroy(): void;
47
+ };
48
+ type RejectsBogusClient = Assert<
49
+ ClientWithoutIndividuality extends IndividualityChain ? false : true
50
+ >;
51
+
52
+ test("the individuality chain contract is asserted at compile time", () => {
53
+ // The type assertions above are the test. This keeps vitest from reporting
54
+ // the file as an empty suite.
55
+ expect(true).toBe(true);
56
+ });
@@ -0,0 +1,8 @@
1
+ // Copyright 2026 Parity Technologies (UK) Ltd.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * @parity/product-sdk/individuality
5
+ *
6
+ * Re-exports from @parity/product-sdk-individuality.
7
+ */
8
+ export * from "@parity/product-sdk-individuality";