@mysten/seal 0.4.0 → 0.4.2
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 +19 -0
- package/dist/cjs/error.d.ts +9 -1
- package/dist/cjs/error.js +26 -6
- package/dist/cjs/error.js.map +2 -2
- package/dist/cjs/key-server.d.ts +8 -0
- package/dist/cjs/key-server.js +17 -1
- package/dist/cjs/key-server.js.map +2 -2
- package/dist/cjs/keys.js +2 -0
- package/dist/cjs/keys.js.map +2 -2
- package/dist/cjs/session-key.d.ts +19 -0
- package/dist/cjs/session-key.js +48 -2
- package/dist/cjs/session-key.js.map +2 -2
- package/dist/cjs/utils.d.ts +10 -0
- package/dist/cjs/utils.js +21 -0
- package/dist/cjs/utils.js.map +2 -2
- 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/error.d.ts +9 -1
- package/dist/esm/error.js +26 -6
- package/dist/esm/error.js.map +2 -2
- package/dist/esm/key-server.d.ts +8 -0
- package/dist/esm/key-server.js +18 -1
- package/dist/esm/key-server.js.map +2 -2
- package/dist/esm/keys.js +2 -0
- package/dist/esm/keys.js.map +2 -2
- package/dist/esm/session-key.d.ts +19 -0
- package/dist/esm/session-key.js +48 -2
- package/dist/esm/session-key.js.map +2 -2
- package/dist/esm/utils.d.ts +10 -0
- package/dist/esm/utils.js +21 -0
- package/dist/esm/utils.js.map +2 -2
- 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 +3 -3
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
|
-
|
|
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 (
|
|
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,
|
package/dist/esm/error.js.map
CHANGED
|
@@ -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 (
|
|
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,
|
|
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": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/esm/key-server.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
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.
|
|
@@ -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;
|
package/dist/esm/key-server.js
CHANGED
|
@@ -3,16 +3,19 @@ import { bls12_381 } from "@noble/curves/bls12-381";
|
|
|
3
3
|
import { KeyServerMove } from "./bcs.js";
|
|
4
4
|
import {
|
|
5
5
|
InvalidGetObjectError,
|
|
6
|
+
InvalidKeyServerVersionError,
|
|
6
7
|
SealAPIError,
|
|
7
8
|
UnsupportedFeatureError,
|
|
8
9
|
UnsupportedNetworkError
|
|
9
10
|
} from "./error.js";
|
|
10
11
|
import { DST_POP } from "./ibe.js";
|
|
11
12
|
import { PACKAGE_VERSION } from "./version.js";
|
|
13
|
+
import { Version } from "./utils.js";
|
|
12
14
|
var KeyServerType = /* @__PURE__ */ ((KeyServerType2) => {
|
|
13
15
|
KeyServerType2[KeyServerType2["BonehFranklinBLS12381"] = 0] = "BonehFranklinBLS12381";
|
|
14
16
|
return KeyServerType2;
|
|
15
17
|
})(KeyServerType || {});
|
|
18
|
+
const SERVER_VERSION_REQUIREMENT = new Version("0.2.0");
|
|
16
19
|
function getAllowlistedKeyServers(network) {
|
|
17
20
|
if (network === "testnet") {
|
|
18
21
|
return [
|
|
@@ -64,6 +67,7 @@ async function verifyKeyServer(server, timeout) {
|
|
|
64
67
|
signal: AbortSignal.timeout(timeout)
|
|
65
68
|
});
|
|
66
69
|
await SealAPIError.assertResponse(response, requestId);
|
|
70
|
+
verifyKeyServerVersion(response);
|
|
67
71
|
const serviceResponse = await response.json();
|
|
68
72
|
if (serviceResponse.service_id !== server.objectId) {
|
|
69
73
|
return false;
|
|
@@ -71,10 +75,23 @@ async function verifyKeyServer(server, timeout) {
|
|
|
71
75
|
const fullMsg = new Uint8Array([...DST_POP, ...server.pk, ...fromHex(server.objectId)]);
|
|
72
76
|
return bls12_381.verifyShortSignature(fromBase64(serviceResponse.pop), fullMsg, server.pk);
|
|
73
77
|
}
|
|
78
|
+
function verifyKeyServerVersion(response) {
|
|
79
|
+
const keyServerVersion = response.headers.get("X-KeyServer-Version");
|
|
80
|
+
if (keyServerVersion == null) {
|
|
81
|
+
throw new InvalidKeyServerVersionError("Key server version not found");
|
|
82
|
+
}
|
|
83
|
+
if (new Version(keyServerVersion).older_than(SERVER_VERSION_REQUIREMENT)) {
|
|
84
|
+
throw new InvalidKeyServerVersionError(
|
|
85
|
+
`Key server version ${keyServerVersion} is not supported`
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
74
89
|
export {
|
|
75
90
|
KeyServerType,
|
|
91
|
+
SERVER_VERSION_REQUIREMENT,
|
|
76
92
|
getAllowlistedKeyServers,
|
|
77
93
|
retrieveKeyServers,
|
|
78
|
-
verifyKeyServer
|
|
94
|
+
verifyKeyServer,
|
|
95
|
+
verifyKeyServerVersion
|
|
79
96
|
};
|
|
80
97
|
//# sourceMappingURL=key-server.js.map
|
|
@@ -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 { fromBase64, fromHex } from '@mysten/bcs';\nimport { bls12_381 } from '@noble/curves/bls12-381';\n\nimport { KeyServerMove } from './bcs.js';\nimport {\n\tInvalidGetObjectError,\n\tSealAPIError,\n\tUnsupportedFeatureError,\n\tUnsupportedNetworkError,\n} from './error.js';\nimport { DST_POP } from './ibe.js';\nimport { PACKAGE_VERSION } from './version.js';\nimport type { SealCompatibleClient } from './types.js';\n\nexport type KeyServer = {\n\tobjectId: string;\n\tname: string;\n\turl: string;\n\tkeyType: KeyServerType;\n\tpk: Uint8Array;\n};\n\nexport enum KeyServerType {\n\tBonehFranklinBLS12381 = 0,\n}\n\n/**\n * Returns a static list of Seal key server object ids that the dapp can choose to use.\n * @param network - The network to use.\n * @returns The object id's of the key servers.\n */\nexport function getAllowlistedKeyServers(network: 'testnet' | 'mainnet'): string[] {\n\tif (network === 'testnet') {\n\t\treturn [\n\t\t\t'0xb35a7228d8cf224ad1e828c0217c95a5153bafc2906d6f9c178197dce26fbcf8',\n\t\t\t'0x2d6cde8a9d9a65bde3b0a346566945a63b4bfb70e9a06c41bdb70807e2502b06',\n\t\t];\n\t} else {\n\t\tthrow new UnsupportedNetworkError(`Unsupported network ${network}`);\n\t}\n}\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\t// todo: do not fetch the same object ID if this is fetched before.\n\treturn await Promise.all(\n\t\tobjectIds.map(async (objectId) => {\n\t\t\tlet res;\n\t\t\ttry {\n\t\t\t\tres = await client.core.getObject({\n\t\t\t\t\tobjectId,\n\t\t\t\t});\n\t\t\t} catch (e) {\n\t\t\t\tthrow new InvalidGetObjectError(`KeyServer ${objectId} not found; ${(e as Error).message}`);\n\t\t\t}\n\n\t\t\tconst ks = KeyServerMove.parse(res.object.content);\n\t\t\tif (ks.keyType !== 0) {\n\t\t\t\tthrow new UnsupportedFeatureError(`Unsupported key type ${ks.keyType}`);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tobjectId,\n\t\t\t\tname: ks.name,\n\t\t\t\turl: ks.url,\n\t\t\t\tkeyType: KeyServerType.BonehFranklinBLS12381,\n\t\t\t\tpk: new Uint8Array(ks.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(server: KeyServer, timeout: number): Promise<boolean> {\n\tconst requestId = crypto.randomUUID();\n\tconst response = await fetch(server.url! + '/v1/service', {\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},\n\t\tsignal: AbortSignal.timeout(timeout),\n\t});\n\n\tawait SealAPIError.assertResponse(response, requestId);\n\tconst serviceResponse = await response.json();\n\n\tif (serviceResponse.service_id !== server.objectId) {\n\t\treturn false;\n\t}\n\tconst fullMsg = new Uint8Array([...DST_POP, ...server.pk, ...fromHex(server.objectId)]);\n\treturn bls12_381.verifyShortSignature(fromBase64(serviceResponse.pop), fullMsg, server.pk);\n}\n"],
|
|
5
|
-
"mappings": "AAEA,SAAS,YAAY,eAAe;AACpC,SAAS,iBAAiB;AAE1B,SAAS,qBAAqB;AAC9B;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,eAAe;AACxB,SAAS,uBAAuB;
|
|
4
|
+
"sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\nimport { fromBase64, fromHex } from '@mysten/bcs';\nimport { bls12_381 } from '@noble/curves/bls12-381';\n\nimport { KeyServerMove } from './bcs.js';\nimport {\n\tInvalidGetObjectError,\n\tInvalidKeyServerVersionError,\n\tSealAPIError,\n\tUnsupportedFeatureError,\n\tUnsupportedNetworkError,\n} from './error.js';\nimport { DST_POP } from './ibe.js';\nimport { PACKAGE_VERSION } from './version.js';\nimport type { SealCompatibleClient } from './types.js';\nimport { Version } from './utils.js';\n\nexport type KeyServer = {\n\tobjectId: string;\n\tname: string;\n\turl: string;\n\tkeyType: KeyServerType;\n\tpk: Uint8Array;\n};\n\nexport enum KeyServerType {\n\tBonehFranklinBLS12381 = 0,\n}\n\nexport const SERVER_VERSION_REQUIREMENT = new Version('0.2.0');\n\n/**\n * Returns a static list of Seal key server object ids that the dapp can choose to use.\n * @param network - The network to use.\n * @returns The object id's of the key servers.\n */\nexport function getAllowlistedKeyServers(network: 'testnet' | 'mainnet'): string[] {\n\tif (network === 'testnet') {\n\t\treturn [\n\t\t\t'0xb35a7228d8cf224ad1e828c0217c95a5153bafc2906d6f9c178197dce26fbcf8',\n\t\t\t'0x2d6cde8a9d9a65bde3b0a346566945a63b4bfb70e9a06c41bdb70807e2502b06',\n\t\t];\n\t} else {\n\t\tthrow new UnsupportedNetworkError(`Unsupported network ${network}`);\n\t}\n}\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\t// todo: do not fetch the same object ID if this is fetched before.\n\treturn await Promise.all(\n\t\tobjectIds.map(async (objectId) => {\n\t\t\tlet res;\n\t\t\ttry {\n\t\t\t\tres = await client.core.getObject({\n\t\t\t\t\tobjectId,\n\t\t\t\t});\n\t\t\t} catch (e) {\n\t\t\t\tthrow new InvalidGetObjectError(`KeyServer ${objectId} not found; ${(e as Error).message}`);\n\t\t\t}\n\n\t\t\tconst ks = KeyServerMove.parse(res.object.content);\n\t\t\tif (ks.keyType !== 0) {\n\t\t\t\tthrow new UnsupportedFeatureError(`Unsupported key type ${ks.keyType}`);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tobjectId,\n\t\t\t\tname: ks.name,\n\t\t\t\turl: ks.url,\n\t\t\t\tkeyType: KeyServerType.BonehFranklinBLS12381,\n\t\t\t\tpk: new Uint8Array(ks.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(server: KeyServer, timeout: number): Promise<boolean> {\n\tconst requestId = crypto.randomUUID();\n\tconst response = await fetch(server.url! + '/v1/service', {\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},\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 = new Uint8Array([...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"],
|
|
5
|
+
"mappings": "AAEA,SAAS,YAAY,eAAe;AACpC,SAAS,iBAAiB;AAE1B,SAAS,qBAAqB;AAC9B;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,eAAe;AACxB,SAAS,uBAAuB;AAEhC,SAAS,eAAe;AAUjB,IAAK,gBAAL,kBAAKA,mBAAL;AACN,EAAAA,8BAAA,2BAAwB,KAAxB;AADW,SAAAA;AAAA,GAAA;AAIL,MAAM,6BAA6B,IAAI,QAAQ,OAAO;AAOtD,SAAS,yBAAyB,SAA0C;AAClF,MAAI,YAAY,WAAW;AAC1B,WAAO;AAAA,MACN;AAAA,MACA;AAAA,IACD;AAAA,EACD,OAAO;AACN,UAAM,IAAI,wBAAwB,uBAAuB,OAAO,EAAE;AAAA,EACnE;AACD;AAUA,eAAsB,mBAAmB;AAAA,EACxC;AAAA,EACA;AACD,GAGyB;AAExB,SAAO,MAAM,QAAQ;AAAA,IACpB,UAAU,IAAI,OAAO,aAAa;AACjC,UAAI;AACJ,UAAI;AACH,cAAM,MAAM,OAAO,KAAK,UAAU;AAAA,UACjC;AAAA,QACD,CAAC;AAAA,MACF,SAAS,GAAG;AACX,cAAM,IAAI,sBAAsB,aAAa,QAAQ,eAAgB,EAAY,OAAO,EAAE;AAAA,MAC3F;AAEA,YAAM,KAAK,cAAc,MAAM,IAAI,OAAO,OAAO;AACjD,UAAI,GAAG,YAAY,GAAG;AACrB,cAAM,IAAI,wBAAwB,wBAAwB,GAAG,OAAO,EAAE;AAAA,MACvE;AAEA,aAAO;AAAA,QACN;AAAA,QACA,MAAM,GAAG;AAAA,QACT,KAAK,GAAG;AAAA,QACR,SAAS;AAAA,QACT,IAAI,IAAI,WAAW,GAAG,EAAE;AAAA,MACzB;AAAA,IACD,CAAC;AAAA,EACF;AACD;AAUA,eAAsB,gBAAgB,QAAmB,SAAmC;AAC3F,QAAM,YAAY,OAAO,WAAW;AACpC,QAAM,WAAW,MAAM,MAAM,OAAO,MAAO,eAAe;AAAA,IACzD,QAAQ;AAAA,IACR,SAAS;AAAA,MACR,gBAAgB;AAAA,MAChB,cAAc;AAAA,MACd,mBAAmB;AAAA,MACnB,sBAAsB;AAAA,IACvB;AAAA,IACA,QAAQ,YAAY,QAAQ,OAAO;AAAA,EACpC,CAAC;AAED,QAAM,aAAa,eAAe,UAAU,SAAS;AACrD,yBAAuB,QAAQ;AAC/B,QAAM,kBAAkB,MAAM,SAAS,KAAK;AAE5C,MAAI,gBAAgB,eAAe,OAAO,UAAU;AACnD,WAAO;AAAA,EACR;AACA,QAAM,UAAU,IAAI,WAAW,CAAC,GAAG,SAAS,GAAG,OAAO,IAAI,GAAG,QAAQ,OAAO,QAAQ,CAAC,CAAC;AACtF,SAAO,UAAU,qBAAqB,WAAW,gBAAgB,GAAG,GAAG,SAAS,OAAO,EAAE;AAC1F;AAOO,SAAS,uBAAuB,UAAoB;AAC1D,QAAM,mBAAmB,SAAS,QAAQ,IAAI,qBAAqB;AACnE,MAAI,oBAAoB,MAAM;AAC7B,UAAM,IAAI,6BAA6B,8BAA8B;AAAA,EACtE;AACA,MAAI,IAAI,QAAQ,gBAAgB,EAAE,WAAW,0BAA0B,GAAG;AACzE,UAAM,IAAI;AAAA,MACT,sBAAsB,gBAAgB;AAAA,IACvC;AAAA,EACD;AACD;",
|
|
6
6
|
"names": ["KeyServerType"]
|
|
7
7
|
}
|
package/dist/esm/keys.js
CHANGED
|
@@ -2,6 +2,7 @@ import { fromBase64, toBase64, toHex } from "@mysten/bcs";
|
|
|
2
2
|
import { elgamalDecrypt, toPublicKey, toVerificationKey } from "./elgamal.js";
|
|
3
3
|
import { SealAPIError } from "./error.js";
|
|
4
4
|
import { PACKAGE_VERSION } from "./version.js";
|
|
5
|
+
import { verifyKeyServerVersion } from "./key-server.js";
|
|
5
6
|
async function fetchKeysForAllIds(url, requestSig, txBytes, encKey, certificate, timeout, signal) {
|
|
6
7
|
const encKeyPk = toPublicKey(encKey);
|
|
7
8
|
const encVerificationKey = toVerificationKey(encKey);
|
|
@@ -30,6 +31,7 @@ async function fetchKeysForAllIds(url, requestSig, txBytes, encKey, certificate,
|
|
|
30
31
|
});
|
|
31
32
|
await SealAPIError.assertResponse(response, requestId);
|
|
32
33
|
const resp = await response.json();
|
|
34
|
+
verifyKeyServerVersion(response);
|
|
33
35
|
return resp.decryption_keys.map((dk) => ({
|
|
34
36
|
fullId: toHex(new Uint8Array(dk.id)),
|
|
35
37
|
key: elgamalDecrypt(encKey, dk.encrypted_key.map(fromBase64))
|
package/dist/esm/keys.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/keys.ts"],
|
|
4
|
-
"sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { fromBase64, toBase64, toHex } from '@mysten/bcs';\n\nimport { elgamalDecrypt, toPublicKey, toVerificationKey } from './elgamal.js';\nimport { SealAPIError } from './error.js';\nimport type { Certificate } from './session-key.js';\nimport { PACKAGE_VERSION } from './version.js';\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: string,\n\trequestSig: string,\n\ttxBytes: Uint8Array,\n\tencKey: Uint8Array,\n\tcertificate: Certificate,\n\ttimeout: number,\n\tsignal?: AbortSignal,\n): Promise<{ fullId: string; key: Uint8Array }[]> {\n\tconst encKeyPk = toPublicKey(encKey);\n\tconst encVerificationKey = toVerificationKey(encKey);\n\tconst body = {\n\t\tptb: toBase64(txBytes.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: requestSig, // 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},\n\t\tbody: JSON.stringify(body),\n\t\tsignal: combinedSignal,\n\t});\n\tawait SealAPIError.assertResponse(response, requestId);\n\
|
|
5
|
-
"mappings": "AAGA,SAAS,YAAY,UAAU,aAAa;AAE5C,SAAS,gBAAgB,aAAa,yBAAyB;AAC/D,SAAS,oBAAoB;AAE7B,SAAS,uBAAuB;
|
|
4
|
+
"sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { fromBase64, toBase64, toHex } from '@mysten/bcs';\n\nimport { elgamalDecrypt, toPublicKey, toVerificationKey } from './elgamal.js';\nimport { SealAPIError } from './error.js';\nimport type { Certificate } from './session-key.js';\nimport { PACKAGE_VERSION } from './version.js';\nimport { verifyKeyServerVersion } from './key-server.js';\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: string,\n\trequestSig: string,\n\ttxBytes: Uint8Array,\n\tencKey: Uint8Array,\n\tcertificate: Certificate,\n\ttimeout: number,\n\tsignal?: AbortSignal,\n): Promise<{ fullId: string; key: Uint8Array }[]> {\n\tconst encKeyPk = toPublicKey(encKey);\n\tconst encVerificationKey = toVerificationKey(encKey);\n\tconst body = {\n\t\tptb: toBase64(txBytes.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: requestSig, // 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},\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((dk: { id: Uint8Array; encrypted_key: [string, string] }) => ({\n\t\tfullId: toHex(new Uint8Array(dk.id)),\n\t\tkey: elgamalDecrypt(encKey, dk.encrypted_key.map(fromBase64) as [Uint8Array, Uint8Array]),\n\t}));\n}\n"],
|
|
5
|
+
"mappings": "AAGA,SAAS,YAAY,UAAU,aAAa;AAE5C,SAAS,gBAAgB,aAAa,yBAAyB;AAC/D,SAAS,oBAAoB;AAE7B,SAAS,uBAAuB;AAChC,SAAS,8BAA8B;AAcvC,eAAsB,mBACrB,KACA,YACA,SACA,QACA,aACA,SACA,QACiD;AACjD,QAAM,WAAW,YAAY,MAAM;AACnC,QAAM,qBAAqB,kBAAkB,MAAM;AACnD,QAAM,OAAO;AAAA,IACZ,KAAK,SAAS,QAAQ,MAAM,CAAC,CAAC;AAAA;AAAA,IAC9B,SAAS,SAAS,QAAQ;AAAA,IAC1B,sBAAsB,SAAS,kBAAkB;AAAA,IACjD,mBAAmB;AAAA;AAAA,IACnB;AAAA,EACD;AAEA,QAAM,gBAAgB,YAAY,QAAQ,OAAO;AACjD,QAAM,iBAAiB,SAAS,YAAY,IAAI,CAAC,QAAQ,aAAa,CAAC,IAAI;AAE3E,QAAM,YAAY,OAAO,WAAW;AACpC,QAAM,WAAW,MAAM,MAAM,MAAM,iBAAiB;AAAA,IACnD,QAAQ;AAAA,IACR,SAAS;AAAA,MACR,gBAAgB;AAAA,MAChB,cAAc;AAAA,MACd,mBAAmB;AAAA,MACnB,sBAAsB;AAAA,IACvB;AAAA,IACA,MAAM,KAAK,UAAU,IAAI;AAAA,IACzB,QAAQ;AAAA,EACT,CAAC;AACD,QAAM,aAAa,eAAe,UAAU,SAAS;AACrD,QAAM,OAAO,MAAM,SAAS,KAAK;AACjC,yBAAuB,QAAQ;AAE/B,SAAO,KAAK,gBAAgB,IAAI,CAAC,QAA6D;AAAA,IAC7F,QAAQ,MAAM,IAAI,WAAW,GAAG,EAAE,CAAC;AAAA,IACnC,KAAK,eAAe,QAAQ,GAAG,cAAc,IAAI,UAAU,CAA6B;AAAA,EACzF,EAAE;AACH;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -21,6 +21,14 @@ export type Certificate = {
|
|
|
21
21
|
ttl_min: number;
|
|
22
22
|
signature: string;
|
|
23
23
|
};
|
|
24
|
+
export type SessionKeyType = {
|
|
25
|
+
address: string;
|
|
26
|
+
packageId: string;
|
|
27
|
+
creationTimeMs: number;
|
|
28
|
+
ttlMin: number;
|
|
29
|
+
personalMessageSignature?: string;
|
|
30
|
+
sessionKey: string;
|
|
31
|
+
};
|
|
24
32
|
export declare class SessionKey {
|
|
25
33
|
#private;
|
|
26
34
|
constructor({ address, packageId, ttlMin, signer, }: {
|
|
@@ -39,4 +47,15 @@ export declare class SessionKey {
|
|
|
39
47
|
decryptionKey: Uint8Array;
|
|
40
48
|
requestSignature: string;
|
|
41
49
|
}>;
|
|
50
|
+
/**
|
|
51
|
+
* Export the Session Key object from the instance. Store the object in IndexedDB to persist.
|
|
52
|
+
*/
|
|
53
|
+
export(): SessionKeyType;
|
|
54
|
+
/**
|
|
55
|
+
* Restore a SessionKey instance for the given object.
|
|
56
|
+
* @returns A new SessionKey instance with restored state
|
|
57
|
+
*/
|
|
58
|
+
static import(data: SessionKeyType, { signer }: {
|
|
59
|
+
signer?: Signer;
|
|
60
|
+
}): Promise<SessionKey>;
|
|
42
61
|
}
|
package/dist/esm/session-key.js
CHANGED
|
@@ -23,7 +23,7 @@ const RequestFormat = bcs.struct("RequestFormat", {
|
|
|
23
23
|
encKey: bcs.vector(bcs.U8),
|
|
24
24
|
encVerificationKey: bcs.vector(bcs.U8)
|
|
25
25
|
});
|
|
26
|
-
class
|
|
26
|
+
const _SessionKey = class _SessionKey {
|
|
27
27
|
constructor({
|
|
28
28
|
address,
|
|
29
29
|
packageId,
|
|
@@ -43,6 +43,9 @@ class SessionKey {
|
|
|
43
43
|
if (ttlMin > 30 || ttlMin < 1) {
|
|
44
44
|
throw new UserError(`Invalid TTL ${ttlMin}, must be between 1 and 30`);
|
|
45
45
|
}
|
|
46
|
+
if (signer && signer.getPublicKey().toSuiAddress() !== address) {
|
|
47
|
+
throw new UserError("Signer address does not match session key address");
|
|
48
|
+
}
|
|
46
49
|
__privateSet(this, _address, address);
|
|
47
50
|
__privateSet(this, _packageId, packageId);
|
|
48
51
|
__privateSet(this, _creationTimeMs, Date.now());
|
|
@@ -109,7 +112,49 @@ class SessionKey {
|
|
|
109
112
|
requestSignature: toBase64(await __privateGet(this, _sessionKey).sign(msgToSign))
|
|
110
113
|
};
|
|
111
114
|
}
|
|
112
|
-
|
|
115
|
+
/**
|
|
116
|
+
* Export the Session Key object from the instance. Store the object in IndexedDB to persist.
|
|
117
|
+
*/
|
|
118
|
+
export() {
|
|
119
|
+
const obj = {
|
|
120
|
+
address: __privateGet(this, _address),
|
|
121
|
+
packageId: __privateGet(this, _packageId),
|
|
122
|
+
creationTimeMs: __privateGet(this, _creationTimeMs),
|
|
123
|
+
ttlMin: __privateGet(this, _ttlMin),
|
|
124
|
+
personalMessageSignature: __privateGet(this, _personalMessageSignature),
|
|
125
|
+
sessionKey: __privateGet(this, _sessionKey).getSecretKey()
|
|
126
|
+
// bech32 encoded string
|
|
127
|
+
};
|
|
128
|
+
Object.defineProperty(obj, "toJSON", {
|
|
129
|
+
enumerable: false,
|
|
130
|
+
value: () => {
|
|
131
|
+
throw new Error("This object is not serializable");
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
return obj;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Restore a SessionKey instance for the given object.
|
|
138
|
+
* @returns A new SessionKey instance with restored state
|
|
139
|
+
*/
|
|
140
|
+
static async import(data, { signer }) {
|
|
141
|
+
const instance = new _SessionKey({
|
|
142
|
+
address: data.address,
|
|
143
|
+
packageId: data.packageId,
|
|
144
|
+
ttlMin: data.ttlMin,
|
|
145
|
+
signer
|
|
146
|
+
});
|
|
147
|
+
__privateSet(instance, _creationTimeMs, data.creationTimeMs);
|
|
148
|
+
__privateSet(instance, _sessionKey, Ed25519Keypair.fromSecretKey(data.sessionKey));
|
|
149
|
+
if (data.personalMessageSignature) {
|
|
150
|
+
await instance.setPersonalMessageSignature(data.personalMessageSignature);
|
|
151
|
+
}
|
|
152
|
+
if (instance.isExpired()) {
|
|
153
|
+
throw new ExpiredSessionKeyError();
|
|
154
|
+
}
|
|
155
|
+
return instance;
|
|
156
|
+
}
|
|
157
|
+
};
|
|
113
158
|
_address = new WeakMap();
|
|
114
159
|
_packageId = new WeakMap();
|
|
115
160
|
_creationTimeMs = new WeakMap();
|
|
@@ -117,6 +162,7 @@ _ttlMin = new WeakMap();
|
|
|
117
162
|
_sessionKey = new WeakMap();
|
|
118
163
|
_personalMessageSignature = new WeakMap();
|
|
119
164
|
_signer = new WeakMap();
|
|
165
|
+
let SessionKey = _SessionKey;
|
|
120
166
|
export {
|
|
121
167
|
RequestFormat,
|
|
122
168
|
SessionKey
|
|
@@ -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';\
|
|
5
|
-
"mappings": ";;;;;;;AAAA;AAGA,SAAS,gBAAgB;AACzB,SAAS,WAAW;AAEpB,SAAS,wBAAwB;AACjC,SAAS,sBAAsB;AAC/B,SAAS,mBAAmB,0BAA0B;AACtD,SAAS,sCAAsC;
|
|
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": []
|
|
7
7
|
}
|
package/dist/esm/utils.d.ts
CHANGED
|
@@ -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/esm/utils.js
CHANGED
|
@@ -23,7 +23,28 @@ function createFullId(dst, packageId, innerId) {
|
|
|
23
23
|
fullId.set(innerIdBytes, 1 + dst.length + packageIdBytes.length);
|
|
24
24
|
return toHex(fullId);
|
|
25
25
|
}
|
|
26
|
+
class Version {
|
|
27
|
+
constructor(version) {
|
|
28
|
+
const parts = version.split(".").map(Number);
|
|
29
|
+
if (parts.length !== 3 || parts.some((part) => isNaN(part) || part < 0)) {
|
|
30
|
+
throw new UserError(`Invalid version format: ${version}`);
|
|
31
|
+
}
|
|
32
|
+
this.major = parts[0];
|
|
33
|
+
this.minor = parts[1];
|
|
34
|
+
this.patch = parts[2];
|
|
35
|
+
}
|
|
36
|
+
// Compare this version with another version. True if this version is older than the other version.
|
|
37
|
+
older_than(other) {
|
|
38
|
+
if (this.major !== other.major) {
|
|
39
|
+
return this.major < other.major;
|
|
40
|
+
} else if (this.minor !== other.minor) {
|
|
41
|
+
return this.minor < other.minor;
|
|
42
|
+
}
|
|
43
|
+
return this.patch < other.patch;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
26
46
|
export {
|
|
47
|
+
Version,
|
|
27
48
|
createFullId,
|
|
28
49
|
xor,
|
|
29
50
|
xorUnchecked
|
package/dist/esm/utils.js.map
CHANGED
|
@@ -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": "AAGA,SAAS,SAAS,aAAa;AAC/B,SAAS,0BAA0B;AAEnC,SAAS,iBAAiB;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,CAAC,mBAAmB,SAAS,GAAG;AACnC,UAAM,IAAI,UAAU,sBAAsB,SAAS,EAAE;AAAA,EACtD;AACA,QAAM,iBAAiB,QAAQ,SAAS;AACxC,QAAM,eAAe,QAAQ,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,SAAO,MAAM,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": "AAGA,SAAS,SAAS,aAAa;AAC/B,SAAS,0BAA0B;AAEnC,SAAS,iBAAiB;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,CAAC,mBAAmB,SAAS,GAAG;AACnC,UAAM,IAAI,UAAU,sBAAsB,SAAS,EAAE;AAAA,EACtD;AACA,QAAM,iBAAiB,QAAQ,SAAS;AACxC,QAAM,eAAe,QAAQ,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,SAAO,MAAM,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,UAAU,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
|
}
|
package/dist/esm/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const PACKAGE_VERSION = "0.4.
|
|
1
|
+
export declare const PACKAGE_VERSION = "0.4.2";
|
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.
|
|
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.2';\n"],
|
|
5
5
|
"mappings": "AAKO,MAAM,kBAAkB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|