@mysten/seal 0.9.6 → 0.10.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.
- package/CHANGELOG.md +6 -0
- package/dist/cjs/bcs.d.ts +76 -0
- package/dist/cjs/bcs.js +31 -1
- package/dist/cjs/bcs.js.map +2 -2
- package/dist/cjs/client.js +8 -3
- package/dist/cjs/client.js.map +2 -2
- package/dist/cjs/error.d.ts +3 -0
- package/dist/cjs/error.js +8 -0
- package/dist/cjs/error.js.map +2 -2
- package/dist/cjs/key-server.d.ts +11 -4
- package/dist/cjs/key-server.js +82 -23
- package/dist/cjs/key-server.js.map +3 -3
- package/dist/cjs/types.d.ts +3 -0
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/version.js.map +1 -1
- package/dist/esm/bcs.d.ts +76 -0
- package/dist/esm/bcs.js +31 -1
- package/dist/esm/bcs.js.map +2 -2
- package/dist/esm/client.js +8 -3
- package/dist/esm/client.js.map +2 -2
- package/dist/esm/error.d.ts +3 -0
- package/dist/esm/error.js +8 -0
- package/dist/esm/error.js.map +2 -2
- package/dist/esm/key-server.d.ts +11 -4
- package/dist/esm/key-server.js +89 -25
- package/dist/esm/key-server.js.map +3 -3
- package/dist/esm/types.d.ts +3 -0
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
package/dist/esm/key-server.js
CHANGED
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
import { bcs, fromBase64, fromHex, toBase64, toHex } from "@mysten/bcs";
|
|
2
2
|
import { bls12_381 } from "@noble/curves/bls12-381";
|
|
3
|
-
import { KeyServerMove, KeyServerMoveV1 } from "./bcs.js";
|
|
4
|
-
import {
|
|
3
|
+
import { KeyServerMove, KeyServerMoveV1, KeyServerMoveV2 } from "./bcs.js";
|
|
4
|
+
import {
|
|
5
|
+
InvalidClientOptionsError,
|
|
6
|
+
InvalidKeyServerError,
|
|
7
|
+
InvalidKeyServerVersionError,
|
|
8
|
+
SealAPIError
|
|
9
|
+
} from "./error.js";
|
|
5
10
|
import { DST_POP } from "./ibe.js";
|
|
6
11
|
import { PACKAGE_VERSION } from "./version.js";
|
|
7
12
|
import { flatten, Version } from "./utils.js";
|
|
8
13
|
import { elgamalDecrypt } from "./elgamal.js";
|
|
9
|
-
const
|
|
10
|
-
var
|
|
11
|
-
|
|
12
|
-
return
|
|
13
|
-
})(
|
|
14
|
+
const SUPPORTED_SERVER_VERSIONS = [2, 1];
|
|
15
|
+
var KeyType = /* @__PURE__ */ ((KeyType2) => {
|
|
16
|
+
KeyType2[KeyType2["BonehFranklinBLS12381"] = 0] = "BonehFranklinBLS12381";
|
|
17
|
+
return KeyType2;
|
|
18
|
+
})(KeyType || {});
|
|
14
19
|
const SERVER_VERSION_REQUIREMENT = new Version("0.4.1");
|
|
15
20
|
async function retrieveKeyServers({
|
|
16
21
|
objectIds,
|
|
17
|
-
client
|
|
22
|
+
client,
|
|
23
|
+
configs
|
|
18
24
|
}) {
|
|
19
25
|
return await Promise.all(
|
|
20
26
|
objectIds.map(async (objectId) => {
|
|
@@ -22,31 +28,89 @@ async function retrieveKeyServers({
|
|
|
22
28
|
objectId
|
|
23
29
|
});
|
|
24
30
|
const ks = KeyServerMove.parse(await res.object.content);
|
|
25
|
-
|
|
31
|
+
const firstVersion = Number(ks.firstVersion);
|
|
32
|
+
const lastVersion = Number(ks.lastVersion);
|
|
33
|
+
const version = SUPPORTED_SERVER_VERSIONS.find((v) => v >= firstVersion && v <= lastVersion);
|
|
34
|
+
if (version === void 0) {
|
|
26
35
|
throw new InvalidKeyServerVersionError(
|
|
27
|
-
`Key server ${objectId} supports versions between ${ks.firstVersion} and ${ks.lastVersion} (inclusive), but SDK expects
|
|
36
|
+
`Key server ${objectId} supports versions between ${ks.firstVersion} and ${ks.lastVersion} (inclusive), but SDK expects one of ${SUPPORTED_SERVER_VERSIONS.join(", ")}`
|
|
28
37
|
);
|
|
29
38
|
}
|
|
30
|
-
const
|
|
39
|
+
const versionedKeyServer = await client.core.getDynamicField({
|
|
31
40
|
parentId: objectId,
|
|
32
41
|
name: {
|
|
33
42
|
type: "u64",
|
|
34
|
-
bcs: bcs.u64().serialize(
|
|
43
|
+
bcs: bcs.u64().serialize(version).toBytes()
|
|
35
44
|
}
|
|
36
45
|
});
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
46
|
+
switch (version) {
|
|
47
|
+
case 2: {
|
|
48
|
+
const ksV2 = KeyServerMoveV2.parse(versionedKeyServer.dynamicField.value.bcs);
|
|
49
|
+
if (ksV2.keyType !== 0 /* BonehFranklinBLS12381 */) {
|
|
50
|
+
throw new InvalidKeyServerError(
|
|
51
|
+
`Server ${objectId} has invalid key type: ${ksV2.keyType}`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
switch (ksV2.serverType.$kind) {
|
|
55
|
+
case "Independent": {
|
|
56
|
+
if (configs.get(objectId)?.aggregatorUrl) {
|
|
57
|
+
throw new InvalidClientOptionsError(
|
|
58
|
+
`Independent server ${objectId} should not have aggregatorUrl in config`
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
objectId,
|
|
63
|
+
name: ksV2.name,
|
|
64
|
+
url: ksV2.serverType.Independent.url,
|
|
65
|
+
keyType: ksV2.keyType,
|
|
66
|
+
pk: new Uint8Array(ksV2.pk),
|
|
67
|
+
serverType: "Independent"
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
case "Committee": {
|
|
71
|
+
const config = configs.get(objectId);
|
|
72
|
+
if (!config?.aggregatorUrl) {
|
|
73
|
+
throw new InvalidClientOptionsError(
|
|
74
|
+
`Committee server ${objectId} requires aggregatorUrl in config`
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
objectId,
|
|
79
|
+
name: ksV2.name,
|
|
80
|
+
url: config.aggregatorUrl,
|
|
81
|
+
keyType: ksV2.keyType,
|
|
82
|
+
pk: new Uint8Array(ksV2.pk),
|
|
83
|
+
serverType: "Committee"
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
default:
|
|
87
|
+
throw new InvalidKeyServerError(`Unknown server type for ${objectId}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
case 1: {
|
|
91
|
+
const ksV1 = KeyServerMoveV1.parse(versionedKeyServer.dynamicField.value.bcs);
|
|
92
|
+
if (ksV1.keyType !== 0 /* BonehFranklinBLS12381 */) {
|
|
93
|
+
throw new InvalidKeyServerError(
|
|
94
|
+
`Server ${objectId} has invalid key type: ${ksV1.keyType}`
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
if (configs.get(objectId)?.aggregatorUrl) {
|
|
98
|
+
throw new InvalidClientOptionsError(
|
|
99
|
+
`V1 server ${objectId} is always Independent and should not have aggregatorUrl in config`
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
objectId,
|
|
104
|
+
name: ksV1.name,
|
|
105
|
+
url: ksV1.url,
|
|
106
|
+
keyType: ksV1.keyType,
|
|
107
|
+
pk: new Uint8Array(ksV1.pk),
|
|
108
|
+
serverType: "Independent"
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
default:
|
|
112
|
+
throw new InvalidKeyServerVersionError(`Unsupported key server version: ${version}`);
|
|
42
113
|
}
|
|
43
|
-
return {
|
|
44
|
-
objectId,
|
|
45
|
-
name: ksVersioned.name,
|
|
46
|
-
url: ksVersioned.url,
|
|
47
|
-
keyType: ksVersioned.keyType,
|
|
48
|
-
pk: new Uint8Array(ksVersioned.pk)
|
|
49
|
-
};
|
|
50
114
|
})
|
|
51
115
|
);
|
|
52
116
|
}
|
|
@@ -141,7 +205,7 @@ async function fetchKeysForAllIds({
|
|
|
141
205
|
}
|
|
142
206
|
export {
|
|
143
207
|
BonehFranklinBLS12381DerivedKey,
|
|
144
|
-
|
|
208
|
+
KeyType,
|
|
145
209
|
SERVER_VERSION_REQUIREMENT,
|
|
146
210
|
fetchKeysForAllIds,
|
|
147
211
|
retrieveKeyServers,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/key-server.ts"],
|
|
4
|
-
"sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\nimport { bcs, fromBase64, fromHex, toBase64, toHex } from '@mysten/bcs';\nimport { bls12_381 } from '@noble/curves/bls12-381';\n\nimport { KeyServerMove, KeyServerMoveV1 } from './bcs.js';\nimport { InvalidKeyServerError, InvalidKeyServerVersionError, SealAPIError } from './error.js';\nimport { DST_POP } from './ibe.js';\nimport { PACKAGE_VERSION } from './version.js';\nimport type { SealCompatibleClient } from './types.js';\nimport type { G1Element } from './bls12381.js';\nimport { flatten, Version } from './utils.js';\nimport { elgamalDecrypt } from './elgamal.js';\nimport type { Certificate } from './session-key.js';\n\nconst EXPECTED_SERVER_VERSION = 1;\n\nexport type KeyServer = {\n\tobjectId: string;\n\tname: string;\n\turl: string;\n\tkeyType: KeyServerType;\n\tpk: Uint8Array<ArrayBuffer>;\n};\n\nexport enum KeyServerType {\n\tBonehFranklinBLS12381 = 0,\n}\n\nexport const SERVER_VERSION_REQUIREMENT = new Version('0.4.1');\n\n/**\n * Given a list of key server object IDs, returns a list of SealKeyServer\n * from onchain state containing name, objectId, URL and pk.\n *\n * @param objectIds - The key server object IDs.\n * @param client - The SuiClient to use.\n * @returns - An array of SealKeyServer.\n */\nexport async function retrieveKeyServers({\n\tobjectIds,\n\tclient,\n}: {\n\tobjectIds: string[];\n\tclient: SealCompatibleClient;\n}): Promise<KeyServer[]> {\n\treturn await Promise.all(\n\t\tobjectIds.map(async (objectId) => {\n\t\t\t// First get the KeyServer object and validate it.\n\t\t\tconst res = await client.core.getObject({\n\t\t\t\tobjectId,\n\t\t\t});\n\t\t\tconst ks = KeyServerMove.parse(await res.object.content);\n\t\t\tif (\n\t\t\t\tEXPECTED_SERVER_VERSION < Number(ks.firstVersion) ||\n\t\t\t\tEXPECTED_SERVER_VERSION > Number(ks.lastVersion)\n\t\t\t) {\n\t\t\t\tthrow new InvalidKeyServerVersionError(\n\t\t\t\t\t`Key server ${objectId} supports versions between ${ks.firstVersion} and ${ks.lastVersion} (inclusive), but SDK expects version ${EXPECTED_SERVER_VERSION}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Then fetch the expected versioned object and parse it.\n\t\t\tconst resVersionedKs = await client.core.getDynamicField({\n\t\t\t\tparentId: objectId,\n\t\t\t\tname: {\n\t\t\t\t\ttype: 'u64',\n\t\t\t\t\tbcs: bcs.u64().serialize(EXPECTED_SERVER_VERSION).toBytes(),\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tconst ksVersioned = KeyServerMoveV1.parse(resVersionedKs.dynamicField.value.bcs);\n\n\t\t\tif (ksVersioned.keyType !== KeyServerType.BonehFranklinBLS12381) {\n\t\t\t\tthrow new InvalidKeyServerError(\n\t\t\t\t\t`Server ${objectId} has invalid key type: ${ksVersioned.keyType}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tobjectId,\n\t\t\t\tname: ksVersioned.name,\n\t\t\t\turl: ksVersioned.url,\n\t\t\t\tkeyType: ksVersioned.keyType,\n\t\t\t\tpk: new Uint8Array(ksVersioned.pk),\n\t\t\t};\n\t\t}),\n\t);\n}\n\n/**\n * Given a KeyServer, fetch the proof of possession (PoP) from the URL and verify it\n * against the pubkey. This should be used only rarely when the dapp uses a dynamic\n * set of key servers.\n *\n * @param server - The KeyServer to verify.\n * @returns - True if the key server is valid, false otherwise.\n */\nexport async function verifyKeyServer(\n\tserver: KeyServer,\n\ttimeout: number,\n\tapiKeyName?: string,\n\tapiKey?: string,\n): Promise<boolean> {\n\tconst requestId = crypto.randomUUID();\n\tconst response = await fetch(server.url! + '/v1/service?service_id=' + server.objectId, {\n\t\tmethod: 'GET',\n\t\theaders: {\n\t\t\t'Content-Type': 'application/json',\n\t\t\t'Request-Id': requestId,\n\t\t\t'Client-Sdk-Type': 'typescript',\n\t\t\t'Client-Sdk-Version': PACKAGE_VERSION,\n\t\t\t...(apiKeyName && apiKey ? { [apiKeyName]: apiKey } : {}),\n\t\t},\n\t\tsignal: AbortSignal.timeout(timeout),\n\t});\n\n\tawait SealAPIError.assertResponse(response, requestId);\n\tverifyKeyServerVersion(response);\n\tconst serviceResponse = await response.json();\n\n\tif (serviceResponse.service_id !== server.objectId) {\n\t\treturn false;\n\t}\n\tconst fullMsg = flatten([DST_POP, server.pk, fromHex(server.objectId)]);\n\treturn bls12_381.verifyShortSignature(fromBase64(serviceResponse.pop), fullMsg, server.pk);\n}\n\n/**\n * Verify the key server version. Throws an `InvalidKeyServerError` if the version is not supported.\n *\n * @param response - The response from the key server.\n */\nexport function verifyKeyServerVersion(response: Response) {\n\tconst keyServerVersion = response.headers.get('X-KeyServer-Version');\n\tif (keyServerVersion == null) {\n\t\tthrow new InvalidKeyServerVersionError('Key server version not found');\n\t}\n\tif (new Version(keyServerVersion).older_than(SERVER_VERSION_REQUIREMENT)) {\n\t\tthrow new InvalidKeyServerVersionError(\n\t\t\t`Key server version ${keyServerVersion} is not supported`,\n\t\t);\n\t}\n}\n\nexport interface DerivedKey {\n\ttoString(): string;\n}\n\n/**\n * A user secret key for the Boneh-Franklin BLS12381 scheme.\n * This is a wrapper around the G1Element type.\n */\nexport class BonehFranklinBLS12381DerivedKey implements DerivedKey {\n\trepresentation: string;\n\n\tconstructor(public key: G1Element) {\n\t\tthis.representation = toHex(key.toBytes());\n\t}\n\n\ttoString(): string {\n\t\treturn this.representation;\n\t}\n}\n\n/**\n * Options for fetching keys from the key server.\n */\nexport interface FetchKeysOptions {\n\t/** The URL of the key server. */\n\turl: string;\n\t/** The Base64 string of request signature. */\n\trequestSignature: string;\n\t/** The transaction bytes. */\n\ttransactionBytes: Uint8Array;\n\t/** The ephemeral secret key. */\n\tencKey: Uint8Array<ArrayBuffer>;\n\t/** The ephemeral public key. */\n\tencKeyPk: Uint8Array<ArrayBuffer>;\n\t/** The ephemeral verification key. */\n\tencVerificationKey: Uint8Array;\n\t/** The certificate. */\n\tcertificate: Certificate;\n\t/** Request timeout in milliseconds. */\n\ttimeout: number;\n\t/** Optional API key name. */\n\tapiKeyName?: string;\n\t/** Optional API key. */\n\tapiKey?: string;\n\t/** Optional abort signal for cancellation. */\n\tsignal?: AbortSignal;\n}\n\n/**\n * Helper function to request all keys from URL with requestSig, txBytes, ephemeral pubkey.\n * Then decrypt the Seal key with ephemeral secret key. Returns a list decryption keys with\n * their full IDs.\n *\n * @param url - The URL of the key server.\n * @param requestSig - The Base64 string of request signature.\n * @param txBytes - The transaction bytes.\n * @param encKey - The ephemeral secret key.\n * @param certificate - The certificate.\n * @returns - A list of full ID and the decrypted key.\n */\nexport async function fetchKeysForAllIds({\n\turl,\n\trequestSignature,\n\ttransactionBytes,\n\tencKey,\n\tencKeyPk,\n\tencVerificationKey,\n\tcertificate,\n\ttimeout,\n\tapiKeyName,\n\tapiKey,\n\tsignal,\n}: FetchKeysOptions): Promise<{ fullId: string; key: Uint8Array<ArrayBuffer> }[]> {\n\tconst body = {\n\t\tptb: toBase64(transactionBytes.slice(1)), // removes the byte of the transaction type version\n\t\tenc_key: toBase64(encKeyPk),\n\t\tenc_verification_key: toBase64(encVerificationKey),\n\t\trequest_signature: requestSignature, // already b64\n\t\tcertificate,\n\t};\n\n\tconst timeoutSignal = AbortSignal.timeout(timeout);\n\tconst combinedSignal = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;\n\n\tconst requestId = crypto.randomUUID();\n\tconst response = await fetch(url + '/v1/fetch_key', {\n\t\tmethod: 'POST',\n\t\theaders: {\n\t\t\t'Content-Type': 'application/json',\n\t\t\t'Request-Id': requestId,\n\t\t\t'Client-Sdk-Type': 'typescript',\n\t\t\t'Client-Sdk-Version': PACKAGE_VERSION,\n\t\t\t...(apiKeyName && apiKey ? { [apiKeyName]: apiKey } : {}),\n\t\t},\n\t\tbody: JSON.stringify(body),\n\t\tsignal: combinedSignal,\n\t});\n\tawait SealAPIError.assertResponse(response, requestId);\n\tconst resp = await response.json();\n\tverifyKeyServerVersion(response);\n\n\treturn resp.decryption_keys.map(\n\t\t(dk: { id: Uint8Array<ArrayBuffer>; encrypted_key: [string, string] }) => ({\n\t\t\tfullId: toHex(dk.id),\n\t\t\tkey: elgamalDecrypt(encKey, dk.encrypted_key.map(fromBase64) as [Uint8Array, Uint8Array]),\n\t\t}),\n\t);\n}\n"],
|
|
5
|
-
"mappings": "AAEA,SAAS,KAAK,YAAY,SAAS,UAAU,aAAa;AAC1D,SAAS,iBAAiB;AAE1B,SAAS,eAAe,uBAAuB;
|
|
6
|
-
"names": ["
|
|
4
|
+
"sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\nimport { bcs, fromBase64, fromHex, toBase64, toHex } from '@mysten/bcs';\nimport { bls12_381 } from '@noble/curves/bls12-381';\n\nimport { KeyServerMove, KeyServerMoveV1, KeyServerMoveV2 } from './bcs.js';\nimport {\n\tInvalidClientOptionsError,\n\tInvalidKeyServerError,\n\tInvalidKeyServerVersionError,\n\tSealAPIError,\n} from './error.js';\nimport { DST_POP } from './ibe.js';\nimport { PACKAGE_VERSION } from './version.js';\nimport type { KeyServerConfig, SealCompatibleClient } from './types.js';\nimport type { G1Element } from './bls12381.js';\nimport { flatten, Version } from './utils.js';\nimport { elgamalDecrypt } from './elgamal.js';\nimport type { Certificate } from './session-key.js';\n\nconst SUPPORTED_SERVER_VERSIONS = [2, 1]; // Must be configured in descending order.\n\nexport type ServerType = 'Independent' | 'Committee';\n\nexport type KeyServer = {\n\tobjectId: string;\n\tname: string;\n\turl: string;\n\tkeyType: KeyType;\n\tpk: Uint8Array<ArrayBuffer>;\n\tserverType: ServerType;\n};\n\nexport enum KeyType {\n\tBonehFranklinBLS12381 = 0,\n}\n\nexport const SERVER_VERSION_REQUIREMENT = new Version('0.4.1');\n\n/**\n * Given a list of key server object IDs, returns a list of SealKeyServer\n * from onchain state containing name, objectId, URL and pk.\n *\n * Supports both V1 (independent servers) and V2 (independent + committee servers).\n * For V2 committee servers, returns the aggregator URL from the config.\n *\n * @param objectIds - The key server object IDs.\n * @param client - The SuiClient to use.\n * @param configs - The key server configurations containing aggregator URLs.\n * @returns - An array of SealKeyServer.\n */\nexport async function retrieveKeyServers({\n\tobjectIds,\n\tclient,\n\tconfigs,\n}: {\n\tobjectIds: string[];\n\tclient: SealCompatibleClient;\n\tconfigs: Map<string, KeyServerConfig>;\n}): Promise<KeyServer[]> {\n\treturn await Promise.all(\n\t\tobjectIds.map(async (objectId) => {\n\t\t\t// First get the KeyServer object and validate it.\n\t\t\tconst res = await client.core.getObject({\n\t\t\t\tobjectId,\n\t\t\t});\n\t\t\tconst ks = KeyServerMove.parse(await res.object.content);\n\n\t\t\t// Find the highest supported version.\n\t\t\tconst firstVersion = Number(ks.firstVersion);\n\t\t\tconst lastVersion = Number(ks.lastVersion);\n\t\t\tconst version = SUPPORTED_SERVER_VERSIONS.find((v) => v >= firstVersion && v <= lastVersion);\n\n\t\t\tif (version === undefined) {\n\t\t\t\tthrow new InvalidKeyServerVersionError(\n\t\t\t\t\t`Key server ${objectId} supports versions between ${ks.firstVersion} and ${ks.lastVersion} (inclusive), but SDK expects one of ${SUPPORTED_SERVER_VERSIONS.join(', ')}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Fetch the versioned object.\n\t\t\tconst versionedKeyServer = await client.core.getDynamicField({\n\t\t\t\tparentId: objectId,\n\t\t\t\tname: {\n\t\t\t\t\ttype: 'u64',\n\t\t\t\t\tbcs: bcs.u64().serialize(version).toBytes(),\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// Parse based on version.\n\t\t\tswitch (version) {\n\t\t\t\tcase 2: {\n\t\t\t\t\tconst ksV2 = KeyServerMoveV2.parse(versionedKeyServer.dynamicField.value.bcs);\n\t\t\t\t\tif (ksV2.keyType !== KeyType.BonehFranklinBLS12381) {\n\t\t\t\t\t\tthrow new InvalidKeyServerError(\n\t\t\t\t\t\t\t`Server ${objectId} has invalid key type: ${ksV2.keyType}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Return based on server type.\n\t\t\t\t\tswitch (ksV2.serverType.$kind) {\n\t\t\t\t\t\tcase 'Independent': {\n\t\t\t\t\t\t\tif (configs.get(objectId)?.aggregatorUrl) {\n\t\t\t\t\t\t\t\tthrow new InvalidClientOptionsError(\n\t\t\t\t\t\t\t\t\t`Independent server ${objectId} should not have aggregatorUrl in config`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tobjectId,\n\t\t\t\t\t\t\t\tname: ksV2.name,\n\t\t\t\t\t\t\t\turl: ksV2.serverType.Independent.url,\n\t\t\t\t\t\t\t\tkeyType: ksV2.keyType,\n\t\t\t\t\t\t\t\tpk: new Uint8Array(ksV2.pk),\n\t\t\t\t\t\t\t\tserverType: 'Independent',\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'Committee': {\n\t\t\t\t\t\t\t// For committee mode, get aggregator URL from config\n\t\t\t\t\t\t\tconst config = configs.get(objectId);\n\t\t\t\t\t\t\tif (!config?.aggregatorUrl) {\n\t\t\t\t\t\t\t\tthrow new InvalidClientOptionsError(\n\t\t\t\t\t\t\t\t\t`Committee server ${objectId} requires aggregatorUrl in config`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tobjectId,\n\t\t\t\t\t\t\t\tname: ksV2.name,\n\t\t\t\t\t\t\t\turl: config.aggregatorUrl,\n\t\t\t\t\t\t\t\tkeyType: ksV2.keyType,\n\t\t\t\t\t\t\t\tpk: new Uint8Array(ksV2.pk),\n\t\t\t\t\t\t\t\tserverType: 'Committee',\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthrow new InvalidKeyServerError(`Unknown server type for ${objectId}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcase 1: {\n\t\t\t\t\tconst ksV1 = KeyServerMoveV1.parse(versionedKeyServer.dynamicField.value.bcs);\n\t\t\t\t\tif (ksV1.keyType !== KeyType.BonehFranklinBLS12381) {\n\t\t\t\t\t\tthrow new InvalidKeyServerError(\n\t\t\t\t\t\t\t`Server ${objectId} has invalid key type: ${ksV1.keyType}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\t// V1 servers are always Independent and should not have aggregatorUrl\n\t\t\t\t\tif (configs.get(objectId)?.aggregatorUrl) {\n\t\t\t\t\t\tthrow new InvalidClientOptionsError(\n\t\t\t\t\t\t\t`V1 server ${objectId} is always Independent and should not have aggregatorUrl in config`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tobjectId,\n\t\t\t\t\t\tname: ksV1.name,\n\t\t\t\t\t\turl: ksV1.url,\n\t\t\t\t\t\tkeyType: ksV1.keyType,\n\t\t\t\t\t\tpk: new Uint8Array(ksV1.pk),\n\t\t\t\t\t\tserverType: 'Independent',\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new InvalidKeyServerVersionError(`Unsupported key server version: ${version}`);\n\t\t\t}\n\t\t}),\n\t);\n}\n\n/**\n * Given a KeyServer, fetch the proof of possession (PoP) from the URL and verify it\n * against the pubkey. This should be used only rarely when the dapp uses a dynamic\n * set of key servers.\n *\n * @param server - The KeyServer to verify.\n * @returns - True if the key server is valid, false otherwise.\n */\nexport async function verifyKeyServer(\n\tserver: KeyServer,\n\ttimeout: number,\n\tapiKeyName?: string,\n\tapiKey?: string,\n): Promise<boolean> {\n\tconst requestId = crypto.randomUUID();\n\tconst response = await fetch(server.url! + '/v1/service?service_id=' + server.objectId, {\n\t\tmethod: 'GET',\n\t\theaders: {\n\t\t\t'Content-Type': 'application/json',\n\t\t\t'Request-Id': requestId,\n\t\t\t'Client-Sdk-Type': 'typescript',\n\t\t\t'Client-Sdk-Version': PACKAGE_VERSION,\n\t\t\t...(apiKeyName && apiKey ? { [apiKeyName]: apiKey } : {}),\n\t\t},\n\t\tsignal: AbortSignal.timeout(timeout),\n\t});\n\n\tawait SealAPIError.assertResponse(response, requestId);\n\tverifyKeyServerVersion(response);\n\tconst serviceResponse = await response.json();\n\n\tif (serviceResponse.service_id !== server.objectId) {\n\t\treturn false;\n\t}\n\tconst fullMsg = flatten([DST_POP, server.pk, fromHex(server.objectId)]);\n\treturn bls12_381.verifyShortSignature(fromBase64(serviceResponse.pop), fullMsg, server.pk);\n}\n\n/**\n * Verify the key server version. Throws an `InvalidKeyServerError` if the version is not supported.\n *\n * @param response - The response from the key server.\n */\nexport function verifyKeyServerVersion(response: Response) {\n\tconst keyServerVersion = response.headers.get('X-KeyServer-Version');\n\tif (keyServerVersion == null) {\n\t\tthrow new InvalidKeyServerVersionError('Key server version not found');\n\t}\n\tif (new Version(keyServerVersion).older_than(SERVER_VERSION_REQUIREMENT)) {\n\t\tthrow new InvalidKeyServerVersionError(\n\t\t\t`Key server version ${keyServerVersion} is not supported`,\n\t\t);\n\t}\n}\n\nexport interface DerivedKey {\n\ttoString(): string;\n}\n\n/**\n * A user secret key for the Boneh-Franklin BLS12381 scheme.\n * This is a wrapper around the G1Element type.\n */\nexport class BonehFranklinBLS12381DerivedKey implements DerivedKey {\n\trepresentation: string;\n\n\tconstructor(public key: G1Element) {\n\t\tthis.representation = toHex(key.toBytes());\n\t}\n\n\ttoString(): string {\n\t\treturn this.representation;\n\t}\n}\n\n/**\n * Options for fetching keys from the key server.\n */\nexport interface FetchKeysOptions {\n\t/** The URL of the key server. */\n\turl: string;\n\t/** The Base64 string of request signature. */\n\trequestSignature: string;\n\t/** The transaction bytes. */\n\ttransactionBytes: Uint8Array;\n\t/** The ephemeral secret key. */\n\tencKey: Uint8Array<ArrayBuffer>;\n\t/** The ephemeral public key. */\n\tencKeyPk: Uint8Array<ArrayBuffer>;\n\t/** The ephemeral verification key. */\n\tencVerificationKey: Uint8Array;\n\t/** The certificate. */\n\tcertificate: Certificate;\n\t/** Request timeout in milliseconds. */\n\ttimeout: number;\n\t/** Optional API key name. */\n\tapiKeyName?: string;\n\t/** Optional API key. */\n\tapiKey?: string;\n\t/** Optional abort signal for cancellation. */\n\tsignal?: AbortSignal;\n}\n\n/**\n * Helper function to request all keys from URL with requestSig, txBytes, ephemeral pubkey.\n * Then decrypt the Seal key with ephemeral secret key. Returns a list decryption keys with\n * their full IDs.\n *\n * @param url - The URL of the key server.\n * @param requestSig - The Base64 string of request signature.\n * @param txBytes - The transaction bytes.\n * @param encKey - The ephemeral secret key.\n * @param certificate - The certificate.\n * @returns - A list of full ID and the decrypted key.\n */\nexport async function fetchKeysForAllIds({\n\turl,\n\trequestSignature,\n\ttransactionBytes,\n\tencKey,\n\tencKeyPk,\n\tencVerificationKey,\n\tcertificate,\n\ttimeout,\n\tapiKeyName,\n\tapiKey,\n\tsignal,\n}: FetchKeysOptions): Promise<{ fullId: string; key: Uint8Array<ArrayBuffer> }[]> {\n\tconst body = {\n\t\tptb: toBase64(transactionBytes.slice(1)), // removes the byte of the transaction type version\n\t\tenc_key: toBase64(encKeyPk),\n\t\tenc_verification_key: toBase64(encVerificationKey),\n\t\trequest_signature: requestSignature, // already b64\n\t\tcertificate,\n\t};\n\n\tconst timeoutSignal = AbortSignal.timeout(timeout);\n\tconst combinedSignal = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;\n\n\tconst requestId = crypto.randomUUID();\n\tconst response = await fetch(url + '/v1/fetch_key', {\n\t\tmethod: 'POST',\n\t\theaders: {\n\t\t\t'Content-Type': 'application/json',\n\t\t\t'Request-Id': requestId,\n\t\t\t'Client-Sdk-Type': 'typescript',\n\t\t\t'Client-Sdk-Version': PACKAGE_VERSION,\n\t\t\t...(apiKeyName && apiKey ? { [apiKeyName]: apiKey } : {}),\n\t\t},\n\t\tbody: JSON.stringify(body),\n\t\tsignal: combinedSignal,\n\t});\n\tawait SealAPIError.assertResponse(response, requestId);\n\tconst resp = await response.json();\n\tverifyKeyServerVersion(response);\n\n\treturn resp.decryption_keys.map(\n\t\t(dk: { id: Uint8Array<ArrayBuffer>; encrypted_key: [string, string] }) => ({\n\t\t\tfullId: toHex(dk.id),\n\t\t\tkey: elgamalDecrypt(encKey, dk.encrypted_key.map(fromBase64) as [Uint8Array, Uint8Array]),\n\t\t}),\n\t);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["KeyType"]
|
|
7
7
|
}
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -28,6 +28,9 @@ export interface KeyServerConfig {
|
|
|
28
28
|
weight: number;
|
|
29
29
|
apiKeyName?: string;
|
|
30
30
|
apiKey?: string;
|
|
31
|
+
/** Must be provided if object ID is for a committee mode server since all fetch key calls go
|
|
32
|
+
* through an aggregator. */
|
|
33
|
+
aggregatorUrl?: string;
|
|
31
34
|
}
|
|
32
35
|
export interface SealClientOptions extends SealClientExtensionOptions {
|
|
33
36
|
suiClient: SealCompatibleClient;
|
package/dist/esm/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const PACKAGE_VERSION = "0.
|
|
1
|
+
export declare const PACKAGE_VERSION = "0.10.0";
|
package/dist/esm/version.js
CHANGED
package/dist/esm/version.js.map
CHANGED
|
@@ -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.
|
|
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.10.0';\n"],
|
|
5
5
|
"mappings": "AAKO,MAAM,kBAAkB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|