walletkit-web 0.22.0 → 0.22.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/generated/index.d.ts +11 -0
- package/dist/generated/walletkit-ffi.d.ts +607 -0
- package/dist/generated/walletkit.d.ts +15 -0
- package/dist/generated/walletkit.wasm +0 -0
- package/dist/generated/walletkit_bg.d.ts +170 -0
- package/dist/generated/walletkit_core-ffi.d.ts +3323 -0
- package/dist/generated/walletkit_core.d.ts +6797 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +134 -0
- package/dist/protocol.d.ts +94 -0
- package/dist/walletkit.worker.d.ts +1 -0
- package/dist/walletkit.worker.js +14597 -0
- package/package.json +1 -1
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { InitializeOptions, RecoveryData, RegistrationStatus } from "./protocol";
|
|
2
|
+
export type { InitializeOptions, RecoveryData, RegistrationStatus, } from "./protocol";
|
|
3
|
+
export interface WalletKit {
|
|
4
|
+
recoveryDataFromSeed(seed: Uint8Array): Promise<RecoveryData>;
|
|
5
|
+
register(seed: Uint8Array): Promise<void>;
|
|
6
|
+
pollRegistration(): Promise<RegistrationStatus>;
|
|
7
|
+
initializeAuthenticator(seed: Uint8Array, now?: bigint): Promise<void>;
|
|
8
|
+
prepareCredential(issuerSchemaId: bigint): Promise<{
|
|
9
|
+
blindingFactor: string;
|
|
10
|
+
sub: string;
|
|
11
|
+
}>;
|
|
12
|
+
storeCredential(credential: Uint8Array, blindingFactor: string, now?: bigint): Promise<{
|
|
13
|
+
credentialId: bigint;
|
|
14
|
+
issuerSchemaId: bigint;
|
|
15
|
+
}>;
|
|
16
|
+
generateProof(requestJson: string, now?: bigint): Promise<string>;
|
|
17
|
+
close(): Promise<void>;
|
|
18
|
+
terminate(): void;
|
|
19
|
+
}
|
|
20
|
+
/** Loads WASM and persistent OPFS storage in a package-managed dedicated worker. */
|
|
21
|
+
export declare function initializeWalletKit(options: InitializeOptions): Promise<WalletKit>;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
var WalletKitClient = class {
|
|
3
|
+
/** @internal Use initializeWalletKit(). */
|
|
4
|
+
constructor(worker) {
|
|
5
|
+
this.worker = worker;
|
|
6
|
+
worker.onmessage = ({ data }) => this.handleResponse(data);
|
|
7
|
+
worker.onerror = (event) => this.stop(new Error(event.message || "WalletKit worker failed"));
|
|
8
|
+
worker.onmessageerror = () => this.stop(new Error("WalletKit worker message could not be decoded"));
|
|
9
|
+
}
|
|
10
|
+
nextId = 0;
|
|
11
|
+
pending = /* @__PURE__ */ new Map();
|
|
12
|
+
stopped = false;
|
|
13
|
+
closing;
|
|
14
|
+
/**
|
|
15
|
+
* Sends a typed RPC request to the worker and returns a promise that is
|
|
16
|
+
* settled by the response with the matching request ID. Rejects immediately
|
|
17
|
+
* if the client is closing or closed.
|
|
18
|
+
*
|
|
19
|
+
* @internal Public methods provide the consumer-facing API.
|
|
20
|
+
*/
|
|
21
|
+
call(method, ...args) {
|
|
22
|
+
if (this.stopped || this.closing && method !== "close")
|
|
23
|
+
return Promise.reject(new Error("WalletKit is closed"));
|
|
24
|
+
const id = this.nextId++;
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
this.pending.set(id, {
|
|
27
|
+
resolve,
|
|
28
|
+
reject
|
|
29
|
+
});
|
|
30
|
+
try {
|
|
31
|
+
this.worker.postMessage({ id, method, args });
|
|
32
|
+
} catch (error) {
|
|
33
|
+
this.pending.delete(id);
|
|
34
|
+
reject(error);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
recoveryDataFromSeed(seed) {
|
|
39
|
+
return this.call("recoveryDataFromSeed", seed);
|
|
40
|
+
}
|
|
41
|
+
register(seed) {
|
|
42
|
+
return this.call("register", seed);
|
|
43
|
+
}
|
|
44
|
+
pollRegistration() {
|
|
45
|
+
return this.call("pollRegistration");
|
|
46
|
+
}
|
|
47
|
+
initializeAuthenticator(seed, now = BigInt(Math.floor(Date.now() / 1e3))) {
|
|
48
|
+
return this.call("initializeAuthenticator", seed, now);
|
|
49
|
+
}
|
|
50
|
+
prepareCredential(issuerSchemaId) {
|
|
51
|
+
return this.call("prepareCredential", issuerSchemaId);
|
|
52
|
+
}
|
|
53
|
+
storeCredential(credential, blindingFactor, now = BigInt(Math.floor(Date.now() / 1e3))) {
|
|
54
|
+
return this.call("storeCredential", credential, blindingFactor, now);
|
|
55
|
+
}
|
|
56
|
+
generateProof(requestJson, now = BigInt(Math.floor(Date.now() / 1e3))) {
|
|
57
|
+
return this.call("generateProof", requestJson, now);
|
|
58
|
+
}
|
|
59
|
+
/** Finishes queued work, releases Rust objects, then terminates the worker. */
|
|
60
|
+
close() {
|
|
61
|
+
if (this.stopped) return Promise.resolve();
|
|
62
|
+
return this.closing ??= this.call("close").finally(
|
|
63
|
+
() => this.stop(new Error("WalletKit is closed"))
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
/** Immediately stops the worker and rejects pending calls. */
|
|
67
|
+
terminate() {
|
|
68
|
+
this.stop(new Error("WalletKit was terminated"));
|
|
69
|
+
}
|
|
70
|
+
handleResponse(response) {
|
|
71
|
+
const pending = this.pending.get(response.id);
|
|
72
|
+
if (!pending) return;
|
|
73
|
+
this.pending.delete(response.id);
|
|
74
|
+
if (response.ok) pending.resolve(response.result);
|
|
75
|
+
else {
|
|
76
|
+
const error = new Error(response.error.message);
|
|
77
|
+
error.name = response.error.name;
|
|
78
|
+
pending.reject(error);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
stop(error) {
|
|
82
|
+
this.stopped = true;
|
|
83
|
+
this.worker.terminate();
|
|
84
|
+
for (const pending of this.pending.values()) pending.reject(error);
|
|
85
|
+
this.pending.clear();
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
async function initializeWalletKit(options) {
|
|
89
|
+
if (options.databaseKey.byteLength !== 32) {
|
|
90
|
+
throw new Error("Expected a 32-byte database key");
|
|
91
|
+
}
|
|
92
|
+
const storageId = options.storageId ?? "default";
|
|
93
|
+
if (!/^[a-zA-Z0-9_-]{1,128}$/.test(storageId)) {
|
|
94
|
+
throw new Error(
|
|
95
|
+
"Invalid storageId: use 1\u2013128 letters, digits, underscores or hyphens"
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
options.signal?.throwIfAborted();
|
|
99
|
+
const worker = options.workerUrl ? new Worker(new URL(options.workerUrl, globalThis.location.href), {
|
|
100
|
+
type: "module"
|
|
101
|
+
}) : new Worker(new URL("./walletkit.worker.js", import.meta.url), {
|
|
102
|
+
type: "module"
|
|
103
|
+
});
|
|
104
|
+
const client = new WalletKitClient(worker);
|
|
105
|
+
const abort = () => client.terminate();
|
|
106
|
+
options.signal?.addEventListener("abort", abort, { once: true });
|
|
107
|
+
const databaseKey = new Uint8Array(options.databaseKey);
|
|
108
|
+
try {
|
|
109
|
+
const wasmUrl = options.wasmUrl ? new URL(options.wasmUrl, globalThis.location.href).href : new URL(
|
|
110
|
+
new URL("./generated/walletkit.wasm", import.meta.url).href,
|
|
111
|
+
globalThis.location.href
|
|
112
|
+
).href;
|
|
113
|
+
const workerOptions = {
|
|
114
|
+
databaseKey,
|
|
115
|
+
storageId,
|
|
116
|
+
environment: options.environment ?? "production",
|
|
117
|
+
region: options.region ?? "eu",
|
|
118
|
+
rpcUrl: options.rpcUrl,
|
|
119
|
+
wasmUrl
|
|
120
|
+
};
|
|
121
|
+
await client.call("initialize", workerOptions);
|
|
122
|
+
return client;
|
|
123
|
+
} catch (error) {
|
|
124
|
+
client.terminate();
|
|
125
|
+
throw error;
|
|
126
|
+
} finally {
|
|
127
|
+
databaseKey.fill(0);
|
|
128
|
+
options.signal?.removeEventListener("abort", abort);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export {
|
|
132
|
+
initializeWalletKit
|
|
133
|
+
};
|
|
134
|
+
export {};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/** Values crossing the worker boundary are plain structured-clone data. */
|
|
2
|
+
export interface RecoveryData {
|
|
3
|
+
authenticatorAddress: string;
|
|
4
|
+
authenticatorPubkey: string;
|
|
5
|
+
offchainSignerCommitment: string;
|
|
6
|
+
}
|
|
7
|
+
export type RegistrationStatus = {
|
|
8
|
+
state: "queued" | "batching" | "submitted" | "finalized";
|
|
9
|
+
} | {
|
|
10
|
+
state: "failed";
|
|
11
|
+
error: string;
|
|
12
|
+
errorCode?: string;
|
|
13
|
+
};
|
|
14
|
+
export interface InitializeOptions {
|
|
15
|
+
/** 32-byte database encryption key. Supply the same databaseKey when reopening storage. */
|
|
16
|
+
databaseKey: Uint8Array;
|
|
17
|
+
/** Stable storage namespace, unique per consumer/account. Default: "default". */
|
|
18
|
+
storageId?: string;
|
|
19
|
+
environment?: "production" | "staging";
|
|
20
|
+
region?: "eu" | "us" | "ap";
|
|
21
|
+
rpcUrl?: string;
|
|
22
|
+
workerUrl?: string | URL;
|
|
23
|
+
wasmUrl?: string | URL;
|
|
24
|
+
/** Abort initialization and release the worker (for example on unmount). */
|
|
25
|
+
signal?: AbortSignal;
|
|
26
|
+
}
|
|
27
|
+
export type WorkerOptions = Required<Pick<InitializeOptions, "storageId" | "environment" | "region">> & Pick<InitializeOptions, "rpcUrl"> & {
|
|
28
|
+
databaseKey: Uint8Array;
|
|
29
|
+
wasmUrl: string;
|
|
30
|
+
};
|
|
31
|
+
export interface Operations {
|
|
32
|
+
initialize: {
|
|
33
|
+
args: [WorkerOptions];
|
|
34
|
+
result: void;
|
|
35
|
+
};
|
|
36
|
+
recoveryDataFromSeed: {
|
|
37
|
+
args: [Uint8Array];
|
|
38
|
+
result: RecoveryData;
|
|
39
|
+
};
|
|
40
|
+
register: {
|
|
41
|
+
args: [Uint8Array];
|
|
42
|
+
result: void;
|
|
43
|
+
};
|
|
44
|
+
pollRegistration: {
|
|
45
|
+
args: [];
|
|
46
|
+
result: RegistrationStatus;
|
|
47
|
+
};
|
|
48
|
+
initializeAuthenticator: {
|
|
49
|
+
args: [Uint8Array, bigint];
|
|
50
|
+
result: void;
|
|
51
|
+
};
|
|
52
|
+
prepareCredential: {
|
|
53
|
+
args: [bigint];
|
|
54
|
+
result: {
|
|
55
|
+
blindingFactor: string;
|
|
56
|
+
sub: string;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
storeCredential: {
|
|
60
|
+
args: [Uint8Array, string, bigint];
|
|
61
|
+
result: {
|
|
62
|
+
credentialId: bigint;
|
|
63
|
+
issuerSchemaId: bigint;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
generateProof: {
|
|
67
|
+
args: [string, bigint];
|
|
68
|
+
result: string;
|
|
69
|
+
};
|
|
70
|
+
close: {
|
|
71
|
+
args: [];
|
|
72
|
+
result: void;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export type Method = keyof Operations;
|
|
76
|
+
export type Request = {
|
|
77
|
+
[M in Method]: {
|
|
78
|
+
id: number;
|
|
79
|
+
method: M;
|
|
80
|
+
args: Operations[M]["args"];
|
|
81
|
+
};
|
|
82
|
+
}[Method];
|
|
83
|
+
export type Response = {
|
|
84
|
+
id: number;
|
|
85
|
+
} & ({
|
|
86
|
+
ok: true;
|
|
87
|
+
result: unknown;
|
|
88
|
+
} | {
|
|
89
|
+
ok: false;
|
|
90
|
+
error: {
|
|
91
|
+
name: string;
|
|
92
|
+
message: string;
|
|
93
|
+
};
|
|
94
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|