@meshconnect/uwc-types 0.19.0 → 0.20.0-snapshot.103d25f

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.
@@ -44,6 +44,12 @@ export interface ConnectorResult {
44
44
  address: string;
45
45
  availableAddresses: AvailableAddress[];
46
46
  publicKey?: string;
47
+ /**
48
+ * True when the connector satisfied this connect() by adopting a live stored
49
+ * session instead of a fresh pairing (WalletConnect session reuse, MFS-642).
50
+ * Propagated onto the Session for observability. Absent = fresh connect.
51
+ */
52
+ reused?: boolean;
47
53
  }
48
54
  /**
49
55
  * Result interface for network switch operations
@@ -53,6 +59,21 @@ export interface SwitchNetworkResult {
53
59
  address: string;
54
60
  availableAddresses?: AvailableAddress[];
55
61
  }
62
+ /**
63
+ * Optional per-call hints for connect(). Additive and connector-agnostic —
64
+ * connectors that do not use a field simply ignore it.
65
+ */
66
+ export interface ConnectOptions {
67
+ /**
68
+ * Display name of the wallet the user selected (from the catalog). The
69
+ * WalletConnect connector keys its session-reuse record on this trusted name:
70
+ * it only ever re-adopts a session it previously recorded for the same selected
71
+ * wallet, never one established by another (possibly rogue) peer. Ignored by
72
+ * connectors without session reuse; absence disables reuse (fresh pairing is
73
+ * always safe).
74
+ */
75
+ walletName?: string;
76
+ }
56
77
  /**
57
78
  * Common interface for all wallet connectors
58
79
  */
