@mysten/seal 0.3.9 → 0.4.1

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 (51) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/cjs/client.d.ts +9 -3
  3. package/dist/cjs/client.js +14 -2
  4. package/dist/cjs/client.js.map +2 -2
  5. package/dist/cjs/error.d.ts +9 -1
  6. package/dist/cjs/error.js +26 -6
  7. package/dist/cjs/error.js.map +2 -2
  8. package/dist/cjs/index.d.ts +1 -0
  9. package/dist/cjs/index.js.map +1 -1
  10. package/dist/cjs/key-server.d.ts +10 -2
  11. package/dist/cjs/key-server.js +25 -15
  12. package/dist/cjs/key-server.js.map +2 -2
  13. package/dist/cjs/keys.js +2 -0
  14. package/dist/cjs/keys.js.map +2 -2
  15. package/dist/cjs/session-key.d.ts +19 -0
  16. package/dist/cjs/session-key.js +48 -2
  17. package/dist/cjs/session-key.js.map +2 -2
  18. package/dist/cjs/types.d.ts +4 -0
  19. package/dist/cjs/types.js.map +1 -1
  20. package/dist/cjs/utils.d.ts +10 -0
  21. package/dist/cjs/utils.js +21 -0
  22. package/dist/cjs/utils.js.map +2 -2
  23. package/dist/cjs/version.d.ts +1 -1
  24. package/dist/cjs/version.js +1 -1
  25. package/dist/cjs/version.js.map +1 -1
  26. package/dist/esm/client.d.ts +9 -3
  27. package/dist/esm/client.js +14 -2
  28. package/dist/esm/client.js.map +2 -2
  29. package/dist/esm/error.d.ts +9 -1
  30. package/dist/esm/error.js +26 -6
  31. package/dist/esm/error.js.map +2 -2
  32. package/dist/esm/index.d.ts +1 -0
  33. package/dist/esm/index.js.map +1 -1
  34. package/dist/esm/key-server.d.ts +10 -2
  35. package/dist/esm/key-server.js +26 -15
  36. package/dist/esm/key-server.js.map +2 -2
  37. package/dist/esm/keys.js +2 -0
  38. package/dist/esm/keys.js.map +2 -2
  39. package/dist/esm/session-key.d.ts +19 -0
  40. package/dist/esm/session-key.js +48 -2
  41. package/dist/esm/session-key.js.map +2 -2
  42. package/dist/esm/types.d.ts +4 -0
  43. package/dist/esm/utils.d.ts +10 -0
  44. package/dist/esm/utils.js +21 -0
  45. package/dist/esm/utils.js.map +2 -2
  46. package/dist/esm/version.d.ts +1 -1
  47. package/dist/esm/version.js +1 -1
  48. package/dist/esm/version.js.map +1 -1
  49. package/dist/tsconfig.esm.tsbuildinfo +1 -1
  50. package/dist/tsconfig.tsbuildinfo +1 -1
  51. package/package.json +2 -2
@@ -43,7 +43,7 @@ const RequestFormat = import_bcs2.bcs.struct("RequestFormat", {
43
43
  encKey: import_bcs2.bcs.vector(import_bcs2.bcs.U8),
44
44
  encVerificationKey: import_bcs2.bcs.vector(import_bcs2.bcs.U8)
45
45
  });
