@novasamatech/host-papp 0.9.1 → 0.9.3

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.
Files changed (37) hide show
  1. package/.papi/descriptors/dist/common-types.d.ts +1483 -1359
  2. package/.papi/descriptors/dist/descriptors-BLqmZ_vS.js +25 -0
  3. package/.papi/descriptors/dist/index.d.ts +1 -1
  4. package/.papi/descriptors/dist/index.js +8 -6
  5. package/.papi/descriptors/dist/metadataTypes-wXgvb64i.js +3 -0
  6. package/.papi/descriptors/dist/metadataTypes.d.ts +1 -1
  7. package/.papi/descriptors/dist/people_lite.d.ts +1175 -1001
  8. package/.papi/descriptors/dist/people_lite_metadata-CwU9OBGy.js +3 -0
  9. package/.papi/descriptors/generated.json +1 -1
  10. package/.papi/descriptors/package.json +1 -1
  11. package/.papi/metadata/people_lite.scale +0 -0
  12. package/.papi/polkadot-api.json +3 -3
  13. package/README.md +140 -87
  14. package/dist/identity/identifierKey.d.ts +19 -0
  15. package/dist/identity/identifierKey.js +17 -0
  16. package/dist/identity/impl.js +12 -17
  17. package/dist/identity/index.d.ts +2 -0
  18. package/dist/identity/index.js +1 -0
  19. package/dist/identity/rpcAdapter.d.ts +5 -1
  20. package/dist/identity/rpcAdapter.js +9 -3
  21. package/dist/identity/types.d.ts +9 -1
  22. package/dist/index.d.ts +5 -2
  23. package/dist/index.js +2 -0
  24. package/dist/sso/sessionManager/scale/remoteMessage.d.ts +102 -2
  25. package/dist/sso/sessionManager/scale/remoteMessage.js +11 -1
  26. package/dist/sso/sessionManager/scale/resourceAllocation.d.ts +3 -0
  27. package/dist/sso/sessionManager/scale/resourceAllocation.js +11 -0
  28. package/dist/sso/sessionManager/scale/ringVrf.d.ts +43 -2
  29. package/dist/sso/sessionManager/scale/ringVrf.js +12 -1
  30. package/dist/sso/sessionManager/scale/ringVrfKeys.d.ts +85 -0
  31. package/dist/sso/sessionManager/scale/ringVrfKeys.js +22 -0
  32. package/dist/sso/sessionManager/userSession.d.ts +22 -3
  33. package/dist/sso/sessionManager/userSession.js +59 -3
  34. package/package.json +9 -5
  35. package/.papi/descriptors/dist/descriptors-D5oN4i7I.js +0 -25
  36. package/.papi/descriptors/dist/metadataTypes-BaUy_4gO.js +0 -3
  37. package/.papi/descriptors/dist/people_lite_metadata-Cj1JLFI2.js +0 -3
