@cofhe/sdk 0.8.0 → 1.0.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.
Files changed (87) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/acps/acp.ts +25 -6
  3. package/acps/index.ts +20 -15
  4. package/acps/onchain-utils.ts +15 -10
  5. package/acps/registry.ts +166 -8
  6. package/acps/sealing.ts +31 -5
  7. package/acps/share-metadata/appKey.ts +8 -0
  8. package/acps/share-metadata/decode.ts +120 -0
  9. package/acps/share-metadata/describe.ts +198 -0
  10. package/acps/share-metadata/encode.ts +147 -0
  11. package/acps/share-metadata/erc7984.ts +26 -0
  12. package/acps/share-metadata/index.ts +9 -0
  13. package/acps/share-metadata/layout.ts +69 -0
  14. package/acps/share-metadata/presets.ts +116 -0
  15. package/acps/share-metadata/schema.ts +47 -0
  16. package/acps/share-metadata/test/codec.test.ts +140 -0
  17. package/acps/share-metadata/test/describe.test.ts +112 -0
  18. package/acps/share-metadata/test/fixtures.ts +157 -0
  19. package/acps/share-metadata/test/live.test.ts +56 -0
  20. package/acps/share-metadata/test/presets.test.ts +119 -0
  21. package/acps/share-metadata/test/verify.test.ts +144 -0
  22. package/acps/share-metadata/verify.ts +155 -0
  23. package/acps/store.ts +48 -18
  24. package/acps/test/aclServedAddresses.test.ts +65 -0
  25. package/acps/test/acp.test.ts +102 -7
  26. package/acps/test/localstorage.test.ts +28 -1
  27. package/acps/test/registry.test.ts +144 -0
  28. package/acps/test/sealing.test.ts +74 -0
  29. package/acps/test/store.test.ts +71 -0
  30. package/acps/test/utils.test.ts +63 -0
  31. package/acps/test/validation.test.ts +0 -4
  32. package/acps/types.ts +43 -6
  33. package/acps/utils.ts +15 -2
  34. package/acps/validation.ts +3 -1
  35. package/core/acps.ts +123 -74
  36. package/core/client.ts +33 -7
  37. package/core/clientTypes.ts +25 -7
  38. package/core/config.ts +8 -0
  39. package/core/decrypt/apiError.ts +4 -1
  40. package/core/decrypt/verifyDecryptResult.ts +4 -1
  41. package/core/encrypt/cofheMocksZkVerifySign.ts +19 -2
  42. package/core/test/acpDefaults.test.ts +108 -19
  43. package/core/test/acpStoreAccountCase.test.ts +80 -0
  44. package/core/test/acps.test.ts +38 -3
  45. package/core/test/apiError.test.ts +8 -0
  46. package/core/test/appKeyConfig.test.ts +94 -0
  47. package/core/test/config.test.ts +8 -0
  48. package/core/test/decryptBuilders.test.ts +110 -2
  49. package/core/test/incomingShares.test.ts +84 -0
  50. package/core/test/mocksEncryptRange.test.ts +90 -0
  51. package/core/test/utils.test.ts +128 -0
  52. package/core/test/verifyDecryptResult.test.ts +51 -0
  53. package/core/utils.ts +16 -9
  54. package/dist/acps.cjs +796 -132
  55. package/dist/acps.d.cts +367 -35
  56. package/dist/acps.d.ts +367 -35
  57. package/dist/acps.js +2 -2
  58. package/dist/{chunk-UJYOBHYA.js → chunk-3L2IVPMI.js} +688 -203
  59. package/dist/chunk-J23FYAI2.js +174 -0
  60. package/dist/{chunk-GGI7Y6AW.js → chunk-O2ITEUEU.js} +110 -269
  61. package/dist/chunk-WJGTPW7K.js +228 -0
  62. package/dist/{clientTypes-D3aIXmUp.d.cts → clientTypes-IO6b5Um8.d.cts} +61 -21
  63. package/dist/{clientTypes-5YPPR16m.d.ts → clientTypes-b1pOxOUE.d.ts} +61 -21
  64. package/dist/core.cjs +3115 -2584
  65. package/dist/core.d.cts +6 -3
  66. package/dist/core.d.ts +6 -3
  67. package/dist/core.js +4 -3
  68. package/dist/node.cjs +3001 -2470
  69. package/dist/node.d.cts +2 -2
  70. package/dist/node.d.ts +2 -2
  71. package/dist/node.js +18 -17
  72. package/dist/{onchain-utils-CUAK8glx.d.cts → onchain-utils-CgOslubH.d.cts} +139 -15
  73. package/dist/{onchain-utils-CUAK8glx.d.ts → onchain-utils-CgOslubH.d.ts} +139 -15
  74. package/dist/web.cjs +3011 -2487
  75. package/dist/web.d.cts +2 -2
  76. package/dist/web.d.ts +2 -2
  77. package/dist/web.js +4 -10
  78. package/dist/zkProve.worker.cjs +14 -7
  79. package/dist/zkProve.worker.js +2 -8
  80. package/node/index.ts +1 -10
  81. package/node/storage.ts +18 -7
  82. package/node/test/storage-permissions.test.ts +40 -0
  83. package/package.json +4 -4
  84. package/web/index.ts +1 -10
  85. package/web/test/threadPoolBenchHelper.ts +1 -7
  86. package/web/zkProve.worker.ts +1 -10
  87. package/dist/chunk-NMKMCAI3.js +0 -14