46
- class SessionKey {
46
+ const _SessionKey = class _SessionKey {
47
47
  constructor({
48
48
  address,
49
49
  packageId,
@@ -63,6 +63,9 @@ class SessionKey {
63
63
  if (ttlMin > 30 || ttlMin < 1) {
64
64
  throw new import_error.UserError(`Invalid TTL ${ttlMin}, must be between 1 and 30`);
65
65
  }
66
+ if (signer && signer.getPublicKey().toSuiAddress() !== address) {
67
+ throw new import_error.UserError("Signer address does not match session key address");
68
+ }
66
69
  __privateSet(this, _address, address);
67
70
  __privateSet(this, _packageId, packageId);
68
71
  __privateSet(this, _creationTimeMs, Date.now());
@@ -129,7 +132,49 @@ class SessionKey {
129
132
  requestSignature: (0, import_bcs.toBase64)(await __privateGet(this, _sessionKey).sign(msgToSign))
130
133
  };
131
134
  }
132
- }
135
+ /**
136
+ * Export the Session Key object from the instance. Store the object in IndexedDB to persist.
137
+ */
138
+ export() {
139
+ const obj = {
140
+ address: __privateGet(this, _address),
141
+ packageId: __privateGet(this, _packageId),
142
+ creationTimeMs: __privateGet(this, _creationTimeMs),
143
+ ttlMin: __privateGet(this, _ttlMin),
144
+ personalMessageSignature: __privateGet(this, _personalMessageSignature),
145
+ sessionKey: __privateGet(this, _sessionKey).getSecretKey()
146
+ // bech32 encoded string
147
+ };
148
+ Object.defineProperty(obj, "toJSON", {
149
+ enumerable: false,
150
+ value: () => {
151
+ throw new Error("This object is not serializable");
152
+ }
153
+ });
154
+ return obj;
155
+ }
156
+ /**
157
+ * Restore a SessionKey instance for the given object.
158
+ * @returns A new SessionKey instance with restored state
159
+ */
160
+ static async import(data, { signer }) {
161
+ const instance = new _SessionKey({
162
+ address: data.address,
163
+ packageId: data.packageId,
164
+ ttlMin: data.ttlMin,
165
+ signer
166
+ });
167
+ __privateSet(instance, _creationTimeMs, data.creationTimeMs);
168
+ __privateSet(instance, _sessionKey, import_ed25519.Ed25519Keypair.fromSecretKey(data.sessionKey));
169
+ if (data.personalMessageSignature) {
170
+ await instance.setPersonalMessageSignature(data.personalMessageSignature);
171
+ }
172
+ if (instance.isExpired()) {
173
+ throw new import_error.ExpiredSessionKeyError();
174
+ }
175
+ return instance;
176
+ }
177
+ };
133
178
  _address = new WeakMap();
134
179
  _packageId = new WeakMap();
135
180
  _creationTimeMs = new WeakMap();
@@ -137,4 +182,5 @@ _ttlMin = new WeakMap();
137
182
  _sessionKey = new WeakMap();
138
183
  _personalMessageSignature = new WeakMap();
139
184
  _signer = new WeakMap();
185
+ let SessionKey = _SessionKey;
140
186
  //# sourceMappingURL=session-key.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/session-key.ts"],
4
- "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { toBase64 } from '@mysten/bcs';\nimport { bcs } from '@mysten/sui/bcs';\nimport type { Signer } from '@mysten/sui/cryptography';\nimport { SuiGraphQLClient } from '@mysten/sui/graphql';\nimport { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';\nimport { isValidSuiAddress, isValidSuiObjectId } from '@mysten/sui/utils';\nimport { verifyPersonalMessageSignature } from '@mysten/sui/verify';\n\nimport { generateSecretKey, toPublicKey, toVerificationKey } from './elgamal.js';\nimport {\n\tExpiredSessionKeyError,\n\tInvalidPersonalMessageSignatureError,\n\tUserError,\n} from './error.js';\n\nexport const RequestFormat = bcs.struct('RequestFormat', {\n\tptb: bcs.vector(bcs.U8),\n\tencKey: bcs.vector(bcs.U8),\n\tencVerificationKey: bcs.vector(bcs.U8),\n});\n\nexport type Certificate = {\n\tuser: string;\n\tsession_vk: string;\n\tcreation_time: number;\n\tttl_min: number;\n\tsignature: string;\n};\n\nexport class SessionKey {\n\t#address: string;\n\t#packageId: string;\n\t#creationTimeMs: number;\n\t#ttlMin: number;\n\t#sessionKey: Ed25519Keypair;\n\t#personalMessageSignature?: string;\n\t#signer?: Signer;\n\n\tconstructor({\n\t\taddress,\n\t\tpackageId,\n\t\tttlMin,\n\t\tsigner,\n\t}: {\n\t\taddress: string;\n\t\tpackageId: string;\n\t\tttlMin: number;\n\t\tsigner?: Signer;\n\t}) {\n\t\tif (!isValidSuiObjectId(packageId) || !isValidSuiAddress(address)) {\n\t\t\tthrow new UserError(`Invalid package ID ${packageId} or address ${address}`);\n\t\t}\n\t\tif (ttlMin > 30 || ttlMin < 1) {\n\t\t\tthrow new UserError(`Invalid TTL ${ttlMin}, must be between 1 and 30`);\n\t\t}\n\n\t\tthis.#address = address;\n\t\tthis.#packageId = packageId;\n\t\tthis.#creationTimeMs = Date.now();\n\t\tthis.#ttlMin = ttlMin;\n\t\tthis.#sessionKey = Ed25519Keypair.generate();\n\t\tthis.#signer = signer;\n\t}\n\n\tisExpired(): boolean {\n\t\t// Allow 10 seconds for clock skew\n\t\treturn this.#creationTimeMs + this.#ttlMin * 60 * 1000 - 10_000 < Date.now();\n\t}\n\n\tgetAddress(): string {\n\t\treturn this.#address;\n\t}\n\n\tgetPackageId(): string {\n\t\treturn this.#packageId;\n\t}\n\n\tgetPersonalMessage(): Uint8Array {\n\t\tconst creationTimeUtc =\n\t\t\tnew Date(this.#creationTimeMs).toISOString().slice(0, 19).replace('T', ' ') + ' UTC';\n\t\tconst message = `Accessing keys of package ${this.#packageId} for ${this.#ttlMin} mins from ${creationTimeUtc}, session key ${toBase64(this.#sessionKey.getPublicKey().toRawBytes())}`;\n\t\treturn new TextEncoder().encode(message);\n\t}\n\n\tasync setPersonalMessageSignature(personalMessageSignature: string) {\n\t\ttry {\n\t\t\t// TODO: Fix this to work with any network\n\t\t\tawait verifyPersonalMessageSignature(this.getPersonalMessage(), personalMessageSignature, {\n\t\t\t\taddress: this.#address,\n\t\t\t\tclient: new SuiGraphQLClient({\n\t\t\t\t\turl: 'https://sui-testnet.mystenlabs.com/graphql',\n\t\t\t\t}),\n\t\t\t});\n\t\t\tthis.#personalMessageSignature = personalMessageSignature;\n\t\t} catch (e) {\n\t\t\tthrow new InvalidPersonalMessageSignatureError('Not valid');\n\t\t}\n\t}\n\n\tasync getCertificate(): Promise<Certificate> {\n\t\tif (!this.#personalMessageSignature) {\n\t\t\tif (this.#signer) {\n\t\t\t\tconst { signature } = await this.#signer.signPersonalMessage(this.getPersonalMessage());\n\t\t\t\tthis.#personalMessageSignature = signature;\n\t\t\t} else {\n\t\t\t\tthrow new InvalidPersonalMessageSignatureError('Personal message signature is not set');\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tuser: this.#address,\n\t\t\tsession_vk: toBase64(this.#sessionKey.getPublicKey().toRawBytes()),\n\t\t\tcreation_time: this.#creationTimeMs,\n\t\t\tttl_min: this.#ttlMin,\n\t\t\tsignature: this.#personalMessageSignature,\n\t\t};\n\t}\n\n\tasync createRequestParams(\n\t\ttxBytes: Uint8Array,\n\t): Promise<{ decryptionKey: Uint8Array; requestSignature: string }> {\n\t\tif (this.isExpired()) {\n\t\t\tthrow new ExpiredSessionKeyError();\n\t\t}\n\t\tconst egSk = generateSecretKey();\n\t\tconst msgToSign = RequestFormat.serialize({\n\t\t\tptb: txBytes.slice(1),\n\t\t\tencKey: toPublicKey(egSk),\n\t\t\tencVerificationKey: toVerificationKey(egSk),\n\t\t}).toBytes();\n\t\treturn {\n\t\t\tdecryptionKey: egSk,\n\t\t\trequestSignature: toBase64(await this.#sessionKey.sign(msgToSign)),\n\t\t};\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { toBase64 } from '@mysten/bcs';\nimport { bcs } from '@mysten/sui/bcs';\nimport type { Signer } from '@mysten/sui/cryptography';\nimport { SuiGraphQLClient } from '@mysten/sui/graphql';\nimport { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';\nimport { isValidSuiAddress, isValidSuiObjectId } from '@mysten/sui/utils';\nimport { verifyPersonalMessageSignature } from '@mysten/sui/verify';\nimport { generateSecretKey, toPublicKey, toVerificationKey } from './elgamal.js';\nimport {\n\tExpiredSessionKeyError,\n\tInvalidPersonalMessageSignatureError,\n\tUserError,\n} from './error.js';\n\nexport const RequestFormat = bcs.struct('RequestFormat', {\n\tptb: bcs.vector(bcs.U8),\n\tencKey: bcs.vector(bcs.U8),\n\tencVerificationKey: bcs.vector(bcs.U8),\n});\n\nexport type Certificate = {\n\tuser: string;\n\tsession_vk: string;\n\tcreation_time: number;\n\tttl_min: number;\n\tsignature: string;\n};\n\nexport type SessionKeyType = {\n\taddress: string;\n\tpackageId: string;\n\tcreationTimeMs: number;\n\tttlMin: number;\n\tpersonalMessageSignature?: string;\n\tsessionKey: string;\n};\n\nexport class SessionKey {\n\t#address: string;\n\t#packageId: string;\n\t#creationTimeMs: number;\n\t#ttlMin: number;\n\t#sessionKey: Ed25519Keypair;\n\t#personalMessageSignature?: string;\n\t#signer?: Signer;\n\n\tconstructor({\n\t\taddress,\n\t\tpackageId,\n\t\tttlMin,\n\t\tsigner,\n\t}: {\n\t\taddress: string;\n\t\tpackageId: string;\n\t\tttlMin: number;\n\t\tsigner?: Signer;\n\t}) {\n\t\tif (!isValidSuiObjectId(packageId) || !isValidSuiAddress(address)) {\n\t\t\tthrow new UserError(`Invalid package ID ${packageId} or address ${address}`);\n\t\t}\n\t\tif (ttlMin > 30 || ttlMin < 1) {\n\t\t\tthrow new UserError(`Invalid TTL ${ttlMin}, must be between 1 and 30`);\n\t\t}\n\n\t\tif (signer && signer.getPublicKey().toSuiAddress() !== address) {\n\t\t\tthrow new UserError('Signer address does not match session key address');\n\t\t}\n\t\tthis.#address = address;\n\t\tthis.#packageId = packageId;\n\t\tthis.#creationTimeMs = Date.now();\n\t\tthis.#ttlMin = ttlMin;\n\t\tthis.#sessionKey = Ed25519Keypair.generate();\n\t\tthis.#signer = signer;\n\t}\n\n\tisExpired(): boolean {\n\t\t// Allow 10 seconds for clock skew\n\t\treturn this.#creationTimeMs + this.#ttlMin * 60 * 1000 - 10_000 < Date.now();\n\t}\n\n\tgetAddress(): string {\n\t\treturn this.#address;\n\t}\n\n\tgetPackageId(): string {\n\t\treturn this.#packageId;\n\t}\n\n\tgetPersonalMessage(): Uint8Array {\n\t\tconst creationTimeUtc =\n\t\t\tnew Date(this.#creationTimeMs).toISOString().slice(0, 19).replace('T', ' ') + ' UTC';\n\t\tconst message = `Accessing keys of package ${this.#packageId} for ${this.#ttlMin} mins from ${creationTimeUtc}, session key ${toBase64(this.#sessionKey.getPublicKey().toRawBytes())}`;\n\t\treturn new TextEncoder().encode(message);\n\t}\n\n\tasync setPersonalMessageSignature(personalMessageSignature: string) {\n\t\ttry {\n\t\t\t// TODO: Fix this to work with any network\n\t\t\tawait verifyPersonalMessageSignature(this.getPersonalMessage(), personalMessageSignature, {\n\t\t\t\taddress: this.#address,\n\t\t\t\tclient: new SuiGraphQLClient({\n\t\t\t\t\turl: 'https://sui-testnet.mystenlabs.com/graphql',\n\t\t\t\t}),\n\t\t\t});\n\t\t\tthis.#personalMessageSignature = personalMessageSignature;\n\t\t} catch (e) {\n\t\t\tthrow new InvalidPersonalMessageSignatureError('Not valid');\n\t\t}\n\t}\n\n\tasync getCertificate(): Promise<Certificate> {\n\t\tif (!this.#personalMessageSignature) {\n\t\t\tif (this.#signer) {\n\t\t\t\tconst { signature } = await this.#signer.signPersonalMessage(this.getPersonalMessage());\n\t\t\t\tthis.#personalMessageSignature = signature;\n\t\t\t} else {\n\t\t\t\tthrow new InvalidPersonalMessageSignatureError('Personal message signature is not set');\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tuser: this.#address,\n\t\t\tsession_vk: toBase64(this.#sessionKey.getPublicKey().toRawBytes()),\n\t\t\tcreation_time: this.#creationTimeMs,\n\t\t\tttl_min: this.#ttlMin,\n\t\t\tsignature: this.#personalMessageSignature,\n\t\t};\n\t}\n\n\tasync createRequestParams(\n\t\ttxBytes: Uint8Array,\n\t): Promise<{ decryptionKey: Uint8Array; requestSignature: string }> {\n\t\tif (this.isExpired()) {\n\t\t\tthrow new ExpiredSessionKeyError();\n\t\t}\n\t\tconst egSk = generateSecretKey();\n\t\tconst msgToSign = RequestFormat.serialize({\n\t\t\tptb: txBytes.slice(1),\n\t\t\tencKey: toPublicKey(egSk),\n\t\t\tencVerificationKey: toVerificationKey(egSk),\n\t\t}).toBytes();\n\t\treturn {\n\t\t\tdecryptionKey: egSk,\n\t\t\trequestSignature: toBase64(await this.#sessionKey.sign(msgToSign)),\n\t\t};\n\t}\n\n\t/**\n\t * Export the Session Key object from the instance. Store the object in IndexedDB to persist.\n\t */\n\texport(): SessionKeyType {\n\t\tconst obj = {\n\t\t\taddress: this.#address,\n\t\t\tpackageId: this.#packageId,\n\t\t\tcreationTimeMs: this.#creationTimeMs,\n\t\t\tttlMin: this.#ttlMin,\n\t\t\tpersonalMessageSignature: this.#personalMessageSignature,\n\t\t\tsessionKey: this.#sessionKey.getSecretKey(), // bech32 encoded string\n\t\t};\n\n\t\tObject.defineProperty(obj, 'toJSON', {\n\t\t\tenumerable: false,\n\t\t\tvalue: () => {\n\t\t\t\tthrow new Error('This object is not serializable');\n\t\t\t},\n\t\t});\n\t\treturn obj;\n\t}\n\n\t/**\n\t * Restore a SessionKey instance for the given object.\n\t * @returns A new SessionKey instance with restored state\n\t */\n\tstatic async import(data: SessionKeyType, { signer }: { signer?: Signer }): Promise<SessionKey> {\n\t\tconst instance = new SessionKey({\n\t\t\taddress: data.address,\n\t\t\tpackageId: data.packageId,\n\t\t\tttlMin: data.ttlMin,\n\t\t\tsigner,\n\t\t});\n\n\t\tinstance.#creationTimeMs = data.creationTimeMs;\n\t\tinstance.#sessionKey = Ed25519Keypair.fromSecretKey(data.sessionKey);\n\n\t\t// check if personal message signature is consistent with the personal message committed to\n\t\t// the session key pk, package id, creationTime and ttlMin.\n\t\tif (data.personalMessageSignature) {\n\t\t\tawait instance.setPersonalMessageSignature(data.personalMessageSignature);\n\t\t}\n\n\t\tif (instance.isExpired()) {\n\t\t\tthrow new ExpiredSessionKeyError();\n\t\t}\n\t\treturn instance;\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["import_bcs"]
7
7
  }
@@ -1 +1,5 @@
1
+ import type { ClientWithExtensions, Experimental_CoreClient } from '@mysten/sui/experimental';
1
2
  export type KeyCacheKey = `${string}:${string}`;
3
+ export type SealCompatibleClient = ClientWithExtensions<{
4
+ core: Experimental_CoreClient;
5
+ }>;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/types.ts"],
4
- "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nexport type KeyCacheKey = `${string}:${string}`;\n"],
4
+ "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { ClientWithExtensions, Experimental_CoreClient } from '@mysten/sui/experimental';\n\nexport type KeyCacheKey = `${string}:${string}`;\nexport type SealCompatibleClient = ClientWithExtensions<{\n\tcore: Experimental_CoreClient;\n}>;\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -8,3 +8,13 @@ export declare function xorUnchecked(a: Uint8Array, b: Uint8Array): Uint8Array;
8
8
  * @returns The full ID.
9
9
  */
10
10
  export declare function createFullId(dst: Uint8Array, packageId: string, innerId: string): string;
