@qrlwallet/connect 3.2.0 → 4.0.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 +123 -49
- package/dist/index.d.mts +375 -70
- package/dist/index.d.ts +375 -70
- package/dist/index.js +2893 -882
- package/dist/index.mjs +2870 -882
- package/package.json +8 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import EventEmitter from 'eventemitter3';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Post-quantum handshake (
|
|
4
|
+
* Post-quantum handshake (v3).
|
|
5
5
|
*
|
|
6
6
|
* Flow:
|
|
7
7
|
* dApp relay wallet
|
|
8
8
|
* ────────────────────────────────────────────────────────────────────
|
|
9
|
-
* initiate() → (pk, sk)
|
|
10
|
-
* QR(cid,
|
|
11
|
-
* receiveQR(cid, pk)
|
|
9
|
+
* initiate() → (pk, sk, cap)
|
|
10
|
+
* QR(cid, fp, cap) rendered scan QR
|
|
11
|
+
* receiveQR(cid, pk, cap)
|
|
12
12
|
* → SYNACK{ct, c0}
|
|
13
13
|
* ◄── SYNACK ─────── send
|
|
14
14
|
* onSynAck(cid, SYNACK)
|
|
@@ -20,6 +20,7 @@ import EventEmitter from 'eventemitter3';
|
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
interface Session {
|
|
23
|
+
protocolVersion: 3;
|
|
23
24
|
cid: Uint8Array;
|
|
24
25
|
key: CryptoKey;
|
|
25
26
|
htx: Uint8Array;
|
|
@@ -30,6 +31,7 @@ interface Session {
|
|
|
30
31
|
}
|
|
31
32
|
/** Wire-safe persisted form for localStorage. */
|
|
32
33
|
interface PersistedSession {
|
|
34
|
+
protocolVersion: 3;
|
|
33
35
|
cid: string;
|
|
34
36
|
kAeadRaw: string;
|
|
35
37
|
htx: string;
|
|
@@ -49,6 +51,10 @@ interface AckMessage {
|
|
|
49
51
|
c1: string;
|
|
50
52
|
v: number;
|
|
51
53
|
}
|
|
54
|
+
interface InitiatedKeyExchange {
|
|
55
|
+
publicKey: Uint8Array;
|
|
56
|
+
capability: Uint8Array;
|
|
57
|
+
}
|
|
52
58
|
interface KeyExchangeEvents {
|
|
53
59
|
keys_exchanged: () => void;
|
|
54
60
|
step_change: (step: KeyExchangeMessageType) => void;
|
|
@@ -56,29 +62,40 @@ interface KeyExchangeEvents {
|
|
|
56
62
|
declare class KeyExchange extends EventEmitter<KeyExchangeEvents> {
|
|
57
63
|
private isOriginator;
|
|
58
64
|
private keypair;
|
|
65
|
+
private capability;
|
|
59
66
|
private session;
|
|
60
67
|
private step;
|
|
61
68
|
private awaitingSynAck;
|
|
62
69
|
private awaitingAck;
|
|
70
|
+
private awaitingAckDelivery;
|
|
63
71
|
private keysExchanged;
|
|
72
|
+
private stateGeneration;
|
|
64
73
|
private lastAck;
|
|
65
74
|
constructor(isOriginator: boolean, restored?: Session);
|
|
66
75
|
/**
|
|
67
76
|
* Originator (dApp) side: begin a fresh handshake by generating an
|
|
68
|
-
* ephemeral ML-KEM-768 keypair
|
|
77
|
+
* ephemeral ML-KEM-768 keypair and a fresh 32-byte pairing capability.
|
|
78
|
+
* Both returned arrays are copies; the originator retains its own secret
|
|
79
|
+
* capability until the handshake succeeds or is retired.
|
|
69
80
|
*/
|
|
70
|
-
initiate():
|
|
81
|
+
initiate(): InitiatedKeyExchange;
|
|
71
82
|
/**
|
|
72
83
|
* Originator: handle a SYNACK received over the relay.
|
|
73
84
|
* Returns an ACK wire message to send, or null if the SYNACK was a
|
|
74
85
|
* duplicate (handshake already complete).
|
|
75
86
|
*/
|
|
76
87
|
onSynAck(cid: Uint8Array, msg: SynAckMessage): Promise<AckMessage | null>;
|
|
88
|
+
/**
|
|
89
|
+
* Originator: publish completion only after the relay acknowledged ACK.
|
|
90
|
+
* This is deliberately separate from onSynAck() so transport ambiguity
|
|
91
|
+
* cannot leave a live or persistable one-sided session.
|
|
92
|
+
*/
|
|
93
|
+
confirmOriginatorAckDelivered(): void;
|
|
77
94
|
/**
|
|
78
95
|
* Responder (wallet) side: begin handshake from a scanned QR.
|
|
79
96
|
* Returns the SYNACK wire message to emit on the relay.
|
|
80
97
|
*/
|
|
81
|
-
receiveQR(cid: Uint8Array, pk: Uint8Array): Promise<SynAckMessage>;
|
|
98
|
+
receiveQR(cid: Uint8Array, pk: Uint8Array, capability: Uint8Array): Promise<SynAckMessage>;
|
|
82
99
|
/**
|
|
83
100
|
* Responder: verify an incoming ACK and finalize the session.
|
|
84
101
|
* Duplicates are silently ignored (handshake is idempotent).
|
|
@@ -108,10 +125,11 @@ interface DAppMetadata {
|
|
|
108
125
|
url: string;
|
|
109
126
|
icon?: string;
|
|
110
127
|
/**
|
|
111
|
-
* Optional "return to dApp" target
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
* so a same-device
|
|
128
|
+
* Optional credential-free HTTP(S) "return to dApp" target. HTTPS is
|
|
129
|
+
* required except for explicit loopback development URLs. Sent to the
|
|
130
|
+
* wallet in ORIGINATOR_INFO; after the wallet resolves a restricted request
|
|
131
|
+
* it bounces the user back here so a same-device flow does not strand the
|
|
132
|
+
* user in the wallet.
|
|
115
133
|
*/
|
|
116
134
|
redirectUrl?: string;
|
|
117
135
|
}
|
|
@@ -122,11 +140,12 @@ interface DAppMetadata {
|
|
|
122
140
|
* the ML-KEM keypair is ephemeral and zeroized after the handshake.
|
|
123
141
|
* Re-pair (generate a new QR) to rotate the session key.
|
|
124
142
|
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
143
|
+
* v5 checkpoints every seal/open, requires exclusive browser-tab ownership,
|
|
144
|
+
* and proves the AEAD key came from a PQP3 capability-bound handshake.
|
|
145
|
+
* Older records cannot prove all three invariants and are dropped.
|
|
127
146
|
*/
|
|
128
147
|
interface DAppSession {
|
|
129
|
-
version:
|
|
148
|
+
version: 5;
|
|
130
149
|
channelId: string;
|
|
131
150
|
keyExchange: PersistedSession;
|
|
132
151
|
dappMetadata: DAppMetadata;
|
|
@@ -140,6 +159,8 @@ interface PendingRequest {
|
|
|
140
159
|
id: string | number;
|
|
141
160
|
method: string;
|
|
142
161
|
params?: unknown[] | undefined;
|
|
162
|
+
/** Immutable postcondition captured before caller-owned params can change. */
|
|
163
|
+
expectedChainId?: string | undefined;
|
|
143
164
|
resolve: (result: unknown) => void;
|
|
144
165
|
reject: (error: Error) => void;
|
|
145
166
|
timestamp: number;
|
|
@@ -147,9 +168,10 @@ interface PendingRequest {
|
|
|
147
168
|
/**
|
|
148
169
|
* Key-exchange wire-message types.
|
|
149
170
|
*
|
|
150
|
-
*
|
|
151
|
-
* over the relay. The SYN step is
|
|
152
|
-
*
|
|
171
|
+
* v3 note: only SYNACK (wallet to dApp) and ACK (dApp to wallet) are
|
|
172
|
+
* transmitted over the relay. The SYN step is represented by the pairing URI,
|
|
173
|
+
* while the relay carries only the dApp's ML-KEM public key. The URI contains
|
|
174
|
+
* the key fingerprint and a capability that is never uploaded to the relay.
|
|
153
175
|
*/
|
|
154
176
|
declare enum KeyExchangeMessageType {
|
|
155
177
|
SYN = "key_handshake_SYN",
|
|
@@ -182,6 +204,22 @@ declare enum ConnectionStatus {
|
|
|
182
204
|
CONNECTED = "connected",
|
|
183
205
|
RECONNECTING = "reconnecting"
|
|
184
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* A response for a request issued by a PREVIOUS page load. Same-device
|
|
209
|
+
* approvals bounce back via a URL open, which reloads the dApp page and
|
|
210
|
+
* destroys the awaiting promise; the SDK persists in-flight restricted
|
|
211
|
+
* request ids and surfaces their eventual responses through this event.
|
|
212
|
+
*/
|
|
213
|
+
interface LateResponse {
|
|
214
|
+
id: string | number;
|
|
215
|
+
method: string;
|
|
216
|
+
result?: unknown;
|
|
217
|
+
error?: {
|
|
218
|
+
code: number;
|
|
219
|
+
message: string;
|
|
220
|
+
data?: unknown;
|
|
221
|
+
};
|
|
222
|
+
}
|
|
185
223
|
/** EIP-1193 provider events */
|
|
186
224
|
interface ProviderEvents {
|
|
187
225
|
connect: (info: {
|
|
@@ -198,6 +236,7 @@ interface ProviderEvents {
|
|
|
198
236
|
data: unknown;
|
|
199
237
|
}) => void;
|
|
200
238
|
statusChanged: (status: ConnectionStatus) => void;
|
|
239
|
+
late_response: (payload: LateResponse) => void;
|
|
201
240
|
}
|
|
202
241
|
/** JSON-RPC request */
|
|
203
242
|
interface JsonRpcRequest {
|
|
@@ -233,28 +272,65 @@ interface EIP6963ProviderInfoOverride {
|
|
|
233
272
|
* Rich response object returned by both `qrl_signMessage` and
|
|
234
273
|
* `qrl_signTypedData`. The signature alone is not enough to verify since
|
|
235
274
|
* ML-DSA-87 public keys cannot be recovered from a signature, so the
|
|
236
|
-
* wallet always returns the public key explicitly. Stateless verifiers
|
|
237
|
-
*
|
|
275
|
+
* wallet always returns the public key explicitly. Stateless verifiers need
|
|
276
|
+
* the original payload plus the signature fields below.
|
|
238
277
|
*/
|
|
239
278
|
interface QrlSignedResult {
|
|
240
|
-
/** 0x-hex of the
|
|
279
|
+
/** 0x-hex of the 4627-byte ML-DSA-87 signature. */
|
|
241
280
|
signature: string;
|
|
242
281
|
/** 0x-hex of the 2592-byte ML-DSA-87 public key. */
|
|
243
282
|
publicKey: string;
|
|
244
|
-
/**
|
|
283
|
+
/**
|
|
284
|
+
* 0x-hex of the 3-byte wallet descriptor used to derive `signer`.
|
|
285
|
+
* Optional while older wallet builds are upgraded; bound verification
|
|
286
|
+
* requires it.
|
|
287
|
+
*/
|
|
288
|
+
descriptor?: string;
|
|
289
|
+
/** Current 41-character checksummed Q-address derived from descriptor + key. */
|
|
245
290
|
signer: string;
|
|
246
291
|
/** 0x-hex of the 64-byte SHAKE256 digest that was signed. */
|
|
247
292
|
digest: string;
|
|
248
293
|
/** Scheme tag: 'QRL-SIGN-MSG-v1' or 'QRL-SIGN-TYPED-v1'. */
|
|
249
|
-
schemeVersion:
|
|
294
|
+
schemeVersion: QrlSigningSchemeVersion;
|
|
295
|
+
}
|
|
296
|
+
/** A current wallet response whose descriptor can be signer-bound. */
|
|
297
|
+
interface QrlSignedResultWithDescriptor extends QrlSignedResult {
|
|
298
|
+
descriptor: string;
|
|
299
|
+
}
|
|
300
|
+
type QrlSigningSchemeVersion = 'QRL-SIGN-MSG-v1' | 'QRL-SIGN-TYPED-v1';
|
|
301
|
+
/** Strict wire shape returned by `qrl_signMessage`. */
|
|
302
|
+
interface QrlSignedMessageResult extends QrlSignedResult {
|
|
303
|
+
schemeVersion: 'QRL-SIGN-MSG-v1';
|
|
250
304
|
}
|
|
251
305
|
/**
|
|
252
306
|
* Response from `qrl_signTypedData`. Echoes `domain` so a stateless
|
|
253
307
|
* verifier doesn't need to be told the domain out-of-band.
|
|
254
308
|
*/
|
|
255
309
|
interface QrlSignedTypedDataResult extends QrlSignedResult {
|
|
310
|
+
schemeVersion: 'QRL-SIGN-TYPED-v1';
|
|
256
311
|
domain: Record<string, unknown>;
|
|
257
312
|
}
|
|
313
|
+
/** Every strict signing-result wire shape understood by this SDK. */
|
|
314
|
+
type QrlSigningResult = QrlSignedMessageResult | QrlSignedTypedDataResult;
|
|
315
|
+
/**
|
|
316
|
+
* Validate an unknown value as the exact `qrl_signMessage` result wire shape.
|
|
317
|
+
* This checks structure and fixed widths only. Use `verifyMessageForSigner`
|
|
318
|
+
* with the original message to authenticate the signature and signer binding.
|
|
319
|
+
*/
|
|
320
|
+
declare function isQrlSignedMessageResult(value: unknown): value is QrlSignedMessageResult;
|
|
321
|
+
/**
|
|
322
|
+
* Validate an unknown value as the exact `qrl_signTypedData` result wire shape.
|
|
323
|
+
* This checks structure and fixed widths only. Use `verifyTypedDataForSigner`
|
|
324
|
+
* with the original payload to authenticate the signature and signer binding.
|
|
325
|
+
*/
|
|
326
|
+
declare function isQrlSignedTypedDataResult(value: unknown): value is QrlSignedTypedDataResult;
|
|
327
|
+
/** Validate either exact signing-result wire shape from an unknown value. */
|
|
328
|
+
declare function isQrlSignedResult(value: unknown): value is QrlSigningResult;
|
|
329
|
+
/**
|
|
330
|
+
* Strictly validate an unknown signing result and narrow it to one carrying
|
|
331
|
+
* the exact 3-byte ML-DSA descriptor required for signer-bound verification.
|
|
332
|
+
*/
|
|
333
|
+
declare function hasSigningDescriptor(result: unknown): result is QrlSigningResult & QrlSignedResultWithDescriptor;
|
|
258
334
|
/**
|
|
259
335
|
* `qrl_signMessage` params: `[signer, messageHex]`. `signer` must equal the
|
|
260
336
|
* dApp's currently-connected account; the wallet rejects mismatches before
|
|
@@ -297,6 +373,16 @@ interface QRLConnectOptions {
|
|
|
297
373
|
announceProvider?: boolean;
|
|
298
374
|
/** Override the EIP-6963 announce metadata (name / icon / rdns). */
|
|
299
375
|
providerInfo?: EIP6963ProviderInfoOverride;
|
|
376
|
+
/**
|
|
377
|
+
* On mobile browsers, deep-link (`qrlconnect://resume`) to foreground the
|
|
378
|
+
* wallet app when a restricted request is made while the wallet is absent
|
|
379
|
+
* from the relay channel. A backgrounded wallet app loses its socket
|
|
380
|
+
* within seconds; the relay buffers the request, and without the redirect
|
|
381
|
+
* it would sit there until the user remembers to switch apps on their
|
|
382
|
+
* own. Defaults to true. Set false when the dApp runs its own
|
|
383
|
+
* "open wallet" UX.
|
|
384
|
+
*/
|
|
385
|
+
walletRedirectOnRequest?: boolean;
|
|
300
386
|
}
|
|
301
387
|
|
|
302
388
|
/**
|
|
@@ -322,8 +408,16 @@ declare class QRLConnectProvider extends EventEmitter<ProviderEvents> {
|
|
|
322
408
|
private eip6963RequestListener;
|
|
323
409
|
private resumeListener;
|
|
324
410
|
private resumeDebounce;
|
|
411
|
+
private inflightKey;
|
|
412
|
+
private orphanedRequests;
|
|
325
413
|
private readonly requestIdPrefix;
|
|
326
414
|
private requestCounter;
|
|
415
|
+
private requestGeneration;
|
|
416
|
+
private requestCancellationMessage;
|
|
417
|
+
private lifecycleTransition;
|
|
418
|
+
private disconnectInFlight;
|
|
419
|
+
private restrictedRequestActive;
|
|
420
|
+
private restrictedRequestQueue;
|
|
327
421
|
readonly isQRLConnect = true;
|
|
328
422
|
constructor(options: QRLConnectOptions);
|
|
329
423
|
private startEip6963Announce;
|
|
@@ -345,6 +439,10 @@ declare class QRLConnectProvider extends EventEmitter<ProviderEvents> {
|
|
|
345
439
|
*/
|
|
346
440
|
stopEip6963Announce(): void;
|
|
347
441
|
private setupConnectionListeners;
|
|
442
|
+
private handleJsonRpcResponse;
|
|
443
|
+
private cancelAllRequests;
|
|
444
|
+
private assertRequestGeneration;
|
|
445
|
+
private isCurrentChain;
|
|
348
446
|
/**
|
|
349
447
|
* Generate a connection URI for QR code display or deep link redirect.
|
|
350
448
|
*/
|
|
@@ -364,6 +462,45 @@ declare class QRLConnectProvider extends EventEmitter<ProviderEvents> {
|
|
|
364
462
|
method: string;
|
|
365
463
|
params?: unknown[];
|
|
366
464
|
}): Promise<unknown>;
|
|
465
|
+
/**
|
|
466
|
+
* Keep at most one approval-bound request active. Wallet approval screens
|
|
467
|
+
* are a serial human interaction, and request-id ordering must remain
|
|
468
|
+
* stable even when a dApp fires several signing calls concurrently.
|
|
469
|
+
*/
|
|
470
|
+
private enqueueRestrictedRequest;
|
|
471
|
+
private runRestrictedRequest;
|
|
472
|
+
private finishRestrictedRequest;
|
|
473
|
+
private performRequest;
|
|
474
|
+
/**
|
|
475
|
+
* Redirect only for calls the user must approve, on mobile, and only when
|
|
476
|
+
* the wallet is actually absent from the channel: right after pairing its
|
|
477
|
+
* socket lingers and a pointless app flash would be jarring.
|
|
478
|
+
*
|
|
479
|
+
* qrl_requestAccounts is excluded even though it is restricted: dApps call
|
|
480
|
+
* it on page load to restore a session, so it can run with no user gesture
|
|
481
|
+
* (an unsolicited "Open in MyQRLWallet?" sheet on load) and pairing UIs
|
|
482
|
+
* already own their own deep-link step.
|
|
483
|
+
*/
|
|
484
|
+
private shouldRedirectToWallet;
|
|
485
|
+
private readInflight;
|
|
486
|
+
private writeInflight;
|
|
487
|
+
private persistInflight;
|
|
488
|
+
private settleInflight;
|
|
489
|
+
private clearAllInflight;
|
|
490
|
+
/**
|
|
491
|
+
* Wake URI for the wallet app. Carries no pairing payload: the app
|
|
492
|
+
* foregrounds on any `qrlconnect:` URL and re-joins its sessions (draining
|
|
493
|
+
* the buffered request); the cid lets a future wallet jump straight to the
|
|
494
|
+
* right approval.
|
|
495
|
+
*
|
|
496
|
+
* MUST stay query-only (no host/path). The mobile app routes deep links
|
|
497
|
+
* with expo-router, which maps anything after the scheme to an in-app
|
|
498
|
+
* route: `qrlconnect://resume?...` lands on the "+not-found" screen and
|
|
499
|
+
* unmounts the WebView, so the wake achieves nothing. The hostless form
|
|
500
|
+
* routes to the WebView tab exactly like the pairing URIs
|
|
501
|
+
* (`qrlconnect://?q=...`), which is the whole point of the wake.
|
|
502
|
+
*/
|
|
503
|
+
private walletWakeUri;
|
|
367
504
|
/**
|
|
368
505
|
* Get the current connection status.
|
|
369
506
|
*/
|
|
@@ -384,6 +521,15 @@ declare class QRLConnectProvider extends EventEmitter<ProviderEvents> {
|
|
|
384
521
|
* Check if a stored session exists that can be reconnected.
|
|
385
522
|
*/
|
|
386
523
|
hasStoredSession(): boolean;
|
|
524
|
+
/**
|
|
525
|
+
* True while a pairing exists (keys exchanged), even when the wallet app
|
|
526
|
+
* is backgrounded and its socket is out of the channel. Combine with
|
|
527
|
+
* getStatus() to tell "wallet away, session intact" (paired + WAITING)
|
|
528
|
+
* apart from "waiting for a first scan" in pairing UIs.
|
|
529
|
+
*/
|
|
530
|
+
isPaired(): boolean;
|
|
531
|
+
/** True while the wallet is actually present in the relay channel. */
|
|
532
|
+
isWalletPresent(): boolean;
|
|
387
533
|
/**
|
|
388
534
|
* Reset the connection and start a fresh pairing with a new channel.
|
|
389
535
|
* Use this when the user wants to create a new connection instead of
|
|
@@ -402,7 +548,7 @@ declare class QRLConnectProvider extends EventEmitter<ProviderEvents> {
|
|
|
402
548
|
/**
|
|
403
549
|
* Connection Manager - orchestrates socket lifecycle, the post-quantum
|
|
404
550
|
* handshake, encrypted message routing, and session persistence for the
|
|
405
|
-
* dApp side of QRL Connect
|
|
551
|
+
* dApp side of QRL Connect v3.
|
|
406
552
|
*/
|
|
407
553
|
|
|
408
554
|
interface ConnectionManagerEvents {
|
|
@@ -415,6 +561,13 @@ interface ConnectionManagerEvents {
|
|
|
415
561
|
chainId: string;
|
|
416
562
|
}) => void;
|
|
417
563
|
connection_lost: () => void;
|
|
564
|
+
/**
|
|
565
|
+
* The session is dead for good (wallet TERMINATE, relay 'close', or a
|
|
566
|
+
* tombstone observed on join). Distinct from a transient DISCONNECTED:
|
|
567
|
+
* in-flight requests can never be answered and must be failed promptly
|
|
568
|
+
* instead of running out the full request timeout.
|
|
569
|
+
*/
|
|
570
|
+
session_terminated: () => void;
|
|
418
571
|
error: (error: Error) => void;
|
|
419
572
|
}
|
|
420
573
|
declare class ConnectionManager extends EventEmitter<ConnectionManagerEvents> {
|
|
@@ -429,12 +582,22 @@ declare class ConnectionManager extends EventEmitter<ConnectionManagerEvents> {
|
|
|
429
582
|
private storageKey;
|
|
430
583
|
private unresponsiveTimer;
|
|
431
584
|
private reconnectProbeTimer;
|
|
585
|
+
private restoreInFlight;
|
|
432
586
|
private failedReconnects;
|
|
433
587
|
private walletPresent;
|
|
434
588
|
private pendingRestore;
|
|
435
589
|
private messageQueue;
|
|
436
590
|
private outboundQueue;
|
|
591
|
+
private persistenceQueue;
|
|
592
|
+
private readonly storage;
|
|
593
|
+
private readonly persistenceEnabled;
|
|
594
|
+
private readonly sessionOwnership;
|
|
595
|
+
private persistenceBroken;
|
|
596
|
+
private sessionCreatedAt;
|
|
597
|
+
private sessionGeneration;
|
|
598
|
+
private consecutiveDecryptFailures;
|
|
437
599
|
private static MAX_RECONNECT_FAILURES;
|
|
600
|
+
private static MAX_DECRYPT_FAILURES;
|
|
438
601
|
constructor(options: {
|
|
439
602
|
dappMetadata: DAppMetadata;
|
|
440
603
|
relayUrl?: string | undefined;
|
|
@@ -442,9 +605,11 @@ declare class ConnectionManager extends EventEmitter<ConnectionManagerEvents> {
|
|
|
442
605
|
storageKey?: string | undefined;
|
|
443
606
|
});
|
|
444
607
|
private setupSocketListeners;
|
|
608
|
+
private handleAutoReconnected;
|
|
445
609
|
private setupKeyExchangeListeners;
|
|
446
610
|
/**
|
|
447
|
-
* Generate a new
|
|
611
|
+
* Generate a new v3 connection URI. Rotates channel id, keypair, and the
|
|
612
|
+
* QR-only pairing capability.
|
|
448
613
|
* Returns a `qrlconnect://?q=…` URI safe for QR-rendering or deep-link.
|
|
449
614
|
*/
|
|
450
615
|
getConnectionURI(retryOnConflict?: boolean): Promise<string>;
|
|
@@ -453,6 +618,7 @@ declare class ConnectionManager extends EventEmitter<ConnectionManagerEvents> {
|
|
|
453
618
|
* Returns false if there is nothing to restore.
|
|
454
619
|
*/
|
|
455
620
|
reconnect(): Promise<boolean>;
|
|
621
|
+
private reconnectNow;
|
|
456
622
|
/**
|
|
457
623
|
* (Re)open the socket, join the persisted channel, drain buffered relay
|
|
458
624
|
* messages, and settle status. Shared by the cold-restore reconnect() and
|
|
@@ -469,6 +635,25 @@ declare class ConnectionManager extends EventEmitter<ConnectionManagerEvents> {
|
|
|
469
635
|
* own connect handler re-joins the channel and drains the relay buffer.
|
|
470
636
|
*/
|
|
471
637
|
resume(): void;
|
|
638
|
+
/**
|
|
639
|
+
* Make sure the socket is open and joined to the paired session's channel
|
|
640
|
+
* so an outbound request can be routed - or relay-buffered if the wallet is
|
|
641
|
+
* currently absent (its socket dies within seconds of the app
|
|
642
|
+
* backgrounding; the relay holds channel traffic for it). Revives the
|
|
643
|
+
* socket after a probe-timeout teardown and hydrates a cold stored
|
|
644
|
+
* session. Returns false when there is no session to revive (never paired,
|
|
645
|
+
* explicit disconnect, or the channel was tombstoned).
|
|
646
|
+
*/
|
|
647
|
+
ensureChannelJoined(): Promise<boolean>;
|
|
648
|
+
/**
|
|
649
|
+
* True while a pairing exists (handshake complete, session keys in
|
|
650
|
+
* memory), even when the wallet's socket is momentarily out of the
|
|
651
|
+
* channel. Survives the reconnect-probe teardown; false after an explicit
|
|
652
|
+
* disconnect or a relay tombstone.
|
|
653
|
+
*/
|
|
654
|
+
isPaired(): boolean;
|
|
655
|
+
/** True while the relay roster last showed the wallet in the channel. */
|
|
656
|
+
isWalletPresent(): boolean;
|
|
472
657
|
/**
|
|
473
658
|
* A session was terminated for good (wallet sent a relay 'close', or the
|
|
474
659
|
* join ack reported a tombstone). Clear local state and surface
|
|
@@ -478,11 +663,20 @@ declare class ConnectionManager extends EventEmitter<ConnectionManagerEvents> {
|
|
|
478
663
|
private armReconnectProbe;
|
|
479
664
|
private clearReconnectProbe;
|
|
480
665
|
/**
|
|
481
|
-
* Send a JSON-RPC request to the wallet
|
|
666
|
+
* Send a JSON-RPC request to the wallet. Returns the outbound send promise
|
|
667
|
+
* (settled on the relay's ack) so callers that must sequence on delivery -
|
|
668
|
+
* e.g. the provider's wallet-wake redirect, which cannot navigate away
|
|
669
|
+
* before the ciphertext reaches the relay - can await it. Callers may also
|
|
670
|
+
* ignore it: failures are logged here either way.
|
|
482
671
|
*/
|
|
483
|
-
sendJsonRpc(request: JsonRpcRequest): void
|
|
672
|
+
sendJsonRpc(request: JsonRpcRequest): Promise<void>;
|
|
484
673
|
getStatus(): ConnectionStatus;
|
|
485
674
|
getAccounts(): string[];
|
|
675
|
+
/**
|
|
676
|
+
* Commit accounts returned by an approved qrl_requestAccounts response.
|
|
677
|
+
* WALLET_INFO alone cannot grant this authorization.
|
|
678
|
+
*/
|
|
679
|
+
authorizeAccounts(value: unknown): Promise<string[]>;
|
|
486
680
|
getChainId(): string;
|
|
487
681
|
getChannelId(): string;
|
|
488
682
|
/** Check (sync) if a persisted session exists and has not expired. */
|
|
@@ -495,6 +689,13 @@ declare class ConnectionManager extends EventEmitter<ConnectionManagerEvents> {
|
|
|
495
689
|
* instant disconnect. Mirrors the wallet side's pattern.
|
|
496
690
|
*/
|
|
497
691
|
private flushTerminate;
|
|
692
|
+
/**
|
|
693
|
+
* Ensure this socket is a relay participant before closing a restorable or
|
|
694
|
+
* temporarily disconnected channel. close_channel is intentionally
|
|
695
|
+
* participant-only on the relay, so a cold stored session cannot be retired
|
|
696
|
+
* by emitting the close event from an unjoined socket.
|
|
697
|
+
*/
|
|
698
|
+
private prepareRelayChannelForRetirement;
|
|
498
699
|
/**
|
|
499
700
|
* Reset to a fresh channel + keypair. Sends TERMINATE to any live peer,
|
|
500
701
|
* drops the persisted session, and prepares a clean state for
|
|
@@ -504,6 +705,17 @@ declare class ConnectionManager extends EventEmitter<ConnectionManagerEvents> {
|
|
|
504
705
|
disconnect(): Promise<void>;
|
|
505
706
|
private enqueueRelayMessage;
|
|
506
707
|
private handleRelayMessage;
|
|
708
|
+
/**
|
|
709
|
+
* The receive stream is cryptographically unrecoverable: the peer's send
|
|
710
|
+
* counter is ahead of our recv counter for good (relay buffer TTL/cap
|
|
711
|
+
* dropped a ciphertext), so every future message would fail its tag.
|
|
712
|
+
* An encrypted TERMINATE cannot communicate this (the desynced peer could
|
|
713
|
+
* not open it either); tombstone the channel on the relay instead so the
|
|
714
|
+
* wallet learns the pairing is dead even if it only re-joins later, then
|
|
715
|
+
* clear local state and surface the standard terminated teardown.
|
|
716
|
+
*/
|
|
717
|
+
private teardownDesyncedSession;
|
|
718
|
+
private teardownPersistenceFailedSession;
|
|
507
719
|
private handleSynAck;
|
|
508
720
|
private handleDecryptedMessage;
|
|
509
721
|
private sendPlaintext;
|
|
@@ -522,8 +734,17 @@ declare class ConnectionManager extends EventEmitter<ConnectionManagerEvents> {
|
|
|
522
734
|
private setStatus;
|
|
523
735
|
private isDappParticipantConflictError;
|
|
524
736
|
private areArraysEqual;
|
|
737
|
+
private invalidateSessionWork;
|
|
738
|
+
private captureSessionWorkContext;
|
|
739
|
+
private isSessionWorkCurrent;
|
|
740
|
+
private assertSessionWorkCurrent;
|
|
741
|
+
private acquireSessionOwnership;
|
|
742
|
+
private releaseSessionOwnership;
|
|
525
743
|
private persistSession;
|
|
744
|
+
private persistSessionNow;
|
|
526
745
|
private readStoredSession;
|
|
746
|
+
private removeStoredSession;
|
|
747
|
+
private removeStoredSessionOrThrow;
|
|
527
748
|
private clearSession;
|
|
528
749
|
}
|
|
529
750
|
|
|
@@ -532,7 +753,7 @@ declare class ConnectionManager extends EventEmitter<ConnectionManagerEvents> {
|
|
|
532
753
|
*/
|
|
533
754
|
|
|
534
755
|
interface SocketClientEvents {
|
|
535
|
-
message: (data:
|
|
756
|
+
message: (data: unknown) => void;
|
|
536
757
|
connected: () => void;
|
|
537
758
|
disconnected: (reason: string) => void;
|
|
538
759
|
reconnected: (result: JoinResult) => void;
|
|
@@ -546,7 +767,7 @@ interface JoinResult {
|
|
|
546
767
|
bufferedMessages: unknown[];
|
|
547
768
|
/**
|
|
548
769
|
* Base64-encoded KEM public key the relay has bound to this channel.
|
|
549
|
-
* Populated for wallet joins (
|
|
770
|
+
* Populated for wallet joins (v3 protocol). `null` if the dApp hasn't
|
|
550
771
|
* registered a PK yet - wallet callers must treat this as a retry signal.
|
|
551
772
|
*/
|
|
552
773
|
channelPublicKey: string | null;
|
|
@@ -571,6 +792,9 @@ declare class SocketClient extends EventEmitter<SocketClientEvents> {
|
|
|
571
792
|
private publicKeyBase64;
|
|
572
793
|
private seq;
|
|
573
794
|
private pendingJoin;
|
|
795
|
+
private pendingSends;
|
|
796
|
+
private pendingJoinAttempts;
|
|
797
|
+
private get expectedPeerType();
|
|
574
798
|
constructor(relayUrl: string, clientType: 'dapp' | 'wallet');
|
|
575
799
|
/**
|
|
576
800
|
* dApp-only: stash the PK so it gets uploaded on every join_channel
|
|
@@ -593,6 +817,7 @@ declare class SocketClient extends EventEmitter<SocketClientEvents> {
|
|
|
593
817
|
*/
|
|
594
818
|
joinChannel(channelId: string): Promise<JoinResult>;
|
|
595
819
|
private joinChannelNow;
|
|
820
|
+
private rejectPendingJoinAttempts;
|
|
596
821
|
/**
|
|
597
822
|
* Send a message through the relay.
|
|
598
823
|
*/
|
|
@@ -600,6 +825,21 @@ declare class SocketClient extends EventEmitter<SocketClientEvents> {
|
|
|
600
825
|
success: boolean;
|
|
601
826
|
buffered: boolean;
|
|
602
827
|
}>;
|
|
828
|
+
private rejectPendingSends;
|
|
829
|
+
/**
|
|
830
|
+
* Emit an event and resolve once the relay acks it, or after a bounded
|
|
831
|
+
* flush window. Lets a caller await transmission before tearing the
|
|
832
|
+
* socket down.
|
|
833
|
+
*/
|
|
834
|
+
private flushEmit;
|
|
835
|
+
/**
|
|
836
|
+
* Explicitly terminate the channel on the relay (durable tombstone), as
|
|
837
|
+
* opposed to the transient leaveChannel(). Used when the session is dead
|
|
838
|
+
* in a way an encrypted TERMINATE cannot communicate (AEAD desync: the
|
|
839
|
+
* peer could not open it). Resolves once the close is flushed or the
|
|
840
|
+
* bounded window elapses, so the caller can safely disconnect afterwards.
|
|
841
|
+
*/
|
|
842
|
+
closeChannel(): Promise<boolean>;
|
|
603
843
|
/**
|
|
604
844
|
* Leave the current channel.
|
|
605
845
|
*/
|
|
@@ -655,6 +895,18 @@ declare function computeMessageDigest(messageBytes: Uint8Array): Uint8Array;
|
|
|
655
895
|
* the wallet copy for the spec-level comments; behavior must stay in
|
|
656
896
|
* lock-step or the cross-repo parity test fails on next CI.
|
|
657
897
|
*/
|
|
898
|
+
declare const TYPED_DATA_LIMITS: Readonly<{
|
|
899
|
+
maxTypes: 32;
|
|
900
|
+
maxFieldsPerType: 32;
|
|
901
|
+
maxTotalFields: 256;
|
|
902
|
+
maxTypeGraphDepth: 12;
|
|
903
|
+
maxArrayNesting: 12;
|
|
904
|
+
maxArrayLength: 256;
|
|
905
|
+
maxEncodedValues: 2048;
|
|
906
|
+
maxDynamicBytes: number;
|
|
907
|
+
maxIdentifierLength: 64;
|
|
908
|
+
maxFieldTypeLength: 128;
|
|
909
|
+
}>;
|
|
658
910
|
type FieldType = string;
|
|
659
911
|
interface TypedField {
|
|
660
912
|
name: string;
|
|
@@ -674,28 +926,70 @@ declare function encodeType(primary: string, types: TypeMap): string;
|
|
|
674
926
|
declare function typeHash(primary: string, types: TypeMap): Uint8Array;
|
|
675
927
|
declare function encodeField(type: FieldType, value: unknown, types: TypeMap): Uint8Array;
|
|
676
928
|
declare function hashStruct(primary: string, data: Message, types: TypeMap): Uint8Array;
|
|
677
|
-
declare function computeTypedDataDigest(payload:
|
|
929
|
+
declare function computeTypedDataDigest(payload: unknown): Uint8Array;
|
|
678
930
|
|
|
679
931
|
/**
|
|
680
932
|
* Stateless verifiers for the two PQ signing schemes. The SDK exposes these
|
|
681
933
|
* so a dApp can re-verify the rich response object returned by the wallet
|
|
682
|
-
* without round-tripping back through the relay.
|
|
683
|
-
*
|
|
934
|
+
* without round-tripping back through the relay. The lower-level
|
|
935
|
+
* verifyMessageSignature / verifyTypedDataSignature prove only that a
|
|
936
|
+
* supplied public key made the signature. Authorization decisions should use
|
|
937
|
+
* the ForSigner variants, which also bind that key to the expected
|
|
938
|
+
* current-format address.
|
|
684
939
|
*/
|
|
685
940
|
|
|
941
|
+
declare const ML_DSA_DESCRIPTOR_BYTES = 3;
|
|
942
|
+
declare const ML_DSA_87_PUBLIC_KEY_BYTES = 2592;
|
|
943
|
+
declare const ML_DSA_87_SIGNATURE_BYTES = 4627;
|
|
686
944
|
interface VerifyMessageParams {
|
|
687
945
|
signature: Uint8Array | string;
|
|
688
946
|
publicKey: Uint8Array | string;
|
|
689
947
|
/** 0x-hex bytes that were originally signed. */
|
|
690
948
|
messageBytes: Uint8Array | string;
|
|
691
949
|
}
|
|
692
|
-
|
|
950
|
+
/**
|
|
951
|
+
* Verify against an explicitly supplied ML-DSA public key only. This does not
|
|
952
|
+
* prove that the key derives the signer claimed by a wallet response. Use
|
|
953
|
+
* verifyMessageForSigner for authentication or authorization decisions.
|
|
954
|
+
*/
|
|
955
|
+
declare function verifyMessageSignature({ signature, publicKey, messageBytes, }: VerifyMessageParams): boolean;
|
|
693
956
|
interface VerifyTypedDataParams {
|
|
694
957
|
signature: Uint8Array | string;
|
|
695
958
|
publicKey: Uint8Array | string;
|
|
696
959
|
payload: TypedDataPayload;
|
|
697
960
|
}
|
|
698
|
-
|
|
961
|
+
/**
|
|
962
|
+
* Verify against an explicitly supplied ML-DSA public key only. This does not
|
|
963
|
+
* bind that key to a Q-address. Use verifyTypedDataForSigner when signer
|
|
964
|
+
* identity matters.
|
|
965
|
+
*/
|
|
966
|
+
declare function verifyTypedDataSignature({ signature, publicKey, payload, }: VerifyTypedDataParams): boolean;
|
|
967
|
+
interface VerifyMessageForSignerParams extends VerifyMessageParams {
|
|
968
|
+
/** Current Q + 40 hex address expected by the dApp. */
|
|
969
|
+
expectedSigner: string;
|
|
970
|
+
/** Exact 3-byte wallet descriptor. Missing legacy values fail closed. */
|
|
971
|
+
descriptor?: Uint8Array | string | undefined;
|
|
972
|
+
}
|
|
973
|
+
/** Verify both the message signature and public-key-to-signer binding. */
|
|
974
|
+
declare function verifyMessageForSigner({ expectedSigner, descriptor, signature, publicKey, messageBytes, }: VerifyMessageForSignerParams): boolean;
|
|
975
|
+
interface VerifyTypedDataForSignerParams extends VerifyTypedDataParams {
|
|
976
|
+
/** Current Q + 40 hex address expected by the dApp. */
|
|
977
|
+
expectedSigner: string;
|
|
978
|
+
/** Exact 3-byte wallet descriptor. Missing legacy values fail closed. */
|
|
979
|
+
descriptor?: Uint8Array | string | undefined;
|
|
980
|
+
}
|
|
981
|
+
/** Verify both the typed-data signature and public-key-to-signer binding. */
|
|
982
|
+
declare function verifyTypedDataForSigner({ expectedSigner, descriptor, signature, publicKey, payload, }: VerifyTypedDataForSignerParams): boolean;
|
|
983
|
+
/**
|
|
984
|
+
* @deprecated Use verifyMessageSignature for a key-only check, or
|
|
985
|
+
* verifyMessageForSigner when signer identity matters.
|
|
986
|
+
*/
|
|
987
|
+
declare function verifyMessage(params: VerifyMessageParams): boolean;
|
|
988
|
+
/**
|
|
989
|
+
* @deprecated Use verifyTypedDataSignature for a key-only check, or
|
|
990
|
+
* verifyTypedDataForSigner when signer identity matters.
|
|
991
|
+
*/
|
|
992
|
+
declare function verifyTypedData(params: VerifyTypedDataParams): boolean;
|
|
699
993
|
|
|
700
994
|
/**
|
|
701
995
|
* Local hex/bytes utilities for the signing module.
|
|
@@ -707,38 +1001,40 @@ declare function bytesToHex(bytes: Uint8Array): string;
|
|
|
707
1001
|
declare function concatBytes(...parts: Uint8Array[]): Uint8Array;
|
|
708
1002
|
|
|
709
1003
|
/**
|
|
710
|
-
*
|
|
1004
|
+
* v3 QR URI codec (PQP3).
|
|
711
1005
|
*
|
|
712
|
-
* Format: qrlconnect://?q=<base45(
|
|
1006
|
+
* Format: qrlconnect://?q=<base45(PQP3 || cid || fp || cap)>[&r=<relayUrl>]
|
|
713
1007
|
*
|
|
714
|
-
*
|
|
715
|
-
* cid = 16 bytes (UUIDv4 raw)
|
|
716
|
-
* fp = SHA-256("pq-fp/
|
|
717
|
-
*
|
|
1008
|
+
* PQP3 = "PQP3" magic (4 B)
|
|
1009
|
+
* cid = 16 bytes (UUIDv4 raw) (16 B)
|
|
1010
|
+
* fp = SHA-256("pq-fp/v3" || cid || pk || cap) (full 32B) (32 B)
|
|
1011
|
+
* cap = fresh CSPRNG pairing capability (32 B)
|
|
1012
|
+
* total (84 B)
|
|
718
1013
|
*
|
|
719
|
-
*
|
|
720
|
-
*
|
|
1014
|
+
* The capability is a bearer secret. It is never uploaded to the relay and
|
|
1015
|
+
* must not be logged or persisted before the handshake consumes it.
|
|
721
1016
|
*
|
|
722
1017
|
* Security: the public key is NOT carried in the QR. It's uploaded by the
|
|
723
1018
|
* dApp to the relay at channel creation, the relay binds it to the cid, and
|
|
724
|
-
* the wallet fetches it via the join_channel ack. The
|
|
725
|
-
* the
|
|
726
|
-
*
|
|
727
|
-
*
|
|
728
|
-
* substitution of a maliciously-crafted PK with the same fingerprint.
|
|
1019
|
+
* the wallet fetches it via the join_channel ack. The fingerprint commits
|
|
1020
|
+
* the relay-served key to the exact out-of-band capability. The capability
|
|
1021
|
+
* is also bound into the transcript and HKDF by the key-exchange layer, so a
|
|
1022
|
+
* relay cannot fabricate an authenticated wallet hello.
|
|
729
1023
|
*
|
|
730
|
-
* Legacy
|
|
731
|
-
*
|
|
732
|
-
*
|
|
1024
|
+
* Legacy PQP1 and PQP2 URIs are rejected with a clear migration error. This
|
|
1025
|
+
* intentional v4.0 break prevents fallback to a pairing mode where the relay
|
|
1026
|
+
* could impersonate a wallet.
|
|
733
1027
|
*/
|
|
734
1028
|
declare const CID_LEN = 16;
|
|
735
1029
|
declare const FP_LEN = 32;
|
|
1030
|
+
declare const CAP_LEN = 32;
|
|
736
1031
|
declare const BLOB_LEN: number;
|
|
1032
|
+
declare const MAX_CONNECTION_URI_LENGTH = 4096;
|
|
737
1033
|
/**
|
|
738
|
-
* Compute the full 32-byte fingerprint binding (label || cid || pk).
|
|
1034
|
+
* Compute the full 32-byte fingerprint binding (label || cid || pk || cap).
|
|
739
1035
|
* Exported so the wallet side can re-derive and verify.
|
|
740
1036
|
*/
|
|
741
|
-
declare function computeFingerprint(cid: Uint8Array, pk: Uint8Array): Promise<Uint8Array>;
|
|
1037
|
+
declare function computeFingerprint(cid: Uint8Array, pk: Uint8Array, capability: Uint8Array): Promise<Uint8Array>;
|
|
742
1038
|
/**
|
|
743
1039
|
* Constant-time comparison of two byte arrays. Both must be the same length.
|
|
744
1040
|
* The verifier MUST use this rather than `===` or `indexOf` so timing signals
|
|
@@ -746,18 +1042,19 @@ declare function computeFingerprint(cid: Uint8Array, pk: Uint8Array): Promise<Ui
|
|
|
746
1042
|
*/
|
|
747
1043
|
declare function fingerprintEquals(a: Uint8Array, b: Uint8Array): boolean;
|
|
748
1044
|
/**
|
|
749
|
-
* Encode (cid, pk) as a qrlconnect:// URI.
|
|
750
|
-
*
|
|
751
|
-
* upload the PK to the relay separately before publishing this URI.
|
|
1045
|
+
* Encode (cid, pk, capability) as a qrlconnect:// URI. The PK is not stored
|
|
1046
|
+
* in the URI; only its capability-bound fingerprint is embedded. The caller
|
|
1047
|
+
* must upload the PK to the relay separately before publishing this URI.
|
|
752
1048
|
*
|
|
753
1049
|
* The optional `relayUrl` rides as a sibling query param (not inside the
|
|
754
1050
|
* fp-bound blob) so a tampered relay can cause the pairing to fail but
|
|
755
1051
|
* cannot substitute the PK - the fp still pins that.
|
|
756
1052
|
*/
|
|
757
|
-
declare function generateConnectionURI(cid: Uint8Array, pk: Uint8Array, relayUrl?: string): Promise<string>;
|
|
1053
|
+
declare function generateConnectionURI(cid: Uint8Array, pk: Uint8Array, capability: Uint8Array, relayUrl?: string): Promise<string>;
|
|
758
1054
|
interface ParsedURI {
|
|
759
1055
|
cid: Uint8Array;
|
|
760
1056
|
fp: Uint8Array;
|
|
1057
|
+
capability: Uint8Array;
|
|
761
1058
|
relayUrl?: string | undefined;
|
|
762
1059
|
}
|
|
763
1060
|
declare function parseConnectionURI(uri: string): Promise<ParsedURI>;
|
|
@@ -797,20 +1094,28 @@ declare function getAppStoreUrl(): string;
|
|
|
797
1094
|
declare function attemptWalletRedirect(uri: string, timeoutMs?: number): Promise<boolean>;
|
|
798
1095
|
|
|
799
1096
|
declare const DEFAULT_RELAY_URL = "https://qrlwallet.com";
|
|
800
|
-
declare const PROTOCOL_VERSION =
|
|
1097
|
+
declare const PROTOCOL_VERSION = 3;
|
|
1098
|
+
declare const PAIRING_CAPABILITY_LEN = 32;
|
|
1099
|
+
declare const MAX_JSON_RPC_ID_LENGTH = 128;
|
|
1100
|
+
declare const MAX_JSON_RPC_METHOD_LENGTH = 128;
|
|
1101
|
+
declare const MAX_RELAY_URL_LENGTH = 2048;
|
|
801
1102
|
/**
|
|
802
|
-
*
|
|
803
|
-
*
|
|
804
|
-
*
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
declare
|
|
813
|
-
|
|
814
|
-
|
|
1103
|
+
* Validate and canonicalize relay endpoints before they reach logging,
|
|
1104
|
+
* Socket.IO, or a QR URI. Production relays require HTTPS; plain HTTP is
|
|
1105
|
+
* limited to explicit loopback hostnames for local development.
|
|
1106
|
+
*/
|
|
1107
|
+
declare function normalizeRelayUrl(value: unknown): string;
|
|
1108
|
+
/** Public snapshots for discovery. Provider authorization uses private sets. */
|
|
1109
|
+
declare const RESTRICTED_METHODS: ReadonlySet<string>;
|
|
1110
|
+
declare const UNRESTRICTED_METHODS: ReadonlySet<string>;
|
|
1111
|
+
declare const EXPLICITLY_UNSUPPORTED_METHODS: ReadonlySet<string>;
|
|
1112
|
+
type RpcMethodPolicy = 'restricted' | 'unrestricted' | 'unsupported';
|
|
1113
|
+
declare function isValidJsonRpcId(value: unknown): value is string | number;
|
|
1114
|
+
declare function isValidJsonRpcMethod(value: unknown): value is string;
|
|
1115
|
+
/**
|
|
1116
|
+
* Classify an RPC method with a closed allowlist. Any method absent from the
|
|
1117
|
+
* two positive policy sets is unsupported, including future signing methods.
|
|
1118
|
+
*/
|
|
1119
|
+
declare function classifyRpcMethod(method: string): RpcMethodPolicy;
|
|
815
1120
|
|
|
816
|
-
export { type AckMessage, BLOB_LEN, CID_LEN, ConnectionManager, ConnectionStatus, type DAppMetadata, type DAppSession, DEFAULT_RELAY_URL, DIGEST_LEN, type Domain, type EIP6963ProviderInfoOverride, FP_LEN, type JsonRpcRequest, type JsonRpcResponse, KeyExchange, KeyExchangeMessageType, type Message, MessageType, PROTOCOL_VERSION, type ParsedURI, type PendingRequest, type PersistedSession, type ProviderEvents, QRLConnectProvider as QRLConnect, type QRLConnectOptions, QRLConnectProvider, QRL_CONNECT_PROVIDER_INFO, type QrlSignMessageParams, type QrlSignTypedDataParams, type QrlSignedResult, type QrlSignedTypedDataResult, type QrlTypedDataPayload, RESTRICTED_METHODS, type RelayMessage, SCHEME_TAG_MSG, SCHEME_TAG_TYPED, SCHEME_VERSION_MSG, SCHEME_VERSION_TYPED, type Session, SocketClient, type StructDef, type SynAckMessage, type TypeMap, type TypedDataPayload, type TypedField, UNRESTRICTED_METHODS, type VerifyMessageParams, type VerifyTypedDataParams, attemptWalletRedirect, bytesToHex, cidFromString, cidRandom, cidToString, computeFingerprint, computeMessageDigest, computeTypedDataDigest, concatBytes, encodeField, encodeType, fingerprintEquals, generateConnectionURI, getAppStoreUrl, hashStruct, hexToBytes, isMobileBrowser, parseConnectionURI, typeHash, verifyMessage, verifyTypedData };
|
|
1121
|
+
export { type AckMessage, BLOB_LEN, CAP_LEN, CID_LEN, ConnectionManager, ConnectionStatus, type DAppMetadata, type DAppSession, DEFAULT_RELAY_URL, DIGEST_LEN, type Domain, type EIP6963ProviderInfoOverride, EXPLICITLY_UNSUPPORTED_METHODS, FP_LEN, type InitiatedKeyExchange, type JsonRpcRequest, type JsonRpcResponse, KeyExchange, KeyExchangeMessageType, MAX_CONNECTION_URI_LENGTH, MAX_JSON_RPC_ID_LENGTH, MAX_JSON_RPC_METHOD_LENGTH, MAX_RELAY_URL_LENGTH, ML_DSA_87_PUBLIC_KEY_BYTES, ML_DSA_87_SIGNATURE_BYTES, ML_DSA_DESCRIPTOR_BYTES, type Message, MessageType, PAIRING_CAPABILITY_LEN, PROTOCOL_VERSION, type ParsedURI, type PendingRequest, type PersistedSession, type ProviderEvents, QRLConnectProvider as QRLConnect, type QRLConnectOptions, QRLConnectProvider, QRL_CONNECT_PROVIDER_INFO, type QrlSignMessageParams, type QrlSignTypedDataParams, type QrlSignedMessageResult, type QrlSignedResult, type QrlSignedResultWithDescriptor, type QrlSignedTypedDataResult, type QrlSigningResult, type QrlSigningSchemeVersion, type QrlTypedDataPayload, RESTRICTED_METHODS, type RelayMessage, type RpcMethodPolicy, SCHEME_TAG_MSG, SCHEME_TAG_TYPED, SCHEME_VERSION_MSG, SCHEME_VERSION_TYPED, type Session, SocketClient, type StructDef, type SynAckMessage, TYPED_DATA_LIMITS, type TypeMap, type TypedDataPayload, type TypedField, UNRESTRICTED_METHODS, type VerifyMessageForSignerParams, type VerifyMessageParams, type VerifyTypedDataForSignerParams, type VerifyTypedDataParams, attemptWalletRedirect, bytesToHex, cidFromString, cidRandom, cidToString, classifyRpcMethod, computeFingerprint, computeMessageDigest, computeTypedDataDigest, concatBytes, encodeField, encodeType, fingerprintEquals, generateConnectionURI, getAppStoreUrl, hasSigningDescriptor, hashStruct, hexToBytes, isMobileBrowser, isQrlSignedMessageResult, isQrlSignedResult, isQrlSignedTypedDataResult, isValidJsonRpcId, isValidJsonRpcMethod, normalizeRelayUrl, parseConnectionURI, typeHash, verifyMessage, verifyMessageForSigner, verifyMessageSignature, verifyTypedData, verifyTypedDataForSigner, verifyTypedDataSignature };
|