@@ -63,7 +84,7 @@ export interface Connector {
63
84
  * @param args Additional arguments specific to the connector type
64
85
  * @returns A promise that resolves to a ConnectorResult containing the network ID, wallet address, and available addresses
65
86
  */
66
- connect(network: Network, provider?: ExtensionInjectedProvider | IntegratedBrowserInjectedProvider | WalletConnectProvider | TonConnectWalletProvider): Promise<ConnectorResult>;
87
+ connect(network: Network, provider?: ExtensionInjectedProvider | IntegratedBrowserInjectedProvider | WalletConnectProvider | TonConnectWalletProvider, options?: ConnectOptions): Promise<ConnectorResult>;
67
88
  /**
68
89
  * Get the connection URI for the wallet, if applicable
69
90
  * This is typically used for WalletConnect or similar protocols
@@ -73,6 +94,18 @@ export interface Connector {
73
94
  * @remarks This method is optional and may not be implemented by all connectors.
74
95
  */
75
96
  getConnectionURI?(): string;
97
+ /**
98
+ * Pre-generate a connection pairing (URI) ahead of wallet selection, WITHOUT
99
+ * waiting for approval. Warms the transport (e.g. opens the WalletConnect relay
100
+ * socket on a cold client) and returns a URI the caller can deep-link inside a
101
+ * user gesture; a subsequent `connect()` adopts the same pairing so the URI the
102
+ * user approves matches the one opened. Optional — only connectors with a
103
+ * pairing step (WalletConnect) implement it.
104
+ * @param provider Only `supportedNetworkIds` is required (pass the UNION of the
105
+ * session's WalletConnect wallets' networks so one pairing serves any wallet).
106
+ * @returns The pairing URI.
107
+ */
108
+ beginPairing?(provider: Pick<WalletConnectProvider, 'supportedNetworkIds'>): Promise<string>;
76
109
  /**
77
110
  * Disconnect from the wallet
78
111
  * This method is optional and may not be implemented by all connectors.
@@ -1 +1 @@
1
- {"version":3,"file":"connector.d.ts","sourceRoot":"","sources":["../src/connector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"connector.d.ts","sourceRoot":"","sources":["../src/connector.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,67 @@
11
11
  * wires them to whatever backend they run (Datadog, Amplitude, Segment, …).
12
12
  */
13
13
  export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
14
+ /**
15
+ * Why an opt-in WalletConnect session-reuse attempt fell back to a fresh pairing
16
+ * instead of adopting a stored session (MFS-642). Small, stable enum so it can
17
+ * drive a reuse-outcome dashboard without high cardinality. Emitted via
18
+ * `WalletConnectConfig.onSessionReuseSkipped`.
19
+ *
20
+ * - `unscoped` — reuse is on but no `sessionReuseScopeId` was supplied (e.g. the
21
+ * link token carries no end-user id), so reuse is disabled by
22
+ * the user-binding rule. Split from `no_record` so the funnel
23
+ * separates "first connect" from "this consumer/user can never
24
+ * reuse" — the latter sizes the traffic where the integration
25
+ * (not the user) blocks adoption.
26
+ * - `no_record` — no topic recorded for the selected wallet (e.g. first connect),
27
+ * or the recorded session is no longer in storage.
28
+ * - `expired` — the recorded session exists but is past its expiry, or expires
29
+ * too soon to survive the signing flow (min-remaining-TTL guard).
30
+ * - `no_address` — the session carries no account for the requested network.
31
+ * - `ping_timeout`— the liveness ping got NO ack within the bounded window (peer
32
+ * slow/suspended or the relay socket is dead — CARE-263). Split
33
+ * from `ping_error` so a slow-but-alive mobile wallet (which
34
+ * would defeat reuse if the window is too tight) is measurable
35
+ * separately from a hard failure.
36
+ * - `ping_error` — the ping REJECTED (offline / relay / protocol error), i.e. an
37
+ * unknown liveness state rather than a confirmed no-ack.
38
+ * - `superseded` — a disconnect()/newer connect() invalidated the attempt mid-ping.
39
+ */
40
+ export type WalletConnectSessionReuseSkipReason = 'unscoped' | 'no_record' | 'expired' | 'no_address' | 'ping_timeout' | 'ping_error' | 'superseded';
41
+ /**
42
+ * Payload for `WalletConnectConfig.onSessionReuseSkipped`. Carries the coarse
43
+ * reason plus, for the two ping outcomes, the ping round-trip in ms — so a
44
+ * consumer can chart the ping-latency distribution and decide whether the bound
45
+ * is clipping live-but-slow wallets. (The healthy-ping latency is separately
46
+ * observable as the reused connect's own handoff duration.)
47
+ */
48
+ export interface WalletConnectSessionReuseSkip {
49
+ reason: WalletConnectSessionReuseSkipReason;
50
+ /** Ping round-trip in ms; present only for `ping_timeout` / `ping_error`. */
51
+ pingMs?: number;
52
+ }
53
+ /**
54
+ * Payload for `WalletConnectConfig.onSessionRestored` — context about the
55
+ * adopted session, for triaging reused-session failures per wallet (e.g. "does
56
+ * wallet X only fail when the session is close to expiry / was adopted stale?").
57
+ * Telemetry-only; adoption itself is decided before this fires.
58
+ */
59
+ export interface WalletConnectSessionRestored {
60
+ /**
61
+ * Seconds until the adopted session's WC expiry. WC v2 extends expiry on
62
+ * activity, so LOW values mean the session sat unused — the stale-session
63
+ * facet to correlate with a subsequent sign timeout on the same session.
64
+ */
65
+ expiresInSeconds: number;
66
+ /**
67
+ * The peer's self-reported wallet name (`session.peer.metadata.name`).
68
+ * UNAUTHENTICATED — never a trust input (adoption is keyed by the app-recorded
69
+ * topic, see the connector's reuse trust anchor); carried only so telemetry can
70
+ * facet reused-session outcomes by what the wallet claims to be, e.g. to isolate
71
+ * a wallet-specific reuse quirk (Rainbow, CARE-263).
72
+ */
73
+ peerName?: string;
74
+ }
14
75
  /**
15
76
  * Pluggable logger. The default implementation (`createLogger`) is console-backed
16
77
  * and level-gated; inject your own to redirect UWC's internal logging into your
@@ -1 +1 @@
1
- {"version":3,"file":"observability.d.ts","sourceRoot":"","sources":["../src/observability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;AAE1D;;;;;GAKG;AACH,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAChD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAC/C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAC/C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;CACjD;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,cAAc,GACtB,wBAAwB,GACxB,+BAA+B,GAC/B,wBAAwB,GACxB,qBAAqB,GACrB,cAAc,GACd,qBAAqB,GACrB,4BAA4B,GAC5B,wBAAwB,GACxB,SAAS,CAAA;AAEb;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAA;AAEnE;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GACnB,eAAe,GACf,gBAAgB,GAChB,cAAc,GACd,eAAe;AACjB,iFAAiF;GAC/E,mBAAmB,GACnB,oBAAoB,GACpB,gBAAgB,GAChB,SAAS;AACX,gFAAgF;GAC9E,oBAAoB,GACpB,SAAS,CAAA;AAEb;;;;GAIG;AACH,MAAM,MAAM,WAAW,GACnB,UAAU,GACV,WAAW,GACX,QAAQ,GACR,KAAK,GACL,SAAS,CAAA;AAEb;;;;GAIG;AACH,MAAM,MAAM,0BAA0B;AACpC,gGAAgG;AAC9F,mCAAmC;AACrC,uFAAuF;GACrF,iCAAiC;AACnC,oEAAoE;GAClE,uBAAuB;AACzB;;;;GAIG;GACD,mBAAmB;AACrB;;;GAGG;GACD,cAAc,CAAA"}
1
+ {"version":3,"file":"observability.d.ts","sourceRoot":"","sources":["../src/observability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,MAAM,mCAAmC,GAC3C,UAAU,GACV,WAAW,GACX,SAAS,GACT,YAAY,GACZ,cAAc,GACd,YAAY,GACZ,YAAY,CAAA;AAEhB;;;;;;GAMG;AACH,MAAM,WAAW,6BAA6B;IAC5C,MAAM,EAAE,mCAAmC,CAAA;IAC3C,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;;GAKG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;;OAIG;IACH,gBAAgB,EAAE,MAAM,CAAA;IACxB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;;;;GAKG;AACH,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAChD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAC/C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAC/C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;CACjD;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,cAAc,GACtB,wBAAwB,GACxB,+BAA+B,GAC/B,wBAAwB,GACxB,qBAAqB,GACrB,cAAc,GACd,qBAAqB,GACrB,4BAA4B,GAC5B,wBAAwB,GACxB,SAAS,CAAA;AAEb;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAA;AAEnE;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GACnB,eAAe,GACf,gBAAgB,GAChB,cAAc,GACd,eAAe;AACjB,iFAAiF;GAC/E,mBAAmB,GACnB,oBAAoB,GACpB,gBAAgB,GAChB,SAAS;AACX,gFAAgF;GAC9E,oBAAoB,GACpB,SAAS,CAAA;AAEb;;;;GAIG;AACH,MAAM,MAAM,WAAW,GACnB,UAAU,GACV,WAAW,GACX,QAAQ,GACR,KAAK,GACL,SAAS,CAAA;AAEb;;;;GAIG;AACH,MAAM,MAAM,0BAA0B;AACpC,gGAAgG;AAC9F,mCAAmC;AACrC,uFAAuF;GACrF,iCAAiC;AACnC,oEAAoE;GAClE,uBAAuB;AACzB;;;;GAIG;GACD,mBAAmB;AACrB;;;GAGG;GACD,cAAc,CAAA"}
package/dist/session.d.ts CHANGED
@@ -16,5 +16,14 @@ export interface Session {
16
16
  availableNetworks: Network[];
17
17
  activeWallet: WalletMetadata | null;
18
18
  availableAddresses: AvailableAddress[];
19
+ /**
20
+ * Connection provenance: true when this session was adopted from a live stored
21
+ * WalletConnect session (MFS-642 reuse) rather than established by a fresh
22
+ * pairing handshake. Drives observability — it rides the `connected` telemetry
23
+ * and every subsequent operation handoff so success/error/timeout of reused
24
+ * sessions can be evaluated and triaged separately from fresh ones. Absent/false
25
+ * for fresh pairings and all non-WalletConnect connections.
26
+ */
27
+ reused?: boolean;
19
28
  }