11
+ /**
12
+ * A simple class to represent a version number of the form x.y.z.
13
+ */
14
+ export declare class Version {
15
+ major: number;
16
+ minor: number;
17
+ patch: number;
18
+ constructor(version: string);
19
+ older_than(other: Version): boolean;
20
+ }
package/dist/cjs/utils.js CHANGED
@@ -18,6 +18,7 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var utils_exports = {};
20
20
  __export(utils_exports, {
21
+ Version: () => Version,
21
22
  createFullId: () => createFullId,
22
23
  xor: () => xor,
23
24
  xorUnchecked: () => xorUnchecked
@@ -48,4 +49,24 @@ function createFullId(dst, packageId, innerId) {
48
49
  fullId.set(innerIdBytes, 1 + dst.length + packageIdBytes.length);
49
50
  return (0, import_bcs.toHex)(fullId);
50
51
  }
52
+ class Version {
53
+ constructor(version) {
54
+ const parts = version.split(".").map(Number);
55
+ if (parts.length !== 3 || parts.some((part) => isNaN(part) || part < 0)) {
56
+ throw new import_error.UserError(`Invalid version format: ${version}`);
57
+ }
58
+ this.major = parts[0];
59
+ this.minor = parts[1];
60
+ this.patch = parts[2];
61
+ }
62
+ // Compare this version with another version. True if this version is older than the other version.
63
+ older_than(other) {
64
+ if (this.major !== other.major) {
65
+ return this.major < other.major;
66
+ } else if (this.minor !== other.minor) {
67
+ return this.minor < other.minor;
68
+ }
69
+ return this.patch < other.patch;
70
+ }
71
+ }
51
72
  //# sourceMappingURL=utils.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils.ts"],
4
- "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { fromHex, toHex } from '@mysten/bcs';\nimport { isValidSuiObjectId } from '@mysten/sui/utils';\n\nimport { UserError } from './error.js';\n\nexport function xor(a: Uint8Array, b: Uint8Array): Uint8Array {\n\tif (a.length !== b.length) {\n\t\tthrow new Error('Invalid input');\n\t}\n\treturn xorUnchecked(a, b);\n}\n\nexport function xorUnchecked(a: Uint8Array, b: Uint8Array): Uint8Array {\n\treturn a.map((ai, i) => ai ^ b[i]);\n}\n\n/**\n * Create a full ID concatenating DST || package ID || inner ID.\n * @param dst - The domain separation tag.\n * @param packageId - The package ID.\n * @param innerId - The inner ID.\n * @returns The full ID.\n */\nexport function createFullId(dst: Uint8Array, packageId: string, innerId: string): string {\n\tif (!isValidSuiObjectId(packageId)) {\n\t\tthrow new UserError(`Invalid package ID ${packageId}`);\n\t}\n\tconst packageIdBytes = fromHex(packageId);\n\tconst innerIdBytes = fromHex(innerId);\n\tconst fullId = new Uint8Array(1 + dst.length + packageIdBytes.length + innerIdBytes.length);\n\tfullId.set([dst.length], 0);\n\tfullId.set(dst, 1);\n\tfullId.set(packageIdBytes, 1 + dst.length);\n\tfullId.set(innerIdBytes, 1 + dst.length + packageIdBytes.length);\n\treturn toHex(fullId);\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,iBAA+B;AAC/B,mBAAmC;AAEnC,mBAA0B;AAEnB,SAAS,IAAI,GAAe,GAA2B;AAC7D,MAAI,EAAE,WAAW,EAAE,QAAQ;AAC1B,UAAM,IAAI,MAAM,eAAe;AAAA,EAChC;AACA,SAAO,aAAa,GAAG,CAAC;AACzB;AAEO,SAAS,aAAa,GAAe,GAA2B;AACtE,SAAO,EAAE,IAAI,CAAC,IAAI,MAAM,KAAK,EAAE,CAAC,CAAC;AAClC;AASO,SAAS,aAAa,KAAiB,WAAmB,SAAyB;AACzF,MAAI,KAAC,iCAAmB,SAAS,GAAG;AACnC,UAAM,IAAI,uBAAU,sBAAsB,SAAS,EAAE;AAAA,EACtD;AACA,QAAM,qBAAiB,oBAAQ,SAAS;AACxC,QAAM,mBAAe,oBAAQ,OAAO;AACpC,QAAM,SAAS,IAAI,WAAW,IAAI,IAAI,SAAS,eAAe,SAAS,aAAa,MAAM;AAC1F,SAAO,IAAI,CAAC,IAAI,MAAM,GAAG,CAAC;AAC1B,SAAO,IAAI,KAAK,CAAC;AACjB,SAAO,IAAI,gBAAgB,IAAI,IAAI,MAAM;AACzC,SAAO,IAAI,cAAc,IAAI,IAAI,SAAS,eAAe,MAAM;AAC/D,aAAO,kBAAM,MAAM;AACpB;",
4
+ "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { fromHex, toHex } from '@mysten/bcs';\nimport { isValidSuiObjectId } from '@mysten/sui/utils';\n\nimport { UserError } from './error.js';\n\nexport function xor(a: Uint8Array, b: Uint8Array): Uint8Array {\n\tif (a.length !== b.length) {\n\t\tthrow new Error('Invalid input');\n\t}\n\treturn xorUnchecked(a, b);\n}\n\nexport function xorUnchecked(a: Uint8Array, b: Uint8Array): Uint8Array {\n\treturn a.map((ai, i) => ai ^ b[i]);\n}\n\n/**\n * Create a full ID concatenating DST || package ID || inner ID.\n * @param dst - The domain separation tag.\n * @param packageId - The package ID.\n * @param innerId - The inner ID.\n * @returns The full ID.\n */\nexport function createFullId(dst: Uint8Array, packageId: string, innerId: string): string {\n\tif (!isValidSuiObjectId(packageId)) {\n\t\tthrow new UserError(`Invalid package ID ${packageId}`);\n\t}\n\tconst packageIdBytes = fromHex(packageId);\n\tconst innerIdBytes = fromHex(innerId);\n\tconst fullId = new Uint8Array(1 + dst.length + packageIdBytes.length + innerIdBytes.length);\n\tfullId.set([dst.length], 0);\n\tfullId.set(dst, 1);\n\tfullId.set(packageIdBytes, 1 + dst.length);\n\tfullId.set(innerIdBytes, 1 + dst.length + packageIdBytes.length);\n\treturn toHex(fullId);\n}\n\n/**\n * A simple class to represent a version number of the form x.y.z.\n */\nexport class Version {\n\tmajor: number;\n\tminor: number;\n\tpatch: number;\n\n\tconstructor(version: string) {\n\t\t// Very basic version parsing. Assumes version is in the format x.y.z where x, y, and z are non-negative integers.\n\t\tconst parts = version.split('.').map(Number);\n\t\tif (parts.length !== 3 || parts.some((part) => isNaN(part) || part < 0)) {\n\t\t\tthrow new UserError(`Invalid version format: ${version}`);\n\t\t}\n\t\tthis.major = parts[0];\n\t\tthis.minor = parts[1];\n\t\tthis.patch = parts[2];\n\t}\n\n\t// Compare this version with another version. True if this version is older than the other version.\n\tolder_than(other: Version): boolean {\n\t\tif (this.major !== other.major) {\n\t\t\treturn this.major < other.major;\n\t\t} else if (this.minor !== other.minor) {\n\t\t\treturn this.minor < other.minor;\n\t\t}\n\t\treturn this.patch < other.patch;\n\t}\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,iBAA+B;AAC/B,mBAAmC;AAEnC,mBAA0B;AAEnB,SAAS,IAAI,GAAe,GAA2B;AAC7D,MAAI,EAAE,WAAW,EAAE,QAAQ;AAC1B,UAAM,IAAI,MAAM,eAAe;AAAA,EAChC;AACA,SAAO,aAAa,GAAG,CAAC;AACzB;AAEO,SAAS,aAAa,GAAe,GAA2B;AACtE,SAAO,EAAE,IAAI,CAAC,IAAI,MAAM,KAAK,EAAE,CAAC,CAAC;AAClC;AASO,SAAS,aAAa,KAAiB,WAAmB,SAAyB;AACzF,MAAI,KAAC,iCAAmB,SAAS,GAAG;AACnC,UAAM,IAAI,uBAAU,sBAAsB,SAAS,EAAE;AAAA,EACtD;AACA,QAAM,qBAAiB,oBAAQ,SAAS;AACxC,QAAM,mBAAe,oBAAQ,OAAO;AACpC,QAAM,SAAS,IAAI,WAAW,IAAI,IAAI,SAAS,eAAe,SAAS,aAAa,MAAM;AAC1F,SAAO,IAAI,CAAC,IAAI,MAAM,GAAG,CAAC;AAC1B,SAAO,IAAI,KAAK,CAAC;AACjB,SAAO,IAAI,gBAAgB,IAAI,IAAI,MAAM;AACzC,SAAO,IAAI,cAAc,IAAI,IAAI,SAAS,eAAe,MAAM;AAC/D,aAAO,kBAAM,MAAM;AACpB;AAKO,MAAM,QAAQ;AAAA,EAKpB,YAAY,SAAiB;AAE5B,UAAM,QAAQ,QAAQ,MAAM,GAAG,EAAE,IAAI,MAAM;AAC3C,QAAI,MAAM,WAAW,KAAK,MAAM,KAAK,CAAC,SAAS,MAAM,IAAI,KAAK,OAAO,CAAC,GAAG;AACxE,YAAM,IAAI,uBAAU,2BAA2B,OAAO,EAAE;AAAA,IACzD;AACA,SAAK,QAAQ,MAAM,CAAC;AACpB,SAAK,QAAQ,MAAM,CAAC;AACpB,SAAK,QAAQ,MAAM,CAAC;AAAA,EACrB;AAAA;AAAA,EAGA,WAAW,OAAyB;AACnC,QAAI,KAAK,UAAU,MAAM,OAAO;AAC/B,aAAO,KAAK,QAAQ,MAAM;AAAA,IAC3B,WAAW,KAAK,UAAU,MAAM,OAAO;AACtC,aAAO,KAAK,QAAQ,MAAM;AAAA,IAC3B;AACA,WAAO,KAAK,QAAQ,MAAM;AAAA,EAC3B;AACD;",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- export declare const PACKAGE_VERSION = "0.3.9";
1
+ export declare const PACKAGE_VERSION = "0.4.1";
@@ -21,5 +21,5 @@ __export(version_exports, {
21
21
  PACKAGE_VERSION: () => PACKAGE_VERSION
22
22
  });
23
23
  module.exports = __toCommonJS(version_exports);
24
- const PACKAGE_VERSION = "0.3.9";
24
+ const PACKAGE_VERSION = "0.4.1";
25
25
  //# sourceMappingURL=version.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/version.ts"],
4
- "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\n// This file is generated by genversion.mjs. Do not edit it directly.\n\nexport const PACKAGE_VERSION = '0.3.9';\n"],
4
+ "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\n// This file is generated by genversion.mjs. Do not edit it directly.\n\nexport const PACKAGE_VERSION = '0.4.1';\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAKO,MAAM,kBAAkB;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
- import type { SuiClient } from '@mysten/sui/client';
2
1
  import { DemType, KemType } from './encrypt.js';
3
2
  import type { KeyServer } from './key-server.js';
4
3
  import type { SessionKey } from './session-key.js';
4
+ import type { SealCompatibleClient } from './types.js';
5
5
  /**
6
6
  * Configuration options for initializing a SealClient
7
7
  * @property serverObjectIds: Array of object IDs for the key servers to use.
@@ -10,15 +10,21 @@ import type { SessionKey } from './session-key.js';
10
10
  * Defaults to true.
11
11
  * @property timeout: Timeout in milliseconds for network requests. Defaults to 10 seconds.
12
12
  */
13
- export interface SealClientOptions {
14
- suiClient: SuiClient;
13
+ export interface SealClientExtensionOptions {
15
14
  serverObjectIds: string[];
16
15
  verifyKeyServers?: boolean;
17
16
  timeout?: number;
18
17
  }
18
+ export interface SealClientOptions extends SealClientExtensionOptions {
19
+ suiClient: SealCompatibleClient;
20
+ }
19
21
  export declare class SealClient {
20
22
  #private;
21
23
  constructor(options: SealClientOptions);
24
+ static experimental_asClientExtension(options: SealClientExtensionOptions): {
25
+ name: "seal";
26
+ register: (client: SealCompatibleClient) => SealClient;
27
+ };
22
28
  /**
23
29
  * Return an encrypted message under the identity.
24
30
  *
@@ -22,7 +22,7 @@ import { BonehFranklinBLS12381Services, DST } from "./ibe.js";
22
22
  import { KeyServerType, retrieveKeyServers, verifyKeyServer } from "./key-server.js";
23
23
  import { fetchKeysForAllIds } from "./keys.js";
24
24
  import { createFullId } from "./utils.js";
25
- class SealClient {
25
+ const _SealClient = class _SealClient {
26
26
  constructor(options) {
27
27
  __privateAdd(this, _SealClient_instances);
28
28
  __privateAdd(this, _suiClient);
@@ -37,6 +37,17 @@ class SealClient {
37
37
  __privateSet(this, _verifyKeyServers, options.verifyKeyServers ?? true);
38
38
  __privateSet(this, _timeout, options.timeout ?? 1e4);
39
39
  }
40
+ static experimental_asClientExtension(options) {
41
+ return {
42
+ name: "seal",
43
+ register: (client) => {
44
+ return new _SealClient({
45
+ suiClient: client,
46
+ ...options
47
+ });
48
+ }
49
+ };
50
+ }
40
51
  /**
41
52
  * Return an encrypted message under the identity.
42
53
  *
@@ -205,7 +216,7 @@ class SealClient {
205
216
  throw toMajorityError(errors);
206
217
  }
207
218
  }
208
- }
219
+ };
209
220
  _suiClient = new WeakMap();
210
221
  _serverObjectIds = new WeakMap();
211
222
  _verifyKeyServers = new WeakMap();
@@ -262,6 +273,7 @@ loadKeyServers_fn = async function() {
262
273
  }
263
274
  return keyServers;
264
275
  };
276
+ let SealClient = _SealClient;
265
277
  export {
266
278
  SealClient
267
279
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/client.ts"],
4
- "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { SuiClient } from '@mysten/sui/client';\n\nimport { EncryptedObject } from './bcs.js';\nimport { G1Element, G2Element } from './bls12381.js';\nimport { decrypt } from './decrypt.js';\nimport type { EncryptionInput } from './dem.js';\nimport { AesGcm256, Hmac256Ctr } from './dem.js';\nimport { DemType, encrypt, KemType } from './encrypt.js';\nimport {\n\tInconsistentKeyServersError,\n\tInvalidKeyServerError,\n\tInvalidThresholdError,\n\ttoMajorityError,\n} from './error.js';\nimport { BonehFranklinBLS12381Services, DST } from './ibe.js';\nimport { KeyServerType, retrieveKeyServers, verifyKeyServer } from './key-server.js';\nimport type { KeyServer } from './key-server.js';\nimport { fetchKeysForAllIds } from './keys.js';\nimport type { SessionKey } from './session-key.js';\nimport type { KeyCacheKey } from './types.js';\nimport { createFullId } from './utils.js';\n\n/**\n * Configuration options for initializing a SealClient\n * @property serverObjectIds: Array of object IDs for the key servers to use.\n * @property verifyKeyServers: Whether to verify the key servers' authenticity.\n * \t Should be false if servers are pre-verified (e.g., getAllowlistedKeyServers).\n * \t Defaults to true.\n * @property timeout: Timeout in milliseconds for network requests. Defaults to 10 seconds.\n */\nexport interface SealClientOptions {\n\tsuiClient: SuiClient;\n\tserverObjectIds: string[];\n\tverifyKeyServers?: boolean;\n\ttimeout?: number;\n}\n\nexport class SealClient {\n\t#suiClient: SuiClient;\n\t#serverObjectIds: string[];\n\t#verifyKeyServers: boolean;\n\t#keyServers: Promise<KeyServer[]> | null = null;\n\t// A caching map for: fullId:object_id -> partial key.\n\t#cachedKeys = new Map<KeyCacheKey, G1Element>();\n\t#timeout: number;\n\n\tconstructor(options: SealClientOptions) {\n\t\tthis.#suiClient = options.suiClient;\n\t\tthis.#serverObjectIds = options.serverObjectIds;\n\t\tthis.#verifyKeyServers = options.verifyKeyServers ?? true;\n\t\tthis.#timeout = options.timeout ?? 10_000;\n\t}\n\n\t/**\n\t * Return an encrypted message under the identity.\n\t *\n\t * @param kemType - The type of KEM to use.\n\t * @param demType - The type of DEM to use.\n\t * @param threshold - The threshold for the TSS encryption.\n\t * @param packageId - the packageId namespace.\n\t * @param id - the identity to use.\n\t * @param data - the data to encrypt.\n\t * @param aad - optional additional authenticated data.\n\t * @returns The bcs bytes of the encrypted object containing all metadata and the 256-bit symmetric key that was used to encrypt the object.\n\t * \tSince the symmetric key can be used to decrypt, it should not be shared but can be used e.g. for backup.\n\t */\n\tasync encrypt({\n\t\tkemType = KemType.BonehFranklinBLS12381DemCCA,\n\t\tdemType = DemType.AesGcm256,\n\t\tthreshold,\n\t\tpackageId,\n\t\tid,\n\t\tdata,\n\t\taad = new Uint8Array(),\n\t}: {\n\t\tkemType?: KemType;\n\t\tdemType?: DemType;\n\t\tthreshold: number;\n\t\tpackageId: string;\n\t\tid: string;\n\t\tdata: Uint8Array;\n\t\taad?: Uint8Array;\n\t}) {\n\t\t// TODO: Verify that packageId is first version of its package (else throw error).\n\t\treturn encrypt({\n\t\t\tkeyServers: await this.getKeyServers(),\n\t\t\tkemType,\n\t\t\tthreshold,\n\t\t\tpackageId,\n\t\t\tid,\n\t\t\tencryptionInput: this.#createEncryptionInput(demType, data, aad),\n\t\t});\n\t}\n\n\t#createEncryptionInput(type: DemType, data: Uint8Array, aad: Uint8Array): EncryptionInput {\n\t\tswitch (type) {\n\t\t\tcase DemType.AesGcm256:\n\t\t\t\treturn new AesGcm256(data, aad);\n\t\t\tcase DemType.Hmac256Ctr:\n\t\t\t\treturn new Hmac256Ctr(data, aad);\n\t\t}\n\t}\n\n\t/**\n\t * Decrypt the given encrypted bytes using cached keys.\n\t * Calls fetchKeys in case one or more of the required keys is not cached yet.\n\t * The function throws an error if the client's key servers are not a subset of\n\t * the encrypted object's key servers (including the same weights) or if the\n\t * threshold cannot be met.\n\t *\n\t * @param data - The encrypted bytes to decrypt.\n\t * @param sessionKey - The session key to use.\n\t * @param txBytes - The transaction bytes to use (that calls seal_approve* functions).\n\t * @returns - The decrypted plaintext corresponding to ciphertext.\n\t */\n\tasync decrypt({\n\t\tdata,\n\t\tsessionKey,\n\t\ttxBytes,\n\t}: {\n\t\tdata: Uint8Array;\n\t\tsessionKey: SessionKey;\n\t\ttxBytes: Uint8Array;\n\t}) {\n\t\tconst encryptedObject = EncryptedObject.parse(data);\n\n\t\tthis.#validateEncryptionServices(\n\t\t\tencryptedObject.services.map((s) => s[0]),\n\t\t\tencryptedObject.threshold,\n\t\t);\n\n\t\tawait this.fetchKeys({\n\t\t\tids: [encryptedObject.id],\n\t\t\ttxBytes,\n\t\t\tsessionKey,\n\t\t\tthreshold: encryptedObject.threshold,\n\t\t});\n\n\t\treturn decrypt({ encryptedObject, keys: this.#cachedKeys });\n\t}\n\n\t#validateEncryptionServices(services: string[], threshold: number) {\n\t\t// Check that the client's key servers are a subset of the encrypted object's key servers.\n\t\tconst serverObjectIdsMap = new Map<string, number>();\n\t\tfor (const objectId of this.#serverObjectIds) {\n\t\t\tserverObjectIdsMap.set(objectId, (serverObjectIdsMap.get(objectId) ?? 0) + 1);\n\t\t}\n\t\tconst servicesMap = new Map<string, number>();\n\t\tfor (const service of services) {\n\t\t\tservicesMap.set(service, (servicesMap.get(service) ?? 0) + 1);\n\t\t}\n\t\tfor (const [objectId, count] of serverObjectIdsMap) {\n\t\t\tif (servicesMap.get(objectId) !== count) {\n\t\t\t\tthrow new InconsistentKeyServersError(\n\t\t\t\t\t`Client's key servers must be a subset of the encrypted object's key servers`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\t// Check that the threshold can be met with the client's key servers.\n\t\tif (threshold > this.#serverObjectIds.length) {\n\t\t\tthrow new InvalidThresholdError(\n\t\t\t\t`Invalid threshold ${threshold} for ${this.#serverObjectIds.length} servers`,\n\t\t\t);\n\t\t}\n\t}\n\n\tasync getKeyServers() {\n\t\tif (!this.#keyServers) {\n\t\t\tthis.#keyServers = this.#loadKeyServers().catch((error) => {\n\t\t\t\tthis.#keyServers = null;\n\t\t\t\tthrow error;\n\t\t\t});\n\t\t}\n\n\t\treturn this.#keyServers;\n\t}\n\n\tasync #loadKeyServers(): Promise<KeyServer[]> {\n\t\tconst keyServers = await retrieveKeyServers({\n\t\t\tobjectIds: this.#serverObjectIds,\n\t\t\tclient: this.#suiClient,\n\t\t});\n\n\t\tif (keyServers.length === 0) {\n\t\t\tthrow new InvalidKeyServerError('No key servers found');\n\t\t}\n\n\t\tif (this.#verifyKeyServers) {\n\t\t\tawait Promise.all(\n\t\t\t\tkeyServers.map(async (server) => {\n\t\t\t\t\tif (!(await verifyKeyServer(server, this.#timeout))) {\n\t\t\t\t\t\tthrow new InvalidKeyServerError(`Key server ${server.objectId} is not valid`);\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\treturn keyServers;\n\t}\n\n\t/**\n\t * Fetch keys from the key servers and update the cache.\n\t *\n\t * It is recommended to call this function once for all ids of all encrypted obejcts if\n\t * there are multiple, then call decrypt for each object. This avoids calling fetchKey\n\t * individually for each decrypt.\n\t *\n\t * @param ids - The ids of the encrypted objects.\n\t * @param txBytes - The transaction bytes to use (that calls seal_approve* functions).\n\t * @param sessionKey - The session key to use.\n\t * @param threshold - The threshold for the TSS encryptions. The function returns when a threshold of key servers had returned keys for all ids.\n\t */\n\tasync fetchKeys({\n\t\tids,\n\t\ttxBytes,\n\t\tsessionKey,\n\t\tthreshold,\n\t}: {\n\t\tids: string[];\n\t\ttxBytes: Uint8Array;\n\t\tsessionKey: SessionKey;\n\t\tthreshold: number;\n\t}) {\n\t\tconst keyServers = await this.getKeyServers();\n\t\tif (threshold > keyServers.length || threshold < 1 || keyServers.length < 1) {\n\t\t\tthrow new InvalidThresholdError(\n\t\t\t\t`Invalid threshold ${threshold} for ${keyServers.length} servers`,\n\t\t\t);\n\t\t}\n\n\t\tlet completedServerCount = 0;\n\t\tconst remainingKeyServers = new Set<KeyServer>();\n\t\tconst fullIds = ids.map((id) => createFullId(DST, sessionKey.getPackageId(), id));\n\n\t\t// Count a server as completed if it has keys for all fullIds.\n\t\t// Duplicated key server ids will be counted towards the threshold.\n\t\tfor (const server of keyServers) {\n\t\t\tlet hasAllKeys = true;\n\t\t\tfor (const fullId of fullIds) {\n\t\t\t\tif (!this.#cachedKeys.has(`${fullId}:${server.objectId}`)) {\n\t\t\t\t\thasAllKeys = false;\n\t\t\t\t\tremainingKeyServers.add(server);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (hasAllKeys) {\n\t\t\t\tcompletedServerCount++;\n\t\t\t}\n\t\t}\n\n\t\t// Return early if we have enough keys from cache.\n\t\tif (completedServerCount >= threshold) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check server validities.\n\t\tfor (const server of remainingKeyServers) {\n\t\t\tif (server.keyType !== KeyServerType.BonehFranklinBLS12381) {\n\t\t\t\tthrow new InvalidKeyServerError(\n\t\t\t\t\t`Server ${server.objectId} has invalid key type: ${server.keyType}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst cert = await sessionKey.getCertificate();\n\t\tconst signedRequest = await sessionKey.createRequestParams(txBytes);\n\n\t\tconst controller = new AbortController();\n\t\tconst errors: Error[] = [];\n\n\t\tconst keyFetches = [...remainingKeyServers].map(async (server) => {\n\t\t\ttry {\n\t\t\t\tconst allKeys = await fetchKeysForAllIds(\n\t\t\t\t\tserver.url,\n\t\t\t\t\tsignedRequest.requestSignature,\n\t\t\t\t\ttxBytes,\n\t\t\t\t\tsignedRequest.decryptionKey,\n\t\t\t\t\tcert,\n\t\t\t\t\tthis.#timeout,\n\t\t\t\t\tcontroller.signal,\n\t\t\t\t);\n\t\t\t\t// Check validity of the keys and add them to the cache.\n\t\t\t\tconst receivedIds = new Set<string>();\n\t\t\t\tfor (const { fullId, key } of allKeys) {\n\t\t\t\t\tconst keyElement = G1Element.fromBytes(key);\n\t\t\t\t\tif (\n\t\t\t\t\t\t!BonehFranklinBLS12381Services.verifyUserSecretKey(\n\t\t\t\t\t\t\tkeyElement,\n\t\t\t\t\t\t\tfullId,\n\t\t\t\t\t\t\tG2Element.fromBytes(server.pk),\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\tconsole.warn('Received invalid key from key server ' + server.objectId);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tthis.#cachedKeys.set(`${fullId}:${server.objectId}`, keyElement);\n\t\t\t\t\treceivedIds.add(fullId);\n\t\t\t\t}\n\n\t\t\t\t// Check if all the receivedIds are consistent with the requested fullIds.\n\t\t\t\t// If so, consider the key server got all keys and mark as completed.\n\t\t\t\tconst expectedIds = new Set(fullIds);\n\t\t\t\tconst hasAllKeys =\n\t\t\t\t\treceivedIds.size === expectedIds.size &&\n\t\t\t\t\t[...receivedIds].every((id) => expectedIds.has(id));\n\n\t\t\t\t// Return early if the completed servers is more than threshold.\n\t\t\t\tif (hasAllKeys) {\n\t\t\t\t\tcompletedServerCount++;\n\t\t\t\t\tif (completedServerCount >= threshold) {\n\t\t\t\t\t\tcontroller.abort();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (!controller.signal.aborted) {\n\t\t\t\t\terrors.push(error as Error);\n\t\t\t\t}\n\t\t\t\t// If there are too many errors that the threshold is not attainable, return early with error.\n\t\t\t\tif (remainingKeyServers.size - errors.length < threshold - completedServerCount) {\n\t\t\t\t\tcontroller.abort(error);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tawait Promise.allSettled(keyFetches);\n\n\t\tif (completedServerCount < threshold) {\n\t\t\tthrow toMajorityError(errors);\n\t\t}\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { EncryptedObject } from './bcs.js';\nimport { G1Element, G2Element } from './bls12381.js';\nimport { decrypt } from './decrypt.js';\nimport type { EncryptionInput } from './dem.js';\nimport { AesGcm256, Hmac256Ctr } from './dem.js';\nimport { DemType, encrypt, KemType } from './encrypt.js';\nimport {\n\tInconsistentKeyServersError,\n\tInvalidKeyServerError,\n\tInvalidThresholdError,\n\ttoMajorityError,\n} from './error.js';\nimport { BonehFranklinBLS12381Services, DST } from './ibe.js';\nimport { KeyServerType, retrieveKeyServers, verifyKeyServer } from './key-server.js';\nimport type { KeyServer } from './key-server.js';\nimport { fetchKeysForAllIds } from './keys.js';\nimport type { SessionKey } from './session-key.js';\nimport type { KeyCacheKey, SealCompatibleClient } from './types.js';\nimport { createFullId } from './utils.js';\n\n/**\n * Configuration options for initializing a SealClient\n * @property serverObjectIds: Array of object IDs for the key servers to use.\n * @property verifyKeyServers: Whether to verify the key servers' authenticity.\n * \t Should be false if servers are pre-verified (e.g., getAllowlistedKeyServers).\n * \t Defaults to true.\n * @property timeout: Timeout in milliseconds for network requests. Defaults to 10 seconds.\n */\n\nexport interface SealClientExtensionOptions {\n\tserverObjectIds: string[];\n\tverifyKeyServers?: boolean;\n\ttimeout?: number;\n}\n\nexport interface SealClientOptions extends SealClientExtensionOptions {\n\tsuiClient: SealCompatibleClient;\n}\n\nexport class SealClient {\n\t#suiClient: SealCompatibleClient;\n\t#serverObjectIds: string[];\n\t#verifyKeyServers: boolean;\n\t#keyServers: Promise<KeyServer[]> | null = null;\n\t// A caching map for: fullId:object_id -> partial key.\n\t#cachedKeys = new Map<KeyCacheKey, G1Element>();\n\t#timeout: number;\n\n\tconstructor(options: SealClientOptions) {\n\t\tthis.#suiClient = options.suiClient;\n\t\tthis.#serverObjectIds = options.serverObjectIds;\n\t\tthis.#verifyKeyServers = options.verifyKeyServers ?? true;\n\t\tthis.#timeout = options.timeout ?? 10_000;\n\t}\n\n\tstatic experimental_asClientExtension(options: SealClientExtensionOptions) {\n\t\treturn {\n\t\t\tname: 'seal' as const,\n\t\t\tregister: (client: SealCompatibleClient) => {\n\t\t\t\treturn new SealClient({\n\t\t\t\t\tsuiClient: client,\n\t\t\t\t\t...options,\n\t\t\t\t});\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * Return an encrypted message under the identity.\n\t *\n\t * @param kemType - The type of KEM to use.\n\t * @param demType - The type of DEM to use.\n\t * @param threshold - The threshold for the TSS encryption.\n\t * @param packageId - the packageId namespace.\n\t * @param id - the identity to use.\n\t * @param data - the data to encrypt.\n\t * @param aad - optional additional authenticated data.\n\t * @returns The bcs bytes of the encrypted object containing all metadata and the 256-bit symmetric key that was used to encrypt the object.\n\t * \tSince the symmetric key can be used to decrypt, it should not be shared but can be used e.g. for backup.\n\t */\n\tasync encrypt({\n\t\tkemType = KemType.BonehFranklinBLS12381DemCCA,\n\t\tdemType = DemType.AesGcm256,\n\t\tthreshold,\n\t\tpackageId,\n\t\tid,\n\t\tdata,\n\t\taad = new Uint8Array(),\n\t}: {\n\t\tkemType?: KemType;\n\t\tdemType?: DemType;\n\t\tthreshold: number;\n\t\tpackageId: string;\n\t\tid: string;\n\t\tdata: Uint8Array;\n\t\taad?: Uint8Array;\n\t}) {\n\t\t// TODO: Verify that packageId is first version of its package (else throw error).\n\t\treturn encrypt({\n\t\t\tkeyServers: await this.getKeyServers(),\n\t\t\tkemType,\n\t\t\tthreshold,\n\t\t\tpackageId,\n\t\t\tid,\n\t\t\tencryptionInput: this.#createEncryptionInput(demType, data, aad),\n\t\t});\n\t}\n\n\t#createEncryptionInput(type: DemType, data: Uint8Array, aad: Uint8Array): EncryptionInput {\n\t\tswitch (type) {\n\t\t\tcase DemType.AesGcm256:\n\t\t\t\treturn new AesGcm256(data, aad);\n\t\t\tcase DemType.Hmac256Ctr:\n\t\t\t\treturn new Hmac256Ctr(data, aad);\n\t\t}\n\t}\n\n\t/**\n\t * Decrypt the given encrypted bytes using cached keys.\n\t * Calls fetchKeys in case one or more of the required keys is not cached yet.\n\t * The function throws an error if the client's key servers are not a subset of\n\t * the encrypted object's key servers (including the same weights) or if the\n\t * threshold cannot be met.\n\t *\n\t * @param data - The encrypted bytes to decrypt.\n\t * @param sessionKey - The session key to use.\n\t * @param txBytes - The transaction bytes to use (that calls seal_approve* functions).\n\t * @returns - The decrypted plaintext corresponding to ciphertext.\n\t */\n\tasync decrypt({\n\t\tdata,\n\t\tsessionKey,\n\t\ttxBytes,\n\t}: {\n\t\tdata: Uint8Array;\n\t\tsessionKey: SessionKey;\n\t\ttxBytes: Uint8Array;\n\t}) {\n\t\tconst encryptedObject = EncryptedObject.parse(data);\n\n\t\tthis.#validateEncryptionServices(\n\t\t\tencryptedObject.services.map((s) => s[0]),\n\t\t\tencryptedObject.threshold,\n\t\t);\n\n\t\tawait this.fetchKeys({\n\t\t\tids: [encryptedObject.id],\n\t\t\ttxBytes,\n\t\t\tsessionKey,\n\t\t\tthreshold: encryptedObject.threshold,\n\t\t});\n\n\t\treturn decrypt({ encryptedObject, keys: this.#cachedKeys });\n\t}\n\n\t#validateEncryptionServices(services: string[], threshold: number) {\n\t\t// Check that the client's key servers are a subset of the encrypted object's key servers.\n\t\tconst serverObjectIdsMap = new Map<string, number>();\n\t\tfor (const objectId of this.#serverObjectIds) {\n\t\t\tserverObjectIdsMap.set(objectId, (serverObjectIdsMap.get(objectId) ?? 0) + 1);\n\t\t}\n\t\tconst servicesMap = new Map<string, number>();\n\t\tfor (const service of services) {\n\t\t\tservicesMap.set(service, (servicesMap.get(service) ?? 0) + 1);\n\t\t}\n\t\tfor (const [objectId, count] of serverObjectIdsMap) {\n\t\t\tif (servicesMap.get(objectId) !== count) {\n\t\t\t\tthrow new InconsistentKeyServersError(\n\t\t\t\t\t`Client's key servers must be a subset of the encrypted object's key servers`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\t// Check that the threshold can be met with the client's key servers.\n\t\tif (threshold > this.#serverObjectIds.length) {\n\t\t\tthrow new InvalidThresholdError(\n\t\t\t\t`Invalid threshold ${threshold} for ${this.#serverObjectIds.length} servers`,\n\t\t\t);\n\t\t}\n\t}\n\n\tasync getKeyServers() {\n\t\tif (!this.#keyServers) {\n\t\t\tthis.#keyServers = this.#loadKeyServers().catch((error) => {\n\t\t\t\tthis.#keyServers = null;\n\t\t\t\tthrow error;\n\t\t\t});\n\t\t}\n\n\t\treturn this.#keyServers;\n\t}\n\n\tasync #loadKeyServers(): Promise<KeyServer[]> {\n\t\tconst keyServers = await retrieveKeyServers({\n\t\t\tobjectIds: this.#serverObjectIds,\n\t\t\tclient: this.#suiClient,\n\t\t});\n\n\t\tif (keyServers.length === 0) {\n\t\t\tthrow new InvalidKeyServerError('No key servers found');\n\t\t}\n\n\t\tif (this.#verifyKeyServers) {\n\t\t\tawait Promise.all(\n\t\t\t\tkeyServers.map(async (server) => {\n\t\t\t\t\tif (!(await verifyKeyServer(server, this.#timeout))) {\n\t\t\t\t\t\tthrow new InvalidKeyServerError(`Key server ${server.objectId} is not valid`);\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\treturn keyServers;\n\t}\n\n\t/**\n\t * Fetch keys from the key servers and update the cache.\n\t *\n\t * It is recommended to call this function once for all ids of all encrypted obejcts if\n\t * there are multiple, then call decrypt for each object. This avoids calling fetchKey\n\t * individually for each decrypt.\n\t *\n\t * @param ids - The ids of the encrypted objects.\n\t * @param txBytes - The transaction bytes to use (that calls seal_approve* functions).\n\t * @param sessionKey - The session key to use.\n\t * @param threshold - The threshold for the TSS encryptions. The function returns when a threshold of key servers had returned keys for all ids.\n\t */\n\tasync fetchKeys({\n\t\tids,\n\t\ttxBytes,\n\t\tsessionKey,\n\t\tthreshold,\n\t}: {\n\t\tids: string[];\n\t\ttxBytes: Uint8Array;\n\t\tsessionKey: SessionKey;\n\t\tthreshold: number;\n\t}) {\n\t\tconst keyServers = await this.getKeyServers();\n\t\tif (threshold > keyServers.length || threshold < 1 || keyServers.length < 1) {\n\t\t\tthrow new InvalidThresholdError(\n\t\t\t\t`Invalid threshold ${threshold} for ${keyServers.length} servers`,\n\t\t\t);\n\t\t}\n\n\t\tlet completedServerCount = 0;\n\t\tconst remainingKeyServers = new Set<KeyServer>();\n\t\tconst fullIds = ids.map((id) => createFullId(DST, sessionKey.getPackageId(), id));\n\n\t\t// Count a server as completed if it has keys for all fullIds.\n\t\t// Duplicated key server ids will be counted towards the threshold.\n\t\tfor (const server of keyServers) {\n\t\t\tlet hasAllKeys = true;\n\t\t\tfor (const fullId of fullIds) {\n\t\t\t\tif (!this.#cachedKeys.has(`${fullId}:${server.objectId}`)) {\n\t\t\t\t\thasAllKeys = false;\n\t\t\t\t\tremainingKeyServers.add(server);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (hasAllKeys) {\n\t\t\t\tcompletedServerCount++;\n\t\t\t}\n\t\t}\n\n\t\t// Return early if we have enough keys from cache.\n\t\tif (completedServerCount >= threshold) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check server validities.\n\t\tfor (const server of remainingKeyServers) {\n\t\t\tif (server.keyType !== KeyServerType.BonehFranklinBLS12381) {\n\t\t\t\tthrow new InvalidKeyServerError(\n\t\t\t\t\t`Server ${server.objectId} has invalid key type: ${server.keyType}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst cert = await sessionKey.getCertificate();\n\t\tconst signedRequest = await sessionKey.createRequestParams(txBytes);\n\n\t\tconst controller = new AbortController();\n\t\tconst errors: Error[] = [];\n\n\t\tconst keyFetches = [...remainingKeyServers].map(async (server) => {\n\t\t\ttry {\n\t\t\t\tconst allKeys = await fetchKeysForAllIds(\n\t\t\t\t\tserver.url,\n\t\t\t\t\tsignedRequest.requestSignature,\n\t\t\t\t\ttxBytes,\n\t\t\t\t\tsignedRequest.decryptionKey,\n\t\t\t\t\tcert,\n\t\t\t\t\tthis.#timeout,\n\t\t\t\t\tcontroller.signal,\n\t\t\t\t);\n\t\t\t\t// Check validity of the keys and add them to the cache.\n\t\t\t\tconst receivedIds = new Set<string>();\n\t\t\t\tfor (const { fullId, key } of allKeys) {\n\t\t\t\t\tconst keyElement = G1Element.fromBytes(key);\n\t\t\t\t\tif (\n\t\t\t\t\t\t!BonehFranklinBLS12381Services.verifyUserSecretKey(\n\t\t\t\t\t\t\tkeyElement,\n\t\t\t\t\t\t\tfullId,\n\t\t\t\t\t\t\tG2Element.fromBytes(server.pk),\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\tconsole.warn('Received invalid key from key server ' + server.objectId);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tthis.#cachedKeys.set(`${fullId}:${server.objectId}`, keyElement);\n\t\t\t\t\treceivedIds.add(fullId);\n\t\t\t\t}\n\n\t\t\t\t// Check if all the receivedIds are consistent with the requested fullIds.\n\t\t\t\t// If so, consider the key server got all keys and mark as completed.\n\t\t\t\tconst expectedIds = new Set(fullIds);\n\t\t\t\tconst hasAllKeys =\n\t\t\t\t\treceivedIds.size === expectedIds.size &&\n\t\t\t\t\t[...receivedIds].every((id) => expectedIds.has(id));\n\n\t\t\t\t// Return early if the completed servers is more than threshold.\n\t\t\t\tif (hasAllKeys) {\n\t\t\t\t\tcompletedServerCount++;\n\t\t\t\t\tif (completedServerCount >= threshold) {\n\t\t\t\t\t\tcontroller.abort();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (!controller.signal.aborted) {\n\t\t\t\t\terrors.push(error as Error);\n\t\t\t\t}\n\t\t\t\t// If there are too many errors that the threshold is not attainable, return early with error.\n\t\t\t\tif (remainingKeyServers.size - errors.length < threshold - completedServerCount) {\n\t\t\t\t\tcontroller.abort(error);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tawait Promise.allSettled(keyFetches);\n\n\t\tif (completedServerCount < threshold) {\n\t\t\tthrow toMajorityError(errors);\n\t\t}\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -10,7 +10,7 @@ export declare class SealAPIError extends SealError {
10
10
  static assertResponse(response: Response, requestId: string): Promise<void>;
11
11
  }
12
12
  export declare class InvalidPTBError extends SealAPIError {
13
- constructor(requestId?: string);
13
+ constructor(requestId?: string, message?: string);
14
14
  }
15
15
  export declare class InvalidPackageError extends SealAPIError {
16
16
  constructor(requestId?: string);
@@ -24,6 +24,12 @@ export declare class InvalidUserSignatureError extends SealAPIError {
24
24
  export declare class InvalidSessionKeySignatureError extends SealAPIError {
25
25
  constructor(requestId?: string);
26
26
  }
27
+ export declare class InvalidSDKVersionError extends SealAPIError {
28
+ constructor(requestId?: string);
29
+ }
30
+ export declare class DeprecatedSDKVersionError extends SealAPIError {
31
+ constructor(requestId?: string);
32
+ }
27
33
  /** Server error indicating that the user does not have access to one or more of the requested keys */
28
34
  export declare class NoAccessError extends SealAPIError {
29
35
  constructor(requestId?: string);
@@ -49,6 +55,8 @@ export declare class UnsupportedNetworkError extends UserError {
49
55
  }
50
56
  export declare class InvalidKeyServerError extends UserError {
51
57
  }
58
+ export declare class InvalidKeyServerVersionError extends UserError {
59
+ }
52
60
  export declare class InvalidCiphertextError extends UserError {
53
61
  }
54
62
  export declare class InvalidThresholdError extends UserError {
package/dist/esm/error.js CHANGED
@@ -24,7 +24,8 @@ const _SealAPIError = class _SealAPIError extends SealError {
24
24
  try {
25
25
  const text = await response.text();
26
26
  const error = JSON.parse(text)["error"];
27
- errorInstance = __privateMethod(_a = _SealAPIError, _SealAPIError_static, generate_fn).call(_a, error, requestId);
27
+ const message = JSON.parse(text)["message"];
28
+ errorInstance = __privateMethod(_a = _SealAPIError, _SealAPIError_static, generate_fn).call(_a, error, message, requestId);
28
29
  } catch (e) {
29
30
  errorInstance = new GeneralError(response.statusText, requestId, response.status);
30
31
  }
@@ -32,10 +33,10 @@ const _SealAPIError = class _SealAPIError extends SealError {
32
33
  }
33
34
  };
34
35
  _SealAPIError_static = new WeakSet();
35
- generate_fn = function(message, requestId, status) {
36
- switch (message) {
36
+ generate_fn = function(error, message, requestId, status) {
37
+ switch (error) {
37
38
  case "InvalidPTB":
38
- return new InvalidPTBError(requestId);
39
+ return new InvalidPTBError(requestId, message);
39
40
  case "InvalidPackage":
40
41
  return new InvalidPackageError(requestId);
41
42
  case "NoAccess":
@@ -48,6 +49,10 @@ generate_fn = function(message, requestId, status) {
48
49
  return new InvalidUserSignatureError(requestId);
49
50
  case "InvalidSessionSignature":
50
51
  return new InvalidSessionKeySignatureError(requestId);
52
+ case "InvalidSDKVersion":
53
+ return new InvalidSDKVersionError(requestId);
54
+ case "DeprecatedSDKVersion":
55
+ return new DeprecatedSDKVersionError(requestId);
51
56
  case "Failure":
52
57
  return new InternalError(requestId);
53
58
  default:
@@ -57,8 +62,8 @@ generate_fn = function(message, requestId, status) {
57
62
  __privateAdd(_SealAPIError, _SealAPIError_static);
58
63
  let SealAPIError = _SealAPIError;
59
64
  class InvalidPTBError extends SealAPIError {
60
- constructor(requestId) {
61
- super("PTB does not conform to the expected format", requestId);
65
+ constructor(requestId, message) {
66
+ super("PTB does not conform to the expected format " + message, requestId);
62
67
  }
63
68
  }
64
69
  class InvalidPackageError extends SealAPIError {
@@ -81,6 +86,16 @@ class InvalidSessionKeySignatureError extends SealAPIError {
81
86
  super("Session key signature is invalid", requestId);
82
87
  }
83
88
  }
89
+ class InvalidSDKVersionError extends SealAPIError {
90
+ constructor(requestId) {
91
+ super("SDK version is invalid", requestId);
92
+ }
93
+ }
94
+ class DeprecatedSDKVersionError extends SealAPIError {
95
+ constructor(requestId) {
96
+ super("SDK version is deprecated", requestId);
97
+ }
98
+ }
84
99
  class NoAccessError extends SealAPIError {
85
100
  constructor(requestId) {
86
101
  super("User does not have access to one or more of the requested keys", requestId);
@@ -108,6 +123,8 @@ class UnsupportedNetworkError extends UserError {
108
123
  }
109
124
  class InvalidKeyServerError extends UserError {
110
125
  }
126
+ class InvalidKeyServerVersionError extends UserError {
127
+ }
111
128
  class InvalidCiphertextError extends UserError {
112
129
  }
113
130
  class InvalidThresholdError extends UserError {
@@ -130,6 +147,7 @@ function toMajorityError(errors) {
130
147
  return majorityError;
131
148
  }
132
149
  export {
150
+ DeprecatedSDKVersionError,
133
151
  ExpiredSessionKeyError,
134
152
  GeneralError,
135
153
  InconsistentKeyServersError,
@@ -137,9 +155,11 @@ export {
137
155
  InvalidCiphertextError,
138
156
  InvalidGetObjectError,
139
157
  InvalidKeyServerError,
158
+ InvalidKeyServerVersionError,
140
159
  InvalidPTBError,
141
160
  InvalidPackageError,
142
161
  InvalidPersonalMessageSignatureError,
162
+ InvalidSDKVersionError,
143
163
  InvalidSessionKeySignatureError,
144
164
  InvalidThresholdError,
145
165
  InvalidUserSignatureError,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/error.ts"],
4
- "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nexport class SealError extends Error {}\n\nexport class UserError extends SealError {}\n\n// Errors returned by the Seal server\nexport class SealAPIError extends SealError {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic requestId?: string,\n\t\tpublic status?: number,\n\t) {\n\t\tsuper(message);\n\t}\n\n\tstatic #generate(message: string, requestId: string, status?: number) {\n\t\tswitch (message) {\n\t\t\tcase 'InvalidPTB':\n\t\t\t\treturn new InvalidPTBError(requestId);\n\t\t\tcase 'InvalidPackage':\n\t\t\t\treturn new InvalidPackageError(requestId);\n\t\t\tcase 'NoAccess':\n\t\t\t\treturn new NoAccessError(requestId);\n\t\t\tcase 'InvalidCertificate':\n\t\t\t\treturn new ExpiredSessionKeyError(requestId);\n\t\t\tcase 'OldPackageVersion':\n\t\t\t\treturn new OldPackageError(requestId);\n\t\t\tcase 'InvalidSignature':\n\t\t\t\treturn new InvalidUserSignatureError(requestId);\n\t\t\tcase 'InvalidSessionSignature':\n\t\t\t\treturn new InvalidSessionKeySignatureError(requestId);\n\t\t\tcase 'Failure':\n\t\t\t\treturn new InternalError(requestId);\n\t\t\tdefault:\n\t\t\t\treturn new GeneralError(message, requestId, status);\n\t\t}\n\t}\n\n\tstatic async assertResponse(response: Response, requestId: string) {\n\t\tif (response.ok) {\n\t\t\treturn;\n\t\t}\n\t\tlet errorInstance: SealAPIError;\n\t\ttry {\n\t\t\tconst text = await response.text();\n\t\t\tconst error = JSON.parse(text)['error'];\n\t\t\terrorInstance = SealAPIError.#generate(error, requestId);\n\t\t} catch (e) {\n\t\t\t// If we can't parse the response as JSON or if it doesn't have the expected format,\n\t\t\t// fall back to using the status text\n\t\t\terrorInstance = new GeneralError(response.statusText, requestId, response.status);\n\t\t}\n\t\tthrow errorInstance;\n\t}\n}\n\n// Errors returned by the Seal server that indicate that the PTB is invalid\n\nexport class InvalidPTBError extends SealAPIError {\n\tconstructor(requestId?: string) {\n\t\tsuper('PTB does not conform to the expected format', requestId);\n\t}\n}\n\nexport class InvalidPackageError extends SealAPIError {\n\tconstructor(requestId?: string) {\n\t\tsuper('Package ID used in PTB is invalid', requestId);\n\t}\n}\n\nexport class OldPackageError extends SealAPIError {\n\tconstructor(requestId?: string) {\n\t\tsuper('PTB must call the latest version of the package', requestId);\n\t}\n}\n\n// Errors returned by the Seal server that indicate that the user's signature is invalid\n\nexport class InvalidUserSignatureError extends SealAPIError {\n\tconstructor(requestId?: string) {\n\t\tsuper('User signature on the session key is invalid', requestId);\n\t}\n}\n\nexport class InvalidSessionKeySignatureError extends SealAPIError {\n\tconstructor(requestId?: string) {\n\t\tsuper('Session key signature is invalid', requestId);\n\t}\n}\n\n/** Server error indicating that the user does not have access to one or more of the requested keys */\nexport class NoAccessError extends SealAPIError {\n\tconstructor(requestId?: string) {\n\t\tsuper('User does not have access to one or more of the requested keys', requestId);\n\t}\n}\n\n/** Server error indicating that the session key has expired */\nexport class ExpiredSessionKeyError extends SealAPIError {\n\tconstructor(requestId?: string) {\n\t\tsuper('Session key has expired', requestId);\n\t}\n}\n\n/** Internal server error, caller should retry */\nexport class InternalError extends SealAPIError {\n\tconstructor(requestId?: string) {\n\t\tsuper('Internal server error, caller should retry', requestId);\n\t}\n}\n\n/** General server errors that are not specific to the Seal API (e.g., 404 \"Not Found\") */\nexport class GeneralError extends SealAPIError {}\n\n// Errors returned by the SDK\nexport class InvalidPersonalMessageSignatureError extends UserError {}\nexport class InvalidGetObjectError extends UserError {}\nexport class UnsupportedFeatureError extends UserError {}\nexport class UnsupportedNetworkError extends UserError {}\nexport class InvalidKeyServerError extends UserError {}\nexport class InvalidCiphertextError extends UserError {}\nexport class InvalidThresholdError extends UserError {}\nexport class InconsistentKeyServersError extends UserError {}\n\nexport function toMajorityError(errors: Error[]): Error {\n\tlet maxCount = 0;\n\tlet majorityError = errors[0];\n\tconst counts = new Map<string, number>();\n\tfor (const error of errors) {\n\t\tconst errorName = error.constructor.name;\n\t\tconst newCount = (counts.get(errorName) || 0) + 1;\n\t\tcounts.set(errorName, newCount);\n\n\t\tif (newCount > maxCount) {\n\t\t\tmaxCount = newCount;\n\t\t\tmajorityError = error;\n\t\t}\n\t}\n\n\treturn majorityError;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nexport class SealError extends Error {}\n\nexport class UserError extends SealError {}\n\n// Errors returned by the Seal server\nexport class SealAPIError extends SealError {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic requestId?: string,\n\t\tpublic status?: number,\n\t) {\n\t\tsuper(message);\n\t}\n\n\tstatic #generate(error: string, message: string, requestId: string, status?: number) {\n\t\tswitch (error) {\n\t\t\tcase 'InvalidPTB':\n\t\t\t\treturn new InvalidPTBError(requestId, message);\n\t\t\tcase 'InvalidPackage':\n\t\t\t\treturn new InvalidPackageError(requestId);\n\t\t\tcase 'NoAccess':\n\t\t\t\treturn new NoAccessError(requestId);\n\t\t\tcase 'InvalidCertificate':\n\t\t\t\treturn new ExpiredSessionKeyError(requestId);\n\t\t\tcase 'OldPackageVersion':\n\t\t\t\treturn new OldPackageError(requestId);\n\t\t\tcase 'InvalidSignature':\n\t\t\t\treturn new InvalidUserSignatureError(requestId);\n\t\t\tcase 'InvalidSessionSignature':\n\t\t\t\treturn new InvalidSessionKeySignatureError(requestId);\n\t\t\tcase 'InvalidSDKVersion':\n\t\t\t\treturn new InvalidSDKVersionError(requestId);\n\t\t\tcase 'DeprecatedSDKVersion':\n\t\t\t\treturn new DeprecatedSDKVersionError(requestId);\n\t\t\tcase 'Failure':\n\t\t\t\treturn new InternalError(requestId);\n\t\t\tdefault:\n\t\t\t\treturn new GeneralError(message, requestId, status);\n\t\t}\n\t}\n\n\tstatic async assertResponse(response: Response, requestId: string) {\n\t\tif (response.ok) {\n\t\t\treturn;\n\t\t}\n\t\tlet errorInstance: SealAPIError;\n\t\ttry {\n\t\t\tconst text = await response.text();\n\t\t\tconst error = JSON.parse(text)['error'];\n\t\t\tconst message = JSON.parse(text)['message'];\n\t\t\terrorInstance = SealAPIError.#generate(error, message, requestId);\n\t\t} catch (e) {\n\t\t\t// If we can't parse the response as JSON or if it doesn't have the expected format,\n\t\t\t// fall back to using the status text\n\t\t\terrorInstance = new GeneralError(response.statusText, requestId, response.status);\n\t\t}\n\t\tthrow errorInstance;\n\t}\n}\n\n// Errors returned by the Seal server that indicate that the PTB is invalid\n\nexport class InvalidPTBError extends SealAPIError {\n\tconstructor(requestId?: string, message?: string) {\n\t\tsuper('PTB does not conform to the expected format ' + message, requestId);\n\t}\n}\n\nexport class InvalidPackageError extends SealAPIError {\n\tconstructor(requestId?: string) {\n\t\tsuper('Package ID used in PTB is invalid', requestId);\n\t}\n}\n\nexport class OldPackageError extends SealAPIError {\n\tconstructor(requestId?: string) {\n\t\tsuper('PTB must call the latest version of the package', requestId);\n\t}\n}\n\n// Errors returned by the Seal server that indicate that the user's signature is invalid\n\nexport class InvalidUserSignatureError extends SealAPIError {\n\tconstructor(requestId?: string) {\n\t\tsuper('User signature on the session key is invalid', requestId);\n\t}\n}\n\nexport class InvalidSessionKeySignatureError extends SealAPIError {\n\tconstructor(requestId?: string) {\n\t\tsuper('Session key signature is invalid', requestId);\n\t}\n}\n\n// Errors returned by the Seal server that indicate that the SDK version is invalid (implying that HTTP headers used by the SDK are being removed) or deprecated (implying that the SDK should be upgraded).\n\nexport class InvalidSDKVersionError extends SealAPIError {\n\tconstructor(requestId?: string) {\n\t\tsuper('SDK version is invalid', requestId);\n\t}\n}\n\nexport class DeprecatedSDKVersionError extends SealAPIError {\n\tconstructor(requestId?: string) {\n\t\tsuper('SDK version is deprecated', requestId);\n\t}\n}\n\n/** Server error indicating that the user does not have access to one or more of the requested keys */\nexport class NoAccessError extends SealAPIError {\n\tconstructor(requestId?: string) {\n\t\tsuper('User does not have access to one or more of the requested keys', requestId);\n\t}\n}\n\n/** Server error indicating that the session key has expired */\nexport class ExpiredSessionKeyError extends SealAPIError {\n\tconstructor(requestId?: string) {\n\t\tsuper('Session key has expired', requestId);\n\t}\n}\n\n/** Internal server error, caller should retry */\nexport class InternalError extends SealAPIError {\n\tconstructor(requestId?: string) {\n\t\tsuper('Internal server error, caller should retry', requestId);\n\t}\n}\n\n/** General server errors that are not specific to the Seal API (e.g., 404 \"Not Found\") */\nexport class GeneralError extends SealAPIError {}\n\n// Errors returned by the SDK\nexport class InvalidPersonalMessageSignatureError extends UserError {}\nexport class InvalidGetObjectError extends UserError {}\nexport class UnsupportedFeatureError extends UserError {}\nexport class UnsupportedNetworkError extends UserError {}\nexport class InvalidKeyServerError extends UserError {}\nexport class InvalidKeyServerVersionError extends UserError {}\nexport class InvalidCiphertextError extends UserError {}\nexport class InvalidThresholdError extends UserError {}\nexport class InconsistentKeyServersError extends UserError {}\n\nexport function toMajorityError(errors: Error[]): Error {\n\tlet maxCount = 0;\n\tlet majorityError = errors[0];\n\tconst counts = new Map<string, number>();\n\tfor (const error of errors) {\n\t\tconst errorName = error.constructor.name;\n\t\tconst newCount = (counts.get(errorName) || 0) + 1;\n\t\tcounts.set(errorName, newCount);\n\n\t\tif (newCount > maxCount) {\n\t\t\tmaxCount = newCount;\n\t\t\tmajorityError = error;\n\t\t}\n\t}\n\n\treturn majorityError;\n}\n"],
5
+ "mappings": ";;;;;;AAAA;AAGO,MAAM,kBAAkB,MAAM;AAAC;AAE/B,MAAM,kBAAkB,UAAU;AAAC;AAGnC,MAAM,gBAAN,MAAM,sBAAqB,UAAU;AAAA,EAC3C,YACC,SACO,WACA,QACN;AACD,UAAM,OAAO;AAHN;AACA;AAAA,EAGR;AAAA,EA6BA,aAAa,eAAe,UAAoB,WAAmB;AA5CpE;AA6CE,QAAI,SAAS,IAAI;AAChB;AAAA,IACD;AACA,QAAI;AACJ,QAAI;AACH,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,QAAQ,KAAK,MAAM,IAAI,EAAE,OAAO;AACtC,YAAM,UAAU,KAAK,MAAM,IAAI,EAAE,SAAS;AAC1C,sBAAgB,oCAAa,mCAAb,SAAuB,OAAO,SAAS;AAAA,IACxD,SAAS,GAAG;AAGX,sBAAgB,IAAI,aAAa,SAAS,YAAY,WAAW,SAAS,MAAM;AAAA,IACjF;AACA,UAAM;AAAA,EACP;AACD;AArDO;AASC,cAAS,SAAC,OAAe,SAAiB,WAAmB,QAAiB;AACpF,UAAQ,OAAO;AAAA,IACd,KAAK;AACJ,aAAO,IAAI,gBAAgB,WAAW,OAAO;AAAA,IAC9C,KAAK;AACJ,aAAO,IAAI,oBAAoB,SAAS;AAAA,IACzC,KAAK;AACJ,aAAO,IAAI,cAAc,SAAS;AAAA,IACnC,KAAK;AACJ,aAAO,IAAI,uBAAuB,SAAS;AAAA,IAC5C,KAAK;AACJ,aAAO,IAAI,gBAAgB,SAAS;AAAA,IACrC,KAAK;AACJ,aAAO,IAAI,0BAA0B,SAAS;AAAA,IAC/C,KAAK;AACJ,aAAO,IAAI,gCAAgC,SAAS;AAAA,IACrD,KAAK;AACJ,aAAO,IAAI,uBAAuB,SAAS;AAAA,IAC5C,KAAK;AACJ,aAAO,IAAI,0BAA0B,SAAS;AAAA,IAC/C,KAAK;AACJ,aAAO,IAAI,cAAc,SAAS;AAAA,IACnC;AACC,aAAO,IAAI,aAAa,SAAS,WAAW,MAAM;AAAA,EACpD;AACD;AAlCM,aAAM,eAAN;AAAA,IAAM,eAAN;AAyDA,MAAM,wBAAwB,aAAa;AAAA,EACjD,YAAY,WAAoB,SAAkB;AACjD,UAAM,iDAAiD,SAAS,SAAS;AAAA,EAC1E;AACD;AAEO,MAAM,4BAA4B,aAAa;AAAA,EACrD,YAAY,WAAoB;AAC/B,UAAM,qCAAqC,SAAS;AAAA,EACrD;AACD;AAEO,MAAM,wBAAwB,aAAa;AAAA,EACjD,YAAY,WAAoB;AAC/B,UAAM,mDAAmD,SAAS;AAAA,EACnE;AACD;AAIO,MAAM,kCAAkC,aAAa;AAAA,EAC3D,YAAY,WAAoB;AAC/B,UAAM,gDAAgD,SAAS;AAAA,EAChE;AACD;AAEO,MAAM,wCAAwC,aAAa;AAAA,EACjE,YAAY,WAAoB;AAC/B,UAAM,oCAAoC,SAAS;AAAA,EACpD;AACD;AAIO,MAAM,+BAA+B,aAAa;AAAA,EACxD,YAAY,WAAoB;AAC/B,UAAM,0BAA0B,SAAS;AAAA,EAC1C;AACD;AAEO,MAAM,kCAAkC,aAAa;AAAA,EAC3D,YAAY,WAAoB;AAC/B,UAAM,6BAA6B,SAAS;AAAA,EAC7C;AACD;AAGO,MAAM,sBAAsB,aAAa;AAAA,EAC/C,YAAY,WAAoB;AAC/B,UAAM,kEAAkE,SAAS;AAAA,EAClF;AACD;AAGO,MAAM,+BAA+B,aAAa;AAAA,EACxD,YAAY,WAAoB;AAC/B,UAAM,2BAA2B,SAAS;AAAA,EAC3C;AACD;AAGO,MAAM,sBAAsB,aAAa;AAAA,EAC/C,YAAY,WAAoB;AAC/B,UAAM,8CAA8C,SAAS;AAAA,EAC9D;AACD;AAGO,MAAM,qBAAqB,aAAa;AAAC;AAGzC,MAAM,6CAA6C,UAAU;AAAC;AAC9D,MAAM,8BAA8B,UAAU;AAAC;AAC/C,MAAM,gCAAgC,UAAU;AAAC;AACjD,MAAM,gCAAgC,UAAU;AAAC;AACjD,MAAM,8BAA8B,UAAU;AAAC;AAC/C,MAAM,qCAAqC,UAAU;AAAC;AACtD,MAAM,+BAA+B,UAAU;AAAC;AAChD,MAAM,8BAA8B,UAAU;AAAC;AAC/C,MAAM,oCAAoC,UAAU;AAAC;AAErD,SAAS,gBAAgB,QAAwB;AACvD,MAAI,WAAW;AACf,MAAI,gBAAgB,OAAO,CAAC;AAC5B,QAAM,SAAS,oBAAI,IAAoB;AACvC,aAAW,SAAS,QAAQ;AAC3B,UAAM,YAAY,MAAM,YAAY;AACpC,UAAM,YAAY,OAAO,IAAI,SAAS,KAAK,KAAK;AAChD,WAAO,IAAI,WAAW,QAAQ;AAE9B,QAAI,WAAW,UAAU;AACxB,iBAAW;AACX,sBAAgB;AAAA,IACjB;AAAA,EACD;AAEA,SAAO;AACR;",
6
6
  "names": []
7
7
  }
@@ -3,3 +3,4 @@ export { EncryptedObject } from './bcs.js';
3
3
  export { SealClient, type SealClientOptions } from './client.js';
4
4
  export { SessionKey } from './session-key.js';
5
5
  export * from './error.js';
6
+ export type { SealCompatibleClient } from './types.js';
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/index.ts"],
4
- "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nexport { getAllowlistedKeyServers } from './key-server.js';\nexport { EncryptedObject } from './bcs.js';\nexport { SealClient, type SealClientOptions } from './client.js';\nexport { SessionKey } from './session-key.js';\nexport * from './error.js';\n"],
4
+ "sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nexport { getAllowlistedKeyServers } from './key-server.js';\nexport { EncryptedObject } from './bcs.js';\nexport { SealClient, type SealClientOptions } from './client.js';\nexport { SessionKey } from './session-key.js';\nexport * from './error.js';\nexport type { SealCompatibleClient } from './types.js';\n"],
5
5
  "mappings": "AAGA,SAAS,gCAAgC;AACzC,SAAS,uBAAuB;AAChC,SAAS,kBAA0C;AACnD,SAAS,kBAAkB;AAC3B,cAAc;",
6
6
  "names": []
7
7
  }
@@ -1,4 +1,5 @@
1
- import type { SuiClient } from '@mysten/sui/client';
1
+ import type { SealCompatibleClient } from './types.js';
2
+ import { Version } from './utils.js';
2
3
  export type KeyServer = {
3
4
  objectId: string;
4
5
  name: string;
@@ -9,6 +10,7 @@ export type KeyServer = {
9
10
  export declare enum KeyServerType {
10
11
  BonehFranklinBLS12381 = 0
11
12
  }
13
+ export declare const SERVER_VERSION_REQUIREMENT: Version;
12
14
  /**
13
15
  * Returns a static list of Seal key server object ids that the dapp can choose to use.
14
16
  * @param network - The network to use.
@@ -25,7 +27,7 @@ export declare function getAllowlistedKeyServers(network: 'testnet' | 'mainnet')
25
27
  */
26
28
  export declare function retrieveKeyServers({ objectIds, client, }: {
27
29
  objectIds: string[];
28
- client: SuiClient;
30
+ client: SealCompatibleClient;
29
31
  }): Promise<KeyServer[]>;
30
32
  /**
31
33
  * Given a KeyServer, fetch the proof of possession (PoP) from the URL and verify it
@@ -36,3 +38,9 @@ export declare function retrieveKeyServers({ objectIds, client, }: {
36
38
  * @returns - True if the key server is valid, false otherwise.
37
39
  */
38
40
  export declare function verifyKeyServer(server: KeyServer, timeout: number): Promise<boolean>;
41
+ /**
42
+ * Verify the key server version. Throws an `InvalidKeyServerError` if the version is not supported.
43
+ *
44
+ * @param response - The response from the key server.
45
+ */
46
+ export declare function verifyKeyServerVersion(response: Response): void;