package/dist/node.d.cts CHANGED
@@ -1,8 +1,8 @@
1
- import { C as CofheInputConfig, a as CofheConfig, b as CofheClient } from './clientTypes-D3aIXmUp.cjs';
1
+ import { C as CofheInputConfig, a as CofheConfig, b as CofheClient } from './clientTypes-IO6b5Um8.cjs';
2
2
  import 'viem';
3
3
  import './types-C07FK-cL.cjs';
4
4
  import 'zod';
5
- import './onchain-utils-CUAK8glx.cjs';
5
+ import './onchain-utils-CgOslubH.cjs';
6
6
  import 'zustand/vanilla';
7
7
 
8
8
  /**
package/dist/node.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { C as CofheInputConfig, a as CofheConfig, b as CofheClient } from './clientTypes-5YPPR16m.js';
1
+ import { C as CofheInputConfig, a as CofheConfig, b as CofheClient } from './clientTypes-b1pOxOUE.js';
2
2
  import 'viem';
3
3
  import './types-C07FK-cL.js';
4
4
  import 'zod';
5
- import './onchain-utils-CUAK8glx.js';
5
+ import './onchain-utils-CgOslubH.js';
6
6
  import 'zustand/vanilla';
7
7
 
8
8
  /**
package/dist/node.js CHANGED
@@ -1,18 +1,25 @@
1
- import { createCofheConfigBase, createCofheClientBase } from './chunk-GGI7Y6AW.js';
1
+ import { createCofheConfigBase, createCofheClientBase } from './chunk-O2ITEUEU.js';
2
2
  import './chunk-UKQAJK4N.js';
3
- import './chunk-UJYOBHYA.js';
4
- import { TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT } from './chunk-NMKMCAI3.js';
3
+ import './chunk-3L2IVPMI.js';
4
+ import { fromHexString } from './chunk-WJGTPW7K.js';
5
+ import { TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT } from './chunk-J23FYAI2.js';
5
6
  import { promises } from 'fs';
6
7
  import { join } from 'path';
7
8
  import { init_panic_hook, ProvenCompactCiphertextList, CompactPkeCrs, TfheCompactPublicKey } from 'node-tfhe';
8
9
 
9
10
  var memoryStorage = {};
11
+ var getStorageDir = () => join(process.env.HOME || process.env.USERPROFILE || ".", ".cofhesdk");
12
+ var ensureStorageDir = async (storageDir) => {
13
+ await promises.mkdir(storageDir, { recursive: true, mode: 448 });
14
+ await promises.chmod(storageDir, 448).catch(() => {
15
+ });
16
+ };
10
17
  var createNodeStorage = () => {
11
18
  return {
12
19
  getItem: async (name) => {
13
20
  try {
14
- const storageDir = join(process.env.HOME || process.env.USERPROFILE || ".", ".cofhesdk");
15
- await promises.mkdir(storageDir, { recursive: true });
21
+ const storageDir = getStorageDir();
22
+ await ensureStorageDir(storageDir);
16
23
  const filePath = join(storageDir, `${name}.json`);
17
24
  const data = await promises.readFile(filePath, "utf8").catch(() => null);
18
25
  return data ? JSON.parse(data) : null;
@@ -23,10 +30,12 @@ var createNodeStorage = () => {
23
30
  },
24
31
  setItem: async (name, value) => {
25
32
  try {
26
- const storageDir = join(process.env.HOME || process.env.USERPROFILE || ".", ".cofhesdk");
27
- await promises.mkdir(storageDir, { recursive: true });
33
+ const storageDir = getStorageDir();
34
+ await ensureStorageDir(storageDir);
28
35
  const filePath = join(storageDir, `${name}.json`);
29
- await promises.writeFile(filePath, JSON.stringify(value));
36
+ await promises.writeFile(filePath, JSON.stringify(value), { mode: 384 });
37
+ await promises.chmod(filePath, 384).catch(() => {
38
+ });
30
39
  } catch (e) {
31
40
  console.warn("Node.js filesystem modules not available, falling back to memory storage" + e);
32
41
  memoryStorage[name] = value;
@@ -34,8 +43,7 @@ var createNodeStorage = () => {
34
43
  },
35
44
  removeItem: async (name) => {
36
45
  try {
37
- const storageDir = join(process.env.HOME || process.env.USERPROFILE || ".", ".cofhesdk");
38
- const filePath = join(storageDir, `${name}.json`);
46
+ const filePath = join(getStorageDir(), `${name}.json`);
39
47
  await promises.unlink(filePath).catch(() => {
40
48
  });
41
49
  } catch (e) {
@@ -53,13 +61,6 @@ async function initTfhe() {
53
61
  tfheInitialized = true;
54
62
  return true;
55
63
  }
56
- var fromHexString = (hexString) => {
57
- const cleanString = hexString.length % 2 === 1 ? `0${hexString}` : hexString;
58
- const arr = cleanString.replace(/^0x/, "").match(/.{1,2}/g);
59
- if (!arr)
60
- return new Uint8Array();
61
- return new Uint8Array(arr.map((byte) => parseInt(byte, 16)));
62
- };
63
64
  var _deserializeTfhePublicKey = (buff) => {
64
65
  return TfheCompactPublicKey.safe_deserialize(fromHexString(buff), TFHE_RS_SAFE_SERIALIZATION_SIZE_LIMIT);
65
66
  };
@@ -1,4 +1,4 @@
1
- import { Hex, PublicClient, WalletClient } from 'viem';
1
+ import { Hex, Address, PublicClient, WalletClient } from 'viem';
2
2
 
3
3
  type EthEncryptedData = {
4
4
  data: Uint8Array;
@@ -35,6 +35,52 @@ declare const seal: (value: bigint | number, publicKey: string) => EthEncryptedD
35
35
  */