20
29
  //# sourceMappingURL=session.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,SAAS,CAAA;CACrB;AAED,MAAM,WAAW,OAAO;IACtB,cAAc,EAAE,cAAc,GAAG,IAAI,CAAA;IACrC,aAAa,EAAE,OAAO,GAAG,IAAI,CAAA;IAC7B,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,IAAI,CAAA;IAChE,+BAA+B,EAAE,eAAe,GAAG,IAAI,CAAA;IACvD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,iBAAiB,EAAE,OAAO,EAAE,CAAA;IAC5B,YAAY,EAAE,cAAc,GAAG,IAAI,CAAA;IACnC,kBAAkB,EAAE,gBAAgB,EAAE,CAAA;CACvC"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,SAAS,CAAA;CACrB;AAED,MAAM,WAAW,OAAO;IACtB,cAAc,EAAE,cAAc,GAAG,IAAI,CAAA;IACrC,aAAa,EAAE,OAAO,GAAG,IAAI,CAAA;IAC7B,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,IAAI,CAAA;IAChE,+BAA+B,EAAE,eAAe,GAAG,IAAI,CAAA;IACvD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,iBAAiB,EAAE,OAAO,EAAE,CAAA;IAC5B,YAAY,EAAE,cAAc,GAAG,IAAI,CAAA;IACnC,kBAAkB,EAAE,gBAAgB,EAAE,CAAA;IACtC;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB"}
