walletkit-web 0.21.3 → 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/README.md +105 -17
- package/dist/generated/walletkit.wasm +0 -0
- package/dist/generated/walletkit_bg.d.ts +30 -0
- package/dist/generated/walletkit_core-ffi.d.ts +210 -26
- package/dist/generated/walletkit_core.d.ts +662 -48
- package/dist/index.d.ts +21 -10
- package/dist/index.js +110 -11416
- 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 +14 -6
package/README.md
CHANGED
|
@@ -1,28 +1,116 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `walletkit-web`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
WalletKit's browser client. The package always runs Rust/WASM, cryptography,
|
|
4
|
+
proof generation and SQLite in a dedicated Web Worker. Importing the package
|
|
5
|
+
is safe during SSR; call `initializeWalletKit` in a browser.
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
```ts
|
|
8
|
+
import { initializeWalletKit } from "walletkit-web";
|
|
9
|
+
|
|
10
|
+
const wallet = await initializeWalletKit({
|
|
11
|
+
databaseKey, // Uint8Array containing the resolved 32-byte K_intermediate
|
|
12
|
+
storageId: "my-account", // stable namespace for this consumer/account
|
|
13
|
+
environment: "staging", // defaults to production
|
|
14
|
+
region: "eu",
|
|
15
|
+
});
|
|
16
|
+
const recovery = await wallet.recoveryDataFromSeed(seed);
|
|
17
|
+
// For an already registered account:
|
|
18
|
+
await wallet.initializeAuthenticator(seed);
|
|
19
|
+
const proofJson = await wallet.generateProof(requestJson);
|
|
20
|
+
await wallet.close();
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The host supplies the resolved `databaseKey`, for example after obtaining passkey
|
|
24
|
+
PRF output and deriving the database key. PRF acquisition/derivation happens before
|
|
25
|
+
initialization; WalletKit does not call WebAuthn or wrap this key in an envelope.
|
|
26
|
+
The worker constructs `StorageKeys.fromBytes(databaseKey)` and passes those keys to
|
|
27
|
+
`CredentialStore`. Both vault and cache use that key directly through sqlite3mc.
|
|
28
|
+
|
|
29
|
+
Supply the same key and storage ID when reopening. The authenticator seed and
|
|
30
|
+
database key are separate inputs. The package does not persist the database key;
|
|
31
|
+
initialization copies it and the caller owns clearing its own copy. Rust keeps the
|
|
32
|
+
resolved key in zeroizing memory until its last owner releases it.
|
|
33
|
+
|
|
34
|
+
Mobile hosts can instead resolve `openOrCreateStorageKeys(paths, keystore,
|
|
35
|
+
blobStore, now)` before constructing the same `CredentialStore(paths, keys)`.
|
|
36
|
+
The store retains no keystore or blob-store references. It releases its key
|
|
37
|
+
reference on destruction and requires a new instance to reopen. The host separately
|
|
38
|
+
calls `deleteStorageKeyEnvelope(paths, blobStore)` if it owns an envelope that should
|
|
39
|
+
be deleted. Existing envelope-backed databases still use their resolved intermediate
|
|
40
|
+
key; the old wrapping secret is not a replacement for that database key.
|
|
41
|
+
|
|
42
|
+
## Browser API
|
|
43
|
+
|
|
44
|
+
All calls into the worker return Promises. The public client exposes
|
|
45
|
+
`recoveryDataFromSeed`, `register`, `pollRegistration`, `initializeAuthenticator`,
|
|
46
|
+
`prepareCredential`, `storeCredential`, and `generateProof`. Registration polling
|
|
47
|
+
returns plain status records, including failure details. `prepareCredential`
|
|
48
|
+
returns the subject and serialized blinding factor for an issuer flow;
|
|
49
|
+
`storeCredential` accepts credential bytes and that factor. Issuer HTTP calls and
|
|
50
|
+
relying-party request construction remain application code.
|
|
51
|
+
|
|
52
|
+
This replaces the prototype API that returned the generated UniFFI namespace.
|
|
53
|
+
Generated Rust objects are internal and never cross the worker boundary. Existing
|
|
54
|
+
consumers must migrate their calls to the browser client; it is not a transparent
|
|
55
|
+
proxy for every generated binding. See the Next.js demo for a complete registration,
|
|
56
|
+
issuance and proof flow.
|
|
7
57
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
58
|
+
Operations run in order, including asynchronous work. `close()` drains queued
|
|
59
|
+
operations, destroys owned Rust objects and terminates the worker. `terminate()`
|
|
60
|
+
interrupts immediately and rejects pending requests. Worker failures also reject
|
|
61
|
+
pending requests. An optional `signal` cancels initialization only; after it
|
|
62
|
+
resolves, use `close()` or `terminate()`.
|
|
63
|
+
|
|
64
|
+
## Assets and deployment
|
|
65
|
+
|
|
66
|
+
Default URLs are resolved by the application's bundler. Both worker JavaScript
|
|
67
|
+
and the roughly 40 MB WASM asset ship in `dist`. The worker is self-contained,
|
|
68
|
+
including the generated glue and its runtime dependencies.
|
|
69
|
+
|
|
70
|
+
Hosts with custom asset layouts can provide explicit URLs:
|
|
11
71
|
|
|
12
72
|
```ts
|
|
13
|
-
const
|
|
14
|
-
|
|
73
|
+
const wallet = await initializeWalletKit({
|
|
74
|
+
databaseKey,
|
|
75
|
+
workerUrl: "/assets/walletkit.worker.js",
|
|
76
|
+
wasmUrl: "/assets/walletkit.wasm",
|
|
77
|
+
});
|
|
15
78
|
```
|
|
16
79
|
|
|
17
|
-
|
|
80
|
+
Relative overrides resolve against the page URL. These options change asset
|
|
81
|
+
locations; they do not enable main-thread execution. Serve the worker from a
|
|
82
|
+
permitted same-origin location and the WASM file as `application/wasm`.
|
|
83
|
+
|
|
84
|
+
## Persistent storage
|
|
85
|
+
|
|
86
|
+
Initialization acquires the OPFS sync-access-handle pool asynchronously. SQLite
|
|
87
|
+
operations are synchronous afterward. The browser's direct-key path needs no envelope database. The encrypted credential
|
|
88
|
+
vault/cache retain their existing format and use rollback journals on WASM.
|
|
89
|
+
|
|
90
|
+
Closing a SQLite connection does not release the pool's OPFS handles: the pool
|
|
91
|
+
remains alive until worker termination. Currently one worker owns the WalletKit
|
|
92
|
+
pool per origin. A second tab/client receives an initialization error, even with
|
|
93
|
+
a different storage ID. After shutdown, browser handle release may be asynchronous;
|
|
94
|
+
a subsequent initializer may need to retry. There is no silent memory fallback.
|
|
95
|
+
Pool capacity is reserved at startup rather than expanded during synchronous SQL.
|
|
96
|
+
|
|
97
|
+
Browser storage requires a supported secure context (localhost is suitable for
|
|
98
|
+
development). The SAH pool does not require cross-origin-isolation headers.
|
|
99
|
+
Browser quota and eviction policy still apply.
|
|
100
|
+
|
|
101
|
+
## Build and verify
|
|
18
102
|
|
|
19
103
|
```sh
|
|
20
|
-
nix develop .#wasm --command
|
|
21
|
-
nix develop .#wasm --command
|
|
104
|
+
nix develop .#wasm --command bun install --cwd web/walletkit --frozen-lockfile
|
|
105
|
+
nix develop .#wasm --command bun run --cwd web/walletkit build
|
|
106
|
+
nix develop .#wasm --command bun run --cwd web/walletkit test:browser
|
|
22
107
|
```
|
|
23
108
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
109
|
+
Browser tests use installed Google Chrome and a production Vite fixture. They
|
|
110
|
+
cover worker startup and lifecycle, URL overrides, exclusive pool ownership,
|
|
111
|
+
wrong-key rejection, and reopening storage with directly supplied keys.
|
|
112
|
+
`bun run bundle` reuses generated bindings for TypeScript-only development.
|
|
113
|
+
|
|
114
|
+
The example uses a new namespace and memory-only database keys on each load. Its encrypted
|
|
115
|
+
files persist, but it intentionally cannot unlock them after reload; a production
|
|
116
|
+
host must implement key recovery/unlock and stable account namespace selection.
|
|
Binary file
|
|
@@ -12,22 +12,32 @@ export function __wbg_addEventListener_520e749bbae24529(...args: any[]): any;
|
|
|
12
12
|
export function __wbg_addEventListener_d85450ee1320c989(...args: any[]): any;
|
|
13
13
|
export function __wbg_append_01c74e5c6b58aa64(...args: any[]): any;
|
|
14
14
|
export function __wbg_arrayBuffer_3b637f0fa65c5351(...args: any[]): any;
|
|
15
|
+
export function __wbg_buffer_54b87055582c8a81(arg0: any): any;
|
|
16
|
+
export function __wbg_byteLength_41862ca4020b9c43(arg0: any): any;
|
|
17
|
+
export function __wbg_byteOffset_d42e18c4441f628b(arg0: any): any;
|
|
15
18
|
export function __wbg_call_8a2dd23819f8a60a(...args: any[]): any;
|
|
16
19
|
export function __wbg_call_a6e5c5dce5018821(...args: any[]): any;
|
|
17
20
|
export function __wbg_clearTimeout_333bba87532ab9d3(arg0: any): void;
|
|
18
21
|
export function __wbg_clearTimeout_6b8d9a38b9263d65(arg0: any): void;
|
|
19
22
|
export function __wbg_close_c65ca0257e895318(...args: any[]): any;
|
|
20
23
|
export function __wbg_code_1fc52b4142a112ac(arg0: any): any;
|
|
24
|
+
export function __wbg_createSyncAccessHandle_0caafebe31e4f2d9(arg0: any): any;
|
|
21
25
|
export function __wbg_crypto_38df2bab126b63dc(arg0: any): any;
|
|
22
26
|
export function __wbg_data_328de4280640da92(arg0: any): any;
|
|
23
27
|
export function __wbg_dispatchEvent_ca78eaf3d469bc25(...args: any[]): any;
|
|
24
28
|
export function __wbg_done_89b2b13e91a60321(arg0: any): any;
|
|
29
|
+
export function __wbg_entries_3d99c52a47728e2f(arg0: any): any;
|
|
25
30
|
export function __wbg_entries_900cefd6f70eb290(arg0: any): any;
|
|
26
31
|
export function __wbg_fetch_074561c3e313c86f(arg0: any): Promise<Response>;
|
|
27
32
|
export function __wbg_fetch_9dad4fe911207b37(arg0: any): Promise<Response>;
|
|
28
33
|
export function __wbg_fetch_b5951fc96f52f786(arg0: any, arg1: any): any;
|
|
34
|
+
export function __wbg_fill_5663f5c647107cce(arg0: any, arg1: any, arg2: any, arg3: any): any;
|
|
35
|
+
export function __wbg_flush_a4bd8d4e05ad23f6(...args: any[]): any;
|
|
29
36
|
export function __wbg_getDate_a1a40c1c5f40fe3b(arg0: any): any;
|
|
30
37
|
export function __wbg_getDay_aa318cce5da74c49(arg0: any): any;
|
|
38
|
+
export function __wbg_getDirectoryHandle_cf175faf1a75a384(arg0: any, arg1: any, arg2: any, arg3: any): any;
|
|
39
|
+
export function __wbg_getDirectory_389283588dfb8117(arg0: any): any;
|
|
40
|
+
export function __wbg_getFileHandle_72de55ab3ca9ad57(arg0: any, arg1: any, arg2: any, arg3: any): any;
|
|
31
41
|
export function __wbg_getFullYear_6af8b229792ae254(arg0: any): any;
|
|
32
42
|
export function __wbg_getHours_9f6561095682ce51(arg0: any): any;
|
|
33
43
|
export function __wbg_getMinutes_b0d5cd90bf9b8f22(arg0: any): any;
|
|
@@ -37,22 +47,29 @@ export function __wbg_getRandomValues_3f44b700395062e5(...args: any[]): any;
|
|
|
37
47
|
export function __wbg_getRandomValues_bf16787eede473f5(...args: any[]): any;
|
|
38
48
|
export function __wbg_getRandomValues_c44a50d8cfdaebeb(...args: any[]): any;
|
|
39
49
|
export function __wbg_getSeconds_40c565b3a6cb05fe(arg0: any): any;
|
|
50
|
+
export function __wbg_getSize_29187e13478442fb(...args: any[]): any;
|
|
40
51
|
export function __wbg_getTime_d6f070c088c9b5ed(arg0: any): any;
|
|
41
52
|
export function __wbg_getTimezoneOffset_dc9862c79e5a81a3(arg0: any): any;
|
|
53
|
+
export function __wbg_getUint32_11fb2913bdb7d394(arg0: any, arg1: any): any;
|
|
42
54
|
export function __wbg_get_507a50627bffa49b(arg0: any, arg1: any): any;
|
|
55
|
+
export function __wbg_get_78f252d074a84d0b(...args: any[]): any;
|
|
43
56
|
export function __wbg_get_c7eb1f358a7654df(...args: any[]): any;
|
|
57
|
+
export function __wbg_get_index_e68b01fac18aa799(arg0: any, arg1: any): any;
|
|
44
58
|
export function __wbg_has_8374cf06984d8bfc(...args: any[]): any;
|
|
45
59
|
export function __wbg_headers_cf9c80f30e2a4eff(arg0: any): any;
|
|
46
60
|
export function __wbg_instanceof_ArrayBuffer_4480b9e0068a8adb(arg0: any): boolean;
|
|
47
61
|
export function __wbg_instanceof_Error_1fdac9f13a8181ba(arg0: any): boolean;
|
|
48
62
|
export function __wbg_instanceof_Response_c8b64b2256f01bec(arg0: any): boolean;
|
|
63
|
+
export function __wbg_instanceof_WorkerGlobalScope_8ec07b5e040a41c3(arg0: any): boolean;
|
|
49
64
|
export function __wbg_isArray_0677c962b281d01a(arg0: any): arg0 is any[];
|
|
50
65
|
export function __wbg_iterator_6f722e4a93058b71(): symbol;
|
|
51
66
|
export function __wbg_length_1f0964f4a5e2c6d8(arg0: any): any;
|
|
52
67
|
export function __wbg_message_8326fb1d549bebc5(arg0: any): any;
|
|
53
68
|
export function __wbg_msCrypto_bd5a034af96bcba6(arg0: any): any;
|
|
54
69
|
export function __wbg_name_b0b4809690944614(arg0: any): any;
|
|
70
|
+
export function __wbg_navigator_51379c10a84aeec9(arg0: any): any;
|
|
55
71
|
export function __wbg_new_0_3da9e97f24fc69be(): Date;
|
|
72
|
+
export function __wbg_new_0c72e559145ea733(arg0: any, arg1: any, arg2: any): DataView<any>;
|
|
56
73
|
export function __wbg_new_0d809930cd1354c6(...args: any[]): any;
|
|
57
74
|
export function __wbg_new_4339b2a2675a03e3(...args: any[]): any;
|
|
58
75
|
export function __wbg_new_bf8729ffe10e9ee7(...args: any[]): any;
|
|
@@ -66,11 +83,14 @@ export function __wbg_new_with_str_and_init_d95cbe11ce28e65e(...args: any[]): an
|
|
|
66
83
|
export function __wbg_new_with_year_month_day_f2354b74b4b2a4f3(arg0: any, arg1: any, arg2: any): Date;
|
|
67
84
|
export function __wbg_next_6dbf2c0ac8cde20f(arg0: any): any;
|
|
68
85
|
export function __wbg_next_71f2aa1cb3d1e37e(...args: any[]): any;
|
|
86
|
+
export function __wbg_next_dfa6c7f0ee891663(...args: any[]): any;
|
|
69
87
|
export function __wbg_node_84ea875411254db1(arg0: any): any;
|
|
70
88
|
export function __wbg_process_44c7a14e11e9f69e(arg0: any): any;
|
|
71
89
|
export function __wbg_prototypesetcall_4770620bbe4688a0(arg0: any, arg1: any, arg2: any): void;
|
|
72
90
|
export function __wbg_randomFillSync_6c25eac9869eb53c(...args: any[]): any;
|
|
73
91
|
export function __wbg_random_039a7d5d06e0d333(): number;
|
|
92
|
+
export function __wbg_read_27d98fb08886b1fc(...args: any[]): any;
|
|
93
|
+
export function __wbg_read_ab82a1efee669e3b(...args: any[]): any;
|
|
74
94
|
export function __wbg_readyState_50bc38c2a9e83db6(arg0: any): any;
|
|
75
95
|
export function __wbg_reason_5dc8e429d537d6a9(arg0: any, arg1: any): void;
|
|
76
96
|
export function __wbg_removeEventListener_a3f23c70077bdcc1(...args: any[]): any;
|
|
@@ -79,10 +99,15 @@ export function __wbg_send_a321b376d40ec867(...args: any[]): any;
|
|
|
79
99
|
export function __wbg_send_df98dd5ede9b3f4d(...args: any[]): any;
|
|
80
100
|
export function __wbg_setTimeout_3a808dd861dd3c12(arg0: any, arg1: any): number;
|
|
81
101
|
export function __wbg_setTimeout_f757f00851f76c42(arg0: any, arg1: any): number;
|
|
102
|
+
export function __wbg_setUint32_1a26b3818324ed47(arg0: any, arg1: any, arg2: any): void;
|
|
103
|
+
export function __wbg_set_4d7dd76f3dae2926(arg0: any, arg1: any, arg2: any): void;
|
|
104
|
+
export function __wbg_set_at_674f6538cd77adef(arg0: any, arg1: any): void;
|
|
82
105
|
export function __wbg_set_binaryType_a37b086c78ca7c29(arg0: any, arg1: any): void;
|
|
83
106
|
export function __wbg_set_body_029f2d171e0a005f(arg0: any, arg1: any): void;
|
|
84
107
|
export function __wbg_set_cache_b4a740b195c051f4(arg0: any, arg1: any): void;
|
|
85
108
|
export function __wbg_set_code_9d09aecd77d789f4(arg0: any, arg1: any): void;
|
|
109
|
+
export function __wbg_set_create_a807a6e9ac628698(arg0: any, arg1: any): void;
|
|
110
|
+
export function __wbg_set_create_fa1dfa475fac91e9(arg0: any, arg1: any): void;
|
|
86
111
|
export function __wbg_set_credentials_bb34a40189e3b43b(arg0: any, arg1: any): void;
|
|
87
112
|
export function __wbg_set_headers_9c61d123c3ee1f10(arg0: any, arg1: any): void;
|
|
88
113
|
export function __wbg_set_method_5532d59b92d76467(arg0: any, arg1: any, arg2: any): void;
|
|
@@ -96,15 +121,20 @@ export function __wbg_static_accessor_GLOBAL_THIS_8d1badc68b5a74f4(): any;
|
|
|
96
121
|
export function __wbg_static_accessor_SELF_146583524fe1469b(): any;
|
|
97
122
|
export function __wbg_static_accessor_WINDOW_f2829a2234d7819e(): any;
|
|
98
123
|
export function __wbg_status_c45b3b9b3033184a(arg0: any): any;
|
|
124
|
+
export function __wbg_storage_3c893ad40b9e831e(arg0: any): any;
|
|
99
125
|
export function __wbg_stringify_b54333f60f1e4dad(...args: any[]): any;
|
|
100
126
|
export function __wbg_subarray_3ed232c8a6baee09(arg0: any, arg1: any, arg2: any): any;
|
|
101
127
|
export function __wbg_text_d3a29f7525a132c3(...args: any[]): any;
|
|
102
128
|
export function __wbg_then_16d107c451e9905d(arg0: any, arg1: any, arg2: any): any;
|
|
103
129
|
export function __wbg_toString_bac9199ff382784d(arg0: any): any;
|
|
130
|
+
export function __wbg_truncate_8832884f3fa99eab(...args: any[]): any;
|
|
131
|
+
export function __wbg_truncate_98a6032d23095328(...args: any[]): any;
|
|
104
132
|
export function __wbg_url_abdb8fb08377f8c0(arg0: any, arg1: any): void;
|
|
105
133
|
export function __wbg_value_a5d5488a9589444a(arg0: any): any;
|
|
106
134
|
export function __wbg_versions_276b2795b1c6a219(arg0: any): any;
|
|
107
135
|
export function __wbg_wasClean_3c7aa2335da09e74(arg0: any): any;
|
|
136
|
+
export function __wbg_write_66c6f8f1293992eb(...args: any[]): any;
|
|
137
|
+
export function __wbg_write_e557b5312ec23477(...args: any[]): any;
|
|
108
138
|
export function __wbindgen_cast_0000000000000001(arg0: any, arg1: any): {
|
|
109
139
|
(...args: any[]): any;
|
|
110
140
|
_wbg_cb_unref(): void;
|