36
36
  declare const unsealWithPrivateKey: (privateKey: string, parsedData: EthEncryptedData) => bigint;
37
37
 
38
+ /**
39
+ * A label says where one ctHash of a SNAPSHOT share came from, as something the recipient can
40
+ * check against the chain. It speaks of contracts, selectors and positions in the chain only:
41
+ * it does not know what a token, a balance or a transfer is. A reader that recognises a selector
42
+ * can present the value accordingly (see `describeShareMetadata`). A share carries one label per
43
+ * ctHash, in the order of `acp.handles`, so the ctHashes themselves are never repeated.
44
+ */
45
+ /** One argument of a stored-value read: the share issuer, or a literal 32-byte ABI word. */
46
+ type ShareLabelReadArg = {
47
+ type: 'issuer';
48
+ } | {
49
+ type: 'word';
50
+ value: Hex;
51
+ };
52
+ /** A stored value: what a view function of a contract returned at a block. */
53
+ type StoredValueLabel = {
54
+ kind: 'stored';
55
+ contract: Address;
56
+ /** 4-byte selector of the view function. */
57
+ selector: Hex;
58
+ /** Static ABI types only: each argument is one 32-byte word. */
59
+ args: ShareLabelReadArg[];
60
+ /** Which 32-byte word of the return data is the ctHash (0 for a single return value). */
61
+ returnWord: number;
62
+ /** Block the value was read at (on Arbitrum: the L2 block number). */
63
+ block: bigint;
64
+ };
65
+ /** An event value: a value carried by one event (log) that a contract emitted. */
66
+ type EventValueLabel = {
67
+ kind: 'event';
68
+ contract: Address;
69
+ /** Block of the log (on Arbitrum: the L2 block number). */
70
+ block: bigint;
71
+ /** Index of the log's transaction within its block. */
72
+ txIndex: number;
73
+ /** Block-wide index of the log, as RPC nodes return it. */
74
+ logIndex: number;
75
+ /** First 4 bytes of the log's topic0: the event selector. */
76
+ selector: Hex;
77
+ };
78
+ /** The issuer chose not to say where the ctHash came from. */
79
+ type UnlabelledLabel = {
80
+ kind: 'unlabelled';
81
+ };
82
+ type ShareLabel = StoredValueLabel | EventValueLabel | UnlabelledLabel;
83
+
38
84
  /**
39
85
  * EIP712 related types
40
86
  */
@@ -76,6 +122,12 @@ interface ACPPrivate {
76
122
  * Never leaves the client.
77
123
  */
78
124
  sealingPrivateKey: Hex;
125
+ /**
126
+ * (sharing / recipient) The share metadata: the labels of its handles, a v3 blob
127
+ * (`decodeShareMetadata` / `describeShareMetadata`). Not signed; travels with the share, in the
128
+ * exported JSON or in the registry's `Shared` event. Absent when the share has none.
129
+ */
130
+ metadata?: Hex;
79
131
  /**
80
132
  * EIP712 domain used to sign this acp.
81
133
  * Should not be set manually, included in metadata as part of serialization flows.
@@ -211,29 +263,44 @@ type CreateSharingACPOptions = ACPScopeOptions & {
211
263
  expiration?: number;
212
264
  revokerData?: number;
213
265
  revokerContract?: string;
266
+ /**
267
+ * The labels of the handles, one per handle in order. Kept on the acp as `metadata`, then
268
+ * written into `export()` and posted by `shareOnChain`.
269
+ */
270
+ labels?: readonly ShareLabel[];
271
+ /**
272
+ * The key of the app the share is for (`shareAppKey(app)`), kept in `metadata` with the labels.
273
+ * A client configured with `acp: { app }` fills it in; a recipient client with the same `app`
274
+ * lists the share, one with another app does not.
275
+ */
276
+ appKey?: Hex;
214
277
  };
278
+ /** A share as exported (`SharedACP`) or read from the registry. A `name` in it is ignored. */
215
279
  type ImportSharedACPOptions = ACPScopeOptions & {
216
280
  type?: 'sharing';
217
281
  issuer: string;
218
282
  recipient: string;
219
283
  issuerSignature: string;
220
- name?: string;
221
284
  expiration: number;
222
285
  revokerData?: number;
223
286
  revokerContract?: string;
287
+ /** The share metadata (labels blob), kept on the recipient acp; `0x` or absent for none. */
288
+ metadata?: string;
224
289
  };
225
290
  /** An ACP is plain JSON-serializable data — the serialized form is the ACP itself. */
226
291
  type SerializedACP = ACP;
227
292
  /**
228
293
  * The share payload produced by `ACPUtils.export()` — the full public component
229
294
  * with `sealingKey`/`recipientSignature` left for the recipient to fill, plus
230
- * the display name and acp type. Fixed shape: every field is always present
295
+ * the acp type. The issuer's `name` is not exported: it is their own note, and the
296
+ * recipient names the share themselves. Fixed shape: every field is always present
231
297
  * (zero-values instead of omissions), so importers can parse a single schema.
232
- * Mirrors the on-chain sharing payload struct field-for-field.
298
+ * Mirrors the on-chain sharing payload struct field-for-field. The one optional
299
+ * field is `metadata`, the labels of the handles, present only when the share has them.
233
300
  */