@@ -1,3 +1,4 @@
1
+ import type { WalletConnectSessionRestored, WalletConnectSessionReuseSkip } from './observability';
1
2
  /**
2
3
  * Configuration for WalletConnect connector
3
4
  */
@@ -9,5 +10,65 @@ export interface WalletConnectConfig {
9
10
  url: string;
10
11
  icons: string[];
11
12
  };
13
+ /**
14
+ * Opt-in: reuse a live WalletConnect session persisted in storage instead of
15
+ * forcing a fresh pairing approval on every connect(). WC v2 keeps approved
16
+ * sessions in the SignClient's storage (IndexedDB) for their full ~7-day TTL;
17
+ * with this off (the default) UWC ignores them and always re-pairs — the
18
+ * historical behaviour (MFS-642). When on, connect() first looks for a stored
19
+ * session whose namespaces cover the requested network and reuses it, skipping
20
+ * the QR/deep-link round-trip; it falls back to a fresh pairing when none is
21
+ * usable. Default false so existing consumers are byte-for-byte unaffected and
22
+ * the blast radius is opt-in per consumer.
23
+ *
24
+ * The SignClient (and its storage) lives in the SAME context that runs this
25
+ * connector — for Mesh Link that is the web.meshconnect.com iframe, whose
26
+ * per-origin IndexedDB survives the iframe being torn down and re-created — so
27
+ * reuse works in the production iframe without any bridge round-trip.
28
+ */
29
+ enableSessionReuse?: boolean;
30
+ /**
31
+ * Fired once when connect() resolves from a reused stored session instead of a
32
+ * fresh pairing handshake, with context about the adopted session — time to WC
33
+ * expiry and the peer's (unauthenticated) self-reported name — so reused-session
34
+ * failures can be triaged per wallet and correlated with session staleness.
35
+ * Optional — omitting it keeps reuse working, only the signal is dropped.
36
+ * No-op unless enableSessionReuse is on. Mirrors TonConnectConfig.onSessionRestored.
37
+ */
38
+ onSessionRestored?: (restored: WalletConnectSessionRestored) => void;
39
+ /**
40
+ * Fired when reuse was attempted (enableSessionReuse on + wallet known) but fell
41
+ * back to a fresh pairing. Carries the coarse `reason` plus, for the ping
42
+ * outcomes, the ping round-trip (`pingMs`). The counterpart to onSessionRestored:
43
+ * together they give a reuse-outcome funnel (reused vs the reason it wasn't) for
44
+ * monitoring. Telemetry-only; never affects behaviour. No-op unless
45
+ * enableSessionReuse is on.
46
+ */
47
+ onSessionReuseSkipped?: (skip: WalletConnectSessionReuseSkip) => void;
48
+ /**
49
+ * SECURITY-CRITICAL user binding for session reuse. The Mesh Link iframe shares
50
+ * one origin across every client and end-user, so a stored session must be
51
+ * bound to the authenticated Link user — otherwise a later user on the same
52
+ * device could silently adopt an earlier user's live session without a fresh
53
+ * approval. Pass a stable per-user id (the Link user id). Reuse is DISABLED when
54
+ * this is empty/absent, regardless of `enableSessionReuse` (skips report as
55
+ * `unscoped`) — origin persistence alone is never sufficient. The id is hashed
56
+ * before it is persisted, so a PII-bearing id (merchants sometimes use emails as
57
+ * user ids) never lands in storage verbatim. No-op unless enableSessionReuse is on.
58
+ */
59
+ sessionReuseScopeId?: string;
60
+ /**
61
+ * Opt-in liveness-ping window (ms) for session reuse. Reuse is OPTIMISTIC by
62
+ * default: when this is unset (or ≤ 0) connect() adopts a stored session with no
63
+ * blocking probe — matching WC's own restore and every mainstream dApp connector
64
+ * — and a dead peer surfaces at the first sign (bounded by the app's signing
65
+ * escape hatch), not by making every relaunch wait. Set a positive number only if
66
+ * you would rather pay an up-front ping and re-pair immediately than risk a late
67
+ * failure; a too-tight bound will discard live-but-slow mobile peers (they often
68
+ * need > 4s to ack over the relay), so calibrate against the `pingMs` carried by
69
+ * onSessionReuseSkipped. Exposed as config so this bound can be tuned per consumer
70
+ * without a new UWC release. No-op unless enableSessionReuse is on.
71
+ */
72
+ sessionReusePingTimeoutMs?: number;
12
73
  }
