@cofhe/sdk 0.8.0 → 1.0.0-alpha.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 (84) hide show
  1. package/acps/acp.ts +25 -6
  2. package/acps/index.ts +20 -15
  3. package/acps/registry.ts +166 -8
  4. package/acps/sealing.ts +9 -3
  5. package/acps/share-metadata/appKey.ts +8 -0
  6. package/acps/share-metadata/decode.ts +120 -0
  7. package/acps/share-metadata/describe.ts +198 -0
  8. package/acps/share-metadata/encode.ts +147 -0
  9. package/acps/share-metadata/erc7984.ts +26 -0
  10. package/acps/share-metadata/index.ts +9 -0
  11. package/acps/share-metadata/layout.ts +69 -0
  12. package/acps/share-metadata/presets.ts +116 -0
  13. package/acps/share-metadata/schema.ts +47 -0
  14. package/acps/share-metadata/test/codec.test.ts +140 -0
  15. package/acps/share-metadata/test/describe.test.ts +112 -0
  16. package/acps/share-metadata/test/fixtures.ts +157 -0
  17. package/acps/share-metadata/test/live.test.ts +56 -0
  18. package/acps/share-metadata/test/presets.test.ts +119 -0
  19. package/acps/share-metadata/test/verify.test.ts +144 -0
  20. package/acps/share-metadata/verify.ts +155 -0
  21. package/acps/store.ts +48 -18
  22. package/acps/test/acp.test.ts +102 -7
  23. package/acps/test/localstorage.test.ts +28 -1
  24. package/acps/test/registry.test.ts +144 -0
  25. package/acps/test/sealing.test.ts +23 -0
  26. package/acps/test/store.test.ts +71 -0
  27. package/acps/test/utils.test.ts +63 -0
  28. package/acps/test/validation.test.ts +0 -4
  29. package/acps/types.ts +43 -6
  30. package/acps/utils.ts +15 -2
  31. package/acps/validation.ts +3 -1
  32. package/core/acps.ts +123 -74
  33. package/core/client.ts +33 -7
  34. package/core/clientTypes.ts +25 -7
  35. package/core/config.ts +8 -0
  36. package/core/decrypt/apiError.ts +4 -1
  37. package/core/decrypt/verifyDecryptResult.ts +4 -1
  38. package/core/encrypt/cofheMocksZkVerifySign.ts +19 -2
  39. package/core/test/acpDefaults.test.ts +108 -19
  40. package/core/test/acpStoreAccountCase.test.ts +80 -0
  41. package/core/test/acps.test.ts +38 -3
  42. package/core/test/apiError.test.ts +8 -0
  43. package/core/test/appKeyConfig.test.ts +94 -0
  44. package/core/test/config.test.ts +8 -0
  45. package/core/test/decryptBuilders.test.ts +110 -2
  46. package/core/test/incomingShares.test.ts +84 -0
  47. package/core/test/mocksEncryptRange.test.ts +90 -0
  48. package/core/test/utils.test.ts +128 -0
  49. package/core/test/verifyDecryptResult.test.ts +51 -0
  50. package/core/utils.ts +16 -9
  51. package/dist/acps.cjs +674 -33
  52. package/dist/acps.d.cts +367 -35
  53. package/dist/acps.d.ts +367 -35
  54. package/dist/acps.js +2 -2
  55. package/dist/chunk-6ZW76ZKB.js +228 -0
  56. package/dist/{chunk-UJYOBHYA.js → chunk-BQWHPIYU.js} +660 -198
  57. package/dist/{chunk-GGI7Y6AW.js → chunk-OL3DZN7A.js} +110 -269
  58. package/dist/chunk-XQ32JG3T.js +174 -0
  59. package/dist/{clientTypes-D3aIXmUp.d.cts → clientTypes-C0A9ji5O.d.cts} +61 -21
  60. package/dist/{clientTypes-5YPPR16m.d.ts → clientTypes-CcU5WvdV.d.ts} +61 -21
  61. package/dist/core.cjs +3239 -2731
  62. package/dist/core.d.cts +6 -3
  63. package/dist/core.d.ts +6 -3
  64. package/dist/core.js +4 -3
  65. package/dist/node.cjs +3046 -2538
  66. package/dist/node.d.cts +2 -2
  67. package/dist/node.d.ts +2 -2
  68. package/dist/node.js +18 -17
  69. package/dist/{onchain-utils-CUAK8glx.d.cts → onchain-utils-D9Z33IP7.d.cts} +136 -12
  70. package/dist/{onchain-utils-CUAK8glx.d.ts → onchain-utils-D9Z33IP7.d.ts} +136 -12
  71. package/dist/web.cjs +3074 -2573
  72. package/dist/web.d.cts +2 -2
  73. package/dist/web.d.ts +2 -2
  74. package/dist/web.js +4 -10
  75. package/dist/zkProve.worker.cjs +14 -7
  76. package/dist/zkProve.worker.js +2 -8
  77. package/node/index.ts +1 -10
  78. package/node/storage.ts +18 -7
  79. package/node/test/storage-permissions.test.ts +40 -0
  80. package/package.json +4 -4
  81. package/web/index.ts +1 -10
  82. package/web/test/threadPoolBenchHelper.ts +1 -7
  83. package/web/zkProve.worker.ts +1 -10
  84. package/dist/chunk-NMKMCAI3.js +0 -14
package/dist/acps.cjs CHANGED
@@ -14,9 +14,14 @@ var nacl__default = /*#__PURE__*/_interopDefault(nacl);
14
14
  // acps/acp.ts
15
15
 
16
16
  // acps/utils.ts