234
301
  type SharedACP = Expand<Omit<ACPPublic, 'sealingKey' | 'recipientSignature'> & {
235
- name: string;
236
302
  type: 'sharing';
303
+ metadata?: Hex;
237
304
  }>;
238
305
  /**
239
306
  * An ACP on-chain status, as `client.acp.checkAccess` reports it instead of a revert.
@@ -244,11 +311,25 @@ type SharedACP = Expand<Omit<ACPPublic, 'sealingKey' | 'recipientSignature'> & {
244
311
  type ACPAccessStatus = 'valid' | 'allowed' | 'out-of-scope' | 'issuer-not-allowed' | 'expired' | 'revoked' | 'invalid-issuer-signature' | 'invalid-recipient-signature';
245
312
  /**
246
313
  * A share read back from the on-chain ACPShareRegistry: the posted payload
247
- * (SharedACP minus the client-side name/type) plus its registry id.
314
+ * (SharedACP minus its type), its registry id, and the
315
+ * metadata blob posted with it (`0x` when none) — for a SNAPSHOT share, the
316
+ * labels of its handles (`decodeShareMetadata` / `describeShareMetadata`).
248
317
  */
249
- type IncomingShare = Expand<Omit<SharedACP, 'name' | 'type'> & {
318
+ type IncomingShare = Expand<Omit<SharedACP, 'type' | 'metadata'> & {
250
319
  shareId: Hex;
320
+ metadata: Hex;
321
+ /** The key of the app the share was posted for (`shareAppKey(app)`), when it names one. */
322
+ appKey?: Hex;
251
323
  }>;
324
+ /**
325
+ * What the share label helpers read: the handles, their issuer and the metadata blob. An
326
+ * `IncomingShare` (on-chain route) and a sharing or recipient `ACP` (exported JSON route) both fit.
327
+ */
328
+ type LabelledShare = {
329
+ issuer: Hex;
330
+ handles: readonly Hex[];
331
+ metadata?: Hex;
332
+ };
252
333
  /**
253
334
  * A type representing the acp fields that are used to generate the hash
254
335
  */
@@ -281,9 +362,12 @@ declare const ACPUtils: {
281
362
  */
282
363
  createSharing: (options: CreateSharingACPOptions) => SharingACP;
283
364
  /**
284
- * Import a shared acp from various input formats
365
+ * Import a shared acp from various input formats. The acp is named `name`, or after its issuer
366
+ * ("Shared by 0x1234…abcd"); a `name` in the share itself is ignored.
285
367
  */
286
- importShared: (options: ImportSharedACPOptions | string) => RecipientACP;
368
+ importShared: (options: ImportSharedACPOptions | string, { name }?: {
369
+ name?: string;
370
+ }) => RecipientACP;
287
371
  /**
288
372
  * Sign an ACP with the provided wallet client
289
373
  */
@@ -299,7 +383,9 @@ declare const ACPUtils: {
299
383
  /**
300
384
  * Import and sign a shared acp in one operation from various input formats
301
385
  */
302
- importSharedAndSign: (options: ImportSharedACPOptions | string, publicClient: PublicClient, walletClient: WalletClient) => Promise<RecipientACP>;
386
+ importSharedAndSign: (options: ImportSharedACPOptions | string, publicClient: PublicClient, walletClient: WalletClient, importOptions?: {
387
+ name?: string;
388
+ }) => Promise<RecipientACP>;
303
389
  /**
304
390
  * Deserialize an ACP from serialized data
305
391
  */
@@ -324,6 +410,7 @@ declare const ACPUtils: {
324
410
  handles: `0x${string}`[];
325
411
  issuerSignature: `0x${string}`;
326
412
  recipientSignature: `0x${string}`;
413
+ metadata?: `0x${string}` | undefined;
327
414
  sealingPrivateKey?: string | undefined;
328
415
  sealingKey?: string | undefined;
329
416
  };
@@ -350,6 +437,7 @@ declare const ACPUtils: {
350
437
  handles: `0x${string}`[];
351
438
  issuerSignature: `0x${string}`;
352
439
  recipientSignature: `0x${string}`;
440
+ metadata?: `0x${string}` | undefined;
353
441
  sealingPrivateKey?: string | undefined;
354
442
  sealingKey?: string | undefined;
355
443
  };
@@ -365,7 +453,7 @@ declare const ACPUtils: {
365
453
  /**
366
454
  * Export acp data for sharing (strips the private component).
367
455
  * Fixed `SharedACP` shape — every field always present, aligned with
368
- * `ACPPublic` and the on-chain sharing payload.
456
+ * `ACPPublic` and the on-chain sharing payload — plus `metadata` when the acp has labels.
369
457
  */
370
458
  export: (acp: ACP) => string;
371
459
  /**
@@ -416,6 +504,42 @@ declare const ACPUtils: {
416
504
  checkAccessOnChain: (acp: ACP, publicClient: PublicClient, handle?: bigint | Hex) => Promise<ACPAccessStatus>;
417
505
  };
418
506
 
507
+ /**
508
+ * - `verified`: the chain confirms the label.
509
+ * - `mismatch`: the chain contradicts it.
510
+ * - `unverifiable`: the chain could not be asked — an unlabelled ctHash, a node without the
511
+ * state of that block (a stored value needs an archive node once its block is old), or a
512
+ * failed request.
513
+ */
514
+ type LabelVerification = 'verified' | 'mismatch' | 'unverifiable';
515
+ /**
516
+ * How much of a share's labels a reader checks against the chain. Labels are the issuer's claim:
517
+ * - `all` (default): every label — one `getLogs` per contract and block, one call per stored value;
518
+ * - `events`: event values only, which any node can answer however old the block;
519
+ * - `none`: trust the labels as written, no requests (the issuer previewing their own share).
520
+ */
521
+ type ShareLabelVerifyMode = 'all' | 'events' | 'none';
522
+ /** A label's verification, or `skipped` when the verify mode leaves it unchecked. */
523
+ type ShareLabelCheck = LabelVerification | 'skipped';
524
+ /**
525
+ * Checks one label against the chain: does the ctHash really come from where the label says?
526
+ * `issuer` is the share issuer (`acp.issuer`), which an issuer argument of a stored value stands
527
+ * for. One request.
528
+ */
529
+ declare const verifyShareLabel: (label: ShareLabel, handle: Hex, publicClient: PublicClient, issuer: Address) => Promise<LabelVerification>;
530
+ /**
531
+ * Checks the labels of a share, index for index with `handles`, as far as `verify` says. Requests
532
+ * are shared: one `getLogs` per contract and block, however many values it carries, and one call
533
+ * per distinct stored read.
534
+ */
535
+ declare const verifyShareLabels: ({ labels, handles, issuer, publicClient, verify, }: {
536
+ labels: readonly ShareLabel[];
537
+ handles: readonly Hex[];
538
+ issuer: Address;
539
+ publicClient: PublicClient;
540
+ verify?: ShareLabelVerifyMode;
541
+ }) => Promise<ShareLabelCheck[]>;
542
+
419
543
  declare const getAclAddress: (publicClient: PublicClient) => Promise<Hex>;
420
544
  interface AclServedAddresses {
421
545
  defaultRevoker?: Hex;
@@ -428,10 +552,10 @@ declare const clearAclServedAddresses: () => void;
428
552
  * TaskManager -> acl() -> getters). Zero addresses and pre-upgrade ACLs (getters absent -> revert)
429
553
  * resolve to `undefined` — callers fall back to `acp.*` config.
430
554
  *
431
- * Resolutions are cached per chainId. A failure to reach the TaskManager (network
432
- * error, no CoFHE deployment) is NOT cached, so a transient outage does not pin
433
- * an empty result for the whole session.
555
+ * Resolutions are cached per chainId. A failure to reach the TaskManager or the ACL
556
+ * getters (network error, no CoFHE deployment) is NOT cached, so a transient outage
557
+ * does not pin an empty result for the whole session.
434
558
  */
435
559
  declare const getAclServedAddresses: (publicClient: PublicClient, chainId: number) => Promise<AclServedAddresses>;
436
560
 
437
- export { type ACP as A, type ACPHashFields as B, type CreateSelfACPOptions as C, type Expand as D, type EIP712Types as E, GenerateSealingKey as G, type ImportSharedACPOptions as I, type RecipientACP as R, type SerializedACP as S, type ValidationResult as V, type ACPPublic as a, type ACPSignaturePrimaryType as b, type EIP712Message as c, type CreateSharingACPOptions as d, type ACPMetadata as e, type SharedACP as f, type IncomingShare as g, type EIP712Domain as h, ACPUtils as i, getAclAddress as j, getAclServedAddresses as k, clearAclServedAddresses as l, type AclServedAddresses as m, type SealingKeyPair as n, type EthEncryptedData as o, type EIP712Type as p, type ACPPrivate as q, type ACPType as r, seal as s, type ACPOf as t, unsealWithPrivateKey as u, type SelfACP as v, type SharingACP as w, ACPScope as x, type ACPScopeOptions as y, type ACPAccessStatus as z };
561
+ export { type ACP as A, type EIP712Type as B, type CreateSelfACPOptions as C, type ACPPrivate as D, type EventValueLabel as E, type ACPType as F, GenerateSealingKey as G, type ACPOf as H, type ImportSharedACPOptions as I, type SelfACP as J, type SharingACP as K, type LabelledShare as L, ACPScope as M, type ACPScopeOptions as N, type ACPAccessStatus as O, type ACPHashFields as P, type Expand as Q, type RecipientACP as R, type ShareLabel as S, type UnlabelledLabel as U, type ValidationResult as V, type StoredValueLabel as a, type ACPPublic as b, type ACPSignaturePrimaryType as c, type EIP712Types as d, type EIP712Message as e, type SerializedACP as f, type CreateSharingACPOptions as g, type ACPMetadata as h, type SharedACP as i, type IncomingShare as j, type EIP712Domain as k, ACPUtils as l, getAclAddress as m, getAclServedAddresses as n, clearAclServedAddresses as o, type AclServedAddresses as p, type SealingKeyPair as q, type EthEncryptedData as r, seal as s, type ShareLabelReadArg as t, unsealWithPrivateKey as u, type LabelVerification as v, type ShareLabelVerifyMode as w, type ShareLabelCheck as x, verifyShareLabel as y, verifyShareLabels as z };
@@ -1,4 +1,4 @@
1
- import { Hex, PublicClient, WalletClient } from 'viem';
1
+ import { Hex, Address, PublicClient, WalletClient } from 'viem';
2
2
 
3
3
  type EthEncryptedData = {
4
4
  data: Uint8Array;
@@ -35,6 +35,52 @@ declare const seal: (value: bigint | number, publicKey: string) => EthEncryptedD
35
35
  */
36
36
  declare const unsealWithPrivateKey: (privateKey: string, parsedData: EthEncryptedData) => bigint;
37
37
 
38
+ /**
39
+ * A label says where one ctHash of a SNAPSHOT share came from, as something the recipient can
40
+ * check against the chain. It speaks of contracts, selectors and positions in the chain only:
41
+ * it does not know what a token, a balance or a transfer is. A reader that recognises a selector
42
+ * can present the value accordingly (see `describeShareMetadata`). A share carries one label per
43
+ * ctHash, in the order of `acp.handles`, so the ctHashes themselves are never repeated.
44
+ */
45
+ /** One argument of a stored-value read: the share issuer, or a literal 32-byte ABI word. */
46
+ type ShareLabelReadArg = {
47
+ type: 'issuer';
48
+ } | {
49
+ type: 'word';
50
+ value: Hex;
51
+ };
52
+ /** A stored value: what a view function of a contract returned at a block. */
53
+ type StoredValueLabel = {
54
+ kind: 'stored';
55
+ contract: Address;
56
+ /** 4-byte selector of the view function. */
57
+ selector: Hex;
58
+ /** Static ABI types only: each argument is one 32-byte word. */
59
+ args: ShareLabelReadArg[];
60
+ /** Which 32-byte word of the return data is the ctHash (0 for a single return value). */
61
+ returnWord: number;
62
+ /** Block the value was read at (on Arbitrum: the L2 block number). */
63
+ block: bigint;
64
+ };
65
+ /** An event value: a value carried by one event (log) that a contract emitted. */
66
+ type EventValueLabel = {
67
+ kind: 'event';
68
+ contract: Address;
69
+ /** Block of the log (on Arbitrum: the L2 block number). */
70
+ block: bigint;
71
+ /** Index of the log's transaction within its block. */
72
+ txIndex: number;
73
+ /** Block-wide index of the log, as RPC nodes return it. */
74
+ logIndex: number;
75
+ /** First 4 bytes of the log's topic0: the event selector. */
76
+ selector: Hex;
77
+ };
78
+ /** The issuer chose not to say where the ctHash came from. */
79
+ type UnlabelledLabel = {
80
+ kind: 'unlabelled';
81
+ };
82
+ type ShareLabel = StoredValueLabel | EventValueLabel | UnlabelledLabel;
83
+
38
84
  /**
39
85
  * EIP712 related types
40
86
  */
@@ -76,6 +122,12 @@ interface ACPPrivate {
76
122
  * Never leaves the client.
77
123
  */
78
124
  sealingPrivateKey: Hex;
125
+ /**
126
+ * (sharing / recipient) The share metadata: the labels of its handles, a v3 blob
127
+ * (`decodeShareMetadata` / `describeShareMetadata`). Not signed; travels with the share, in the
128
+ * exported JSON or in the registry's `Shared` event. Absent when the share has none.
129
+ */
130
+ metadata?: Hex;
79
131
  /**
80
132
  * EIP712 domain used to sign this acp.
81
133
  * Should not be set manually, included in metadata as part of serialization flows.
@@ -211,29 +263,44 @@ type CreateSharingACPOptions = ACPScopeOptions & {
211
263
  expiration?: number;
212
264
  revokerData?: number;
213
265
  revokerContract?: string;
266
+ /**
267
+ * The labels of the handles, one per handle in order. Kept on the acp as `metadata`, then
268
+ * written into `export()` and posted by `shareOnChain`.
269
+ */
270
+ labels?: readonly ShareLabel[];
271
+ /**
272
+ * The key of the app the share is for (`shareAppKey(app)`), kept in `metadata` with the labels.
273
+ * A client configured with `acp: { app }` fills it in; a recipient client with the same `app`
274
+ * lists the share, one with another app does not.
275
+ */
276
+ appKey?: Hex;
214
277
  };
278
+ /** A share as exported (`SharedACP`) or read from the registry. A `name` in it is ignored. */
215
279
  type ImportSharedACPOptions = ACPScopeOptions & {
216
280
  type?: 'sharing';
217
281
  issuer: string;
218
282
  recipient: string;
219
283
  issuerSignature: string;
220
- name?: string;
221
284
  expiration: number;
222
285
  revokerData?: number;
223
286
  revokerContract?: string;
287
+ /** The share metadata (labels blob), kept on the recipient acp; `0x` or absent for none. */
288
+ metadata?: string;
224
289
  };
225
290
  /** An ACP is plain JSON-serializable data — the serialized form is the ACP itself. */
226
291
  type SerializedACP = ACP;
227
292
  /**
228
293
  * The share payload produced by `ACPUtils.export()` — the full public component
229
294
  * with `sealingKey`/`recipientSignature` left for the recipient to fill, plus
230
- * the display name and acp type. Fixed shape: every field is always present
295
+ * the acp type. The issuer's `name` is not exported: it is their own note, and the
296
+ * recipient names the share themselves. Fixed shape: every field is always present
231
297
  * (zero-values instead of omissions), so importers can parse a single schema.
232
- * Mirrors the on-chain sharing payload struct field-for-field.
298
+ * Mirrors the on-chain sharing payload struct field-for-field. The one optional
299
+ * field is `metadata`, the labels of the handles, present only when the share has them.
233
300
  */
234
301
  type SharedACP = Expand<Omit<ACPPublic, 'sealingKey' | 'recipientSignature'> & {
235
- name: string;
236
302
  type: 'sharing';
303
+ metadata?: Hex;
237
304
  }>;
238
305
  /**
239
306
  * An ACP on-chain status, as `client.acp.checkAccess` reports it instead of a revert.
@@ -244,11 +311,25 @@ type SharedACP = Expand<Omit<ACPPublic, 'sealingKey' | 'recipientSignature'> & {
244
311
  type ACPAccessStatus = 'valid' | 'allowed' | 'out-of-scope' | 'issuer-not-allowed' | 'expired' | 'revoked' | 'invalid-issuer-signature' | 'invalid-recipient-signature';
245
312
  /**
246
313
  * A share read back from the on-chain ACPShareRegistry: the posted payload
247
- * (SharedACP minus the client-side name/type) plus its registry id.
314
+ * (SharedACP minus its type), its registry id, and the
315
+ * metadata blob posted with it (`0x` when none) — for a SNAPSHOT share, the
316
+ * labels of its handles (`decodeShareMetadata` / `describeShareMetadata`).
248
317
  */
249
- type IncomingShare = Expand<Omit<SharedACP, 'name' | 'type'> & {
318
+ type IncomingShare = Expand<Omit<SharedACP, 'type' | 'metadata'> & {
250
319
  shareId: Hex;
320
+ metadata: Hex;
321
+ /** The key of the app the share was posted for (`shareAppKey(app)`), when it names one. */
322
+ appKey?: Hex;
251
323
  }>;
324
+ /**
325
+ * What the share label helpers read: the handles, their issuer and the metadata blob. An
326
+ * `IncomingShare` (on-chain route) and a sharing or recipient `ACP` (exported JSON route) both fit.
327
+ */
328
+ type LabelledShare = {
329
+ issuer: Hex;
330
+ handles: readonly Hex[];
331
+ metadata?: Hex;
332
+ };
252
333
  /**
253
334
  * A type representing the acp fields that are used to generate the hash
254
335
  */
@@ -281,9 +362,12 @@ declare const ACPUtils: {
281
362
  */
282
363
  createSharing: (options: CreateSharingACPOptions) => SharingACP;
283
364
  /**
284
- * Import a shared acp from various input formats
365
+ * Import a shared acp from various input formats. The acp is named `name`, or after its issuer
366
+ * ("Shared by 0x1234…abcd"); a `name` in the share itself is ignored.
285
367
  */
286
- importShared: (options: ImportSharedACPOptions | string) => RecipientACP;
368
+ importShared: (options: ImportSharedACPOptions | string, { name }?: {
369
+ name?: string;
370
+ }) => RecipientACP;
287
371
  /**
288
372
  * Sign an ACP with the provided wallet client
289
373
  */
@@ -299,7 +383,9 @@ declare const ACPUtils: {
299
383
  /**
300
384
  * Import and sign a shared acp in one operation from various input formats
301
385
  */
302
- importSharedAndSign: (options: ImportSharedACPOptions | string, publicClient: PublicClient, walletClient: WalletClient) => Promise<RecipientACP>;
386
+ importSharedAndSign: (options: ImportSharedACPOptions | string, publicClient: PublicClient, walletClient: WalletClient, importOptions?: {
387
+ name?: string;
388
+ }) => Promise<RecipientACP>;
303
389
  /**
304
390
  * Deserialize an ACP from serialized data
305
391
  */
@@ -324,6 +410,7 @@ declare const ACPUtils: {
324
410
  handles: `0x${string}`[];
325
411
  issuerSignature: `0x${string}`;
326
412
  recipientSignature: `0x${string}`;
413
+ metadata?: `0x${string}` | undefined;
327
414
  sealingPrivateKey?: string | undefined;
328
415
  sealingKey?: string | undefined;
329
416
  };
@@ -350,6 +437,7 @@ declare const ACPUtils: {
350
437
  handles: `0x${string}`[];
351
438
  issuerSignature: `0x${string}`;
352
439
  recipientSignature: `0x${string}`;
440
+ metadata?: `0x${string}` | undefined;
353
441
  sealingPrivateKey?: string | undefined;
354
442
  sealingKey?: string | undefined;
355
443
  };
@@ -365,7 +453,7 @@ declare const ACPUtils: {
365
453
  /**
366
454
  * Export acp data for sharing (strips the private component).
367
455
  * Fixed `SharedACP` shape — every field always present, aligned with
368
- * `ACPPublic` and the on-chain sharing payload.
456
+ * `ACPPublic` and the on-chain sharing payload — plus `metadata` when the acp has labels.
369
457
  */
370
458
  export: (acp: ACP) => string;
371
459
  /**
@@ -416,6 +504,42 @@ declare const ACPUtils: {
416
504
  checkAccessOnChain: (acp: ACP, publicClient: PublicClient, handle?: bigint | Hex) => Promise<ACPAccessStatus>;
417
505
  };
418
506
 
507
+ /**
508
+ * - `verified`: the chain confirms the label.
509
+ * - `mismatch`: the chain contradicts it.
510
+ * - `unverifiable`: the chain could not be asked — an unlabelled ctHash, a node without the
511
+ * state of that block (a stored value needs an archive node once its block is old), or a
512
+ * failed request.
513
+ */
514
+ type LabelVerification = 'verified' | 'mismatch' | 'unverifiable';
515
+ /**
516
+ * How much of a share's labels a reader checks against the chain. Labels are the issuer's claim:
517
+ * - `all` (default): every label — one `getLogs` per contract and block, one call per stored value;
518
+ * - `events`: event values only, which any node can answer however old the block;
519
+ * - `none`: trust the labels as written, no requests (the issuer previewing their own share).
520
+ */
521
+ type ShareLabelVerifyMode = 'all' | 'events' | 'none';
522
+ /** A label's verification, or `skipped` when the verify mode leaves it unchecked. */
523
+ type ShareLabelCheck = LabelVerification | 'skipped';
524
+ /**
525
+ * Checks one label against the chain: does the ctHash really come from where the label says?
526
+ * `issuer` is the share issuer (`acp.issuer`), which an issuer argument of a stored value stands
527
+ * for. One request.
528
+ */
529
+ declare const verifyShareLabel: (label: ShareLabel, handle: Hex, publicClient: PublicClient, issuer: Address) => Promise<LabelVerification>;
530
+ /**
531
+ * Checks the labels of a share, index for index with `handles`, as far as `verify` says. Requests
532
+ * are shared: one `getLogs` per contract and block, however many values it carries, and one call
533
+ * per distinct stored read.
534
+ */
535
+ declare const verifyShareLabels: ({ labels, handles, issuer, publicClient, verify, }: {
536
+ labels: readonly ShareLabel[];
537
+ handles: readonly Hex[];
538
+ issuer: Address;
539
+ publicClient: PublicClient;
540
+ verify?: ShareLabelVerifyMode;
541
+ }) => Promise<ShareLabelCheck[]>;
542
+
419
543
  declare const getAclAddress: (publicClient: PublicClient) => Promise<Hex>;
420
544
  interface AclServedAddresses {
421
545
  defaultRevoker?: Hex;
@@ -428,10 +552,10 @@ declare const clearAclServedAddresses: () => void;
428
552
  * TaskManager -> acl() -> getters). Zero addresses and pre-upgrade ACLs (getters absent -> revert)
429
553
  * resolve to `undefined` — callers fall back to `acp.*` config.
430
554
  *
431
- * Resolutions are cached per chainId. A failure to reach the TaskManager (network
432
- * error, no CoFHE deployment) is NOT cached, so a transient outage does not pin
433
- * an empty result for the whole session.
555
+ * Resolutions are cached per chainId. A failure to reach the TaskManager or the ACL
556
+ * getters (network error, no CoFHE deployment) is NOT cached, so a transient outage
557
+ * does not pin an empty result for the whole session.
434
558
  */
435
559
  declare const getAclServedAddresses: (publicClient: PublicClient, chainId: number) => Promise<AclServedAddresses>;
436
560
 
437
- export { type ACP as A, type ACPHashFields as B, type CreateSelfACPOptions as C, type Expand as D, type EIP712Types as E, GenerateSealingKey as G, type ImportSharedACPOptions as I, type RecipientACP as R, type SerializedACP as S, type ValidationResult as V, type ACPPublic as a, type ACPSignaturePrimaryType as b, type EIP712Message as c, type CreateSharingACPOptions as d, type ACPMetadata as e, type SharedACP as f, type IncomingShare as g, type EIP712Domain as h, ACPUtils as i, getAclAddress as j, getAclServedAddresses as k, clearAclServedAddresses as l, type AclServedAddresses as m, type SealingKeyPair as n, type EthEncryptedData as o, type EIP712Type as p, type ACPPrivate as q, type ACPType as r, seal as s, type ACPOf as t, unsealWithPrivateKey as u, type SelfACP as v, type SharingACP as w, ACPScope as x, type ACPScopeOptions as y, type ACPAccessStatus as z };
561
+ export { type ACP as A, type EIP712Type as B, type CreateSelfACPOptions as C, type ACPPrivate as D, type EventValueLabel as E, type ACPType as F, GenerateSealingKey as G, type ACPOf as H, type ImportSharedACPOptions as I, type SelfACP as J, type SharingACP as K, type LabelledShare as L, ACPScope as M, type ACPScopeOptions as N, type ACPAccessStatus as O, type ACPHashFields as P, type Expand as Q, type RecipientACP as R, type ShareLabel as S, type UnlabelledLabel as U, type ValidationResult as V, type StoredValueLabel as a, type ACPPublic as b, type ACPSignaturePrimaryType as c, type EIP712Types as d, type EIP712Message as e, type SerializedACP as f, type CreateSharingACPOptions as g, type ACPMetadata as h, type SharedACP as i, type IncomingShare as j, type EIP712Domain as k, ACPUtils as l, getAclAddress as m, getAclServedAddresses as n, clearAclServedAddresses as o, type AclServedAddresses as p, type SealingKeyPair as q, type EthEncryptedData as r, seal as s, type ShareLabelReadArg as t, unsealWithPrivateKey as u, type LabelVerification as v, type ShareLabelVerifyMode as w, type ShareLabelCheck as x, verifyShareLabel as y, verifyShareLabels as z };