13
74
  //# sourceMappingURL=wallet-connect-connector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wallet-connect-connector.d.ts","sourceRoot":"","sources":["../src/wallet-connect-connector.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE;QACT,IAAI,EAAE,MAAM,CAAA;QACZ,WAAW,EAAE,MAAM,CAAA;QACnB,GAAG,EAAE,MAAM,CAAA;QACX,KAAK,EAAE,MAAM,EAAE,CAAA;KAChB,CAAA;CACF"}
1
+ {"version":3,"file":"wallet-connect-connector.d.ts","sourceRoot":"","sources":["../src/wallet-connect-connector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,4BAA4B,EAC5B,6BAA6B,EAC9B,MAAM,iBAAiB,CAAA;AAExB;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE;QACT,IAAI,EAAE,MAAM,CAAA;QACZ,WAAW,EAAE,MAAM,CAAA;QACnB,GAAG,EAAE,MAAM,CAAA;QACX,KAAK,EAAE,MAAM,EAAE,CAAA;KAChB,CAAA;IACD;;;;;;;;;;;;;;;OAeG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE,4BAA4B,KAAK,IAAI,CAAA;IACpE;;;;;;;OAOG;IACH,qBAAqB,CAAC,EAAE,CAAC,IAAI,EAAE,6BAA6B,KAAK,IAAI,CAAA;IACrE;;;;;;;;;;OAUG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B;;;;;;;;;;;OAWG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAA;CACnC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meshconnect/uwc-types",
3
- "version": "0.19.0",
3
+ "version": "0.20.0-snapshot.103d25f",
4
4
  "description": "TypeScript types for Universal Wallet Connector",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/src/connector.ts CHANGED
@@ -56,6 +56,12 @@ export interface ConnectorResult {
56
56
  address: string
57
57
  availableAddresses: AvailableAddress[]
58
58
  publicKey?: string
59
+ /**
60
+ * True when the connector satisfied this connect() by adopting a live stored
61
+ * session instead of a fresh pairing (WalletConnect session reuse, MFS-642).
62
+ * Propagated onto the Session for observability. Absent = fresh connect.
63
+ */
64
+ reused?: boolean
59
65
  }
60
66
 
61
67
  /**
@@ -67,6 +73,22 @@ export interface SwitchNetworkResult {
67
73
  availableAddresses?: AvailableAddress[]
68
74
  }
69
75
 
76
+ /**
77
+ * Optional per-call hints for connect(). Additive and connector-agnostic —
78
+ * connectors that do not use a field simply ignore it.
79
+ */
80
+ export interface ConnectOptions {
81
+ /**
82
+ * Display name of the wallet the user selected (from the catalog). The
83
+ * WalletConnect connector keys its session-reuse record on this trusted name:
84
+ * it only ever re-adopts a session it previously recorded for the same selected
85
+ * wallet, never one established by another (possibly rogue) peer. Ignored by
86
+ * connectors without session reuse; absence disables reuse (fresh pairing is
87
+ * always safe).
88
+ */
89
+ walletName?: string
90
+ }
91
+
70
92
  /**
71
93
  * Common interface for all wallet connectors
72
94
  */
@@ -84,7 +106,8 @@ export interface Connector {
84
106
  | ExtensionInjectedProvider
85
107
  | IntegratedBrowserInjectedProvider
86
108
  | WalletConnectProvider
87
- | TonConnectWalletProvider
109
+ | TonConnectWalletProvider,
110
+ options?: ConnectOptions
88
111
  ): Promise<ConnectorResult>
89
112
 
90
113
  /**
@@ -97,6 +120,21 @@ export interface Connector {
97
120
  */
98
121
  getConnectionURI?(): string
99
122
 
123
+ /**
124
+ * Pre-generate a connection pairing (URI) ahead of wallet selection, WITHOUT
125
+ * waiting for approval. Warms the transport (e.g. opens the WalletConnect relay
126
+ * socket on a cold client) and returns a URI the caller can deep-link inside a
127
+ * user gesture; a subsequent `connect()` adopts the same pairing so the URI the
128
+ * user approves matches the one opened. Optional — only connectors with a
129
+ * pairing step (WalletConnect) implement it.
130
+ * @param provider Only `supportedNetworkIds` is required (pass the UNION of the
131
+ * session's WalletConnect wallets' networks so one pairing serves any wallet).
132
+ * @returns The pairing URI.
133
+ */
134
+ beginPairing?(
135
+ provider: Pick<WalletConnectProvider, 'supportedNetworkIds'>
136
+ ): Promise<string>
137
+
100
138
  /**
101
139
  * Disconnect from the wallet
102
140
  * This method is optional and may not be implemented by all connectors.
@@ -13,6 +13,77 @@
13
13
 
14
14
  export type LogLevel = 'debug' | 'info' | 'warn' | 'error'
15
15
 
16
+ /**
17
+ * Why an opt-in WalletConnect session-reuse attempt fell back to a fresh pairing
18
+ * instead of adopting a stored session (MFS-642). Small, stable enum so it can
19
+ * drive a reuse-outcome dashboard without high cardinality. Emitted via
20
+ * `WalletConnectConfig.onSessionReuseSkipped`.
21
+ *
22
+ * - `unscoped` — reuse is on but no `sessionReuseScopeId` was supplied (e.g. the
23
+ * link token carries no end-user id), so reuse is disabled by
24
+ * the user-binding rule. Split from `no_record` so the funnel
25
+ * separates "first connect" from "this consumer/user can never
26
+ * reuse" — the latter sizes the traffic where the integration
27
+ * (not the user) blocks adoption.
28
+ * - `no_record` — no topic recorded for the selected wallet (e.g. first connect),
29
+ * or the recorded session is no longer in storage.
30
+ * - `expired` — the recorded session exists but is past its expiry, or expires
31
+ * too soon to survive the signing flow (min-remaining-TTL guard).
32
+ * - `no_address` — the session carries no account for the requested network.
33
+ * - `ping_timeout`— the liveness ping got NO ack within the bounded window (peer
34
+ * slow/suspended or the relay socket is dead — CARE-263). Split
35
+ * from `ping_error` so a slow-but-alive mobile wallet (which
36
+ * would defeat reuse if the window is too tight) is measurable
37
+ * separately from a hard failure.
38
+ * - `ping_error` — the ping REJECTED (offline / relay / protocol error), i.e. an
39
+ * unknown liveness state rather than a confirmed no-ack.
40
+ * - `superseded` — a disconnect()/newer connect() invalidated the attempt mid-ping.
41
+ */
42
+ export type WalletConnectSessionReuseSkipReason =
43
+ | 'unscoped'
44
+ | 'no_record'
45
+ | 'expired'
46
+ | 'no_address'
47
+ | 'ping_timeout'
48
+ | 'ping_error'
49
+ | 'superseded'
50
+
51
+ /**
52
+ * Payload for `WalletConnectConfig.onSessionReuseSkipped`. Carries the coarse
53
+ * reason plus, for the two ping outcomes, the ping round-trip in ms — so a
54
+ * consumer can chart the ping-latency distribution and decide whether the bound
55
+ * is clipping live-but-slow wallets. (The healthy-ping latency is separately
56
+ * observable as the reused connect's own handoff duration.)
57
+ */
58
+ export interface WalletConnectSessionReuseSkip {
59
+ reason: WalletConnectSessionReuseSkipReason
60
+ /** Ping round-trip in ms; present only for `ping_timeout` / `ping_error`. */
61
+ pingMs?: number
62
+ }
63
+
64
+ /**
65
+ * Payload for `WalletConnectConfig.onSessionRestored` — context about the
66
+ * adopted session, for triaging reused-session failures per wallet (e.g. "does
67
+ * wallet X only fail when the session is close to expiry / was adopted stale?").
68
+ * Telemetry-only; adoption itself is decided before this fires.
69
+ */
70
+ export interface WalletConnectSessionRestored {
71
+ /**
72
+ * Seconds until the adopted session's WC expiry. WC v2 extends expiry on
73
+ * activity, so LOW values mean the session sat unused — the stale-session
74
+ * facet to correlate with a subsequent sign timeout on the same session.
75
+ */
76
+ expiresInSeconds: number
77
+ /**
78
+ * The peer's self-reported wallet name (`session.peer.metadata.name`).
79
+ * UNAUTHENTICATED — never a trust input (adoption is keyed by the app-recorded
80
+ * topic, see the connector's reuse trust anchor); carried only so telemetry can
81
+ * facet reused-session outcomes by what the wallet claims to be, e.g. to isolate
82
+ * a wallet-specific reuse quirk (Rainbow, CARE-263).
83
+ */
84
+ peerName?: string
85
+ }
86
+
16
87
  /**
17
88
  * Pluggable logger. The default implementation (`createLogger`) is console-backed
18
89
  * and level-gated; inject your own to redirect UWC's internal logging into your
package/src/session.ts CHANGED
@@ -18,4 +18,13 @@ export interface Session {
18
18
  availableNetworks: Network[]
19
19
  activeWallet: WalletMetadata | null
20
20
  availableAddresses: AvailableAddress[]
21
+ /**
22
+ * Connection provenance: true when this session was adopted from a live stored
23
+ * WalletConnect session (MFS-642 reuse) rather than established by a fresh
24
+ * pairing handshake. Drives observability — it rides the `connected` telemetry
25
+ * and every subsequent operation handoff so success/error/timeout of reused
26
+ * sessions can be evaluated and triaged separately from fresh ones. Absent/false
27
+ * for fresh pairings and all non-WalletConnect connections.
28
+ */
29
+ reused?: boolean
21
30
  }
@@ -1,3 +1,8 @@
1
+ import type {
2
+ WalletConnectSessionRestored,
3
+ WalletConnectSessionReuseSkip
4
+ } from './observability'
5
+
1
6
  /**
2
7
  * Configuration for WalletConnect connector
3
8
  */
@@ -9,4 +14,64 @@ export interface WalletConnectConfig {
9
14
  url: string
10
15
  icons: string[]
11
16
  }
17
+ /**
18
+ * Opt-in: reuse a live WalletConnect session persisted in storage instead of
19
+ * forcing a fresh pairing approval on every connect(). WC v2 keeps approved
20
+ * sessions in the SignClient's storage (IndexedDB) for their full ~7-day TTL;
21
+ * with this off (the default) UWC ignores them and always re-pairs — the
22
+ * historical behaviour (MFS-642). When on, connect() first looks for a stored
23
+ * session whose namespaces cover the requested network and reuses it, skipping
24
+ * the QR/deep-link round-trip; it falls back to a fresh pairing when none is
25
+ * usable. Default false so existing consumers are byte-for-byte unaffected and
26
+ * the blast radius is opt-in per consumer.
27
+ *
28
+ * The SignClient (and its storage) lives in the SAME context that runs this
29
+ * connector — for Mesh Link that is the web.meshconnect.com iframe, whose
30
+ * per-origin IndexedDB survives the iframe being torn down and re-created — so
31
+ * reuse works in the production iframe without any bridge round-trip.
32
+ */
33
+ enableSessionReuse?: boolean
34
+ /**
35
+ * Fired once when connect() resolves from a reused stored session instead of a
36
+ * fresh pairing handshake, with context about the adopted session — time to WC
37
+ * expiry and the peer's (unauthenticated) self-reported name — so reused-session
38
+ * failures can be triaged per wallet and correlated with session staleness.
39
+ * Optional — omitting it keeps reuse working, only the signal is dropped.
40
+ * No-op unless enableSessionReuse is on. Mirrors TonConnectConfig.onSessionRestored.
41
+ */
42
+ onSessionRestored?: (restored: WalletConnectSessionRestored) => void
43
+ /**
44
+ * Fired when reuse was attempted (enableSessionReuse on + wallet known) but fell
45
+ * back to a fresh pairing. Carries the coarse `reason` plus, for the ping
46
+ * outcomes, the ping round-trip (`pingMs`). The counterpart to onSessionRestored:
47
+ * together they give a reuse-outcome funnel (reused vs the reason it wasn't) for
48
+ * monitoring. Telemetry-only; never affects behaviour. No-op unless
49
+ * enableSessionReuse is on.
50
+ */
51
+ onSessionReuseSkipped?: (skip: WalletConnectSessionReuseSkip) => void
52
+ /**
53
+ * SECURITY-CRITICAL user binding for session reuse. The Mesh Link iframe shares
54
+ * one origin across every client and end-user, so a stored session must be
55
+ * bound to the authenticated Link user — otherwise a later user on the same
56
+ * device could silently adopt an earlier user's live session without a fresh
57
+ * approval. Pass a stable per-user id (the Link user id). Reuse is DISABLED when
58
+ * this is empty/absent, regardless of `enableSessionReuse` (skips report as
59
+ * `unscoped`) — origin persistence alone is never sufficient. The id is hashed
60
+ * before it is persisted, so a PII-bearing id (merchants sometimes use emails as
61
+ * user ids) never lands in storage verbatim. No-op unless enableSessionReuse is on.
62
+ */
63
+ sessionReuseScopeId?: string
64
+ /**
65
+ * Opt-in liveness-ping window (ms) for session reuse. Reuse is OPTIMISTIC by
66
+ * default: when this is unset (or ≤ 0) connect() adopts a stored session with no
67
+ * blocking probe — matching WC's own restore and every mainstream dApp connector
68
+ * — and a dead peer surfaces at the first sign (bounded by the app's signing
69
+ * escape hatch), not by making every relaunch wait. Set a positive number only if
70
+ * you would rather pay an up-front ping and re-pair immediately than risk a late
71
+ * failure; a too-tight bound will discard live-but-slow mobile peers (they often
72
+ * need > 4s to ack over the relay), so calibrate against the `pingMs` carried by
73
+ * onSessionReuseSkipped. Exposed as config so this bound can be tuned per consumer
74
+ * without a new UWC release. No-op unless enableSessionReuse is on.
75
+ */
76
+ sessionReusePingTimeoutMs?: number
12
77
  }