@fhevm/sdk 1.1.0-alpha.5 → 1.1.0-alpha.6
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/_cjs/core/_version.js +1 -1
- package/_cjs/core/base/bytes.js +2 -1
- package/_cjs/core/base/bytes.js.map +1 -1
- package/_cjs/core/base/environment.js +122 -0
- package/_cjs/core/base/environment.js.map +1 -0
- package/_cjs/core/base/errors/Sha256VerificationError.js +15 -0
- package/_cjs/core/base/errors/Sha256VerificationError.js.map +1 -0
- package/_cjs/core/base/inflate.js +282 -0
- package/_cjs/core/base/inflate.js.map +1 -0
- package/_cjs/core/base/isomorphicFs.js +24 -0
- package/_cjs/core/base/isomorphicFs.js.map +1 -0
- package/_cjs/core/base/isomorphicWorker.js +42 -111
- package/_cjs/core/base/isomorphicWorker.js.map +1 -1
- package/_cjs/core/base/wasm.js +15 -55
- package/_cjs/core/base/wasm.js.map +1 -1
- package/_cjs/core/kms/TransportKeyPair-p.js +0 -4
- package/_cjs/core/kms/TransportKeyPair-p.js.map +1 -1
- package/_cjs/core/kms/createKmsUserDecryptEip712.js +5 -1
- package/_cjs/core/kms/createKmsUserDecryptEip712.js.map +1 -1
- package/_cjs/core/modules/decrypt/module/init-p.js +124 -39
- package/_cjs/core/modules/decrypt/module/init-p.js.map +1 -1
- package/_cjs/core/modules/encrypt/module/init-p.js +148 -45
- package/_cjs/core/modules/encrypt/module/init-p.js.map +1 -1
- package/_cjs/core/runtime/HyperWasmSolver-p.js +4 -4
- package/_cjs/core/runtime/initFhevmEncryptRuntime-p.js +1 -1
- package/_cjs/core/runtime/initFhevmRuntime-p.js +1 -1
- package/_cjs/wasm/tfhe/TfheApi.d.ts +12 -12
- package/_cjs/wasm/tfhe/loadTfheLib.js +11 -11
- package/_cjs/wasm/tfhe/loadTfheLib.js.map +2 -2
- package/_cjs/wasm/tfhe/v1.5.3/startWorkers.js +26 -9
- package/_cjs/wasm/tfhe/v1.5.3/startWorkers.js.map +2 -2
- package/_cjs/wasm/tfhe/v1.5.3/tfhe.d.ts +3 -0
- package/_cjs/wasm/tfhe/{v1.6.1 → v1.6.2}/startWorkers.js +28 -11
- package/_cjs/wasm/tfhe/v1.6.2/startWorkers.js.map +7 -0
- package/{_esm/wasm/tfhe/v1.6.1 → _cjs/wasm/tfhe/v1.6.2}/tfhe-worker.mjs +40 -40
- package/{_esm/wasm/tfhe/v1.6.1 → _cjs/wasm/tfhe/v1.6.2}/tfhe.d.ts +88 -85
- package/_cjs/wasm/tfhe/{v1.6.1 → v1.6.2}/tfhe.js +245 -442
- package/_cjs/wasm/tfhe/v1.6.2/tfhe.js.map +7 -0
- package/_cjs/wasm/tfhe/v1.6.2/tfhe_bg.wasm +0 -0
- package/_cjs/wasm/tfhe/v1.6.2/tfhe_bg.wasm.base64.js +35 -0
- package/_cjs/wasm/tfhe/v1.6.2/tfhe_bg.wasm.base64.js.map +7 -0
- package/_cjs/wasm/tkms/loadKmsLib.js.map +1 -1
- package/_cjs/wasm/wasmBaseUrl.js +8 -19
- package/_cjs/wasm/wasmBaseUrl.js.map +2 -2
- package/_esm/core/_version.js +1 -1
- package/_esm/core/base/bytes.js +2 -1
- package/_esm/core/base/bytes.js.map +1 -1
- package/_esm/core/base/environment.js +164 -0
- package/_esm/core/base/environment.js.map +1 -0
- package/_esm/core/base/errors/Sha256VerificationError.js +11 -0
- package/_esm/core/base/errors/Sha256VerificationError.js.map +1 -0
- package/_esm/core/base/inflate.js +337 -0
- package/_esm/core/base/inflate.js.map +1 -0
- package/_esm/core/base/isomorphicFs.js +21 -0
- package/_esm/core/base/isomorphicFs.js.map +1 -0
- package/_esm/core/base/isomorphicWorker.js +92 -85
- package/_esm/core/base/isomorphicWorker.js.map +1 -1
- package/_esm/core/base/wasm.js +25 -31
- package/_esm/core/base/wasm.js.map +1 -1
- package/_esm/core/kms/TransportKeyPair-p.js +0 -4
- package/_esm/core/kms/TransportKeyPair-p.js.map +1 -1
- package/_esm/core/kms/createKmsUserDecryptEip712.js +5 -1
- package/_esm/core/kms/createKmsUserDecryptEip712.js.map +1 -1
- package/_esm/core/modules/decrypt/module/init-p.js +109 -54
- package/_esm/core/modules/decrypt/module/init-p.js.map +1 -1
- package/_esm/core/modules/encrypt/module/init-p.js +300 -53
- package/_esm/core/modules/encrypt/module/init-p.js.map +1 -1
- package/_esm/core/runtime/HyperWasmSolver-p.js +4 -4
- package/_esm/core/runtime/initFhevmEncryptRuntime-p.js +1 -1
- package/_esm/core/runtime/initFhevmRuntime-p.js +1 -1
- package/_esm/wasm/tfhe/TfheApi.d.ts +12 -12
- package/_esm/wasm/tfhe/loadTfheLib.js +11 -11
- package/_esm/wasm/tfhe/v1.5.3/startWorkers.js +41 -20
- package/_esm/wasm/tfhe/v1.5.3/tfhe.d.ts +3 -0
- package/_esm/wasm/tfhe/{v1.6.1 → v1.6.2}/startWorkers.js +46 -25
- package/{_cjs/wasm/tfhe/v1.6.1 → _esm/wasm/tfhe/v1.6.2}/tfhe-worker.mjs +40 -40
- package/{_types/wasm/tfhe/v1.6.1 → _esm/wasm/tfhe/v1.6.2}/tfhe.d.ts +88 -85
- package/_esm/wasm/tfhe/{v1.6.1 → v1.6.2}/tfhe.js +245 -442
- package/_esm/wasm/tfhe/v1.6.2/tfhe_bg.wasm +0 -0
- package/_esm/wasm/tfhe/v1.6.2/tfhe_bg.wasm.base64.js +7 -0
- package/_esm/wasm/wasmBaseUrl.js +17 -54
- package/_types/core/base/bytes.d.ts.map +1 -1
- package/_types/core/base/environment.d.ts +92 -0
- package/_types/core/base/environment.d.ts.map +1 -0
- package/_types/core/base/errors/Sha256VerificationError.d.ts +14 -0
- package/_types/core/base/errors/Sha256VerificationError.d.ts.map +1 -0
- package/_types/core/base/inflate.d.ts +25 -0
- package/_types/core/base/inflate.d.ts.map +1 -0
- package/_types/core/base/isomorphicFs.d.ts +2 -0
- package/_types/core/base/isomorphicFs.d.ts.map +1 -0
- package/_types/core/base/isomorphicWorker.d.ts +27 -43
- package/_types/core/base/isomorphicWorker.d.ts.map +1 -1
- package/_types/core/base/wasm.d.ts +0 -8
- package/_types/core/base/wasm.d.ts.map +1 -1
- package/_types/core/kms/TransportKeyPair-p.d.ts.map +1 -1
- package/_types/core/kms/createKmsUserDecryptEip712.d.ts.map +1 -1
- package/_types/core/modules/decrypt/module/init-p.d.ts.map +1 -1
- package/_types/core/modules/encrypt/module/init-p.d.ts.map +1 -1
- package/_types/core/types/wasmAssets.d.ts.map +1 -1
- package/_types/wasm/tfhe/TfheApi.d.ts +12 -12
- package/_types/wasm/tfhe/v1.5.3/tfhe.d.ts +3 -0
- package/{wasm/tfhe/v1.6.1 → _types/wasm/tfhe/v1.6.2}/tfhe.d.ts +88 -85
- package/core/_version.ts +1 -1
- package/core/base/bytes.ts +2 -1
- package/core/base/environment.ts +210 -0
- package/core/base/errors/Sha256VerificationError.ts +22 -0
- package/core/base/inflate.ts +373 -0
- package/core/base/isomorphicFs.ts +23 -0
- package/core/base/isomorphicWorker.ts +96 -123
- package/core/base/wasm.ts +28 -35
- package/core/kms/TransportKeyPair-p.ts +0 -5
- package/core/kms/createKmsUserDecryptEip712.ts +8 -1
- package/core/modules/decrypt/module/init-p.ts +148 -59
- package/core/modules/encrypt/module/init-p.ts +368 -63
- package/core/runtime/HyperWasmSolver-p.ts +4 -4
- package/core/runtime/initFhevmEncryptRuntime-p.ts +1 -1
- package/core/runtime/initFhevmRuntime-p.ts +1 -1
- package/core/types/wasmAssets.ts +58 -0
- package/package.json +1 -1
- package/wasm/tfhe/TfheApi.d.ts +12 -12
- package/wasm/tfhe/loadTfheLib.js +11 -11
- package/wasm/tfhe/v1.5.3/startWorkers.js +41 -20
- package/wasm/tfhe/v1.5.3/tfhe.d.ts +3 -0
- package/wasm/tfhe/v1.6.0-dev/startWorkers.js +41 -20
- package/wasm/tfhe/v1.6.0-dev/tfhe.d.ts +3 -0
- package/wasm/tfhe/{v1.6.1 → v1.6.2}/startWorkers.js +46 -25
- package/wasm/tfhe/{v1.6.1 → v1.6.2}/tfhe-worker.mjs +40 -40
- package/{_cjs/wasm/tfhe/v1.6.1 → wasm/tfhe/v1.6.2}/tfhe.d.ts +88 -85
- package/wasm/tfhe/{v1.6.1 → v1.6.2}/tfhe.js +245 -442
- package/wasm/tfhe/v1.6.2/tfhe_bg.wasm +0 -0
- package/wasm/tfhe/v1.6.2/tfhe_bg.wasm.base64.js +7 -0
- package/wasm/wasmBaseUrl.js +17 -54
- package/_cjs/wasm/tfhe/v1.6.1/startWorkers.js.map +0 -7
- package/_cjs/wasm/tfhe/v1.6.1/tfhe.js.map +0 -7
- package/_cjs/wasm/tfhe/v1.6.1/tfhe_bg.wasm +0 -0
- package/_cjs/wasm/tfhe/v1.6.1/tfhe_bg.wasm.base64.js +0 -35
- package/_cjs/wasm/tfhe/v1.6.1/tfhe_bg.wasm.base64.js.map +0 -7
- package/_esm/wasm/tfhe/v1.6.1/tfhe_bg.wasm +0 -0
- package/_esm/wasm/tfhe/v1.6.1/tfhe_bg.wasm.base64.js +0 -7
- package/wasm/tfhe/v1.6.1/tfhe_bg.wasm +0 -0
- package/wasm/tfhe/v1.6.1/tfhe_bg.wasm.base64.js +0 -7
- /package/_cjs/wasm/tfhe/{v1.6.1 → v1.6.2}/tfhe_bg.wasm.base64.d.ts +0 -0
- /package/_esm/wasm/tfhe/{v1.6.1 → v1.6.2}/tfhe_bg.wasm.base64.d.ts +0 -0
- /package/_types/wasm/tfhe/{v1.6.1 → v1.6.2}/tfhe_bg.wasm.base64.d.ts +0 -0
- /package/wasm/tfhe/{v1.6.1 → v1.6.2}/tfhe_bg.wasm.base64.d.ts +0 -0
package/core/base/wasm.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { verifySha256 } from './bytes.js';
|
|
2
2
|
import { FetchError } from './errors/FetchError.js';
|
|
3
3
|
import { isDataUrlFetchSupported } from './fetch.js';
|
|
4
|
-
import { isBrowserLike } from './
|
|
4
|
+
import { getNodeBuffer, getNodeFs, getNodeUrl, isBrowserLike, supportsDecompressionStream } from './environment.js';
|
|
5
|
+
import { inflateDecompress } from './inflate.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Decodes a base64 string to bytes using the fastest available method.
|
|
@@ -12,8 +13,12 @@ import { isBrowserLike } from './isomorphicWorker.js';
|
|
|
12
13
|
*/
|
|
13
14
|
async function _isomorphicDecodeBase64(base64: string): Promise<BufferSource> {
|
|
14
15
|
if (!isBrowserLike()) {
|
|
15
|
-
const
|
|
16
|
-
|
|
16
|
+
const NodeBuffer = await getNodeBuffer();
|
|
17
|
+
if (NodeBuffer) {
|
|
18
|
+
return NodeBuffer.from(base64, 'base64');
|
|
19
|
+
}
|
|
20
|
+
// Not a browser, but no node:buffer either (edge runtime). Fall through to
|
|
21
|
+
// the web-standard data-URL fetch / atob paths below, which edge supports.
|
|
17
22
|
}
|
|
18
23
|
|
|
19
24
|
if (await isDataUrlFetchSupported()) {
|
|
@@ -47,43 +52,21 @@ async function _isomorphicFetchWasmResponse(wasmUrl: URL): Promise<Response> {
|
|
|
47
52
|
|
|
48
53
|
async function _isomorphicReadWasmBytes(wasmUrl: URL): Promise<BufferSource> {
|
|
49
54
|
if (!isBrowserLike() && wasmUrl.protocol === 'file:') {
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
const [fs, url] = await Promise.all([getNodeFs(), getNodeUrl()]);
|
|
56
|
+
if (fs && url) {
|
|
57
|
+
// The BufferSource-safe cast for Node's Buffer lives in getNodeFs's
|
|
58
|
+
// return type (see environment.ts), so the bytes can flow straight into
|
|
59
|
+
// WebAssembly.compile without copying.
|
|
60
|
+
return fs.readFile(url.fileURLToPath(wasmUrl));
|
|
61
|
+
}
|
|
62
|
+
// Not a browser, but no node:fs either (edge runtime). Fall through to
|
|
63
|
+
// fetch below — a file: URL will fail there, surfacing a clear error.
|
|
58
64
|
}
|
|
59
65
|
|
|
60
66
|
const res = await _isomorphicFetchWasmResponse(wasmUrl);
|
|
61
67
|
return res.arrayBuffer();
|
|
62
68
|
}
|
|
63
69
|
|
|
64
|
-
/**
|
|
65
|
-
* Compiles a WASM module from a URL, isomorphically (browser and Node.js).
|
|
66
|
-
*
|
|
67
|
-
* - Node + `file://`: uses `readFile` (Node `fetch` doesn't support `file://`)
|
|
68
|
-
* - Browser + streaming: uses `WebAssembly.compileStreaming` (fastest path)
|
|
69
|
-
* - Fallback: `fetch` + `arrayBuffer` + `WebAssembly.compile`
|
|
70
|
-
*/
|
|
71
|
-
export async function isomorphicCompileWasm(wasmUrl: URL): Promise<WebAssembly.Module> {
|
|
72
|
-
const isBrowser = isBrowserLike();
|
|
73
|
-
|
|
74
|
-
if (isBrowser) {
|
|
75
|
-
const res = await _isomorphicFetchWasmResponse(wasmUrl);
|
|
76
|
-
if (typeof WebAssembly.compileStreaming === 'function') {
|
|
77
|
-
return await WebAssembly.compileStreaming(res);
|
|
78
|
-
}
|
|
79
|
-
return WebAssembly.compile(await res.arrayBuffer());
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const bytes = await _isomorphicReadWasmBytes(wasmUrl);
|
|
83
|
-
// Safe cast: Node's Buffer is always backed by ArrayBuffer at runtime.
|
|
84
|
-
return WebAssembly.compile(bytes);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
70
|
/**
|
|
88
71
|
* Fetches/reads a WASM module, verifies its SHA-256 digest, then compiles it.
|
|
89
72
|
*
|
|
@@ -120,9 +103,19 @@ export async function isomorphicCompileWasmFromBase64(
|
|
|
120
103
|
|
|
121
104
|
if (compressionFormat === undefined) {
|
|
122
105
|
return WebAssembly.compile(bytes);
|
|
123
|
-
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Preferred: stream through the platform DecompressionStream (native, zero-copy).
|
|
109
|
+
if (supportsDecompressionStream()) {
|
|
124
110
|
const stream = new Blob([bytes]).stream().pipeThrough(new DecompressionStream(compressionFormat));
|
|
125
111
|
// compileStreaming requires Content-Type: application/wasm — supply it explicitly.
|
|
126
112
|
return WebAssembly.compileStreaming(new Response(stream, { headers: { 'Content-Type': 'application/wasm' } }));
|
|
127
113
|
}
|
|
114
|
+
|
|
115
|
+
// Fallback for runtimes without a usable DecompressionStream — older browsers
|
|
116
|
+
// (Firefox <113, Safari <16.4) and the Next.js Edge Runtime (whose stub throws on
|
|
117
|
+
// construction). Inflate in pure JS, then compile. Keeps the small compressed
|
|
118
|
+
// embedded payload working everywhere with no caller action.
|
|
119
|
+
const compressed = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes as ArrayBuffer);
|
|
120
|
+
return WebAssembly.compile(inflateDecompress(compressed, compressionFormat));
|
|
128
121
|
}
|
|
@@ -237,11 +237,6 @@ export async function toTransportKeyPair(
|
|
|
237
237
|
expectedType: 'Bytes | BytesHex',
|
|
238
238
|
...options,
|
|
239
239
|
});
|
|
240
|
-
assertRecordNonNullableProperty(value, 'tkmsVersion', name, {
|
|
241
|
-
expectedType: 'string',
|
|
242
|
-
...options,
|
|
243
|
-
});
|
|
244
|
-
|
|
245
240
|
const rawPublicKey = value.publicKey;
|
|
246
241
|
const rawPrivateKey = value.privateKey;
|
|
247
242
|
const rawTkmsVersion = value.tkmsVersion;
|
|
@@ -16,6 +16,7 @@ import { assertIsUint64, assertIsUintNumber } from '../base/uint.js';
|
|
|
16
16
|
import { assertIsKmsExtraData } from './kmsExtraData.js';
|
|
17
17
|
import { kmsUserDecryptEip712Types } from './kmsUserDecryptEip712Types.js';
|
|
18
18
|
import { isDeepEqual } from '../base/object.js';
|
|
19
|
+
import { kmsDelegatedUserDecryptEip712Types } from './kmsDelegatedUserDecryptEip712Types.js';
|
|
19
20
|
|
|
20
21
|
////////////////////////////////////////////////////////////////////////////////
|
|
21
22
|
|
|
@@ -121,7 +122,13 @@ export function _assertIsKmsUserDecryptEip712Base(
|
|
|
121
122
|
assertIsKmsEip712Domain((value as Record<string, unknown>).domain, `${name}.domain`, options);
|
|
122
123
|
|
|
123
124
|
assertRecordNonNullableProperty(value, 'types', name, options);
|
|
124
|
-
|
|
125
|
+
|
|
126
|
+
const expectedTypes =
|
|
127
|
+
primaryType === 'DelegatedUserDecryptRequestVerification'
|
|
128
|
+
? kmsDelegatedUserDecryptEip712Types
|
|
129
|
+
: kmsUserDecryptEip712Types;
|
|
130
|
+
|
|
131
|
+
if (!isDeepEqual(value.types, expectedTypes)) {
|
|
125
132
|
throw new Error('Unexpected KmsUserDecryptEip712Types');
|
|
126
133
|
}
|
|
127
134
|
|
|
@@ -6,91 +6,167 @@ import type {
|
|
|
6
6
|
TkmsModuleInfo,
|
|
7
7
|
} from '../types.js';
|
|
8
8
|
import type { KmsLibApi, TkmsVersion } from '../../../../wasm/tkms/KmsLibApi.js';
|
|
9
|
-
import type { KmsAssetMetadata } from '../../../../wasm/tkms/loadKmsLib.js';
|
|
10
|
-
import { isBrowserLike } from '../../../base/
|
|
9
|
+
import type { KmsAssetMetadata, KmsAssets } from '../../../../wasm/tkms/loadKmsLib.js';
|
|
10
|
+
import { isBrowserLike } from '../../../base/environment.js';
|
|
11
11
|
import { isomorphicCompileVerifiedWasm, isomorphicCompileWasmFromBase64 } from '../../../base/wasm.js';
|
|
12
12
|
import { assertIsFhevmRuntime } from '../../../runtime/CoreFhevmRuntime-p.js';
|
|
13
|
-
import { wasmBaseUrl } from '../../../../wasm/wasmBaseUrl.js';
|
|
14
13
|
import { kmsAssetsWithVersion, loadKmsLib, loadKmsWasmBase64 } from '../../../../wasm/tkms/loadKmsLib.js';
|
|
14
|
+
import { isomorphicFileUrlExists } from '../../../base/isomorphicFs.js';
|
|
15
15
|
|
|
16
16
|
////////////////////////////////////////////////////////////////////////////////
|
|
17
17
|
|
|
18
|
-
const ownerUidByVersion = new Map<TkmsVersion, string>();
|
|
19
|
-
const cachedTkmsModulePromiseByVersion = new Map<TkmsVersion, Promise<KmsLibApi>>();
|
|
20
|
-
const moduleInfoByVersion = new Map<TkmsVersion, TkmsModuleInfo>();
|
|
21
|
-
|
|
22
|
-
////////////////////////////////////////////////////////////////////////////////
|
|
23
|
-
|
|
24
|
-
// Pure JS file (not compiled by tsc) — provides cross-platform base URL
|
|
25
|
-
// for resolving WASM paths. Uses import.meta.url in ESM, __filename in CJS.
|
|
26
|
-
|
|
27
18
|
// (Node only) Path relative to src/wasm/ where wasmBaseUrl is anchored
|
|
28
|
-
const nodeDefaultLocateFile = (file: string): URL => {
|
|
19
|
+
const nodeDefaultLocateFile = async (file: string): Promise<URL> => {
|
|
20
|
+
// Pure JS file (not compiled by tsc) — provides cross-platform base URL
|
|
21
|
+
// for resolving WASM paths. Uses import.meta.url in ESM, __filename in CJS.
|
|
22
|
+
const { wasmBaseUrl } = await import('../../../../wasm/wasmBaseUrl.js');
|
|
29
23
|
return new URL(`./tkms/${file}`, wasmBaseUrl);
|
|
30
24
|
};
|
|
31
25
|
|
|
26
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
27
|
+
|
|
28
|
+
type KmsAssetResolution = 'user' | 'node' | 'none';
|
|
29
|
+
|
|
32
30
|
type ResolvedKmsAsset = KmsAssetMetadata & {
|
|
33
31
|
readonly url: URL | undefined;
|
|
32
|
+
readonly resolution: KmsAssetResolution;
|
|
34
33
|
};
|
|
35
34
|
|
|
36
|
-
|
|
35
|
+
type ResolvedKmsAssets = {
|
|
36
|
+
readonly wasm: ResolvedKmsAsset;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
40
|
+
|
|
41
|
+
async function _resolveSingleKmsAsset(
|
|
42
|
+
asset: KmsAssetMetadata,
|
|
43
|
+
locateFile: FhevmRuntimeConfig['locateFile'],
|
|
44
|
+
): Promise<ResolvedKmsAsset> {
|
|
37
45
|
let url: URL | undefined;
|
|
46
|
+
let resolution: KmsAssetResolution = 'none';
|
|
38
47
|
|
|
39
48
|
if (locateFile !== undefined) {
|
|
40
|
-
|
|
49
|
+
const located = locateFile(asset.filename) as unknown;
|
|
50
|
+
if (located === null || located === undefined) {
|
|
51
|
+
url = undefined;
|
|
52
|
+
} else if (located instanceof URL) {
|
|
53
|
+
url = located;
|
|
54
|
+
} else {
|
|
55
|
+
throw new TypeError(
|
|
56
|
+
`Invalid locateFile result for TKMS asset '${asset.filename}': expected URL, null, or undefined.`,
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
resolution = 'user';
|
|
41
60
|
} else if (!isBrowserLike()) {
|
|
42
|
-
url = nodeDefaultLocateFile(asset.localRelativePath);
|
|
61
|
+
url = await nodeDefaultLocateFile(asset.localRelativePath);
|
|
62
|
+
resolution = 'node';
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return Object.freeze({ ...asset, url, resolution });
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
69
|
+
|
|
70
|
+
async function _resolveKmsAssets(
|
|
71
|
+
assets: KmsAssets,
|
|
72
|
+
locateFile: FhevmRuntimeConfig['locateFile'],
|
|
73
|
+
): Promise<{ readonly wasm: ResolvedKmsAsset }> {
|
|
74
|
+
let wasm = await _resolveSingleKmsAsset(assets.wasm, locateFile);
|
|
75
|
+
|
|
76
|
+
// Only auto-derived ('node') file:// URLs need on-disk validation; the mode is
|
|
77
|
+
// shared across all assets, so checking one is enough to know the set's mode.
|
|
78
|
+
if (wasm.resolution === 'node') {
|
|
79
|
+
const allExist = await isomorphicFileUrlExists(wasm.url);
|
|
80
|
+
if (!allExist) {
|
|
81
|
+
wasm = Object.freeze({ ...wasm, url: undefined });
|
|
82
|
+
}
|
|
43
83
|
}
|
|
44
84
|
|
|
45
|
-
return
|
|
85
|
+
return { wasm };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
89
|
+
|
|
90
|
+
function _logResolvedKmsAssets(resolvedAssets: ResolvedKmsAssets, logger: FhevmRuntimeConfig['logger']): void {
|
|
91
|
+
const { wasm } = resolvedAssets;
|
|
92
|
+
if (wasm.resolution === 'user') {
|
|
93
|
+
logger?.debug(`resolve tkms wasm filename using 'locateFile' function: ${wasm.filename} -> url: ${wasm.url}`);
|
|
94
|
+
} else if (wasm.resolution === 'node') {
|
|
95
|
+
if (wasm.url === undefined) {
|
|
96
|
+
// Auto-derived assets were missing on disk (e.g. a bundler such as Turbopack
|
|
97
|
+
// relocated the package) and were cleared by _resolveTkmsAssets -> base64.
|
|
98
|
+
logger?.debug(
|
|
99
|
+
`tkms auto-derived assets not found on disk (bundler relocation?); using embedded base64 ` +
|
|
100
|
+
`(wasm: ${wasm.localRelativePath})`,
|
|
101
|
+
);
|
|
102
|
+
} else {
|
|
103
|
+
logger?.debug(`resolve tkms wasm local path: ${wasm.localRelativePath} -> url: ${wasm.url}`);
|
|
104
|
+
}
|
|
105
|
+
} else {
|
|
106
|
+
// 'none': browser zero-config (no 'locateFile', not Node) -> embedded base64.
|
|
107
|
+
logger?.debug(`resolve tkms assets using embedded base64 (browser, no 'locateFile')`);
|
|
108
|
+
}
|
|
46
109
|
}
|
|
47
110
|
|
|
111
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
112
|
+
|
|
48
113
|
type ResolvedTkmsModuleConfig = {
|
|
49
114
|
readonly version: TkmsVersion;
|
|
50
|
-
readonly
|
|
115
|
+
readonly assets: ResolvedKmsAssets;
|
|
51
116
|
readonly logger: FhevmRuntimeConfig['logger'];
|
|
52
117
|
};
|
|
53
118
|
|
|
54
119
|
const resolvedTkmsModuleConfigByVersion = new Map<TkmsVersion, ResolvedTkmsModuleConfig>();
|
|
120
|
+
const resolvingTkmsModuleConfigPromiseByVersion = new Map<TkmsVersion, Promise<ResolvedTkmsModuleConfig>>();
|
|
55
121
|
|
|
56
122
|
/**
|
|
57
123
|
* @internal
|
|
58
|
-
* Returns the existing resolved config, or resolves it from
|
|
124
|
+
* Returns the existing resolved config for a TKMS version, or resolves it from
|
|
125
|
+
* the runtime config.
|
|
59
126
|
*/
|
|
60
|
-
function _getOrResolveTkmsModuleConfig(
|
|
61
|
-
|
|
127
|
+
async function _getOrResolveTkmsModuleConfig(
|
|
128
|
+
runtime: FhevmRuntime,
|
|
129
|
+
tkmsVersion: TkmsVersion,
|
|
130
|
+
): Promise<ResolvedTkmsModuleConfig> {
|
|
131
|
+
const resolvedTkmsModuleConfig = resolvedTkmsModuleConfigByVersion.get(tkmsVersion);
|
|
62
132
|
if (resolvedTkmsModuleConfig !== undefined) {
|
|
63
133
|
return resolvedTkmsModuleConfig;
|
|
64
134
|
}
|
|
65
135
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
136
|
+
let resolvingTkmsModuleConfigPromise = resolvingTkmsModuleConfigPromiseByVersion.get(tkmsVersion);
|
|
137
|
+
if (resolvingTkmsModuleConfigPromise === undefined) {
|
|
138
|
+
resolvingTkmsModuleConfigPromise = _resolveTkmsModuleConfig(runtime.config, tkmsVersion)
|
|
139
|
+
.then((cfg) => {
|
|
140
|
+
resolvedTkmsModuleConfigByVersion.set(tkmsVersion, cfg);
|
|
141
|
+
return cfg;
|
|
142
|
+
})
|
|
143
|
+
.catch((error: unknown) => {
|
|
144
|
+
resolvingTkmsModuleConfigPromiseByVersion.delete(tkmsVersion);
|
|
145
|
+
throw error;
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
resolvingTkmsModuleConfigPromiseByVersion.set(tkmsVersion, resolvingTkmsModuleConfigPromise);
|
|
149
|
+
}
|
|
69
150
|
|
|
70
|
-
return
|
|
151
|
+
return resolvingTkmsModuleConfigPromise;
|
|
71
152
|
}
|
|
72
153
|
|
|
73
|
-
function _resolveTkmsModuleConfig(
|
|
154
|
+
async function _resolveTkmsModuleConfig(
|
|
155
|
+
parameters: FhevmRuntimeConfig,
|
|
156
|
+
version: TkmsVersion,
|
|
157
|
+
): Promise<ResolvedTkmsModuleConfig> {
|
|
74
158
|
const { locateFile } = parameters;
|
|
75
159
|
|
|
76
160
|
const assets = kmsAssetsWithVersion(version);
|
|
77
|
-
const wasm = _resolveKmsAsset(assets.wasm, locateFile);
|
|
78
161
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
/*
|
|
83
|
-
if run in Node only, use defaultLocateFile!
|
|
84
|
-
*/
|
|
85
|
-
if (!isBrowserLike()) {
|
|
86
|
-
parameters.logger?.debug(`resolve kms wasm local path: ${wasm.localRelativePath} -> url: ${wasm.url}`);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
162
|
+
const resolvedAssets = await _resolveKmsAssets(assets, locateFile);
|
|
163
|
+
|
|
164
|
+
_logResolvedKmsAssets(resolvedAssets, parameters.logger);
|
|
89
165
|
|
|
90
166
|
// if wasmUrl is undefined, use base64 code instead
|
|
91
167
|
const cfg = {
|
|
92
168
|
version,
|
|
93
|
-
|
|
169
|
+
assets: resolvedAssets,
|
|
94
170
|
logger: parameters.logger,
|
|
95
171
|
};
|
|
96
172
|
|
|
@@ -103,6 +179,12 @@ function _resolveTkmsModuleConfig(parameters: FhevmRuntimeConfig, version: TkmsV
|
|
|
103
179
|
// initTkmsModule
|
|
104
180
|
////////////////////////////////////////////////////////////////////////////////
|
|
105
181
|
|
|
182
|
+
const ownerUidByVersion = new Map<TkmsVersion, string>();
|
|
183
|
+
const cachedTkmsModulePromiseByVersion = new Map<TkmsVersion, Promise<KmsLibApi>>();
|
|
184
|
+
const moduleInfoByVersion = new Map<TkmsVersion, TkmsModuleInfo>();
|
|
185
|
+
|
|
186
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
187
|
+
|
|
106
188
|
type TkmsInitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
|
107
189
|
|
|
108
190
|
type TkmsLibInitAsyncParameters = {
|
|
@@ -121,40 +203,47 @@ export async function initTkmsModule(runtime: FhevmRuntime, parameters: InitTkms
|
|
|
121
203
|
|
|
122
204
|
ownerUidByVersion.set(parameters.tkmsVersion, runtime.uid);
|
|
123
205
|
|
|
124
|
-
// Cache the
|
|
125
|
-
//
|
|
206
|
+
// Cache the whole initialization promise before the first await. Several
|
|
207
|
+
// clients may call initTkmsModule concurrently during startup.
|
|
126
208
|
//
|
|
127
|
-
// Retry is not supported
|
|
128
|
-
// -----------------------
|
|
129
|
-
// The underlying KMS/WASM bindings
|
|
130
|
-
// keep module-level state that cannot be reset reliably after a partial
|
|
131
|
-
// initialization failure; later callers should observe the original error
|
|
132
|
-
// instead of retrying against half-initialized state.
|
|
209
|
+
// Retry is not supported
|
|
133
210
|
|
|
134
211
|
let cachedTkmsModulePromise = cachedTkmsModulePromiseByVersion.get(parameters.tkmsVersion);
|
|
135
212
|
if (cachedTkmsModulePromise === undefined) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
213
|
+
cachedTkmsModulePromise = (async () => {
|
|
214
|
+
// resolve is async
|
|
215
|
+
const cfg = await _getOrResolveTkmsModuleConfig(runtime, parameters.tkmsVersion);
|
|
216
|
+
return await _initTkmsModule(cfg);
|
|
217
|
+
})();
|
|
218
|
+
|
|
139
219
|
cachedTkmsModulePromiseByVersion.set(parameters.tkmsVersion, cachedTkmsModulePromise);
|
|
140
220
|
}
|
|
141
221
|
|
|
142
222
|
return cachedTkmsModulePromise;
|
|
143
223
|
}
|
|
144
224
|
|
|
225
|
+
async function _compileWasmModule(cfg: ResolvedTkmsModuleConfig): Promise<WebAssembly.Module> {
|
|
226
|
+
let wasmModule;
|
|
227
|
+
|
|
228
|
+
if (cfg.assets.wasm.url !== undefined) {
|
|
229
|
+
cfg.logger?.debug(`compile tkms verified wasm at: ${cfg.assets.wasm.url}`);
|
|
230
|
+
wasmModule = await isomorphicCompileVerifiedWasm(cfg.assets.wasm.url, cfg.assets.wasm.sha256);
|
|
231
|
+
} else {
|
|
232
|
+
const { tkmsWasmBase64, tkmsWasmBase64CompressionFormat } = await loadKmsWasmBase64(cfg.version);
|
|
233
|
+
cfg.logger?.debug(
|
|
234
|
+
`compile tkms wasm from embedded base64 (compression:${tkmsWasmBase64CompressionFormat ?? 'none'})`,
|
|
235
|
+
);
|
|
236
|
+
wasmModule = await isomorphicCompileWasmFromBase64(tkmsWasmBase64, tkmsWasmBase64CompressionFormat);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return wasmModule;
|
|
240
|
+
}
|
|
241
|
+
|
|
145
242
|
async function _initTkmsModule(cfg: ResolvedTkmsModuleConfig): Promise<KmsLibApi> {
|
|
146
243
|
const kmsLib = await loadKmsLib(cfg.version);
|
|
147
244
|
|
|
148
245
|
// Compile WASM module (see matrix in types.ts)
|
|
149
|
-
|
|
150
|
-
if (cfg.wasm.url !== undefined) {
|
|
151
|
-
cfg.logger?.debug(`compile verified wasm at: ${cfg.wasm.url}`);
|
|
152
|
-
wasmModule = await isomorphicCompileVerifiedWasm(cfg.wasm.url, cfg.wasm.sha256);
|
|
153
|
-
} else {
|
|
154
|
-
const { tkmsWasmBase64, tkmsWasmBase64IsGzipped } = await loadKmsWasmBase64(cfg.version);
|
|
155
|
-
cfg.logger?.debug(`compile wasm from embedded base64 (compression:${tkmsWasmBase64IsGzipped})`);
|
|
156
|
-
wasmModule = await isomorphicCompileWasmFromBase64(tkmsWasmBase64, tkmsWasmBase64IsGzipped ? 'gzip' : undefined);
|
|
157
|
-
}
|
|
246
|
+
const wasmModule = await _compileWasmModule(cfg);
|
|
158
247
|
|
|
159
248
|
const input: TkmsLibInitAsyncParameters = { module_or_path: wasmModule };
|
|
160
249
|
|
|
@@ -171,7 +260,7 @@ async function _initTkmsModule(cfg: ResolvedTkmsModuleConfig): Promise<KmsLibApi
|
|
|
171
260
|
moduleInfoByVersion.set(
|
|
172
261
|
cfg.version,
|
|
173
262
|
Object.freeze({
|
|
174
|
-
wasmUrl: cfg.wasm.url ? new URL(cfg.wasm.url) : undefined,
|
|
263
|
+
wasmUrl: cfg.assets.wasm.url ? new URL(cfg.assets.wasm.url) : undefined,
|
|
175
264
|
version: wasmInfo.version,
|
|
176
265
|
name: wasmInfo.name,
|
|
177
266
|
memory,
|