17
+ var HEX_BODY_REGEX = /^[0-9a-fA-F]*$/;
17
18
  var fromHexString = (hexString) => {
18
- const cleanString = hexString.length % 2 === 1 ? `0${hexString}` : hexString;
19
- const arr = cleanString.replace(/^0x/, "").match(/.{1,2}/g);
19
+ const body = hexString.replace(/^0x/, "");
20
+ if (!HEX_BODY_REGEX.test(body)) {
21
+ throw new Error("Invalid hex string: contains non-hexadecimal characters");
22
+ }
23
+ const padded = body.length % 2 === 1 ? `0${body}` : body;
24
+ const arr = padded.match(/.{1,2}/g);
20
25
  if (!arr)
21
26
  return new Uint8Array();
22
27
  return new Uint8Array(arr.map((byte) => parseInt(byte, 16)));
@@ -73,7 +78,7 @@ var GenerateSealingKey = () => {
73
78
  var seal = (value, publicKey) => {
74
79
  isString(publicKey);
75
80
  isBigIntOrNumber(value);
76
- assertKeyLength(publicKey, "Public");
81
+ assertSealingKey(publicKey, "Public");
77
82
  const ephemeralKeyPair = nacl__default.default.box.keyPair();
78
83
  const nonce = nacl__default.default.randomBytes(nacl__default.default.box.nonceLength);
79
84
  const encryptedMessage = nacl__default.default.box(toBeArray(value), nonce, fromHexString(publicKey), ephemeralKeyPair.secretKey);
@@ -84,7 +89,7 @@ var seal = (value, publicKey) => {
84
89
  };
85
90
  };
86
91
  var unsealWithPrivateKey = (privateKey, parsedData) => {
87
- assertKeyLength(privateKey, "Private");
92
+ assertSealingKey(privateKey, "Private");
88
93
  const nonce = parsedData.nonce instanceof Uint8Array ? parsedData.nonce : new Uint8Array(parsedData.nonce);
89
94
  const ephemPublicKey = parsedData.public_key instanceof Uint8Array ? parsedData.public_key : new Uint8Array(parsedData.public_key);
90
95
  const dataToDecrypt = parsedData.data instanceof Uint8Array ? parsedData.data : new Uint8Array(parsedData.data);
@@ -94,11 +99,14 @@ var unsealWithPrivateKey = (privateKey, parsedData) => {
94
99
  }
95
100
  return toBigInt(decryptedMessage);
96
101
  };
97
- var assertKeyLength = (key, kind) => {
102
+ var assertSealingKey = (key, kind) => {
98
103
  const bare = key.startsWith("0x") ? key.slice(2) : key;
99
104
  if (bare.length !== KEY_HEX_LENGTH) {
100
105
  throw new Error(`${kind} key must be of length ${KEY_HEX_LENGTH}`);
101
106
  }
107
+ if (!/^[0-9a-fA-F]+$/.test(bare)) {
108
+ throw new Error(`${kind} key must contain only hex characters`);
109
+ }
102
110
  };
103
111
  var ACPScope = {
104
112
  Global: 0,
@@ -151,7 +159,8 @@ var zACPWithDefaults = zod.z.object({
151
159
  contracts: contractsSchema,
152
160
  handles: handlesSchema,
153
161
  issuerSignature: bytesSchema.optional().default("0x"),
154
- recipientSignature: bytesSchema.optional().default("0x")
162
+ recipientSignature: bytesSchema.optional().default("0x"),
163
+ metadata: bytesSchema.optional()
155
164
  });
156
165
  var zACPWithSealingKeys = zACPWithDefaults.extend({
157
166
  /** X25519 private key, 0x-prefixed 32-byte hex; never leaves the client */
@@ -222,7 +231,6 @@ var ImportACPOptionsValidator = zod.z.object({
222
231
  type: zod.z.literal("recipient").optional().default("recipient"),
223
232
  issuer: addressNotZeroSchema,
224
233
  recipient: addressNotZeroSchema,
225
- name: zod.z.string().optional().default("Unnamed ACP"),
226
234
  expiration: zod.z.int(),
227
235
  revokerData: zod.z.int().optional().default(0),
228
236
  revokerContract: addressSchema.optional().default(viem.zeroAddress),
@@ -230,7 +238,9 @@ var ImportACPOptionsValidator = zod.z.object({
230
238
  contracts: contractsSchema,
231
239
  handles: handlesSchema,
232
240
  issuerSignature: bytesNotEmptySchema,
233
- recipientSignature: bytesSchema.optional().default("0x")
241
+ recipientSignature: bytesSchema.optional().default("0x"),
242
+ /** The share metadata (labels blob); `0x` means none and is dropped */
243
+ metadata: bytesSchema.optional().transform((val) => val === "0x" ? void 0 : val)
234
244
  }).refine(...ExternalValidatorRefinement).transform(withDerivedScope).refine(...ScopeConsistencyRefinement);
235
245
  var ImportACPValidator = zACPWithSealingKeys.refine((data) => data.type === "recipient", {
236
246
  error: "Type must be 'recipient'"
@@ -815,7 +825,210 @@ var getAclServedAddresses = async (publicClient, chainId) => {
815
825
  return resolved;
816
826
  };
817
827
 
828
+ // acps/share-metadata/layout.ts
829
+ var LAYOUT_VERSION = 3;
830
+ var ENTRY_KIND = {
831
+ stored: 0,
832
+ event: 1,
833
+ unlabelled: 255
834
+ };
835
+ var ARGS_CODE = {
836
+ none: 0,
837
+ issuer: 1,
838
+ explicit: 255
839
+ };
840
+ var ARG_TAG = {
841
+ word: 0,
842
+ issuer: 1
843
+ };
844
+ var APP_KEY_TAG = 1;
845
+ var BYTE_WIDTH = {
846
+ version: 1,
847
+ /** Length of a list, and a position in it: at most 255 of each per share. */
848
+ count: 1,
849
+ index: 1,
850
+ address: 20,
851
+ selector: 4,
852
+ /** uint32: 4.29 billion blocks. */
853
+ block: 4,
854
+ /** uint16: the position of a transaction within its block. */
855
+ txIndex: 2,
856
+ /** uint16: the block-wide position of a log (a busy block passes 255 logs). */
857
+ logIndex: 2,
858
+ kind: 1,
859
+ argsCode: 1,
860
+ returnWord: 1,
861
+ argTag: 1,
862
+ word: 32
863
+ };
864
+
865
+ // acps/share-metadata/encode.ts
866
+ var uint = (value, width) => viem.numberToHex(value, { size: width });
867
+ var BYTES_FIELD = {
868
+ contract: { width: BYTE_WIDTH.address, name: "a contract address" },
869
+ selector: { width: BYTE_WIDTH.selector, name: "a selector" },
870
+ viewCallArgument: { width: BYTE_WIDTH.word, name: "a view call argument" },
871
+ appKey: { width: BYTE_WIDTH.word, name: "an app key" }
872
+ };
873
+ var bytesField = (field, value) => {
874
+ const { width, name } = BYTES_FIELD[field];
875
+ if (!viem.isHex(value, { strict: true }) || viem.size(value) !== width) {
876
+ throw new Error(`share metadata: ${name} must be ${width} bytes`);
877
+ }
878
+ return value.toLowerCase();
879
+ };
880
+ var listOf = (keyOf, what) => {
881
+ const items = [];
882
+ const positions = /* @__PURE__ */ new Map();
883
+ const insert = (item) => {
884
+ const key = keyOf(item);
885
+ if (positions.has(key))
886
+ return;
887
+ positions.set(key, items.length);
888
+ items.push(item);
889
+ };
890
+ const positionOf = (item) => {
891
+ const position = positions.get(keyOf(item));
892
+ if (position === void 0)
893
+ throw new Error(`share metadata: ${what} ${keyOf(item)} was not collected`);
894
+ return position;
895
+ };
896
+ return { items, insert, positionOf };
897
+ };
898
+ var keyOfContract = (contract) => contract.toLowerCase();
899
+ var keyOfSelector = (selector) => selector.toLowerCase();
900
+ var keyOfTransaction = ({ block, txIndex }) => `${block}:${txIndex}`;
901
+ var transactionOf = ({ block, txIndex }) => ({ block, txIndex });
902
+ var encodeArg = (arg) => {
903
+ if (arg.type === "issuer")
904
+ return uint(ARG_TAG.issuer, BYTE_WIDTH.argTag);
905
+ return viem.concatHex([uint(ARG_TAG.word, BYTE_WIDTH.argTag), bytesField("viewCallArgument", arg.value)]);
906
+ };
907
+ var issuerWordOf = (issuer) => issuer == null ? void 0 : viem.padHex(issuer, { size: BYTE_WIDTH.word }).toLowerCase();
908
+ var asIssuer = (arg, issuerWord) => arg.type === "word" && issuerWord != null && arg.value.toLowerCase() === issuerWord ? { type: "issuer" } : arg;
909
+ var encodeArgs = ({ args: given, returnWord }, issuerWord) => {
910
+ const args = given.map((arg) => asIssuer(arg, issuerWord));
911
+ if (returnWord === 0 && args.length === 0)
912
+ return uint(ARGS_CODE.none, BYTE_WIDTH.argsCode);
913
+ if (returnWord === 0 && args.length === 1 && args[0].type === "issuer") {
914
+ return uint(ARGS_CODE.issuer, BYTE_WIDTH.argsCode);
915
+ }
916
+ return viem.concatHex([
917
+ uint(ARGS_CODE.explicit, BYTE_WIDTH.argsCode),
918
+ uint(returnWord, BYTE_WIDTH.returnWord),
919
+ uint(args.length, BYTE_WIDTH.count),
920
+ ...args.map(encodeArg)
921
+ ]);
922
+ };
923
+ var encodeShareMetadata = (labels, { issuer, appKey } = {}) => {
924
+ const issuerWord = issuerWordOf(issuer);
925
+ const contracts = listOf(keyOfContract, "contract");
926
+ const selectors = listOf(keyOfSelector, "selector");
927
+ const transactions = listOf(keyOfTransaction, "transaction");
928
+ for (const label of labels) {
929
+ if (label.kind === "unlabelled")
930
+ continue;
931
+ contracts.insert(label.contract);
932
+ selectors.insert(label.selector);
933
+ if (label.kind === "event")
934
+ transactions.insert(transactionOf(label));
935
+ }
936
+ const entries = labels.map((label) => {
937
+ switch (label.kind) {
938
+ case "stored":
939
+ return viem.concatHex([
940
+ uint(ENTRY_KIND.stored, BYTE_WIDTH.kind),
941
+ uint(contracts.positionOf(label.contract), BYTE_WIDTH.index),
942
+ uint(selectors.positionOf(label.selector), BYTE_WIDTH.index),
943
+ uint(label.block, BYTE_WIDTH.block),
944
+ encodeArgs(label, issuerWord)
945
+ ]);
946
+ case "event":
947
+ return viem.concatHex([
948
+ uint(ENTRY_KIND.event, BYTE_WIDTH.kind),
949
+ uint(contracts.positionOf(label.contract), BYTE_WIDTH.index),
950
+ uint(transactions.positionOf(transactionOf(label)), BYTE_WIDTH.index),
951
+ uint(label.logIndex, BYTE_WIDTH.logIndex),
952
+ uint(selectors.positionOf(label.selector), BYTE_WIDTH.index)
953
+ ]);
954
+ case "unlabelled":
955
+ return uint(ENTRY_KIND.unlabelled, BYTE_WIDTH.kind);
956
+ }
957
+ });
958
+ return viem.concatHex([
959
+ uint(LAYOUT_VERSION, BYTE_WIDTH.version),
960
+ uint(contracts.items.length, BYTE_WIDTH.count),
961
+ ...contracts.items.map((contract) => bytesField("contract", contract)),
962
+ uint(selectors.items.length, BYTE_WIDTH.count),
963
+ ...selectors.items.map((selector) => bytesField("selector", selector)),
964
+ uint(transactions.items.length, BYTE_WIDTH.count),
965
+ ...transactions.items.map(
966
+ (tx) => viem.concatHex([uint(tx.block, BYTE_WIDTH.block), uint(tx.txIndex, BYTE_WIDTH.txIndex)])
967
+ ),
968
+ ...entries,
969
+ ...appKey == null ? [] : [uint(APP_KEY_TAG, BYTE_WIDTH.count), bytesField("appKey", appKey)]
970
+ ]);
971
+ };
972
+ var findViewFunction = (abi, name, arity) => {
973
+ const named = abi.filter((item) => item.type === "function" && item.name === name);
974
+ if (named.length === 0)
975
+ throw new Error(`share metadata: the ABI has no function ${name}`);
976
+ const fitting = named.filter((fn2) => fn2.inputs.length === arity);
977
+ if (fitting.length !== 1) {
978
+ throw new Error(
979
+ named.length === 1 ? `share metadata: ${name} takes ${named[0].inputs.length} arguments, ${arity} given` : `share metadata: no single overload of ${name} takes ${arity} arguments`
980
+ );
981
+ }
982
+ const [fn] = fitting;
983
+ if (fn.stateMutability !== "view" && fn.stateMutability !== "pure") {
984
+ throw new Error(`share metadata: ${name} is not a view function`);
985
+ }
986
+ return fn;
987
+ };
988
+ var encodeReadArg = (fn, index, value) => {
989
+ const input = fn.inputs[index];
990
+ const word = viem.encodeAbiParameters([input], [value]);
991
+ if (viem.size(word) !== BYTE_WIDTH.word) {
992
+ throw new Error(
993
+ `share metadata: argument ${index} of ${fn.name} is ${input.type}; only arguments of one static 32-byte word can be labelled`
994
+ );
995
+ }
996
+ return { type: "word", value: word };
997
+ };
998
+ var viewFunctionLabel = (options) => {
999
+ const { contract, block, returnWord = 0 } = options;
1000
+ const values = options.args ?? [];
1001
+ const fn = findViewFunction(options.abi, options.functionName, values.length);
1002
+ return {
1003
+ kind: "stored",
1004
+ contract,
1005
+ selector: viem.toFunctionSelector(fn),
1006
+ args: values.map((value, i) => encodeReadArg(fn, i, value)),
1007
+ returnWord,
1008
+ block
1009
+ };
1010
+ };
1011
+ var eventLogLabel = (log) => {
1012
+ const { address, blockNumber, transactionIndex, logIndex, topics } = log;
1013
+ const topic0 = topics[0];
1014
+ if (blockNumber == null || transactionIndex == null || logIndex == null) {
1015
+ throw new Error("share metadata: a pending log has no position to label");
1016
+ }
1017
+ if (topic0 == null || viem.size(topic0) !== 32)
1018
+ throw new Error("share metadata: an anonymous log has no event selector");
1019
+ return {
1020
+ kind: "event",
1021
+ contract: address,
1022
+ block: blockNumber,
1023
+ txIndex: transactionIndex,
1024
+ logIndex,
1025
+ selector: viem.sliceHex(topic0, 0, 4)
1026
+ };
1027
+ };
1028
+ var UNLABELLED = { kind: "unlabelled" };
1029
+
818
1030
  // acps/acp.ts
1031
+ var sharedByName = (issuer) => `Shared by ${issuer.slice(0, 6)}\u2026${issuer.slice(-4)}`;
819
1032
  var ACPUtils = {
820
1033
  /**
821
1034
  * Create a self acp for personal use
@@ -837,10 +1050,16 @@ var ACPUtils = {
837
1050
  */
838
1051
  createSharing: (options) => {
839
1052
  const validation = validateSharingACPOptions(options);
1053
+ const { labels, appKey } = options;
1054
+ if (labels != null && labels.length !== validation.handles.length) {
1055
+ throw new Error(`Cannot label a share of ${validation.handles.length} handles with ${labels.length} labels`);
1056
+ }
1057
+ const metadata = labels != null || appKey != null ? encodeShareMetadata(labels ?? validation.handles.map(() => UNLABELLED), { issuer: validation.issuer, appKey }) : void 0;
840
1058
  const sealingPair = GenerateSealingKey();
841
1059
  const acp = {
842
1060
  hash: ACPUtils.getHash(validation),
843
1061
  ...validation,
1062
+ ...metadata != null && { metadata },
844
1063
  sealingPrivateKey: sealingPair.privateKey,
845
1064
  sealingKey: sealingPair.publicKey,
846
1065
  _signedDomain: void 0
@@ -848,9 +1067,10 @@ var ACPUtils = {
848
1067
  return acp;
849
1068
  },
850
1069
  /**
851
- * Import a shared acp from various input formats
1070
+ * Import a shared acp from various input formats. The acp is named `name`, or after its issuer
1071
+ * ("Shared by 0x1234…abcd"); a `name` in the share itself is ignored.
852
1072
  */
853
- importShared: (options) => {
1073
+ importShared: (options, { name } = {}) => {
854
1074
  let parsedOptions;
855
1075
  if (typeof options === "string") {
856
1076
  try {
@@ -871,6 +1091,7 @@ var ACPUtils = {
871
1091
  const acp = {
872
1092
  hash: ACPUtils.getHash(validation),
873
1093
  ...validation,
1094
+ name: name?.trim() || sharedByName(validation.issuer),
874
1095
  sealingPrivateKey: sealingPair.privateKey,
875
1096
  sealingKey: sealingPair.publicKey,
876
1097
  _signedDomain: void 0
@@ -929,8 +1150,8 @@ var ACPUtils = {
929
1150
  /**
930
1151
  * Import and sign a shared acp in one operation from various input formats
931
1152
  */
932
- importSharedAndSign: async (options, publicClient, walletClient) => {
933
- const acp = ACPUtils.importShared(options);
1153
+ importSharedAndSign: async (options, publicClient, walletClient, importOptions = {}) => {
1154
+ const acp = ACPUtils.importShared(options, importOptions);
934
1155
  return ACPUtils.sign(acp, publicClient, walletClient);
935
1156
  },
936
1157
  /**
@@ -959,7 +1180,8 @@ var ACPUtils = {
959
1180
  issuerSignature: acp.issuerSignature,
960
1181
  recipientSignature: acp.recipientSignature,
961
1182
  _signedDomain: acp._signedDomain,
962
- sealingPrivateKey: acp.sealingPrivateKey
1183
+ sealingPrivateKey: acp.sealingPrivateKey,
1184
+ ...acp.metadata != null && { metadata: acp.metadata }
963
1185
  };
964
1186
  },
965
1187
  /**
@@ -1033,7 +1255,7 @@ var ACPUtils = {
1033
1255
  /**
1034
1256
  * Export acp data for sharing (strips the private component).
1035
1257
  * Fixed `SharedACP` shape — every field always present, aligned with
1036
- * `ACPPublic` and the on-chain sharing payload.
1258
+ * `ACPPublic` and the on-chain sharing payload — plus `metadata` when the acp has labels.
1037
1259
  */
1038
1260
  export: (acp) => {
1039
1261
  if (acp.type !== "sharing") {
@@ -1047,7 +1269,6 @@ var ACPUtils = {
1047
1269
  );
1048
1270
  }
1049
1271
  const shared = {
1050
- name: acp.name,
1051
1272
  type: acp.type,
1052
1273
  issuer: acp.issuer,
1053
1274
  expiration: acp.expiration,
@@ -1057,7 +1278,8 @@ var ACPUtils = {
1057
1278
  scope: acp.scope,
1058
1279
  contracts: acp.contracts,
1059
1280
  handles: acp.handles,
1060
- issuerSignature: acp.issuerSignature
1281
+ issuerSignature: acp.issuerSignature,
1282
+ ...acp.metadata != null && acp.metadata !== "0x" && { metadata: acp.metadata }
1061
1283
  };
1062
1284
  return JSON.stringify(shared, void 0, 2);
1063
1285
  },
@@ -1143,11 +1365,14 @@ var ACP_REVOKER_ABI = viem.parseAbi([
1143
1365
  ]);
1144
1366
  var ACP_SHARE_REGISTRY_ABI = viem.parseAbi([
1145
1367
  "struct ACP { address issuer; uint64 expiration; address recipient; uint256 revokerData; address revokerContract; uint8 scope; address[] contracts; bytes32[] handles; bytes32 sealingKey; bytes issuerSignature; bytes recipientSignature; }",
1146
- "function share(ACP calldata acp) external returns (bytes32)",
1368
+ "struct ShareHeader { address issuer; uint64 expiration; address recipient; uint64 blockNumber; address revokerContract; uint256 revokerData; }",
1369
+ "function share(ACP calldata acp, bytes calldata metadata) external returns (bytes32)",
1147
1370
  "function removeShare(bytes32 shareId) external",
1148
- "function sharesFor(address recipient) external view returns (ACP[] memory)",
1149
- "function getShare(bytes32 shareId) external view returns (ACP memory)",
1150
- "function isShareValid(bytes32 shareId) external view returns (bool)"
1371
+ "function sharesFor(address recipient) external view returns (bytes32[] shareIds, ShareHeader[] headers)",
1372
+ "function getShare(bytes32 shareId) external view returns (ShareHeader memory)",
1373
+ "function isShareValid(bytes32 shareId) external view returns (bool)",
1374
+ "event Shared(address indexed recipient, address indexed issuer, bytes32 indexed shareId, ACP acp, bytes metadata)",
1375
+ "event ShareRemoved(address indexed recipient, address indexed issuer, bytes32 indexed shareId)"
1151
1376
  ]);
1152
1377
  var ACP_SHARE_TUPLE_ABI = [
1153
1378
  {
@@ -1183,11 +1408,393 @@ var computeShareId = (acp) => {
1183
1408
  return viem.keccak256(viem.encodeAbiParameters(ACP_SHARE_TUPLE_ABI, [p]));
1184
1409
  };
1185
1410
  var shareIdOfChainShare = (share) => viem.keccak256(viem.encodeAbiParameters(ACP_SHARE_TUPLE_ABI, [share]));
1411
+ var messageOf = (error) => error instanceof Error ? error.message : String(error);
1412
+ var readPostedShares = async (publicClient, registry, headers) => {
1413
+ const idsByBlock = /* @__PURE__ */ new Map();
1414
+ for (const { shareId, header } of headers) {
1415
+ idsByBlock.set(header.blockNumber, [...idsByBlock.get(header.blockNumber) ?? [], shareId]);
1416
+ }
1417
+ const found = /* @__PURE__ */ new Map();
1418
+ await Promise.all(
1419
+ [...idsByBlock].map(async ([block, shareIds]) => {
1420
+ let logs;
1421
+ try {
1422
+ logs = await publicClient.getContractEvents({
1423
+ address: registry,
1424
+ abi: ACP_SHARE_REGISTRY_ABI,
1425
+ eventName: "Shared",
1426
+ args: { shareId: shareIds },
1427
+ fromBlock: block,
1428
+ toBlock: block,
1429
+ strict: true
1430
+ });
1431
+ } catch (error) {
1432
+ for (const shareId of shareIds) {
1433
+ found.set(shareId.toLowerCase(), {
1434
+ reason: `the Shared events of block ${block} could not be read: ${messageOf(error)}`
1435
+ });
1436
+ }
1437
+ return;
1438
+ }
1439
+ for (const { args } of logs) {
1440
+ const hashes = shareIdOfChainShare(args.acp).toLowerCase() === args.shareId.toLowerCase();
1441
+ found.set(
1442
+ args.shareId.toLowerCase(),
1443
+ hashes ? { share: args.acp, metadata: args.metadata } : { reason: "the payload in its Shared event does not hash to its id" }
1444
+ );
1445
+ }
1446
+ })
1447
+ );
1448
+ const result = { posted: [], unreadable: [] };
1449
+ for (const { shareId, header } of headers) {
1450
+ const entry = found.get(shareId.toLowerCase());
1451
+ if (entry == null) {
1452
+ result.unreadable.push({
1453
+ shareId,
1454
+ header,
1455
+ reason: `no Shared event in block ${header.blockNumber}, where the registry points`
1456
+ });
1457
+ } else if ("reason" in entry) {
1458
+ result.unreadable.push({ shareId, header, reason: entry.reason });
1459
+ } else {
1460
+ result.posted.push({ shareId, header, ...entry });
1461
+ }
1462
+ }
1463
+ return result;
1464
+ };
1465
+ var readSharesFor = async (publicClient, registry, recipient) => {
1466
+ const [shareIds, headers] = await publicClient.readContract({
1467
+ address: registry,
1468
+ abi: ACP_SHARE_REGISTRY_ABI,
1469
+ functionName: "sharesFor",
1470
+ args: [recipient]
1471
+ });
1472
+ return readPostedShares(
1473
+ publicClient,
1474
+ registry,
1475
+ shareIds.map((shareId, i) => ({ shareId, header: headers[i] }))
1476
+ );
1477
+ };
1478
+ var readShare = async (publicClient, registry, shareId) => {
1479
+ const header = await publicClient.readContract({
1480
+ address: registry,
1481
+ abi: ACP_SHARE_REGISTRY_ABI,
1482
+ functionName: "getShare",
1483
+ args: [shareId]
1484
+ });
1485
+ if (header.issuer === "0x0000000000000000000000000000000000000000")
1486
+ return null;
1487
+ const { posted, unreadable } = await readPostedShares(publicClient, registry, [{ shareId, header }]);
1488
+ if (unreadable.length > 0)
1489
+ throw new Error(`Share ${shareId}: ${unreadable[0].reason}`);
1490
+ return posted[0];
1491
+ };
1492
+ var readerOf = (blob) => {
1493
+ let offset = 0;
1494
+ const take = (width) => {
1495
+ if (offset + width > viem.size(blob))
1496
+ throw new Error("share metadata: the blob ends in the middle of a field");
1497
+ offset += width;
1498
+ return viem.sliceHex(blob, offset - width, offset);
1499
+ };
1500
+ return {
1501
+ take,
1502
+ takeNumber: (width) => viem.hexToNumber(take(width)),
1503
+ done: () => offset === viem.size(blob),
1504
+ remaining: () => viem.size(blob) - offset
1505
+ };
1506
+ };
1507
+ var takeList = (reader, takeItem) => Array.from({ length: reader.takeNumber(BYTE_WIDTH.count) }, takeItem);
1508
+ var takeFrom = (reader, list, what) => {
1509
+ const position = reader.takeNumber(BYTE_WIDTH.index);
1510
+ if (position >= list.length) {
1511
+ throw new Error(`share metadata: ${what} ${position} is outside the ${what} list`);
1512
+ }
1513
+ return list[position];
1514
+ };
1515
+ var decodeArg = (reader) => {
1516
+ const tag = reader.takeNumber(BYTE_WIDTH.argTag);
1517
+ if (tag === ARG_TAG.issuer)
1518
+ return { type: "issuer" };
1519
+ if (tag === ARG_TAG.word)
1520
+ return { type: "word", value: reader.take(BYTE_WIDTH.word) };
1521
+ throw new Error(`share metadata: unknown argument tag ${tag}`);
1522
+ };
1523
+ var decodeArgs = (reader) => {
1524
+ const code = reader.takeNumber(BYTE_WIDTH.argsCode);
1525
+ if (code === ARGS_CODE.none)
1526
+ return { args: [], returnWord: 0 };
1527
+ if (code === ARGS_CODE.issuer)
1528
+ return { args: [{ type: "issuer" }], returnWord: 0 };
1529
+ if (code !== ARGS_CODE.explicit)
1530
+ throw new Error(`share metadata: unknown args code ${code}`);
1531
+ const returnWord = reader.takeNumber(BYTE_WIDTH.returnWord);
1532
+ return { args: takeList(reader, () => decodeArg(reader)), returnWord };
1533
+ };
1534
+ var takeAppKey = (reader) => {
1535
+ if (reader.done())
1536
+ return void 0;
1537
+ const isKey = reader.remaining() === BYTE_WIDTH.count + BYTE_WIDTH.word && reader.takeNumber(BYTE_WIDTH.count) === APP_KEY_TAG;
1538
+ if (!isKey)
1539
+ throw new Error("share metadata: the blob has more entries than the share has ctHashes");
1540
+ return reader.take(BYTE_WIDTH.word);
1541
+ };
1542
+ var decodeShareMetadataFull = (blob, handles) => {
1543
+ const reader = readerOf(blob);
1544
+ const version = reader.takeNumber(BYTE_WIDTH.version);
1545
+ if (version !== LAYOUT_VERSION)
1546
+ throw new Error(`share metadata: unsupported version ${version}`);
1547
+ const contracts = takeList(reader, () => viem.getAddress(reader.take(BYTE_WIDTH.address)));
1548
+ const selectors = takeList(reader, () => reader.take(BYTE_WIDTH.selector));
1549
+ const transactions = takeList(reader, () => ({
1550
+ block: viem.hexToBigInt(reader.take(BYTE_WIDTH.block)),
1551
+ txIndex: reader.takeNumber(BYTE_WIDTH.txIndex)
1552
+ }));
1553
+ const labels = handles.map(() => {
1554
+ const kind = reader.takeNumber(BYTE_WIDTH.kind);
1555
+ switch (kind) {
1556
+ case ENTRY_KIND.stored: {
1557
+ const contract = takeFrom(reader, contracts, "contract");
1558
+ const selector = takeFrom(reader, selectors, "selector");
1559
+ const block = viem.hexToBigInt(reader.take(BYTE_WIDTH.block));
1560
+ return { kind: "stored", contract, selector, ...decodeArgs(reader), block };
1561
+ }
1562
+ case ENTRY_KIND.event: {
1563
+ const contract = takeFrom(reader, contracts, "contract");
1564
+ const { block, txIndex } = takeFrom(reader, transactions, "transaction");
1565
+ const logIndex = reader.takeNumber(BYTE_WIDTH.logIndex);
1566
+ const selector = takeFrom(reader, selectors, "selector");
1567
+ return { kind: "event", contract, block, txIndex, logIndex, selector };
1568
+ }
1569
+ case ENTRY_KIND.unlabelled:
1570
+ return { kind: "unlabelled" };
1571
+ default:
1572
+ throw new Error(`share metadata: unknown entry kind ${kind}`);
1573
+ }
1574
+ });
1575
+ const appKey = takeAppKey(reader);
1576
+ if (!reader.done())
1577
+ throw new Error("share metadata: the blob has more entries than the share has ctHashes");
1578
+ return { labels, appKey };
1579
+ };
1580
+ var decodeShareMetadata = (blob, handles) => decodeShareMetadataFull(blob, handles).labels;
1581
+ var decodeShareAppKey = (metadata, handles) => metadata == null || metadata === "0x" ? void 0 : decodeShareMetadataFull(metadata, handles).appKey;
1582
+ var sameWord = (a, b) => a.toLowerCase() === b.toLowerCase();
1583
+ var wordsOf = (data) => {
1584
+ const count = Math.floor(viem.size(data) / BYTE_WIDTH.word);
1585
+ return Array.from(
1586
+ { length: count },
1587
+ (_, index) => viem.sliceHex(data, index * BYTE_WIDTH.word, (index + 1) * BYTE_WIDTH.word)
1588
+ );
1589
+ };
1590
+ var storedCallData = (label, issuer) => viem.concatHex([
1591
+ label.selector,
1592
+ ...label.args.map((arg) => arg.type === "issuer" ? viem.padHex(issuer, { size: BYTE_WIDTH.word }) : arg.value)
1593
+ ]);
1594
+ var checkStored = (label, handle, data) => {
1595
+ const found = data ? wordsOf(data)[label.returnWord] : void 0;
1596
+ return found && sameWord(found, handle) ? "verified" : "mismatch";
1597
+ };
1598
+ var checkEvent = (label, handle, logs) => {
1599
+ const log = logs.find((l) => l.logIndex === label.logIndex);
1600
+ if (log == null)
1601
+ return "mismatch";
1602
+ if (log.transactionIndex !== label.txIndex)
1603
+ return "mismatch";
1604
+ const topic0 = log.topics[0];
1605
+ if (topic0 == null || !topic0.toLowerCase().startsWith(label.selector.toLowerCase()))
1606
+ return "mismatch";
1607
+ const carried = [...log.topics.slice(1), ...wordsOf(log.data)].some((word) => word != null && sameWord(word, handle));
1608
+ return carried ? "verified" : "mismatch";
1609
+ };
1610
+ var callAt = async (publicClient, to, data, blockNumber) => (await publicClient.call({ to, data, blockNumber })).data;
1611
+ var logsAt = (publicClient, address, block) => publicClient.getLogs({ address, fromBlock: block, toBlock: block });
1612
+ var verifyShareLabel = async (label, handle, publicClient, issuer) => {
1613
+ try {
1614
+ switch (label.kind) {
1615
+ case "stored":
1616
+ return checkStored(
1617
+ label,
1618
+ handle,
1619
+ await callAt(publicClient, label.contract, storedCallData(label, issuer), label.block)
1620
+ );
1621
+ case "event":
1622
+ return checkEvent(label, handle, await logsAt(publicClient, label.contract, label.block));
1623
+ case "unlabelled":
1624
+ return "unverifiable";
1625
+ }
1626
+ } catch {
1627
+ return "unverifiable";
1628
+ }
1629
+ };
1630
+ var verifyShareLabels = async ({
1631
+ labels,
1632
+ handles,
1633
+ issuer,
1634
+ publicClient,
1635
+ verify = "all"
1636
+ }) => {
1637
+ if (labels.length !== handles.length) {
1638
+ throw new Error(`share metadata: ${labels.length} labels for ${handles.length} ctHashes`);
1639
+ }
1640
+ const requests = /* @__PURE__ */ new Map();
1641
+ const once = (key, request) => {
1642
+ if (!requests.has(key))
1643
+ requests.set(key, request());
1644
+ return requests.get(key);
1645
+ };
1646
+ return Promise.all(
1647
+ labels.map(async (label, i) => {
1648
+ const handle = handles[i];
1649
+ try {
1650
+ switch (label.kind) {
1651
+ case "stored": {
1652
+ if (verify !== "all")
1653
+ return "skipped";
1654
+ const data = storedCallData(label, issuer);
1655
+ const key = `call:${label.contract.toLowerCase()}:${label.block}:${data}`;
1656
+ return checkStored(
1657
+ label,
1658
+ handle,
1659
+ await once(key, () => callAt(publicClient, label.contract, data, label.block))
1660
+ );
1661
+ }
1662
+ case "event": {
1663
+ if (verify === "none")
1664
+ return "skipped";
1665
+ const key = `logs:${label.contract.toLowerCase()}:${label.block}`;
1666
+ return checkEvent(label, handle, await once(key, () => logsAt(publicClient, label.contract, label.block)));
1667
+ }
1668
+ case "unlabelled":
1669
+ return verify === "none" ? "skipped" : "unverifiable";
1670
+ }
1671
+ } catch {
1672
+ return "unverifiable";
1673
+ }
1674
+ })
1675
+ );
1676
+ };
1677
+ var abiOf = (abis, contract) => {
1678
+ const wanted = contract.toLowerCase();
1679
+ const key = Object.keys(abis).find((address) => address.toLowerCase() === wanted);
1680
+ return key ? abis[key] : void 0;
1681
+ };
1682
+ var paramOf = ({ name, type, ...rest }) => {
1683
+ const param = { type };
1684
+ if (name)
1685
+ param.name = name;
1686
+ if ("indexed" in rest && typeof rest.indexed === "boolean")
1687
+ param.indexed = rest.indexed;
1688
+ return param;
1689
+ };
1690
+ var findFunction = (abi, selector) => abi?.find(
1691
+ (item) => item.type === "function" && viem.toFunctionSelector(item).toLowerCase() === selector.toLowerCase()
1692
+ );
1693
+ var findEvent = (abi, selector) => abi?.find(
1694
+ (item) => item.type === "event" && viem.toEventSelector(item).toLowerCase().startsWith(selector.toLowerCase())
1695
+ );
1696
+ var decodeWord = (input, raw) => {
1697
+ if (input == null)
1698
+ return raw;
1699
+ try {
1700
+ return viem.decodeAbiParameters([input], raw)[0];
1701
+ } catch {
1702
+ return raw;
1703
+ }
1704
+ };
1705
+ var describeStored = (base, label, abis, issuer) => {
1706
+ const fn = findFunction(abiOf(abis, label.contract), label.selector);
1707
+ const args = label.args.map((arg, i) => {
1708
+ const input = fn?.inputs[i];
1709
+ const param = input ? paramOf(input) : { type: "bytes32" };
1710
+ if (arg.type === "issuer") {
1711
+ return {
1712
+ ...param,
1713
+ isIssuer: true,
1714
+ raw: issuer ? viem.padHex(issuer, { size: 32 }) : void 0,
1715
+ value: issuer
1716
+ };
1717
+ }
1718
+ return { ...param, isIssuer: false, raw: arg.value, value: decodeWord(input, arg.value) };
1719
+ });
1720
+ const output = fn?.outputs[label.returnWord];
1721
+ return {
1722
+ ...base,
1723
+ kind: "stored",
1724
+ label,
1725
+ contract: label.contract,
1726
+ block: label.block,
1727
+ selector: label.selector,
1728
+ function: fn ? { name: fn.name, signature: viem.toFunctionSignature(fn), inputs: fn.inputs.map(paramOf) } : null,
1729
+ args,
1730
+ output: output ? paramOf(output) : null
1731
+ };
1732
+ };
1733
+ var describeEvent = (base, label, abis) => {
1734
+ const event = findEvent(abiOf(abis, label.contract), label.selector);
1735
+ return {
1736
+ ...base,
1737
+ kind: "event",
1738
+ label,
1739
+ contract: label.contract,
1740
+ block: label.block,
1741
+ txIndex: label.txIndex,
1742
+ logIndex: label.logIndex,
1743
+ selector: label.selector,
1744
+ event: event ? { name: event.name, signature: viem.toEventSignature(event), inputs: event.inputs.map(paramOf) } : null
1745
+ };
1746
+ };
1747
+ var describeShareLabels = (labels, handles, abis = {}, options = {}) => labels.map((label, index) => {
1748
+ const base = { index, handle: handles[index] };
1749
+ switch (label.kind) {
1750
+ case "stored":
1751
+ return describeStored(base, label, abis, options.issuer);
1752
+ case "event":
1753
+ return describeEvent(base, label, abis);
1754
+ case "unlabelled":
1755
+ return { ...base, kind: "unlabelled", label };
1756
+ }
1757
+ });
1758
+ var describeShareMetadata = (share, abis = {}) => {
1759
+ const { issuer, handles, metadata } = share;
1760
+ if (metadata == null || metadata === "0x")
1761
+ return null;
1762
+ return describeShareLabels(decodeShareMetadata(metadata, handles), handles, abis, { issuer });
1763
+ };
1764
+
1765
+ // acps/share-metadata/erc7984.ts
1766
+ var ERC7984_ABI = [
1767
+ {
1768
+ type: "function",
1769
+ name: "confidentialBalanceOf",
1770
+ stateMutability: "view",
1771
+ inputs: [{ name: "account", type: "address", internalType: "address" }],
1772
+ outputs: [{ name: "", type: "bytes32", internalType: "euint64" }]
1773
+ },
1774
+ {
1775
+ type: "event",
1776
+ name: "ConfidentialTransfer",
1777
+ anonymous: false,
1778
+ inputs: [
1779
+ { name: "from", type: "address", indexed: true, internalType: "address" },
1780
+ { name: "to", type: "address", indexed: true, internalType: "address" },
1781
+ { name: "amount", type: "bytes32", indexed: true, internalType: "euint64" }
1782
+ ]
1783
+ }
1784
+ ];
1785
+ var shareAppKey = (app) => viem.keccak256(viem.stringToHex(app));
1186
1786
  var ACP_STORE_DEFAULTS = {
1187
1787
  acps: {},
1188
1788
  activeACPHash: {}
1189
1789
  };
1190
1790
  var ACP_STORE_VERSION = 3;
1791
+ var isRecord = (value) => value != null && typeof value === "object" && !Array.isArray(value);
1792
+ var resolveAccountKey = (records, account) => {
1793
+ if (records == null || account in records)
1794
+ return account;
1795
+ const lower = account.toLowerCase();
1796
+ return Object.keys(records).find((key) => key.toLowerCase() === lower) ?? account;
1797
+ };
1191
1798
  var _acpStore = vanilla.createStore()(
1192
1799
  middleware.persist(() => ACP_STORE_DEFAULTS, {
1193
1800
  name: "cofhesdk-acps",
@@ -1196,12 +1803,23 @@ var _acpStore = vanilla.createStore()(
1196
1803
  if (version < ACP_STORE_VERSION)
1197
1804
  return ACP_STORE_DEFAULTS;
1198
1805
  return persistedState;
1806
+ },
1807
+ // Runs on every rehydrate, including a corrupt state saved at the current version that
1808
+ // `migrate` passes through unchanged. Consumers that read the raw snapshot (e.g. the React
1809
+ // hooks) never go through `clearStaleStore`, so the shape has to be fixed here.
1810
+ merge: (persistedState, currentState) => {
1811
+ const persisted = isRecord(persistedState) ? persistedState : {};
1812
+ return {
1813
+ ...currentState,
1814
+ acps: isRecord(persisted.acps) ? persisted.acps : currentState.acps,
1815
+ activeACPHash: isRecord(persisted.activeACPHash) ? persisted.activeACPHash : currentState.activeACPHash
1816
+ };
1199
1817
  }
1200
1818
  })
1201
1819
  );
1202
1820
  var clearStaleStore = () => {
1203
1821
  const state = _acpStore.getState();
1204
- const hasExpectedStructure = state && typeof state === "object" && "acps" in state && "activeACPHash" in state && typeof state.acps === "object" && typeof state.activeACPHash === "object";
1822
+ const hasExpectedStructure = isRecord(state) && isRecord(state.acps) && isRecord(state.activeACPHash);
1205
1823
  if (hasExpectedStructure)
1206
1824
  return;
1207
1825
  _acpStore.setState({ acps: {}, activeACPHash: {} });
@@ -1210,7 +1828,8 @@ var getACP = (chainId, account, hash) => {
1210
1828
  clearStaleStore();
1211
1829
  if (chainId == null || account == null || hash == null)
1212
1830
  return;
1213
- const savedACP = _acpStore.getState().acps[chainId]?.[account]?.[hash];
1831
+ const accountACPs = _acpStore.getState().acps[chainId];
1832
+ const savedACP = accountACPs?.[resolveAccountKey(accountACPs, account)]?.[hash];
1214
1833
  if (savedACP == null)
1215
1834
  return;
1216
1835
  return ACPUtils.deserialize(savedACP);
@@ -1219,14 +1838,16 @@ var getActiveACP = (chainId, account) => {
1219
1838
  clearStaleStore();
1220
1839
  if (chainId == null || account == null)
1221
1840
  return;
1222
- const activeACPHash = _acpStore.getState().activeACPHash[chainId]?.[account];
1841
+ const activeHashes = _acpStore.getState().activeACPHash[chainId];
1842
+ const activeACPHash = activeHashes?.[resolveAccountKey(activeHashes, account)];
1223
1843
  return getACP(chainId, account, activeACPHash);
1224
1844
  };
1225
1845
  var getACPs = (chainId, account) => {
1226
1846
  clearStaleStore();
1227
1847
  if (chainId == null || account == null)
1228
1848
  return {};
1229
- return Object.entries(_acpStore.getState().acps[chainId]?.[account] ?? {}).reduce(
1849
+ const accountACPs = _acpStore.getState().acps[chainId];
1850
+ return Object.entries(accountACPs?.[resolveAccountKey(accountACPs, account)] ?? {}).reduce(
1230
1851
  (acc, [hash, acp]) => {
1231
1852
  if (acp == void 0)
1232
1853
  return acc;
@@ -1241,9 +1862,10 @@ var setACP = (chainId, account, acp) => {
1241
1862
  immer.produce((state) => {
1242
1863
  if (state.acps[chainId] == null)
1243
1864
  state.acps[chainId] = {};
1244
- if (state.acps[chainId][account] == null)
1245
- state.acps[chainId][account] = {};
1246
- state.acps[chainId][account][acp.hash] = ACPUtils.serialize(acp);
1865
+ const key = resolveAccountKey(state.acps[chainId], account);
1866
+ if (state.acps[chainId][key] == null)
1867
+ state.acps[chainId][key] = {};
1868
+ state.acps[chainId][key][acp.hash] = ACPUtils.serialize(acp);
1247
1869
  })
1248
1870
  );
1249
1871
  };
@@ -1255,13 +1877,14 @@ var removeACP = (chainId, account, hash) => {
1255
1877
  state.acps[chainId] = {};
1256
1878
  if (state.activeACPHash[chainId] == null)
1257
1879
  state.activeACPHash[chainId] = {};
1258
- const accountACPs = state.acps[chainId][account];
1880
+ const accountACPs = state.acps[chainId][resolveAccountKey(state.acps[chainId], account)];
1259
1881
  if (accountACPs == null)
1260
1882
  return;
1261
1883
  if (accountACPs[hash] == null)
1262
1884
  return;
1263
- if (state.activeACPHash[chainId][account] === hash) {
1264
- state.activeACPHash[chainId][account] = void 0;
1885
+ const activeKey = resolveAccountKey(state.activeACPHash[chainId], account);
1886
+ if (state.activeACPHash[chainId][activeKey] === hash) {
1887
+ state.activeACPHash[chainId][activeKey] = void 0;
1265
1888
  }
1266
1889
  accountACPs[hash] = void 0;
1267
1890
  })
@@ -1271,7 +1894,8 @@ var getActiveACPHash = (chainId, account) => {
1271
1894
  clearStaleStore();
1272
1895
  if (chainId == null || account == null)
1273
1896
  return void 0;
1274
- return _acpStore.getState().activeACPHash[chainId]?.[account];
1897
+ const activeHashes = _acpStore.getState().activeACPHash[chainId];
1898
+ return activeHashes?.[resolveAccountKey(activeHashes, account)];
1275
1899
  };
1276
1900
  var setActiveACPHash = (chainId, account, hash) => {
1277
1901
  clearStaleStore();
@@ -1279,7 +1903,7 @@ var setActiveACPHash = (chainId, account, hash) => {
1279
1903
  immer.produce((state) => {
1280
1904
  if (state.activeACPHash[chainId] == null)
1281
1905
  state.activeACPHash[chainId] = {};
1282
- state.activeACPHash[chainId][account] = hash;
1906
+ state.activeACPHash[chainId][resolveAccountKey(state.activeACPHash[chainId], account)] = hash;
1283
1907
  })
1284
1908
  );
1285
1909
  };
@@ -1288,7 +1912,7 @@ var removeActiveACPHash = (chainId, account) => {
1288
1912
  _acpStore.setState(
1289
1913
  immer.produce((state) => {
1290
1914
  if (state.activeACPHash[chainId])
1291
- state.activeACPHash[chainId][account] = void 0;
1915
+ state.activeACPHash[chainId][resolveAccountKey(state.activeACPHash[chainId], account)] = void 0;
1292
1916
  })
1293
1917
  );
1294
1918
  };
@@ -1315,15 +1939,18 @@ exports.ACP_REVOKER_ABI = ACP_REVOKER_ABI;
1315
1939
  exports.ACP_SHARE_REGISTRY_ABI = ACP_SHARE_REGISTRY_ABI;
1316
1940
  exports.ACP_SHARE_TUPLE_ABI = ACP_SHARE_TUPLE_ABI;
1317
1941
  exports.ACP_STORE_DEFAULTS = ACP_STORE_DEFAULTS;
1942
+ exports.ERC7984_ABI = ERC7984_ABI;
1318
1943
  exports.GenerateSealingKey = GenerateSealingKey;
1319
1944
  exports.ImportACPOptionsValidator = ImportACPOptionsValidator;
1320
1945
  exports.ImportACPValidator = ImportACPValidator;
1946
+ exports.SHARE_METADATA_VERSION = LAYOUT_VERSION;
1321
1947
  exports.SelfACPOptionsValidator = SelfACPOptionsValidator;
1322
1948
  exports.SelfACPValidator = SelfACPValidator;
1323
1949
  exports.SharingACPOptionsValidator = SharingACPOptionsValidator;
1324
1950
  exports.SharingACPValidator = SharingACPValidator;
1325
1951
  exports.SignatureTypes = SignatureTypes;
1326
1952
  exports.SignatureUtils = SignatureUtils;
1953
+ exports.UNLABELLED = UNLABELLED;
1327
1954
  exports.ValidationUtils = ValidationUtils;
1328
1955
  exports._acpStore = _acpStore;
1329
1956
  exports.acpStore = acpStore;
@@ -1335,6 +1962,13 @@ exports.clearAclServedAddresses = clearAclServedAddresses;
1335
1962
  exports.clearStaleStore = clearStaleStore;
1336
1963
  exports.computeShareId = computeShareId;
1337
1964
  exports.contractsSchema = contractsSchema;
1965
+ exports.decodeShareAppKey = decodeShareAppKey;
1966
+ exports.decodeShareMetadata = decodeShareMetadata;
1967
+ exports.decodeShareMetadataFull = decodeShareMetadataFull;
1968
+ exports.describeShareLabels = describeShareLabels;
1969
+ exports.describeShareMetadata = describeShareMetadata;
1970
+ exports.encodeShareMetadata = encodeShareMetadata;
1971
+ exports.eventLogLabel = eventLogLabel;
1338
1972
  exports.getACP = getACP;
1339
1973
  exports.getACPs = getACPs;
1340
1974
  exports.getAclAddress = getAclAddress;
@@ -1343,12 +1977,16 @@ exports.getActiveACP = getActiveACP;
1343
1977
  exports.getActiveACPHash = getActiveACPHash;
1344
1978
  exports.getSignatureTypesAndMessage = getSignatureTypesAndMessage;
1345
1979
  exports.handlesSchema = handlesSchema;
1980
+ exports.readPostedShares = readPostedShares;
1981
+ exports.readShare = readShare;
1982
+ exports.readSharesFor = readSharesFor;
1346
1983
  exports.removeACP = removeACP;
1347
1984
  exports.removeActiveACPHash = removeActiveACPHash;
1348
1985
  exports.resetStore = resetStore;
1349
1986
  exports.seal = seal;
1350
1987
  exports.setACP = setACP;
1351
1988
  exports.setActiveACPHash = setActiveACPHash;
1989
+ exports.shareAppKey = shareAppKey;
1352
1990
  exports.shareIdOfChainShare = shareIdOfChainShare;
1353
1991
  exports.toChainShare = toChainShare;
1354
1992
  exports.unsealWithPrivateKey = unsealWithPrivateKey;
@@ -1358,3 +1996,6 @@ exports.validateSelfACP = validateSelfACP;
1358
1996
  exports.validateSelfACPOptions = validateSelfACPOptions;
1359
1997
  exports.validateSharingACP = validateSharingACP;
1360
1998
  exports.validateSharingACPOptions = validateSharingACPOptions;
1999
+ exports.verifyShareLabel = verifyShareLabel;
2000
+ exports.verifyShareLabels = verifyShareLabels;
2001
+ exports.viewFunctionLabel = viewFunctionLabel;