@@ -67,6 +67,13 @@ export declare const RemoteMessageCodec: import("scale-ts").Codec<{
67
67
  tag: "RingVrfAliasRequest";
68
68
  value: {
69
69
  callingProductId: string;
70
+ keyHandle: [string, {
71
+ tag: "Index";
72
+ value: number;
73
+ } | {
74
+ tag: "Raw";
75
+ value: Uint8Array<ArrayBufferLike>;
76
+ }];
70
77
  context: [string, {
71
78
  tag: "Index";
72
79
  value: number;
@@ -94,7 +101,7 @@ export declare const RemoteMessageCodec: import("scale-ts").Codec<{
94
101
  alias: Uint8Array<ArrayBufferLike>;
95
102
  }, import("@novasamatech/scale").CodecError<undefined, "GetAliasErr::Rejected"> | import("@novasamatech/scale").CodecError<{
96
103
  reason: string;
97
- }, "GetAliasErr::Unknown"> | import("@novasamatech/scale").CodecError<undefined, "GetAliasErr::RingNotFound"> | import("@novasamatech/scale").CodecError<undefined, "GetAliasErr::NotMember">>;
104
+ }, "GetAliasErr::Unknown"> | import("@novasamatech/scale").CodecError<undefined, "GetAliasErr::RingNotFound"> | import("@novasamatech/scale").CodecError<undefined, "GetAliasErr::NotMember"> | import("@novasamatech/scale").CodecError<undefined, "GetAliasErr::KeyNotRegistered"> | import("@novasamatech/scale").CodecError<undefined, "GetAliasErr::KeyNotInRing">>;
98
105
  };
99
106
  } | {
100
107
  tag: "ResourceAllocationRequest";
@@ -142,6 +149,7 @@ export declare const RemoteMessageCodec: import("scale-ts").Codec<{
142
149
  tag: "AutoSigning";
143
150
  value: {
144
151
  productRootPrivateKey: Uint8Array<ArrayBufferLike>;
152
+ ringVrfDomainEntropy: Uint8Array<ArrayBufferLike>;
145
153
  };
146
154
  } | {
147
155
  tag: "BulletInAllowance";
@@ -224,6 +232,13 @@ export declare const RemoteMessageCodec: import("scale-ts").Codec<{
224
232
  tag: "RingVrfProofRequest";
225
233
  value: {
226
234
  callingProductId: string;
235
+ keyHandle: [string, {
236
+ tag: "Index";
237
+ value: number;
238
+ } | {
239
+ tag: "Raw";
240
+ value: Uint8Array<ArrayBufferLike>;
241
+ }];
227
242
  context: [string, {
228
243
  tag: "Index";
229
244
  value: number;
@@ -257,7 +272,7 @@ export declare const RemoteMessageCodec: import("scale-ts").Codec<{
257
272
  ringRevision: number;
258
273
  }, import("@novasamatech/scale").CodecError<undefined, "CreateProofErr::Rejected"> | import("@novasamatech/scale").CodecError<{
259
274
  reason: string;
260
- }, "CreateProofErr::Unknown"> | import("@novasamatech/scale").CodecError<undefined, "CreateProofErr::RingNotFound"> | import("@novasamatech/scale").CodecError<undefined, "CreateProofErr::NotMember">>;
275
+ }, "CreateProofErr::Unknown"> | import("@novasamatech/scale").CodecError<undefined, "CreateProofErr::RingNotFound"> | import("@novasamatech/scale").CodecError<undefined, "CreateProofErr::NotMember"> | import("@novasamatech/scale").CodecError<undefined, "CreateProofErr::KeyNotRegistered"> | import("@novasamatech/scale").CodecError<undefined, "CreateProofErr::KeyNotInRing"> | import("@novasamatech/scale").CodecError<undefined, "CreateProofErr::NotAllowlisted">>;
261
276
  };
262
277
  } | {
263
278
  tag: "SignVrfRequest";
@@ -300,6 +315,91 @@ export declare const RemoteMessageCodec: import("scale-ts").Codec<{
300
315
  productPublicKey: Uint8Array<ArrayBufferLike>;
301
316
  }, string>;
302
317
  };
318
+ } | {
319
+ tag: "RegisterRingVrfKeyRequest";
320
+ value: {
321
+ callingProductId: string;
322
+ index: {
323
+ tag: "Index";
324
+ value: number;
325
+ } | {
326
+ tag: "Raw";
327
+ value: Uint8Array<ArrayBufferLike>;
328
+ };
329
+ ring: {
330
+ chainId: `0x${string}`;
331
+ junctions: ({
332
+ tag: "PalletInstance";
333
+ value: number;
334
+ } | {
335
+ tag: "CollectionId";
336
+ value: Uint8Array<ArrayBufferLike>;
337
+ })[];
338
+ };
339
+ };
340
+ } | {
341
+ tag: "RegisterRingVrfKeyResponse";
342
+ value: {
343
+ respondingTo: string;
344
+ payload: import("scale-ts").ResultPayload<Uint8Array<ArrayBufferLike>, import("@novasamatech/scale").CodecError<undefined, "RegisterRingVrfKeyErr::NotConnected"> | import("@novasamatech/scale").CodecError<undefined, "RegisterRingVrfKeyErr::Rejected"> | import("@novasamatech/scale").CodecError<{
345
+ reason: string;
346
+ }, "RegisterRingVrfKeyErr::Unknown"> | import("@novasamatech/scale").CodecError<undefined, "RegisterRingVrfKeyErr::RingNotFound">>;
347
+ };
348
+ } | {
349
+ tag: "ListRingVrfKeysRequest";
350
+ value: {
351
+ callingProductId: string;
352
+ owner: string;
353
+ disclosure: "Anonymized" | "PublicKey";
354
+ };
355
+ } | {
356
+ tag: "ListRingVrfKeysResponse";
357
+ value: {
358
+ respondingTo: string;
359
+ payload: import("scale-ts").ResultPayload<{
360
+ handle: [string, {
361
+ tag: "Index";
362
+ value: number;
363
+ } | {
364
+ tag: "Raw";
365
+ value: Uint8Array<ArrayBufferLike>;
366
+ }];
367
+ rings: {
368
+ chainId: `0x${string}`;
369
+ junctions: ({
370
+ tag: "PalletInstance";
371
+ value: number;
372
+ } | {
373
+ tag: "CollectionId";
374
+ value: Uint8Array<ArrayBufferLike>;
375
+ })[];
376
+ }[];
377
+ publicKey: Uint8Array<ArrayBufferLike> | undefined;
378
+ }[], import("@novasamatech/scale").CodecError<undefined, "ListRingVrfKeysErr::NotConnected"> | import("@novasamatech/scale").CodecError<undefined, "ListRingVrfKeysErr::Rejected"> | import("@novasamatech/scale").CodecError<{
379
+ reason: string;
380
+ }, "ListRingVrfKeysErr::Unknown">>;
381
+ };
382
+ } | {
383
+ tag: "RingVrfSignRequest";
384
+ value: {
385
+ callingProductId: string;
386
+ keyHandle: [string, {
387
+ tag: "Index";
388
+ value: number;
389
+ } | {
390
+ tag: "Raw";
391
+ value: Uint8Array<ArrayBufferLike>;
392
+ }];
393
+ message: Uint8Array<ArrayBufferLike>;
394
+ };
395
+ } | {
396
+ tag: "RingVrfSignResponse";
397
+ value: {
398
+ respondingTo: string;
399
+ payload: import("scale-ts").ResultPayload<Uint8Array<ArrayBufferLike>, import("@novasamatech/scale").CodecError<undefined, "RingVrfSignErr::NotConnected"> | import("@novasamatech/scale").CodecError<undefined, "RingVrfSignErr::Rejected"> | import("@novasamatech/scale").CodecError<{
400
+ reason: string;
401
+ }, "RingVrfSignErr::Unknown"> | import("@novasamatech/scale").CodecError<undefined, "RingVrfSignErr::KeyNotRegistered"> | import("@novasamatech/scale").CodecError<undefined, "RingVrfSignErr::NotAllowlisted">>;
402
+ };
303
403
  };
304
404
  };
305
405
  }>;
@@ -3,7 +3,8 @@ import { Struct, _void, str } from 'scale-ts';
3
3
  import { CreateTransactionLegacyRequestCodec, CreateTransactionRequestCodec, CreateTransactionResponseCodec, } from './createTransaction.js';
4
4
  import { ProductSubtreeRequestCodec, ProductSubtreeResponseCodec } from './productSubtree.js';
5
5
  import { ResourceAllocationRequestCodec, ResourceAllocationResponseCodec } from './resourceAllocation.js';
6
- import { RingVrfAliasRequestCodec, RingVrfAliasResponseCodec, RingVrfProofRequestCodec, RingVrfProofResponseCodec, } from './ringVrf.js';
6
+ import { RingVrfAliasRequestCodec, RingVrfAliasResponseCodec, RingVrfProofRequestCodec, RingVrfProofResponseCodec, RingVrfSignRequestCodec, RingVrfSignResponseCodec, } from './ringVrf.js';
7
+ import { ListRingVrfKeysRequestCodec, ListRingVrfKeysResponseCodec, RegisterRingVrfKeyRequestCodec, RegisterRingVrfKeyResponseCodec, } from './ringVrfKeys.js';
7
8
  import { SignVrfRequestCodec, SignVrfResponseCodec } from './signVrf.js';
8
9
  import { SignRawLegacyRequestCodec, SignRawLegacyResponseCodec, SigningRequestCodec, SigningResponseCodec, } from './signing.js';
9
10
  export const RemoteMessageCodec = Struct({
@@ -31,6 +32,15 @@ export const RemoteMessageCodec = Struct({
31
32
  // RFC-0022 additions — appended so existing variant indexes stay stable.
32
33
  ProductSubtreeRequest: ProductSubtreeRequestCodec,
33
34
  ProductSubtreeResponse: ProductSubtreeResponseCodec,
35
+ // RFC-0024 additions — likewise appended. `RingVrfAliasRequest` and
36
+ // `RingVrfProofRequest` above gained a `keyHandle` field in place rather
37
+ // than being re-added here, since a handle is now mandatory on both.
38
+ RegisterRingVrfKeyRequest: RegisterRingVrfKeyRequestCodec,
39
+ RegisterRingVrfKeyResponse: RegisterRingVrfKeyResponseCodec,
40
+ ListRingVrfKeysRequest: ListRingVrfKeysRequestCodec,
41
+ ListRingVrfKeysResponse: ListRingVrfKeysResponseCodec,
42
+ RingVrfSignRequest: RingVrfSignRequestCodec,
43
+ RingVrfSignResponse: RingVrfSignResponseCodec,
34
44
  }),
35
45
  }),
36
46
  });
