@terminal3/t3n-sdk 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/demo.d.ts +25 -0
- package/dist/index.d.ts +347 -172
- package/dist/index.esm.js +1 -1
- package/dist/index.js +1 -1
- package/dist/src/client/actions.d.ts +22 -0
- package/dist/src/client/config.d.ts +10 -30
- package/dist/src/client/encryption.d.ts +30 -0
- package/dist/src/client/handlers.d.ts +73 -0
- package/dist/src/client/index.d.ts +4 -0
- package/dist/src/client/request-parser.d.ts +48 -0
- package/dist/src/client/t3n-client.d.ts +113 -26
- package/dist/src/index.d.ts +6 -7
- package/dist/src/types/auth.d.ts +5 -6
- package/dist/src/types/index.d.ts +37 -13
- package/dist/src/utils/index.d.ts +0 -1
- package/dist/src/wasm/interface.d.ts +95 -54
- package/dist/src/wasm/loader.d.ts +25 -55
- package/dist/wasm/generated/interfaces/component-session-client-auth.d.ts +12 -0
- package/dist/wasm/generated/interfaces/component-session-client-handshake.d.ts +12 -0
- package/dist/wasm/generated/interfaces/component-session-cookie.d.ts +8 -0
- package/dist/wasm/generated/interfaces/component-session-session.d.ts +7 -0
- package/dist/wasm/generated/session.core.wasm +0 -0
- package/dist/wasm/generated/session.d.ts +10 -87
- package/dist/wasm/generated/session.js +3254 -6713
- package/package.json +1 -1
- package/dist/src/utils/hkdf.d.ts +0 -36
- package/dist/wasm/generated/interfaces/host-session-interfaces-contract-dispatch.d.ts +0 -2
- package/dist/wasm/generated/interfaces/host-session-interfaces-entropy.d.ts +0 -2
- package/dist/wasm/generated/interfaces/host-session-interfaces-eth-signer.d.ts +0 -2
- package/dist/wasm/generated/interfaces/host-session-interfaces-kem.d.ts +0 -3
- package/dist/wasm/generated/interfaces/host-session-interfaces-oidc-client.d.ts +0 -2
- package/dist/wasm/generated/interfaces/host-session-interfaces-oidc.d.ts +0 -3
- package/dist/wasm/generated/interfaces/host-session-interfaces-session-ops.d.ts +0 -9
- package/dist/wasm/generated/interfaces/host-session-interfaces-transport.d.ts +0 -2
- package/dist/wasm/generated/interfaces/tee-session-client-auth.d.ts +0 -7
- package/dist/wasm/generated/interfaces/tee-session-client-handshake.d.ts +0 -12
- package/dist/wasm/generated/interfaces/tee-session-cookie.d.ts +0 -7
- package/dist/wasm/generated/interfaces/tee-session-server-admin.d.ts +0 -2
- package/dist/wasm/generated/interfaces/tee-session-server-auth.d.ts +0 -10
- package/dist/wasm/generated/interfaces/tee-session-server-handshake.d.ts +0 -15
- package/dist/wasm/generated/interfaces/tee-session-server-webhook.d.ts +0 -6
- package/dist/wasm/generated/interfaces/tee-session-session-crypto.d.ts +0 -3
- package/dist/wasm/generated/session.core2.wasm +0 -0
- package/dist/wasm/generated/session.core3.wasm +0 -0
package/README.md
CHANGED
package/dist/demo.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T3n SDK Real WASM Demo Script
|
|
3
|
+
*
|
|
4
|
+
* This script demonstrates the T3n SDK using the actual WASM component
|
|
5
|
+
* built from the node session module.
|
|
6
|
+
*/
|
|
7
|
+
import { SessionStatus, Did } from "./src/index";
|
|
8
|
+
import { type ChildProcess } from "child_process";
|
|
9
|
+
declare global {
|
|
10
|
+
var __oidcServerProcess: ChildProcess | undefined;
|
|
11
|
+
}
|
|
12
|
+
interface DemoResult {
|
|
13
|
+
sessionId: {
|
|
14
|
+
value: string;
|
|
15
|
+
};
|
|
16
|
+
status: SessionStatus;
|
|
17
|
+
wasmLoaded: boolean;
|
|
18
|
+
authenticated: boolean;
|
|
19
|
+
did: Did | null;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Main Demo Function
|
|
23
|
+
*/
|
|
24
|
+
declare function runRealWasmDemo(): Promise<DemoResult>;
|
|
25
|
+
export { runRealWasmDemo, type DemoResult };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,71 +1,112 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* WASM Component Interface
|
|
2
|
+
* WASM Component Interface - Mirrors the WIT specification exactly
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* instantiation); all protocol glue lives inside the contract.
|
|
4
|
+
* This interface works with completely opaque byte arrays, just like the WIT interface.
|
|
5
|
+
* The TypeScript SDK doesn't know about internal state machine phases or details.
|
|
7
6
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
keys: ClientSessionKeys;
|
|
15
|
-
authenticated: boolean;
|
|
16
|
-
did?: string;
|
|
17
|
-
expirySec: bigint;
|
|
7
|
+
/**
|
|
8
|
+
* Result type for WASM next() operations
|
|
9
|
+
*/
|
|
10
|
+
interface WasmNextResult {
|
|
11
|
+
state: Uint8Array;
|
|
12
|
+
request: Uint8Array;
|
|
18
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Client handshake operations - completely opaque byte arrays only
|
|
16
|
+
*/
|
|
19
17
|
interface ClientHandshake {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Process next step in handshake
|
|
20
|
+
* @param state - Current handshake state (null for initial call)
|
|
21
|
+
* @param action - Action to process (opaque bytes)
|
|
22
|
+
* @returns Promise with new state and request to send
|
|
23
|
+
*/
|
|
24
|
+
next(state: Uint8Array | null, action: Uint8Array): Promise<WasmNextResult>;
|
|
25
|
+
/**
|
|
26
|
+
* Attempt to finalize handshake
|
|
27
|
+
* @param state - Current handshake state
|
|
28
|
+
* @returns Promise with session bytes if successful
|
|
29
|
+
* @throws Error containing "not yet finalized" if the state machine
|
|
30
|
+
* has not reached its terminal phase. The SDK runtime treats
|
|
31
|
+
* this as the loop's "keep going" signal, not a real error.
|
|
32
|
+
*/
|
|
33
|
+
finish(state: Uint8Array): Promise<Uint8Array>;
|
|
25
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Client authentication operations - completely opaque byte arrays only
|
|
37
|
+
*/
|
|
26
38
|
interface ClientAuth {
|
|
27
|
-
runEth(sessionKeys: Uint8Array, ethAddress: string, siweDomain: string | undefined, siweUrl: string | undefined, siweChainId: bigint | undefined): AuthOutcome;
|
|
28
39
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
40
|
+
* Process next step in authentication
|
|
41
|
+
* @param state - Current auth state (null for initial call)
|
|
42
|
+
* @param action - Action to process (opaque bytes)
|
|
43
|
+
* @returns Promise with new state and request to send
|
|
32
44
|
*/
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
did?: string;
|
|
44
|
-
expirySec: bigint;
|
|
45
|
-
refreshedCookie?: string;
|
|
45
|
+
next(state: Uint8Array | null, action: Uint8Array): Promise<WasmNextResult>;
|
|
46
|
+
/**
|
|
47
|
+
* Attempt to finalize authentication
|
|
48
|
+
* @param state - Current auth state
|
|
49
|
+
* @returns Promise with DID bytes if successful
|
|
50
|
+
* @throws Error containing "not yet finalized" if the state machine
|
|
51
|
+
* has not reached its terminal phase. The SDK runtime treats
|
|
52
|
+
* this as the loop's "keep going" signal, not a real error.
|
|
53
|
+
*/
|
|
54
|
+
finish(state: Uint8Array): Promise<Uint8Array>;
|
|
46
55
|
}
|
|
47
|
-
|
|
48
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Client authentication operations - completely opaque byte arrays only
|
|
58
|
+
*/
|
|
59
|
+
interface ClientExecute {
|
|
60
|
+
/**
|
|
61
|
+
* Process next step in authentication
|
|
62
|
+
* @param state - Current auth state (null for initial call)
|
|
63
|
+
* @param action - Action to process (opaque bytes)
|
|
64
|
+
* @returns Promise with new state and request to send
|
|
65
|
+
*/
|
|
66
|
+
next(state: Uint8Array | null, action: Uint8Array): Promise<WasmNextResult>;
|
|
67
|
+
/**
|
|
68
|
+
* Attempt to finalize authentication
|
|
69
|
+
* @param state - Current auth state
|
|
70
|
+
* @returns Promise with DID bytes if successful
|
|
71
|
+
* @throws Error containing "not yet finalized" if the state machine
|
|
72
|
+
* has not reached its terminal phase. The SDK runtime treats
|
|
73
|
+
* this as the loop's "keep going" signal, not a real error.
|
|
74
|
+
*/
|
|
75
|
+
finish(state: Uint8Array): Promise<Uint8Array>;
|
|
49
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Session encryption/decryption operations - completely opaque byte arrays only
|
|
79
|
+
*/
|
|
50
80
|
interface SessionCrypto {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Encrypt plaintext using session
|
|
83
|
+
* @param session - Session state (opaque bytes)
|
|
84
|
+
* @param plaintext - Data to encrypt
|
|
85
|
+
* @returns Promise with encrypted bytes
|
|
86
|
+
*/
|
|
87
|
+
encrypt(session: Uint8Array, plaintext: Uint8Array): Promise<Uint8Array>;
|
|
88
|
+
/**
|
|
89
|
+
* Decrypt ciphertext using session
|
|
90
|
+
* @param session - Session state (opaque bytes)
|
|
91
|
+
* @param ciphertext - Data to decrypt
|
|
92
|
+
* @returns Promise with decrypted bytes
|
|
93
|
+
*/
|
|
94
|
+
decrypt(session: Uint8Array, ciphertext: Uint8Array): Promise<Uint8Array>;
|
|
61
95
|
}
|
|
62
|
-
/**
|
|
96
|
+
/**
|
|
97
|
+
* Main WASM Component interface - mirrors the WIT interface exactly
|
|
98
|
+
*
|
|
99
|
+
* This is completely opaque to the TypeScript layer. All state machine logic,
|
|
100
|
+
* authentication flows, and cryptographic operations are handled in WASM.
|
|
101
|
+
*/
|
|
63
102
|
interface WasmComponent {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
103
|
+
/** Client-side state machines exported by the WASM component. */
|
|
104
|
+
flow: {
|
|
105
|
+
handshake: ClientHandshake;
|
|
106
|
+
auth: ClientAuth;
|
|
107
|
+
execute: ClientExecute;
|
|
108
|
+
};
|
|
109
|
+
session: SessionCrypto;
|
|
69
110
|
}
|
|
70
111
|
|
|
71
112
|
/**
|
|
@@ -172,75 +213,38 @@ declare function createLogger(level?: LogLevel): Logger;
|
|
|
172
213
|
declare function getLogger(): Logger;
|
|
173
214
|
|
|
174
215
|
/**
|
|
175
|
-
* WASM Component Loader
|
|
176
|
-
*
|
|
177
|
-
* Loads the `tee:session@1.0.0` jco-transpiled component. Host
|
|
178
|
-
* imports (`host:session-interfaces/*`) are supplied at
|
|
179
|
-
* instantiation; the caller can override any of them via
|
|
180
|
-
* `WasmLoadConfig.hostImports` to plug a custom KEM public-key
|
|
181
|
-
* source, ETH signer, etc. Defaults cover the common case for the
|
|
182
|
-
* browser SDK:
|
|
216
|
+
* WASM Component Loader
|
|
183
217
|
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
* - `eth-signer.eth-sign`: injected wallet (window.ethereum) if present
|
|
188
|
-
* - `session-ops.now-ms`: Date.now()
|
|
189
|
-
* - `session-ops.tee-address`, `set-cookie`: caller-supplied or stubs
|
|
218
|
+
* This module provides utilities for loading and initializing the WASM component.
|
|
219
|
+
* The actual WASM loading implementation will depend on the build system and
|
|
220
|
+
* deployment environment.
|
|
190
221
|
*/
|
|
191
222
|
|
|
192
|
-
/**
|
|
193
|
-
* Host imports supplied at WASM instantiation. Any subset may be
|
|
194
|
-
* overridden by the caller; unset ones fall back to a safe default
|
|
195
|
-
* (or an error stub for server-only methods like `decapsulate`).
|
|
196
|
-
*/
|
|
197
|
-
interface SessionHostImports {
|
|
198
|
-
/** Fetch the server's ML-KEM public key (client-side). */
|
|
199
|
-
mlKemPublicKey?: () => Uint8Array | Promise<Uint8Array>;
|
|
200
|
-
/** CSPRNG. Defaults to WebCrypto `getRandomValues`. */
|
|
201
|
-
random?: (len: number) => Uint8Array;
|
|
202
|
-
/** EIP-191 / SIWE signer. Defaults to error (caller must supply). */
|
|
203
|
-
ethSign?: (message: Uint8Array) => Uint8Array | Promise<Uint8Array>;
|
|
204
|
-
/**
|
|
205
|
-
* OIDC user-interaction callback. The contract supplies the
|
|
206
|
-
* server-bound `nonce`; the SDK consumer runs whatever popup /
|
|
207
|
-
* redirect flow is appropriate for `provider` and returns the
|
|
208
|
-
* IdP-signed `id_token`. Defaults to error (caller must supply
|
|
209
|
-
* when using OIDC auth).
|
|
210
|
-
*/
|
|
211
|
-
getIdToken?: (provider: string, nonce: string) => string | Promise<string>;
|
|
212
|
-
/** Current time in ms. Defaults to Date.now() (as bigint). */
|
|
213
|
-
nowMs?: () => bigint;
|
|
214
|
-
/** TEE address — server-only; client stub returns 20 zero bytes. */
|
|
215
|
-
teeAddress?: () => Uint8Array;
|
|
216
|
-
/** Called when the guest emits a refreshed cookie. */
|
|
217
|
-
setCookie?: (value: string) => void;
|
|
218
|
-
/**
|
|
219
|
-
* HTTP transport the contract uses to POST JSON-RPC requests. The
|
|
220
|
-
* SDK wires this to its `Transport` under the hood — the contract
|
|
221
|
-
* supplies the method name and params bytes; the SDK layers on the
|
|
222
|
-
* Session-Id header, JSON-RPC envelope, and returns the raw result
|
|
223
|
-
* bytes.
|
|
224
|
-
*/
|
|
225
|
-
postRpc?: (method: string, sessionId: string, params: string) => string | Promise<string>;
|
|
226
|
-
}
|
|
227
223
|
/**
|
|
228
224
|
* Configuration for WASM component loading
|
|
229
225
|
*/
|
|
230
226
|
interface WasmLoadConfig {
|
|
231
227
|
/** Path or URL to the WASM module */
|
|
232
228
|
wasmPath?: string;
|
|
229
|
+
/** Custom fetch function for loading WASM */
|
|
230
|
+
fetchFn?: typeof fetch;
|
|
231
|
+
/** Additional initialization options */
|
|
232
|
+
initOptions?: Record<string, unknown>;
|
|
233
233
|
/** Optional logger instance - if not provided, uses global default */
|
|
234
234
|
logger?: Logger;
|
|
235
|
-
/** Overrides for the host-import functions. */
|
|
236
|
-
hostImports?: SessionHostImports;
|
|
237
235
|
}
|
|
238
236
|
/**
|
|
239
|
-
* Load and initialize the T3n WASM component
|
|
237
|
+
* Load and initialize the T3n WASM component
|
|
240
238
|
*
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
*
|
|
239
|
+
* @param config - Optional configuration for loading the WASM component
|
|
240
|
+
* @returns Promise that resolves to the initialized WASM component
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* ```typescript
|
|
244
|
+
* const wasmComponent = await loadWasmComponent({
|
|
245
|
+
* wasmPath: '/path/to/t3n.wasm'
|
|
246
|
+
* });
|
|
247
|
+
* ```
|
|
244
248
|
*/
|
|
245
249
|
declare function loadWasmComponent(config?: WasmLoadConfig): Promise<WasmComponent>;
|
|
246
250
|
|
|
@@ -282,15 +286,14 @@ declare enum AuthMethod {
|
|
|
282
286
|
/**
|
|
283
287
|
* OIDC credentials interface.
|
|
284
288
|
*
|
|
285
|
-
* The TEE generates a session-binding nonce
|
|
286
|
-
*
|
|
287
|
-
*
|
|
288
|
-
*
|
|
289
|
-
* nonce)` from inside `runOidc` and feeds the returned `id_token`
|
|
290
|
-
* to the server.
|
|
289
|
+
* The TEE generates a session-binding nonce that must be included in
|
|
290
|
+
* the Google authorization URL (`&nonce=…`). The `getIdToken` callback
|
|
291
|
+
* receives this nonce and must return the `id_token` JWT obtained
|
|
292
|
+
* from the OIDC provider with the nonce baked into its claims.
|
|
291
293
|
*/
|
|
292
294
|
interface OidcCredentials {
|
|
293
295
|
provider: string;
|
|
296
|
+
getIdToken: (nonce: string) => Promise<string>;
|
|
294
297
|
}
|
|
295
298
|
/**
|
|
296
299
|
* Base authentication input with method discriminator
|
|
@@ -322,6 +325,47 @@ type AuthInput = EthAuthInput | OidcAuthInput;
|
|
|
322
325
|
declare function createEthAuthInput(address: string): EthAuthInput;
|
|
323
326
|
declare function createOidcAuthInput(credentials: OidcCredentials): OidcAuthInput;
|
|
324
327
|
|
|
328
|
+
/**
|
|
329
|
+
* Public types export for T3n SDK
|
|
330
|
+
*/
|
|
331
|
+
/**
|
|
332
|
+
* Guest-to-Host request handler function type
|
|
333
|
+
*
|
|
334
|
+
* Handles requests from WASM guest that need host (SDK) to perform side
|
|
335
|
+
* effects. The exact shape of `requestData` depends on the specific
|
|
336
|
+
* handler — see `GuestToHostHandlers` below for the per-handler shapes.
|
|
337
|
+
* The wrapper layer in `T3nClient.handleGuestToHost` parses the JSON
|
|
338
|
+
* envelope and calls the matching handler with the parsed data, so
|
|
339
|
+
* each handler's implementation should narrow `requestData` to its
|
|
340
|
+
* own expected shape.
|
|
341
|
+
*/
|
|
342
|
+
type GuestToHostHandler = (requestData: Record<string, unknown>) => Promise<Uint8Array>;
|
|
343
|
+
/**
|
|
344
|
+
* Map of guest-to-host request handlers
|
|
345
|
+
* Keys match the guest_to_host tag values from the WASM
|
|
346
|
+
*/
|
|
347
|
+
interface GuestToHostHandlers {
|
|
348
|
+
/**
|
|
349
|
+
* Handle Ethereum signature requests
|
|
350
|
+
* requestData: { guest_to_host: "EthSign", challenge: string (base64) }
|
|
351
|
+
* Returns: JSON bytes of { host_to_guest: "EthSign", challenge: string, signature: string }
|
|
352
|
+
*/
|
|
353
|
+
EthSign?: GuestToHostHandler;
|
|
354
|
+
/**
|
|
355
|
+
* Handle MlKem public key requests
|
|
356
|
+
* requestData: { guest_to_host: "MlKemPublicKey" }
|
|
357
|
+
* Returns: JSON bytes of { host_to_guest: "MlKemPublicKey", key: string }
|
|
358
|
+
*/
|
|
359
|
+
MlKemPublicKey?: GuestToHostHandler;
|
|
360
|
+
/**
|
|
361
|
+
* Handle random bytes requests
|
|
362
|
+
* requestData: { guest_to_host: "Random", len?: number }
|
|
363
|
+
* Returns: JSON bytes of { host_to_guest: "Random", bytes: string (base64) }
|
|
364
|
+
*/
|
|
365
|
+
Random?: GuestToHostHandler;
|
|
366
|
+
[key: string]: GuestToHostHandler | undefined;
|
|
367
|
+
}
|
|
368
|
+
|
|
325
369
|
/**
|
|
326
370
|
* Transport layer for T3n SDK
|
|
327
371
|
*
|
|
@@ -440,7 +484,7 @@ declare class MockTransport implements Transport {
|
|
|
440
484
|
interface T3nClientConfig {
|
|
441
485
|
/** Base URL of the T3n node (used if transport not provided) */
|
|
442
486
|
baseUrl?: string;
|
|
443
|
-
/** WASM component instance
|
|
487
|
+
/** WASM component instance for cryptographic operations */
|
|
444
488
|
wasmComponent: WasmComponent;
|
|
445
489
|
/** Optional transport layer - if not provided, uses HttpTransport with baseUrl */
|
|
446
490
|
transport?: Transport;
|
|
@@ -450,90 +494,221 @@ interface T3nClientConfig {
|
|
|
450
494
|
timeout?: number;
|
|
451
495
|
/** Optional custom headers to include in requests */
|
|
452
496
|
headers?: Record<string, string>;
|
|
453
|
-
/**
|
|
497
|
+
/**
|
|
498
|
+
* Log level for this client instance.
|
|
499
|
+
* Defaults to global log level (LogLevel.ERROR) if not specified.
|
|
500
|
+
* Use LogLevel.DEBUG for verbose logging, LogLevel.INFO for informational messages,
|
|
501
|
+
* LogLevel.WARN for warnings, or LogLevel.ERROR for errors only.
|
|
502
|
+
*/
|
|
454
503
|
logLevel?: LogLevel;
|
|
455
504
|
/** Optional custom logger - if provided, overrides logLevel */
|
|
456
505
|
logger?: Logger;
|
|
457
|
-
/**
|
|
458
|
-
|
|
459
|
-
* (SIWE) flow. Given the SIWE message bytes, the callback must
|
|
460
|
-
* produce a 65-byte `(r || s || v)` signature over the EIP-191
|
|
461
|
-
* personal-sign digest — matching `cryptography::ecdsa::eth`
|
|
462
|
-
* recovery on the node. A convenience wrapper for raw-private-key
|
|
463
|
-
* signing is planned for the follow-up commit that lands full
|
|
464
|
-
* ETH auth support.
|
|
465
|
-
*/
|
|
466
|
-
ethSign?: (message: Uint8Array) => Promise<Uint8Array>;
|
|
467
|
-
/**
|
|
468
|
-
* Ethereum address (0x-prefixed, 20 bytes hex) of the user
|
|
469
|
-
* authenticating. Required by `authenticate()` for the ETH flow —
|
|
470
|
-
* the server recovers the signer from the SIWE message and
|
|
471
|
-
* compares to this address.
|
|
472
|
-
*/
|
|
473
|
-
ethAddress?: string;
|
|
474
|
-
/**
|
|
475
|
-
* SIWE domain / URI / chain-id used in the message the SDK builds.
|
|
476
|
-
* Matches `SiwePolicy` on the server — the server's allowlist
|
|
477
|
-
* policy (if configured in NodeConfig) only accepts matching
|
|
478
|
-
* values. Defaults: domain `"localhost"`, URL `"https://trinity.io"`,
|
|
479
|
-
* chain ID `1` (Ethereum mainnet).
|
|
480
|
-
*/
|
|
481
|
-
siweDomain?: string;
|
|
482
|
-
siweUrl?: string;
|
|
483
|
-
siweChainId?: number;
|
|
506
|
+
/** Optional guest-to-host request handlers - provides custom behavior for WASM requests */
|
|
507
|
+
handlers?: GuestToHostHandlers;
|
|
484
508
|
}
|
|
485
509
|
|
|
486
510
|
/**
|
|
487
|
-
* T3n Client
|
|
488
|
-
*
|
|
489
|
-
* The SDK communicates with the session contract strictly through
|
|
490
|
-
* WIT:
|
|
491
|
-
* - Calls `clientHandshake.run(sid)` — contract handles ML-KEM
|
|
492
|
-
* encapsulation, HKDF, POSTs via `host.transport.postRpc`,
|
|
493
|
-
* derives session keys, returns them.
|
|
494
|
-
* - Calls `clientAuth.runEth(keys, address, ...)` — contract
|
|
495
|
-
* builds the SIWE message, signs via `host.eth-signer.ethSign`,
|
|
496
|
-
* POSTs + parses the Finish response, returns the DID.
|
|
497
|
-
* - For `execute()`, the SDK just encrypts the JSON-RPC payload
|
|
498
|
-
* via `sessionCrypto.encrypt` and POSTs it through its transport.
|
|
511
|
+
* T3n Client - Main SDK class
|
|
499
512
|
*
|
|
500
|
-
*
|
|
501
|
-
*
|
|
502
|
-
* of protocol truth.
|
|
513
|
+
* Provides a simple interface for establishing secure sessions with T3n nodes.
|
|
514
|
+
* All cryptographic complexity is handled in WASM components.
|
|
503
515
|
*/
|
|
504
516
|
|
|
517
|
+
/**
|
|
518
|
+
* Main T3n SDK Client
|
|
519
|
+
*/
|
|
505
520
|
declare class T3nClient {
|
|
506
521
|
private readonly config;
|
|
507
522
|
private readonly transport;
|
|
508
523
|
private readonly sessionId;
|
|
509
524
|
private readonly logger;
|
|
525
|
+
private readonly encryption;
|
|
510
526
|
private status;
|
|
511
|
-
|
|
527
|
+
/**
|
|
528
|
+
* In-flight WASM state-machine bytes. Holds the opaque state
|
|
529
|
+
* returned by `flow[method].next()` between iterations of
|
|
530
|
+
* `runFlow`. Always cleared at the top of `runFlow` and again
|
|
531
|
+
* once `tryFinalize` has extracted the terminal payload — so
|
|
532
|
+
* outside of an active loop these slots are always `null`.
|
|
533
|
+
*/
|
|
534
|
+
private wasmState;
|
|
535
|
+
/**
|
|
536
|
+
* Terminal payloads produced by `flow[method].finish()`:
|
|
537
|
+
* - `handshake` → serialized session blob, used by
|
|
538
|
+
* `getSessionState()` for subsequent `session.encrypt` calls.
|
|
539
|
+
* - `auth` → serialized DID; the public `authenticate()` decodes
|
|
540
|
+
* it into `this.did` and the slot is otherwise unused.
|
|
541
|
+
* - `execute` → unused (executes return immediately to the caller).
|
|
542
|
+
*
|
|
543
|
+
* Stored in a dedicated field instead of reusing `wasmState`
|
|
544
|
+
* because the two meanings — "in-flight state machine" vs
|
|
545
|
+
* "finalized payload" — are semantically different and merging
|
|
546
|
+
* them invites the bug-class Devin flagged in PR #1140.
|
|
547
|
+
*/
|
|
548
|
+
private finalizedPayload;
|
|
512
549
|
private did;
|
|
550
|
+
private handshakeResult;
|
|
513
551
|
constructor(config: T3nClientConfig);
|
|
552
|
+
/**
|
|
553
|
+
* Start the handshake process with the T3n node
|
|
554
|
+
*/
|
|
514
555
|
handshake(): Promise<HandshakeResult>;
|
|
556
|
+
/**
|
|
557
|
+
* Authenticate with the T3n node.
|
|
558
|
+
*
|
|
559
|
+
* For OIDC, this runs a two-step nonce-bound flow:
|
|
560
|
+
* 1. Sends `InitOidcAuth` to server → receives session-binding nonce.
|
|
561
|
+
* 2. Calls `getIdToken(nonce)` callback so the app can include the
|
|
562
|
+
* nonce in the Google authorization URL.
|
|
563
|
+
* 3. Sends `SubmitIdToken` with the nonce-bearing token → receives DID.
|
|
564
|
+
*/
|
|
515
565
|
authenticate(authInput: AuthInput): Promise<Did>;
|
|
566
|
+
/**
|
|
567
|
+
* OIDC two-step authentication with session-binding nonce.
|
|
568
|
+
*
|
|
569
|
+
* Bypasses the WASM client state machine and makes two encrypted
|
|
570
|
+
* RPC calls directly:
|
|
571
|
+
* 1. `InitOidcAuth { provider }` → server generates nonce → returns
|
|
572
|
+
* `ProvideNonce { nonce }`.
|
|
573
|
+
* 2. App calls `getIdToken(nonce)` to obtain a nonce-bound `id_token`.
|
|
574
|
+
* 3. `SubmitIdToken { id_token }` → server verifies token + nonce →
|
|
575
|
+
* returns `Finish { did }`.
|
|
576
|
+
*/
|
|
577
|
+
private authenticateOidc;
|
|
578
|
+
/**
|
|
579
|
+
* Execute an action on the T3n node
|
|
580
|
+
*/
|
|
516
581
|
execute(payload: unknown): Promise<string>;
|
|
517
582
|
getSessionId(): SessionId;
|
|
518
583
|
getStatus(): SessionStatus;
|
|
519
584
|
getDid(): Did | null;
|
|
520
|
-
isAuthenticated(): boolean;
|
|
521
585
|
getLastSetCookie(): string | null;
|
|
522
586
|
getLastResponseHeaders(): Record<string, string>;
|
|
587
|
+
isAuthenticated(): boolean;
|
|
523
588
|
/**
|
|
524
|
-
*
|
|
525
|
-
*
|
|
526
|
-
*
|
|
527
|
-
*
|
|
589
|
+
* Run a WASM state machine flow to completion.
|
|
590
|
+
*
|
|
591
|
+
* Clears both `wasmState[method]` and `finalizedPayload[method]`
|
|
592
|
+
* at entry so a flow that previously threw partway (e.g. an RPC
|
|
593
|
+
* error) starts from a clean slate on retry. Without the reset,
|
|
594
|
+
* stale state from the failed attempt leaks into the new flow
|
|
595
|
+
* and `tryFinalize` may either spuriously succeed or run `next()`
|
|
596
|
+
* against a state that no longer matches the action we're sending.
|
|
528
597
|
*
|
|
529
|
-
* `
|
|
530
|
-
*
|
|
531
|
-
*
|
|
598
|
+
* The `tryFinalize`-then-`next` order is load-bearing: the loop's
|
|
599
|
+
* exit condition fires *after* the previous iteration's
|
|
600
|
+
* `handleWasmRequest` has flushed the outbound peer reply, so
|
|
601
|
+
* every state-machine emission reaches the wire before we extract
|
|
602
|
+
* the final payload.
|
|
532
603
|
*/
|
|
533
|
-
|
|
534
|
-
|
|
604
|
+
private runFlow;
|
|
605
|
+
/**
|
|
606
|
+
* Try to finalize the current flow. Returns the finish() payload
|
|
607
|
+
* (a serialized Session for handshake, a serialized DID for auth)
|
|
608
|
+
* or `null` if the state machine has not reached its terminal phase
|
|
609
|
+
* yet.
|
|
610
|
+
*
|
|
611
|
+
* The "not yet finalized" case is the loop's signal to keep
|
|
612
|
+
* iterating, not a real error. Any *other* failure must propagate
|
|
613
|
+
* so callers see real WASM errors instead of silent retries that
|
|
614
|
+
* spin forever.
|
|
615
|
+
*
|
|
616
|
+
* The terminal payload is stored in `finalizedPayload[method]`
|
|
617
|
+
* (a separate field from `wasmState[method]`) so the in-flight
|
|
618
|
+
* state-machine bytes and the finalized session/DID bytes never
|
|
619
|
+
* occupy the same slot. `getSessionState()` reads from
|
|
620
|
+
* `finalizedPayload.handshake`.
|
|
621
|
+
*/
|
|
622
|
+
private tryFinalize;
|
|
623
|
+
/**
|
|
624
|
+
* Handle a WASM request based on its type
|
|
625
|
+
*/
|
|
626
|
+
private handleWasmRequest;
|
|
627
|
+
/**
|
|
628
|
+
* Handle a send-remote request by calling the RPC endpoint
|
|
629
|
+
*/
|
|
630
|
+
private handleSendRemote;
|
|
631
|
+
private captureHandshakeResult;
|
|
632
|
+
/**
|
|
633
|
+
* Handle a guest-to-host request using configured handlers
|
|
634
|
+
*/
|
|
635
|
+
private handleGuestToHost;
|
|
636
|
+
/**
|
|
637
|
+
* Send an RPC request with automatic encryption/decryption
|
|
638
|
+
*/
|
|
639
|
+
private sendRpcRequest;
|
|
640
|
+
/**
|
|
641
|
+
* Get the finalized session blob (for `session.encrypt` calls).
|
|
642
|
+
* Populated by `tryFinalize` once the handshake state machine
|
|
643
|
+
* reaches its terminal phase.
|
|
644
|
+
*/
|
|
645
|
+
private getSessionState;
|
|
535
646
|
}
|
|
536
647
|
|
|
648
|
+
/**
|
|
649
|
+
* Guest-to-Host Request Handlers
|
|
650
|
+
*
|
|
651
|
+
* These handle requests from WASM that need the host environment to perform side effects.
|
|
652
|
+
* Examples: signing challenges, providing public keys, generating random bytes.
|
|
653
|
+
*/
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* Account — MetaMask handler accepts either a plain address string or an
|
|
657
|
+
* object with an `address` field (for compatibility with various wallet
|
|
658
|
+
* libraries).
|
|
659
|
+
*/
|
|
660
|
+
type EthAccount = string | {
|
|
661
|
+
address: string;
|
|
662
|
+
};
|
|
663
|
+
/**
|
|
664
|
+
* Create an EthSign handler using MetaMask (window.ethereum)
|
|
665
|
+
* @param account - MetaMask account (string address or object with address property)
|
|
666
|
+
* @param logger - Optional logger instance. Defaults to a logger using the global log level (LogLevel.ERROR).
|
|
667
|
+
* Pass a custom logger to override logging behavior for this handler.
|
|
668
|
+
* @param privateKey - Optional private key for signing (if provided, MetaMask is not used)
|
|
669
|
+
*/
|
|
670
|
+
declare function metamask_sign(account: EthAccount, logger?: Logger, privateKey?: string | undefined): GuestToHostHandler;
|
|
671
|
+
/**
|
|
672
|
+
* Get the current MetaMask address
|
|
673
|
+
* @returns Ethereum address (lowercase, 0x prefixed)
|
|
674
|
+
*/
|
|
675
|
+
declare function metamask_get_address(): Promise<string>;
|
|
676
|
+
/**
|
|
677
|
+
* Get the address for a given private key
|
|
678
|
+
* @param privateKey - Ethereum private key (0x prefixed hex string)
|
|
679
|
+
* @returns Ethereum address (lowercase, 0x prefixed)
|
|
680
|
+
*/
|
|
681
|
+
declare function eth_get_address(privateKey: string): string;
|
|
682
|
+
/**
|
|
683
|
+
* Create an MlKemPublicKey handler that lazily fetches the root public key
|
|
684
|
+
* from `${baseUrl}/status` on first invocation and caches the encoded
|
|
685
|
+
* response for subsequent calls.
|
|
686
|
+
*
|
|
687
|
+
* @param baseUrl - **Required**. The node URL whose `/status` endpoint should
|
|
688
|
+
* serve the ML-KEM public key. Must be the same URL the
|
|
689
|
+
* T3nClient is constructed with — otherwise the handshake
|
|
690
|
+
* encrypts to one node and sends ciphertext to another.
|
|
691
|
+
*
|
|
692
|
+
* Was optional in 0.3.x, where omitting it caused the lazy
|
|
693
|
+
* fetch to silently fall back to `NODE_URLS[currentEnv]` and
|
|
694
|
+
* hit the wrong node. Three downstream consumers (demo.ts,
|
|
695
|
+
* t3-apps dev wallet hooks, t3n-mcp session manager) all
|
|
696
|
+
* hit this trap before we tightened the type.
|
|
697
|
+
*/
|
|
698
|
+
declare function createMlKemPublicKeyHandler(baseUrl: string): GuestToHostHandler;
|
|
699
|
+
/**
|
|
700
|
+
* Create Random handler backed by crypto.getRandomValues
|
|
701
|
+
* Note: The Rust Vec<u8> type serializes as an array of bytes, not a base64 string
|
|
702
|
+
*/
|
|
703
|
+
declare function createRandomHandler(): GuestToHostHandler;
|
|
704
|
+
/**
|
|
705
|
+
* Create the default handler set required by the T3n handshake.
|
|
706
|
+
*
|
|
707
|
+
* @param baseUrl - **Required**. Forwarded to `createMlKemPublicKeyHandler`
|
|
708
|
+
* so the lazy /status fetch hits the right node.
|
|
709
|
+
*/
|
|
710
|
+
declare function createDefaultHandlers(baseUrl: string): GuestToHostHandlers;
|
|
711
|
+
|
|
537
712
|
/**
|
|
538
713
|
* Cryptographic utilities for T3n SDK
|
|
539
714
|
*
|
|
@@ -817,5 +992,5 @@ declare function clearKeyCache(): void;
|
|
|
817
992
|
*/
|
|
818
993
|
declare function loadConfig(baseUrl?: string): SdkConfig;
|
|
819
994
|
|
|
820
|
-
export { AuthMethod, AuthenticationError, HandshakeError, HttpTransport, LogLevel, MockTransport, NODE_URLS, RpcError, SessionStateError, SessionStatus, T3nClient, T3nError, WasmError, bytesToString, clearKeyCache, createEthAuthInput, createLogger, createOidcAuthInput, decodeWasmErrorMessage, extractWasmError, fetchDkgAttestation, fetchMlKemPublicKey, generateRandomString, generateUUID, getEnvironment, getEnvironmentName, getGlobalLogLevel, getLogger, getNodeUrl, getScriptVersion, loadConfig, loadWasmComponent, redactSecrets, redactSecretsFromJson, setEnvironment, setGlobalLogLevel, setNodeUrl, stringToBytes, validateConfig, verifyDkgAttestation, verifyTdxQuote };
|
|
821
|
-
export type { AuthInput,
|
|
995
|
+
export { AuthMethod, AuthenticationError, HandshakeError, HttpTransport, LogLevel, MockTransport, NODE_URLS, RpcError, SessionStateError, SessionStatus, T3nClient, T3nError, WasmError, bytesToString, clearKeyCache, createDefaultHandlers, createEthAuthInput, createLogger, createMlKemPublicKeyHandler, createOidcAuthInput, createRandomHandler, decodeWasmErrorMessage, eth_get_address, extractWasmError, fetchDkgAttestation, fetchMlKemPublicKey, generateRandomString, generateUUID, getEnvironment, getEnvironmentName, getGlobalLogLevel, getLogger, getNodeUrl, getScriptVersion, loadConfig, loadWasmComponent, metamask_get_address, metamask_sign, redactSecrets, redactSecretsFromJson, setEnvironment, setGlobalLogLevel, setNodeUrl, stringToBytes, validateConfig, verifyDkgAttestation, verifyTdxQuote };
|
|
996
|
+
export type { AuthInput, ClientAuth, ClientHandshake, ConfigValidationResult, Did, DkgAttestation, DkgVerifyResult, Environment, EthAuthInput, GuestToHostHandler, GuestToHostHandlers, HandshakeResult, JsonRpcRequest, JsonRpcResponse, Logger, OidcAuthInput, OidcCredentials, PeerQuoteResult, QuoteVerifyResult, SdkConfig, SessionCrypto, SessionId, T3nClientConfig, Transport, WasmComponent, WasmNextResult };
|