@@ -32,6 +32,7 @@ export declare const ApAllocatedResourceCodec: import("scale-ts").Codec<{
32
32
  tag: "AutoSigning";
33
33
  value: {
34
34
  productRootPrivateKey: Uint8Array<ArrayBufferLike>;
35
+ ringVrfDomainEntropy: Uint8Array<ArrayBufferLike>;
35
36
  };
36
37
  } | {
37
38
  tag: "BulletInAllowance";
@@ -57,6 +58,7 @@ export declare const ApAllocationOutcomeCodec: import("scale-ts").Codec<{
57
58
  tag: "AutoSigning";
58
59
  value: {
59
60
  productRootPrivateKey: Uint8Array<ArrayBufferLike>;
61
+ ringVrfDomainEntropy: Uint8Array<ArrayBufferLike>;
60
62
  };
61
63
  } | {
62
64
  tag: "BulletInAllowance";
@@ -113,6 +115,7 @@ export declare const ResourceAllocationResponseCodec: import("scale-ts").Codec<{
113
115
  tag: "AutoSigning";
114
116
  value: {
115
117
  productRootPrivateKey: Uint8Array<ArrayBufferLike>;
118
+ ringVrfDomainEntropy: Uint8Array<ArrayBufferLike>;
116
119
  };
117
120
  } | {
118
121
  tag: "BulletInAllowance";
@@ -23,6 +23,17 @@ export const ApAllocatedResourceCodec = Enum({
23
23
  // `Sr25519PrivateKey ++ Sr25519Nonce` (64 bytes): the full expanded secret
24
24
  // needed to sign and soft-derive `/{index}` below the product root.
25
25
  productRootPrivateKey: Bytes(),
26
+ // RFC-0024: entropy of the `//{productId}` node of the ring VRF tree, which
27
+ // is disjoint from the sr25519 product-account tree above. It lets the Host
28
+ // derive the member secret of a *registered* key locally — the second
29
+ // motivation being that a headless Account Holder execution context may not
30
+ // fit a ring VRF proof inside its ~30 s / ~24 MB budget.
31
+ //
32
+ // Derivation from this entropy is unconditional arithmetic: nothing about
33
+ // holding it distinguishes a meaningful index from a meaningless one, so the
34
+ // registry supplies that distinction. A Host MUST NOT derive a member secret
35
+ // for a `(product, index)` pair absent from its registry.
36
+ ringVrfDomainEntropy: Bytes(),
26
37
  }),
27
38
  });
28
39
  export const ApAllocationOutcomeCodec = Enum({
@@ -2,6 +2,13 @@ import type { CodecType } from 'scale-ts';
2
2
  export type RingVrfAliasRequest = CodecType<typeof RingVrfAliasRequestCodec>;
3
3
  export declare const RingVrfAliasRequestCodec: import("scale-ts").Codec<{
4
4
  callingProductId: string;
5
+ keyHandle: [string, {
6
+ tag: "Index";
7
+ value: number;
8
+ } | {
9
+ tag: "Raw";
10
+ value: Uint8Array<ArrayBufferLike>;
11
+ }];
5
12
  context: [string, {
6
13
  tag: "Index";
7
14
  value: number;
@@ -28,11 +35,18 @@ export declare const RingVrfAliasResponseCodec: import("scale-ts").Codec<{
28
35
  alias: Uint8Array<ArrayBufferLike>;
29
36
  }, import("@novasamatech/scale").CodecError<undefined, "GetAliasErr::Rejected"> | import("@novasamatech/scale").CodecError<{
30
37
  reason: string;
31
- }, "GetAliasErr::Unknown"> | import("@novasamatech/scale").CodecError<undefined, "GetAliasErr::RingNotFound"> | import("@novasamatech/scale").CodecError<undefined, "GetAliasErr::NotMember">>;
38
+ }, "GetAliasErr::Unknown"> | import("@novasamatech/scale").CodecError<undefined, "GetAliasErr::RingNotFound"> | import("@novasamatech/scale").CodecError<undefined, "GetAliasErr::NotMember"> | import("@novasamatech/scale").CodecError<undefined, "GetAliasErr::KeyNotRegistered"> | import("@novasamatech/scale").CodecError<undefined, "GetAliasErr::KeyNotInRing">>;
32
39
  }>;
33
40
  export type RingVrfProofRequest = CodecType<typeof RingVrfProofRequestCodec>;
34
41
  export declare const RingVrfProofRequestCodec: import("scale-ts").Codec<{
35
42
  callingProductId: string;
43
+ keyHandle: [string, {
44
+ tag: "Index";
45
+ value: number;
46
+ } | {
47
+ tag: "Raw";
48
+ value: Uint8Array<ArrayBufferLike>;
49
+ }];
36
50
  context: [string, {
37
51
  tag: "Index";
38
52
  value: number;
@@ -65,5 +79,32 @@ export declare const RingVrfProofResponseCodec: import("scale-ts").Codec<{
65
79
  ringRevision: number;
66
80
  }, import("@novasamatech/scale").CodecError<undefined, "CreateProofErr::Rejected"> | import("@novasamatech/scale").CodecError<{
67
81
  reason: string;
68
- }, "CreateProofErr::Unknown"> | import("@novasamatech/scale").CodecError<undefined, "CreateProofErr::RingNotFound"> | import("@novasamatech/scale").CodecError<undefined, "CreateProofErr::NotMember">>;
82
+ }, "CreateProofErr::Unknown"> | import("@novasamatech/scale").CodecError<undefined, "CreateProofErr::RingNotFound"> | import("@novasamatech/scale").CodecError<undefined, "CreateProofErr::NotMember"> | import("@novasamatech/scale").CodecError<undefined, "CreateProofErr::KeyNotRegistered"> | import("@novasamatech/scale").CodecError<undefined, "CreateProofErr::KeyNotInRing"> | import("@novasamatech/scale").CodecError<undefined, "CreateProofErr::NotAllowlisted">>;
83
+ }>;
84
+ /**
85
+ * Host → Account Holder request for a plain signature by the ring VRF member key
86
+ * itself (RFC-0024 `ring_vrf_sign`), rather than an anonymous ring proof.
87
+ *
88
+ * Carries no context and no ring: the signature derives no alias and proves no
89
+ * membership, so there is nothing for either to scope. It is verified against
90
+ * the member public key and is therefore linkable to every other use of the key.
91
+ */
92
+ export type RingVrfSignRequest = CodecType<typeof RingVrfSignRequestCodec>;
93
+ export declare const RingVrfSignRequestCodec: import("scale-ts").Codec<{
94
+ callingProductId: string;
95
+ keyHandle: [string, {
96
+ tag: "Index";
97
+ value: number;
98
+ } | {
99
+ tag: "Raw";
100
+ value: Uint8Array<ArrayBufferLike>;
101
+ }];
102
+ message: Uint8Array<ArrayBufferLike>;
103
+ }>;
104
+ export type RingVrfSignResponse = CodecType<typeof RingVrfSignResponseCodec>;
105
+ export declare const RingVrfSignResponseCodec: import("scale-ts").Codec<{
106
+ respondingTo: string;
107
+ payload: import("scale-ts").ResultPayload<Uint8Array<ArrayBufferLike>, import("@novasamatech/scale").CodecError<undefined, "RingVrfSignErr::NotConnected"> | import("@novasamatech/scale").CodecError<undefined, "RingVrfSignErr::Rejected"> | import("@novasamatech/scale").CodecError<{
108
+ reason: string;
109
+ }, "RingVrfSignErr::Unknown"> | import("@novasamatech/scale").CodecError<undefined, "RingVrfSignErr::KeyNotRegistered"> | import("@novasamatech/scale").CodecError<undefined, "RingVrfSignErr::NotAllowlisted">>;
69
110
  }>;
@@ -1,8 +1,9 @@
1
- import { ContextualAlias, CreateProofErr, DotNsIdentifier, GetAliasErr, ProductProofContext, RingLocation, RingVrfProof, } from '@novasamatech/host-api';
1
+ import { ContextualAlias, CreateProofErr, DotNsIdentifier, GetAliasErr, ProductProofContext, RingLocation, RingVrfKeyHandle, RingVrfProof, RingVrfSignErr, } from '@novasamatech/host-api';
2
2
  import { Bytes } from '@novasamatech/scale';
3
3
  import { Result, Struct, str } from 'scale-ts';
4
4
  export const RingVrfAliasRequestCodec = Struct({
5
5
  callingProductId: DotNsIdentifier,
6
+ keyHandle: RingVrfKeyHandle,
6
7
  context: ProductProofContext,
7
8
  ring: RingLocation,
8
9
  });
@@ -12,6 +13,7 @@ export const RingVrfAliasResponseCodec = Struct({
12
13
  });
13
14
  export const RingVrfProofRequestCodec = Struct({
14
15
  callingProductId: DotNsIdentifier,
16
+ keyHandle: RingVrfKeyHandle,
15
17
  context: ProductProofContext,
16
18
  ring: RingLocation,
17
19
  message: Bytes(),
@@ -20,3 +22,12 @@ export const RingVrfProofResponseCodec = Struct({
20
22
  respondingTo: str,
21
23
  payload: Result(RingVrfProof, CreateProofErr),
22
24
  });
25
+ export const RingVrfSignRequestCodec = Struct({
26
+ callingProductId: DotNsIdentifier,
27
+ keyHandle: RingVrfKeyHandle,
28
+ message: Bytes(),
29
+ });
30
+ export const RingVrfSignResponseCodec = Struct({
31
+ respondingTo: str,
32
+ payload: Result(Bytes(), RingVrfSignErr),
33
+ });
@@ -0,0 +1,85 @@
1
+ import type { CodecType } from 'scale-ts';
2
+ /**
3
+ * Host → Account Holder registration of a key the calling product owns.
4
+ *
5
+ * Ownership is `callingProductId` and is never chosen by the caller, so this is
6
+ * consent-free. Registration is idempotent: re-registering an `index` for an
7
+ * additional `ring` extends the existing entry rather than creating a second
8
+ * one, so re-notifying the phone about an entry it already has costs nothing.
9
+ *
10
+ * A Host holding the product's ring VRF domain entropy (see `AutoSigning` in
11
+ * `resourceAllocation.ts`) answers immediately and mirrors this fire-and-forget;
12
+ * without the entropy it issues the request and waits.
13
+ *
14
+ * > A Host MUST NOT derive a member secret for a `(product, index)` pair absent
15
+ * > from its registry. Domain entropy makes derivation unconditional — only
16
+ * > registration, which always reaches the phone, brings a key into existence.
17
+ */
18
+ export type RegisterRingVrfKeyRequest = CodecType<typeof RegisterRingVrfKeyRequestCodec>;
19
+ export declare const RegisterRingVrfKeyRequestCodec: import("scale-ts").Codec<{
20
+ callingProductId: string;
21
+ index: {
22
+ tag: "Index";
23
+ value: number;
24
+ } | {
25
+ tag: "Raw";
26
+ value: Uint8Array<ArrayBufferLike>;
27
+ };
28
+ ring: {
29
+ chainId: `0x${string}`;
30
+ junctions: ({
31
+ tag: "PalletInstance";
32
+ value: number;
33
+ } | {
34
+ tag: "CollectionId";
35
+ value: Uint8Array<ArrayBufferLike>;
36
+ })[];
37
+ };
38
+ }>;
39
+ export type RegisterRingVrfKeyResponse = CodecType<typeof RegisterRingVrfKeyResponseCodec>;
40
+ export declare const RegisterRingVrfKeyResponseCodec: import("scale-ts").Codec<{
41
+ respondingTo: string;
42
+ payload: import("scale-ts").ResultPayload<Uint8Array<ArrayBufferLike>, import("@novasamatech/scale").CodecError<undefined, "RegisterRingVrfKeyErr::NotConnected"> | import("@novasamatech/scale").CodecError<undefined, "RegisterRingVrfKeyErr::Rejected"> | import("@novasamatech/scale").CodecError<{
43
+ reason: string;
44
+ }, "RegisterRingVrfKeyErr::Unknown"> | import("@novasamatech/scale").CodecError<undefined, "RegisterRingVrfKeyErr::RingNotFound">>;
45
+ }>;
46
+ /**
47
+ * Host → Account Holder listing of the registry entries owned by `owner`.
48
+ *
49
+ * `owner` may be `callingProductId` — permissionless — or another product, in
50
+ * which case the caller needs a grant. `PublicKey` disclosure additionally
51
+ * returns the member public key, which is linkable across every ring it appears
52
+ * in and so is permissioned cross-product even though the handle is not.
53
+ */
54
+ export type ListRingVrfKeysRequest = CodecType<typeof ListRingVrfKeysRequestCodec>;
55
+ export declare const ListRingVrfKeysRequestCodec: import("scale-ts").Codec<{
56
+ callingProductId: string;
57
+ owner: string;
58
+ disclosure: "Anonymized" | "PublicKey";
59
+ }>;
60
+ export type ListRingVrfKeysResponse = CodecType<typeof ListRingVrfKeysResponseCodec>;
61
+ export declare const ListRingVrfKeysResponseCodec: import("scale-ts").Codec<{
62
+ respondingTo: string;
63
+ payload: import("scale-ts").ResultPayload<{
64
+ handle: [string, {
65
+ tag: "Index";
66
+ value: number;
67
+ } | {
68
+ tag: "Raw";
69
+ value: Uint8Array<ArrayBufferLike>;
70
+ }];
71
+ rings: {
72
+ chainId: `0x${string}`;
73
+ junctions: ({
74
+ tag: "PalletInstance";
75
+ value: number;
76
+ } | {
77
+ tag: "CollectionId";
78
+ value: Uint8Array<ArrayBufferLike>;
79
+ })[];
80
+ }[];
81
+ publicKey: Uint8Array<ArrayBufferLike> | undefined;
82
+ }[], import("@novasamatech/scale").CodecError<undefined, "ListRingVrfKeysErr::NotConnected"> | import("@novasamatech/scale").CodecError<undefined, "ListRingVrfKeysErr::Rejected"> | import("@novasamatech/scale").CodecError<{
83
+ reason: string;
84
+ }, "ListRingVrfKeysErr::Unknown">>;
85
+ }>;
@@ -0,0 +1,22 @@
1
+ import { DerivationIndex, DotNsIdentifier, ListRingVrfKeysErr, RegisterRingVrfKeyErr, RegisteredRingVrfKey, RingLocation, RingVrfKeyDisclosure, RingVrfPublicKey, } from '@novasamatech/host-api';
2
+ import { Result, Struct, Vector, str } from 'scale-ts';
3
+ export const RegisterRingVrfKeyRequestCodec = Struct({
4
+ callingProductId: DotNsIdentifier,
5
+ index: DerivationIndex,
6
+ ring: RingLocation,
7
+ });
8
+ export const RegisterRingVrfKeyResponseCodec = Struct({
9
+ // referencing to RemoteMessage.messageId
10
+ respondingTo: str,
11
+ payload: Result(RingVrfPublicKey, RegisterRingVrfKeyErr),
12
+ });
13
+ export const ListRingVrfKeysRequestCodec = Struct({
14
+ callingProductId: DotNsIdentifier,
15
+ owner: DotNsIdentifier,
16
+ disclosure: RingVrfKeyDisclosure,
17
+ });
18
+ export const ListRingVrfKeysResponseCodec = Struct({
19
+ // referencing to RemoteMessage.messageId
20
+ respondingTo: str,
21
+ payload: Result(Vector(RegisteredRingVrfKey), ListRingVrfKeysErr),
22
+ });
@@ -1,4 +1,4 @@
1
- import { ContextualAlias, ProductProofContext, RingLocation, RingVrfProof, VrfSignature } from '@novasamatech/host-api';
1
+ import { ContextualAlias, DerivationIndex, ProductProofContext, RegisteredRingVrfKey, RingLocation, RingVrfKeyDisclosure, RingVrfKeyHandle, RingVrfProof, VrfSignature } from '@novasamatech/host-api';
2
2
  import type { Encryption, StatementProver, StatementStoreAdapter } from '@novasamatech/statement-store';
3
3
  import type { StorageAdapter } from '@novasamatech/storage-adapter';
4
4
  import { ResultAsync } from 'neverthrow';
@@ -24,8 +24,27 @@ export type UserSession = StoredUserSession & {
24
24
  signRawLegacy(payload: SignRawLegacyRequest): ResultAsync<Uint8Array, Error>;
25
25
  createTransaction(payload: CreateTransactionRequest): ResultAsync<Uint8Array, Error>;
26
26
  createTransactionLegacy(payload: CreateTransactionLegacyRequest): ResultAsync<Uint8Array, Error>;
27
- getRingVrfAlias(callingProductId: string, context: CodecType<typeof ProductProofContext>, ring: CodecType<typeof RingLocation>): ResultAsync<CodecType<typeof ContextualAlias>, Error>;
28
- createRingVrfProof(callingProductId: string, context: CodecType<typeof ProductProofContext>, ring: CodecType<typeof RingLocation>, message: Uint8Array): ResultAsync<CodecType<typeof RingVrfProof>, Error>;
27
+ getRingVrfAlias(callingProductId: string, keyHandle: CodecType<typeof RingVrfKeyHandle>, context: CodecType<typeof ProductProofContext>, ring: CodecType<typeof RingLocation>): ResultAsync<CodecType<typeof ContextualAlias>, Error>;
28
+ createRingVrfProof(callingProductId: string, keyHandle: CodecType<typeof RingVrfKeyHandle>, context: CodecType<typeof ProductProofContext>, ring: CodecType<typeof RingLocation>, message: Uint8Array): ResultAsync<CodecType<typeof RingVrfProof>, Error>;
29
+ /**
30
+ * Signs `message` with the ring VRF member key itself (RFC-0024).
31
+ *
32
+ * Unlike {@link createRingVrfProof} this is not anonymous: the result is
33
+ * verified against the member public key and is linkable to every other use
34
+ * of that key.
35
+ */
36
+ ringVrfSign(callingProductId: string, keyHandle: CodecType<typeof RingVrfKeyHandle>, message: Uint8Array): ResultAsync<Uint8Array, Error>;
37
+ /**
38
+ * Registers a ring VRF key owned by `callingProductId` against `ring`,
39
+ * returning the member public key (RFC-0024).
40
+ *
41
+ * The Account Holder is the authoritative registry, so registration always
42
+ * reaches it. Idempotent — re-registering an index for an additional ring
43
+ * extends the existing entry.
44
+ */
45
+ registerRingVrfKey(callingProductId: string, index: CodecType<typeof DerivationIndex>, ring: CodecType<typeof RingLocation>): ResultAsync<Uint8Array, Error>;
46
+ /** Lists the ring VRF registry entries owned by `owner` (RFC-0024). */
47
+ listRingVrfKeys(callingProductId: string, owner: string, disclosure: CodecType<typeof RingVrfKeyDisclosure>): ResultAsync<CodecType<typeof RegisteredRingVrfKey>[], Error>;
29
48
  /**
30
49
  * Fetches the sr25519 public key of `//product//{productId}` (RFC-0022).
31
50
  *
@@ -1,4 +1,4 @@
1
- import { ContextualAlias, ProductProofContext, RingLocation, RingVrfProof, VrfSignature } from '@novasamatech/host-api';
1
+ import { ContextualAlias, DerivationIndex, ProductProofContext, RegisteredRingVrfKey, RingLocation, RingVrfKeyDisclosure, RingVrfKeyHandle, RingVrfProof, VrfSignature, } from '@novasamatech/host-api';
2
2
  import { enumValue } from '@novasamatech/scale';
3
3
  import { createSession } from '@novasamatech/statement-store';
4
4
  import { fieldListView } from '@novasamatech/storage-adapter';
@@ -244,11 +244,12 @@ export function createUserSession({ userSession, statementStore, encryption, sto
244
244
  return withHostActionTrace(withQueueTimeout(inner, 'createTransactionLegacy'), messageId, userSession.id);
245
245
  });
246
246
  },
247
- getRingVrfAlias(callingProductId, context, ring) {
247
+ getRingVrfAlias(callingProductId, keyHandle, context, ring) {
248
248
  return enqueue(() => {
249
249
  const messageId = nanoid();
250
250
  const data = enumValue('v1', enumValue('RingVrfAliasRequest', {
251
251
  callingProductId,
252
+ keyHandle,
252
253
  context,
253
254
  ring,
254
255
  }));
@@ -265,11 +266,12 @@ export function createUserSession({ userSession, statementStore, encryption, sto
265
266
  return withHostActionTrace(awaitReplyOrAckFailure(request, reply).andThen(result => result.success ? ok(result.value) : err(result.value)), messageId, userSession.id);
266
267
  });
267
268
  },
268
- createRingVrfProof(callingProductId, context, ring, message) {
269
+ createRingVrfProof(callingProductId, keyHandle, context, ring, message) {
269
270
  return enqueue(() => {
270
271
  const messageId = nanoid();
271
272
  const data = enumValue('v1', enumValue('RingVrfProofRequest', {
272
273
  callingProductId,
274
+ keyHandle,
273
275
  context,
274
276
  ring,
275
277
  message,
@@ -287,6 +289,60 @@ export function createUserSession({ userSession, statementStore, encryption, sto
287
289
  return withHostActionTrace(awaitReplyOrAckFailure(request, reply).andThen(result => result.success ? ok(result.value) : err(result.value)), messageId, userSession.id);
288
290
  });
289
291
  },
292
+ ringVrfSign(callingProductId, keyHandle, message) {
293
+ return enqueue(() => {
294
+ const messageId = nanoid();
295
+ const data = enumValue('v1', enumValue('RingVrfSignRequest', { callingProductId, keyHandle, message }));
296
+ emitHostAction(messageId, actionKindFromMessageData(data), userSession.id);
297
+ const responseFilter = (incoming) => {
298
+ if (incoming.data.tag === 'v1' &&
299
+ incoming.data.value.tag === 'RingVrfSignResponse' &&
300
+ incoming.data.value.value.respondingTo === messageId) {
301
+ return incoming.data.value.value.payload;
302
+ }
303
+ };
304
+ const request = session.request(RemoteMessageCodec, { messageId, data });
305
+ const reply = session.waitForRequestMessage(RemoteMessageCodec, responseFilter);
306
+ const inner = awaitReplyOrAckFailure(request, reply).andThen(result => result.success ? ok(result.value) : err(result.value));
307
+ return withHostActionTrace(withQueueTimeout(inner, 'ringVrfSign'), messageId, userSession.id);
308
+ });
309
+ },
310
+ registerRingVrfKey(callingProductId, index, ring) {
311
+ return enqueue(() => {
312
+ const messageId = nanoid();
313
+ const data = enumValue('v1', enumValue('RegisterRingVrfKeyRequest', { callingProductId, index, ring }));
314
+ emitHostAction(messageId, actionKindFromMessageData(data), userSession.id);
315
+ const responseFilter = (incoming) => {
316
+ if (incoming.data.tag === 'v1' &&
317
+ incoming.data.value.tag === 'RegisterRingVrfKeyResponse' &&
318
+ incoming.data.value.value.respondingTo === messageId) {
319
+ return incoming.data.value.value.payload;
320
+ }
321
+ };
322
+ const request = session.request(RemoteMessageCodec, { messageId, data });
323
+ const reply = session.waitForRequestMessage(RemoteMessageCodec, responseFilter);
324
+ const inner = awaitReplyOrAckFailure(request, reply).andThen(result => result.success ? ok(result.value) : err(result.value));
325
+ return withHostActionTrace(withQueueTimeout(inner, 'registerRingVrfKey'), messageId, userSession.id);
326
+ });
327
+ },
328
+ listRingVrfKeys(callingProductId, owner, disclosure) {
329
+ return enqueue(() => {
330
+ const messageId = nanoid();
331
+ const data = enumValue('v1', enumValue('ListRingVrfKeysRequest', { callingProductId, owner, disclosure }));
332
+ emitHostAction(messageId, actionKindFromMessageData(data), userSession.id);
333
+ const responseFilter = (incoming) => {
334
+ if (incoming.data.tag === 'v1' &&
335
+ incoming.data.value.tag === 'ListRingVrfKeysResponse' &&
336
+ incoming.data.value.value.respondingTo === messageId) {
337
+ return incoming.data.value.value.payload;
338
+ }
339
+ };
340
+ const request = session.request(RemoteMessageCodec, { messageId, data });
341
+ const reply = session.waitForRequestMessage(RemoteMessageCodec, responseFilter);
342
+ const inner = awaitReplyOrAckFailure(request, reply).andThen(result => result.success ? ok(result.value) : err(result.value));
343
+ return withHostActionTrace(withQueueTimeout(inner, 'listRingVrfKeys'), messageId, userSession.id);
344
+ });
345
+ },
290
346
  getProductSubtree(productId) {
291
347
  return enqueue(() => {
292
348
  const messageId = nanoid();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@novasamatech/host-papp",
3
3
  "type": "module",
4
- "version": "0.9.1",
4
+ "version": "0.9.3",
5
5
  "description": "Polkadot app integration",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {
@@ -11,6 +11,10 @@
11
11
  "keywords": [
12
12
  "polkadot"
13
13
  ],
14
+ "scripts": {
15
+ "papi:fix": "node ../../scripts/fix-papi-descriptors.mjs .papi/descriptors/dist",
16
+ "papi:update": "papi update && npm run papi:fix"
17
+ },
14
18
  "main": "dist/index.js",
15
19
  "exports": {
16
20
  "./package.json": "./package.json",
@@ -34,10 +38,10 @@
34
38
  "@noble/ciphers": "2.2.0",
35
39
  "@noble/curves": "2.2.0",
36
40
  "@noble/hashes": "2.2.0",
37
- "@novasamatech/host-api": "0.9.1",
38
- "@novasamatech/scale": "0.9.1",
39
- "@novasamatech/statement-store": "0.9.1",
40
- "@novasamatech/storage-adapter": "0.9.1",
41
+ "@novasamatech/host-api": "0.9.3",
42
+ "@novasamatech/scale": "0.9.3",
43
+ "@novasamatech/statement-store": "0.9.3",
44
+ "@novasamatech/storage-adapter": "0.9.3",
41
45
  "@polkadot-api/utils": "^0.4.0",
42
46
  "@polkadot-labs/hdkd-helpers": "^0.0.31",
43
47
  "nanoevents": "10.0.0",