@meshconnect/uwc-core 1.0.3 → 1.1.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 +247 -76
- package/dist/events.d.ts +241 -5
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +77 -1
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/logger/create-logger.d.ts +32 -0
- package/dist/logger/create-logger.d.ts.map +1 -0
- package/dist/logger/create-logger.js +79 -0
- package/dist/logger/create-logger.js.map +1 -0
- package/dist/managers/event-manager.d.ts.map +1 -1
- package/dist/managers/event-manager.js +5 -1
- package/dist/managers/event-manager.js.map +1 -1
- package/dist/observability/connect-observer.d.ts +33 -0
- package/dist/observability/connect-observer.d.ts.map +1 -0
- package/dist/observability/connect-observer.js +115 -0
- package/dist/observability/connect-observer.js.map +1 -0
- package/dist/observability/focus-tracker.d.ts +42 -0
- package/dist/observability/focus-tracker.d.ts.map +1 -0
- package/dist/observability/focus-tracker.js +57 -0
- package/dist/observability/focus-tracker.js.map +1 -0
- package/dist/observability/instrument-handoff.d.ts +54 -0
- package/dist/observability/instrument-handoff.d.ts.map +1 -0
- package/dist/observability/instrument-handoff.js +173 -0
- package/dist/observability/instrument-handoff.js.map +1 -0
- package/dist/observability/lifecycle-bridge.d.ts +69 -0
- package/dist/observability/lifecycle-bridge.d.ts.map +1 -0
- package/dist/observability/lifecycle-bridge.js +155 -0
- package/dist/observability/lifecycle-bridge.js.map +1 -0
- package/dist/observability/scrub.d.ts +31 -0
- package/dist/observability/scrub.d.ts.map +1 -0
- package/dist/observability/scrub.js +167 -0
- package/dist/observability/scrub.js.map +1 -0
- package/dist/observability/telemetry.d.ts +157 -0
- package/dist/observability/telemetry.d.ts.map +1 -0
- package/dist/observability/telemetry.js +373 -0
- package/dist/observability/telemetry.js.map +1 -0
- package/dist/services/connection-service.d.ts +23 -1
- package/dist/services/connection-service.d.ts.map +1 -1
- package/dist/services/connection-service.js +128 -19
- package/dist/services/connection-service.js.map +1 -1
- package/dist/services/network-switch-service.d.ts +2 -1
- package/dist/services/network-switch-service.d.ts.map +1 -1
- package/dist/services/network-switch-service.js +45 -16
- package/dist/services/network-switch-service.js.map +1 -1
- package/dist/services/signature-service.d.ts +14 -7
- package/dist/services/signature-service.d.ts.map +1 -1
- package/dist/services/signature-service.js +56 -58
- package/dist/services/signature-service.js.map +1 -1
- package/dist/services/transaction-service.d.ts +19 -5
- package/dist/services/transaction-service.d.ts.map +1 -1
- package/dist/services/transaction-service.js +55 -38
- package/dist/services/transaction-service.js.map +1 -1
- package/dist/universal-wallet-connector.d.ts +56 -1
- package/dist/universal-wallet-connector.d.ts.map +1 -1
- package/dist/universal-wallet-connector.js +207 -110
- package/dist/universal-wallet-connector.js.map +1 -1
- package/dist/utils/id.d.ts +2 -0
- package/dist/utils/id.d.ts.map +1 -0
- package/dist/utils/id.js +41 -0
- package/dist/utils/id.js.map +1 -0
- package/dist/utils/resolve-session-provider.d.ts +10 -0
- package/dist/utils/resolve-session-provider.d.ts.map +1 -0
- package/dist/utils/resolve-session-provider.js +21 -0
- package/dist/utils/resolve-session-provider.js.map +1 -0
- package/dist/utils/to-wallet-error.d.ts +35 -0
- package/dist/utils/to-wallet-error.d.ts.map +1 -0
- package/dist/utils/to-wallet-error.js +130 -0
- package/dist/utils/to-wallet-error.js.map +1 -0
- package/dist/utils/validate-wallet-session.d.ts +15 -0
- package/dist/utils/validate-wallet-session.d.ts.map +1 -0
- package/dist/utils/validate-wallet-session.js +29 -0
- package/dist/utils/validate-wallet-session.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/package.json +6 -6
- package/src/events.ts +326 -14
- package/src/index.ts +10 -0
- package/src/logger/create-logger.test.ts +126 -0
- package/src/logger/create-logger.ts +112 -0
- package/src/managers/event-manager.test.ts +55 -0
- package/src/managers/event-manager.ts +5 -1
- package/src/observability/connect-observer.test.ts +214 -0
- package/src/observability/connect-observer.ts +128 -0
- package/src/observability/focus-tracker.test.ts +191 -0
- package/src/observability/focus-tracker.ts +96 -0
- package/src/observability/instrument-handoff.test.ts +397 -0
- package/src/observability/instrument-handoff.ts +231 -0
- package/src/observability/lifecycle-bridge.test.ts +398 -0
- package/src/observability/lifecycle-bridge.ts +216 -0
- package/src/observability/scrub.test.ts +183 -0
- package/src/observability/scrub.ts +174 -0
- package/src/observability/telemetry.test.ts +549 -0
- package/src/observability/telemetry.ts +546 -0
- package/src/services/connection-service.test.ts +261 -1
- package/src/services/connection-service.ts +167 -38
- package/src/services/network-switch-service.test.ts +51 -1
- package/src/services/network-switch-service.ts +56 -24
- package/src/services/signature-service.test.ts +181 -76
- package/src/services/signature-service.ts +75 -85
- package/src/services/transaction-service.test.ts +270 -69
- package/src/services/transaction-service.ts +74 -51
- package/src/universal-wallet-connector.instrumentation-guard.test.ts +199 -0
- package/src/universal-wallet-connector.observability.test.ts +610 -0
- package/src/universal-wallet-connector.test.ts +27 -146
- package/src/universal-wallet-connector.ts +279 -142
- package/src/utils/id.test.ts +15 -0
- package/src/utils/id.ts +48 -0
- package/src/utils/resolve-session-provider.test.ts +54 -0
- package/src/utils/resolve-session-provider.ts +25 -0
- package/src/utils/to-wallet-error.test.ts +181 -0
- package/src/utils/to-wallet-error.ts +152 -0
- package/src/utils/validate-wallet-session.test.ts +77 -0
- package/src/utils/validate-wallet-session.ts +40 -0
- package/src/version.test.ts +11 -0
- package/src/version.ts +2 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { UniversalWalletConnectorState, Network, WalletMetadata, NetworkId, ConnectionMode, WalletConnectConfig, TonConnectConfig, TransactionRequest, TransactionResult, EVMCapabilities, SignatureType, EIP712TypedData } from '@meshconnect/uwc-types';
|
|
1
|
+
import type { UniversalWalletConnectorState, Network, WalletMetadata, NetworkId, ConnectionMode, WalletConnectConfig, TonConnectConfig, TransactionRequest, TransactionResult, EVMCapabilities, SignatureType, EIP712TypedData, LogLevel, Logger } from '@meshconnect/uwc-types';
|
|
2
2
|
import type { TronConnectorConfig } from '@meshconnect/uwc-tron-connector';
|
|
3
|
+
import type { UWCObserver } from './observability/telemetry';
|
|
3
4
|
import type { UWCEventName, UWCEventListener } from './events';
|
|
4
5
|
/**
|
|
5
6
|
* Configuration object form of the UniversalWalletConnector constructor.
|
|
@@ -12,6 +13,37 @@ export interface UWCConfig {
|
|
|
12
13
|
walletConnectConfig?: WalletConnectConfig;
|
|
13
14
|
tonConnectConfig?: TonConnectConfig;
|
|
14
15
|
tronConnectorConfig?: TronConnectorConfig;
|
|
16
|
+
/**
|
|
17
|
+
* Vendor-agnostic telemetry sink. When omitted, UWC emits NOTHING externally —
|
|
18
|
+
* zero egress is the security-first default for a sign-only wallet layer. The
|
|
19
|
+
* consumer implements the sink and wires it to their backend (Datadog/…).
|
|
20
|
+
*/
|
|
21
|
+
observer?: UWCObserver;
|
|
22
|
+
/**
|
|
23
|
+
* Redirect UWC's internal logging into your own logger. Receives raw
|
|
24
|
+
* `(message, ...args)` at/above `logLevel`. When omitted, a console-backed
|
|
25
|
+
* logger is used. LOCAL SINK by contract: args are NOT scrubbed here — do not
|
|
26
|
+
* wire this to a remote transport; use `observer.onLog` (scrubbed) for egress.
|
|
27
|
+
*/
|
|
28
|
+
logger?: Logger;
|
|
29
|
+
/** Console threshold for the default logger. Default `'warn'`. */
|
|
30
|
+
logLevel?: LogLevel;
|
|
31
|
+
/**
|
|
32
|
+
* Consumer correlation id, surfaced as its OWN `correlationId` field on every
|
|
33
|
+
* telemetry record — never aliased onto the generated `sdkSessionId`, so
|
|
34
|
+
* "no id supplied" and "id == session" stay distinguishable. Supply your own
|
|
35
|
+
* (e.g. the consumer's `link_sess_id`) so UWC events join your existing
|
|
36
|
+
* telemetry in Datadog/RUM without a separate mapping. Pass a getter if the
|
|
37
|
+
* id isn't known at construction or can change; resolved per-event, and a
|
|
38
|
+
* throwing/empty getter OMITS the field for that record.
|
|
39
|
+
*/
|
|
40
|
+
correlationId?: string | (() => string);
|
|
41
|
+
/**
|
|
42
|
+
* Observational wallet-response deadline (ms) for the `walletTimedOut` marker.
|
|
43
|
+
* `0` disables it. TON is always exempt (it bounds its own response). Default
|
|
44
|
+
* 60_000.
|
|
45
|
+
*/
|
|
46
|
+
walletResponseTimeoutMs?: number;
|
|
15
47
|
}
|
|
16
48
|
/** Common options for user-initiated async operations. */
|
|
17
49
|
export interface OperationOptions {
|
|
@@ -35,6 +67,12 @@ export declare class UniversalWalletConnector {
|
|
|
35
67
|
private usingIntegratedBrowser;
|
|
36
68
|
private detectionComplete;
|
|
37
69
|
private networkRpcMap;
|
|
70
|
+
private logger;
|
|
71
|
+
/** Per-instance correlation id stamped on every telemetry record. */
|
|
72
|
+
private readonly sdkSessionId;
|
|
73
|
+
private walletResponseTimeoutMs;
|
|
74
|
+
/** Tears down the observer subscriptions; set only when an observer is wired. */
|
|
75
|
+
private observerTeardown;
|
|
38
76
|
/**
|
|
39
77
|
* Recommended entry point: returns the shared instance, creating it on the
|
|
40
78
|
* first call. Subsequent calls ignore the `config` argument — use
|
|
@@ -55,6 +93,13 @@ export declare class UniversalWalletConnector {
|
|
|
55
93
|
* in parallel without racing on the merge logic.
|
|
56
94
|
*/
|
|
57
95
|
private applyDetectedWallet;
|
|
96
|
+
/**
|
|
97
|
+
* Per-namespace requested-vs-matched counts after detection. `requested` =
|
|
98
|
+
* configured wallets that declared the namespace; `matched` = those now marked
|
|
99
|
+
* installed. Counts only — never a wallet id or address. Feeds `walletsDetected`
|
|
100
|
+
* so a dashboard can answer "asked for N, matched 0?".
|
|
101
|
+
*/
|
|
102
|
+
private summarizeDiscovery;
|
|
58
103
|
getSession(): import("@meshconnect/uwc-types").Session;
|
|
59
104
|
isReady(): boolean;
|
|
60
105
|
/** Subscribe to a typed event. Returns an unsubscribe function. */
|
|
@@ -123,6 +168,16 @@ export declare class UniversalWalletConnector {
|
|
|
123
168
|
*/
|
|
124
169
|
isConnectionModeAvailable(connectionMode: ConnectionMode, walletId: string): boolean;
|
|
125
170
|
getActiveWalletCapabilities(): Record<string, EVMCapabilities> | null;
|
|
171
|
+
/**
|
|
172
|
+
* Set the console log threshold at runtime (e.g. from a support toggle). The
|
|
173
|
+
* global `window.UWC_DEBUG` override still takes precedence for ad-hoc triage.
|
|
174
|
+
*/
|
|
175
|
+
setLogLevel(level: LogLevel): void;
|
|
176
|
+
/**
|
|
177
|
+
* Release observer subscriptions and clear all event listeners. Call on full
|
|
178
|
+
* teardown / logout to avoid leaking listeners across connector lifecycles.
|
|
179
|
+
*/
|
|
180
|
+
dispose(): void;
|
|
126
181
|
private emitError;
|
|
127
182
|
}
|
|
128
183
|
//# sourceMappingURL=universal-wallet-connector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"universal-wallet-connector.d.ts","sourceRoot":"","sources":["../src/universal-wallet-connector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,6BAA6B,EAC7B,OAAO,EACP,cAAc,EACd,SAAS,EACT,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAOhB,kBAAkB,EAClB,iBAAiB,EAEjB,eAAe,EACf,aAAa,EACb,eAAe,
|
|
1
|
+
{"version":3,"file":"universal-wallet-connector.d.ts","sourceRoot":"","sources":["../src/universal-wallet-connector.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { WalletConnectorError } from '@meshconnect/uwc-types';
|
|
2
1
|
import { InjectedConnector } from '@meshconnect/uwc-injected-connector';
|
|
3
2
|
import { WalletConnectConnector } from '@meshconnect/uwc-wallet-connect-connector';
|
|
4
3
|
import { TonConnectConnector } from '@meshconnect/uwc-ton-connector';
|
|
@@ -10,6 +9,14 @@ import { SignatureService } from './services/signature-service';
|
|
|
10
9
|
import { TransactionService } from './services/transaction-service';
|
|
11
10
|
import { WalletCapabilitiesService } from './services/wallet-capabilities-service';
|
|
12
11
|
import { createNetworkRpcMap } from './utils/network-rpc-utils';
|
|
12
|
+
import { generateId } from './utils/id';
|
|
13
|
+
import { toWalletError, isAbortError, classifyError } from './utils/to-wallet-error';
|
|
14
|
+
import { NoCommonNetworkError } from '@meshconnect/uwc-types';
|
|
15
|
+
import { createLogger } from './logger/create-logger';
|
|
16
|
+
import { connectObserver } from './observability/connect-observer';
|
|
17
|
+
import { hasHandoffTerminal } from './observability/instrument-handoff';
|
|
18
|
+
/** Default observational wallet-response deadline (ms). Matches TON's 60s. */
|
|
19
|
+
const DEFAULT_WALLET_RESPONSE_TIMEOUT_MS = 60_000;
|
|
13
20
|
export class UniversalWalletConnector {
|
|
14
21
|
static instance = null;
|
|
15
22
|
static instanceCount = 0;
|
|
@@ -27,6 +34,12 @@ export class UniversalWalletConnector {
|
|
|
27
34
|
usingIntegratedBrowser;
|
|
28
35
|
detectionComplete = false;
|
|
29
36
|
networkRpcMap;
|
|
37
|
+
logger;
|
|
38
|
+
/** Per-instance correlation id stamped on every telemetry record. */
|
|
39
|
+
sdkSessionId = generateId();
|
|
40
|
+
walletResponseTimeoutMs;
|
|
41
|
+
/** Tears down the observer subscriptions; set only when an observer is wired. */
|
|
42
|
+
observerTeardown;
|
|
30
43
|
/**
|
|
31
44
|
* Recommended entry point: returns the shared instance, creating it on the
|
|
32
45
|
* first call. Subsequent calls ignore the `config` argument — use
|
|
@@ -72,12 +85,43 @@ export class UniversalWalletConnector {
|
|
|
72
85
|
config = networksOrConfig;
|
|
73
86
|
}
|
|
74
87
|
const { networks, wallets: configuredWallets = [], usingIntegratedBrowser: configuredUsingIntegratedBrowser = false, walletConnectConfig: configuredWalletConnectConfig, tonConnectConfig: configuredTonConnectConfig, tronConnectorConfig: configuredTronConnectorConfig } = config;
|
|
88
|
+
// Observability seam — wire the event bus, logger, and (optional) observer
|
|
89
|
+
// FIRST so even construction-time logs/events are captured. `sdkSessionId` is
|
|
90
|
+
// already assigned as a field initializer.
|
|
91
|
+
this.eventManager = new EventManager();
|
|
92
|
+
this.walletResponseTimeoutMs =
|
|
93
|
+
config.walletResponseTimeoutMs ?? DEFAULT_WALLET_RESPONSE_TIMEOUT_MS;
|
|
94
|
+
this.logger = createLogger({
|
|
95
|
+
level: config.logLevel ?? 'warn',
|
|
96
|
+
sink: config.logger,
|
|
97
|
+
// Pre-gate tap → typed `log` event → observer.onLog. Fires for all levels
|
|
98
|
+
// regardless of the console threshold.
|
|
99
|
+
onLog: (level, message, args) => this.eventManager.emit('log', { level, message, args })
|
|
100
|
+
});
|
|
101
|
+
if (config.observer) {
|
|
102
|
+
// Resolve the OPTIONAL consumer correlation id per-event so a consumer can
|
|
103
|
+
// align it to their own session key (e.g. link_sess_id). It is kept
|
|
104
|
+
// separate from the always-present generated `sdkSessionId` — never aliased
|
|
105
|
+
// — so a record can distinguish "no consumer id" from "id == session". A
|
|
106
|
+
// missing/empty value or a throwing getter yields `undefined` (no fallback).
|
|
107
|
+
const cid = config.correlationId;
|
|
108
|
+
const getCorrelationId = typeof cid === 'function'
|
|
109
|
+
? () => {
|
|
110
|
+
try {
|
|
111
|
+
return cid() || undefined;
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
: () => cid;
|
|
118
|
+
this.observerTeardown = connectObserver(this.eventManager, config.observer, this.sdkSessionId, getCorrelationId, Date.now, this.logger);
|
|
119
|
+
}
|
|
75
120
|
// Track instance creation and warn on duplicates
|
|
76
121
|
UniversalWalletConnector.instanceCount++;
|
|
77
122
|
if (UniversalWalletConnector.instanceCount > 1 &&
|
|
78
123
|
!UniversalWalletConnector.hasWarnedAboutMultipleInstances) {
|
|
79
|
-
|
|
80
|
-
console.error(`⚠️ WARNING: Multiple instances of UniversalWalletConnector detected (${UniversalWalletConnector.instanceCount} instances). ` +
|
|
124
|
+
this.logger.error(`⚠️ WARNING: Multiple instances of UniversalWalletConnector detected (${UniversalWalletConnector.instanceCount} instances). ` +
|
|
81
125
|
'This can lead to state inconsistencies and unexpected behavior. ' +
|
|
82
126
|
'Please ensure you create only one instance and reuse it throughout your application. ' +
|
|
83
127
|
'Use UniversalWalletConnector.getInstance(config) instead of `new` to guarantee a single instance. ' +
|
|
@@ -100,21 +144,34 @@ export class UniversalWalletConnector {
|
|
|
100
144
|
this.networkRpcMap = createNetworkRpcMap(networks);
|
|
101
145
|
// Initialize connectors with RPC map
|
|
102
146
|
this.connectors = new Map();
|
|
103
|
-
this.injectedConnector = new InjectedConnector(this.networkRpcMap, this.wallets, configuredTonConnectConfig, configuredTronConnectorConfig, networks
|
|
147
|
+
this.injectedConnector = new InjectedConnector(this.networkRpcMap, this.wallets, configuredTonConnectConfig, configuredTronConnectorConfig, networks,
|
|
148
|
+
// Surface BridgeChild discovery failures (the Bitstarz "wallet never
|
|
149
|
+
// appeared via the bridge" class) as a telemetry event.
|
|
150
|
+
info => this.eventManager.emit('bridgeError', {
|
|
151
|
+
namespace: info.namespace,
|
|
152
|
+
error: { type: 'unknown', message: info.message }
|
|
153
|
+
}));
|
|
104
154
|
this.connectors.set('injected', this.injectedConnector);
|
|
105
155
|
if (configuredTonConnectConfig) {
|
|
106
156
|
this.connectors.set('tonConnect', new TonConnectConnector(configuredTonConnectConfig));
|
|
107
157
|
}
|
|
108
158
|
// Only add WalletConnect connector if config is provided
|
|
109
159
|
if (configuredWalletConnectConfig) {
|
|
110
|
-
this.connectors.set('walletConnect', new WalletConnectConnector(configuredWalletConnectConfig, this.networkRpcMap
|
|
160
|
+
this.connectors.set('walletConnect', new WalletConnectConnector(configuredWalletConnectConfig, this.networkRpcMap,
|
|
161
|
+
// Surface relay-socket failures (e.g. code 3000 JWT clock skew) that are
|
|
162
|
+
// detached from the connect handoff, as a telemetry event.
|
|
163
|
+
(error) => this.eventManager.emit('relayError', {
|
|
164
|
+
error: {
|
|
165
|
+
type: 'unknown',
|
|
166
|
+
message: error instanceof Error ? error.message : String(error)
|
|
167
|
+
}
|
|
168
|
+
})));
|
|
111
169
|
}
|
|
112
170
|
this.sessionManager = new SessionManager();
|
|
113
|
-
this.
|
|
114
|
-
this.
|
|
115
|
-
this.
|
|
116
|
-
this.
|
|
117
|
-
this.transactionService = new TransactionService(this.sessionManager, this.connectors);
|
|
171
|
+
this.connectionService = new ConnectionService(networks, this.wallets, this.sessionManager, this.connectors, configuredUsingIntegratedBrowser, this.eventManager, this.walletResponseTimeoutMs);
|
|
172
|
+
this.networkSwitchService = new NetworkSwitchService(networks, this.sessionManager, this.connectors, configuredUsingIntegratedBrowser, this.eventManager, this.walletResponseTimeoutMs);
|
|
173
|
+
this.signatureService = new SignatureService(this.sessionManager, this.connectors, configuredUsingIntegratedBrowser, this.eventManager, this.walletResponseTimeoutMs);
|
|
174
|
+
this.transactionService = new TransactionService(this.sessionManager, this.connectors, configuredUsingIntegratedBrowser, this.eventManager, this.walletResponseTimeoutMs);
|
|
118
175
|
this.walletCapabilitiesService = new WalletCapabilitiesService(networks, this.connectors, this.sessionManager, this.eventManager);
|
|
119
176
|
// Register as the shared instance so getInstance() works
|
|
120
177
|
// (only set if no instance exists, to avoid overwriting an earlier one)
|
|
@@ -148,7 +205,7 @@ export class UniversalWalletConnector {
|
|
|
148
205
|
// call, not the sum.
|
|
149
206
|
const detectionTasks = [];
|
|
150
207
|
for (const namespace of namespaces) {
|
|
151
|
-
for (const [, connector] of this.connectors) {
|
|
208
|
+
for (const [connectionMode, connector] of this.connectors) {
|
|
152
209
|
if (typeof connector.getAvailableWallets !== 'function')
|
|
153
210
|
continue;
|
|
154
211
|
detectionTasks.push(Promise.resolve()
|
|
@@ -158,8 +215,17 @@ export class UniversalWalletConnector {
|
|
|
158
215
|
this.applyDetectedWallet(namespace, d);
|
|
159
216
|
}
|
|
160
217
|
})
|
|
161
|
-
.catch(
|
|
162
|
-
//
|
|
218
|
+
.catch(error => {
|
|
219
|
+
// Was a silent catch — now a telemetry signal so a discovery
|
|
220
|
+
// failure (the "why didn't wallet X appear?" class) is observable
|
|
221
|
+
// rather than vanishing. STILL swallowed for control flow: one
|
|
222
|
+
// namespace × connector failing must not abort the others or
|
|
223
|
+
// reject detection.
|
|
224
|
+
this.eventManager.emit('walletDiscoveryFailed', {
|
|
225
|
+
namespace: namespace,
|
|
226
|
+
connectionMode,
|
|
227
|
+
error: toWalletError(error)
|
|
228
|
+
});
|
|
163
229
|
}));
|
|
164
230
|
}
|
|
165
231
|
}
|
|
@@ -168,7 +234,13 @@ export class UniversalWalletConnector {
|
|
|
168
234
|
this.connectionService.updateWallets(this.wallets);
|
|
169
235
|
// Mark detection as complete
|
|
170
236
|
this.detectionComplete = true;
|
|
171
|
-
|
|
237
|
+
// Per-namespace requested-vs-matched summary (counts only, non-PII) so a
|
|
238
|
+
// dashboard can tell "asked for N solana wallets, matched 0" (a metadata /
|
|
239
|
+
// config problem) from "asked for none".
|
|
240
|
+
this.eventManager.emit('walletsDetected', {
|
|
241
|
+
wallets: this.wallets,
|
|
242
|
+
discovery: this.summarizeDiscovery(namespaces)
|
|
243
|
+
});
|
|
172
244
|
this.eventManager.emit('ready', undefined);
|
|
173
245
|
}
|
|
174
246
|
catch (error) {
|
|
@@ -273,6 +345,32 @@ export class UniversalWalletConnector {
|
|
|
273
345
|
};
|
|
274
346
|
}
|
|
275
347
|
}
|
|
348
|
+
/**
|
|
349
|
+
* Per-namespace requested-vs-matched counts after detection. `requested` =
|
|
350
|
+
* configured wallets that declared the namespace; `matched` = those now marked
|
|
351
|
+
* installed. Counts only — never a wallet id or address. Feeds `walletsDetected`
|
|
352
|
+
* so a dashboard can answer "asked for N, matched 0?".
|
|
353
|
+
*/
|
|
354
|
+
summarizeDiscovery(namespaces) {
|
|
355
|
+
const pickProvider = (w) => this.usingIntegratedBrowser
|
|
356
|
+
? w.integratedBrowserInjectedProvider
|
|
357
|
+
: w.extensionInjectedProvider;
|
|
358
|
+
const summary = {};
|
|
359
|
+
for (const namespace of namespaces) {
|
|
360
|
+
let requested = 0;
|
|
361
|
+
let matched = 0;
|
|
362
|
+
for (const wallet of this.wallets) {
|
|
363
|
+
const nsMeta = pickProvider(wallet)?.namespaceMetaData?.[namespace];
|
|
364
|
+
if (!nsMeta)
|
|
365
|
+
continue;
|
|
366
|
+
requested++;
|
|
367
|
+
if (nsMeta.installed)
|
|
368
|
+
matched++;
|
|
369
|
+
}
|
|
370
|
+
summary[namespace] = { requested, matched };
|
|
371
|
+
}
|
|
372
|
+
return summary;
|
|
373
|
+
}
|
|
276
374
|
getSession() {
|
|
277
375
|
return this.sessionManager.getSession();
|
|
278
376
|
}
|
|
@@ -311,10 +409,13 @@ export class UniversalWalletConnector {
|
|
|
311
409
|
}
|
|
312
410
|
async connect(connectionMode, walletId, networkId, options) {
|
|
313
411
|
try {
|
|
412
|
+
// Hand-off instrumentation lives in ConnectionService.connect (emitted
|
|
413
|
+
// after validation, at the real wallet boundary) — not here, so pre-wallet
|
|
414
|
+
// validation failures don't pollute the funnel.
|
|
314
415
|
await this.connectionService.connect(connectionMode, walletId, networkId, options);
|
|
315
416
|
}
|
|
316
417
|
catch (error) {
|
|
317
|
-
this.emitError(error, 'connect');
|
|
418
|
+
this.emitError(error, 'connect', options?.signal);
|
|
318
419
|
throw error;
|
|
319
420
|
}
|
|
320
421
|
}
|
|
@@ -326,16 +427,27 @@ export class UniversalWalletConnector {
|
|
|
326
427
|
await this.connectionService.disconnect(options);
|
|
327
428
|
}
|
|
328
429
|
catch (error) {
|
|
329
|
-
this.emitError(error, 'disconnect');
|
|
430
|
+
this.emitError(error, 'disconnect', options?.signal);
|
|
330
431
|
throw error;
|
|
331
432
|
}
|
|
332
433
|
}
|
|
333
434
|
async switchNetwork(networkId, options) {
|
|
435
|
+
// Captured before the switch so a cross-namespace move is detectable after.
|
|
436
|
+
const previousNamespace = this.sessionManager.getSession().activeNetwork?.namespace;
|
|
334
437
|
try {
|
|
438
|
+
// Hand-off instrumentation lives in NetworkSwitchService.switchNetwork
|
|
439
|
+
// (emitted after validation, at the real wallet boundary).
|
|
335
440
|
await this.networkSwitchService.switchNetwork(networkId, options);
|
|
441
|
+
// A cross-namespace switch changes the live provider, so the connect-time
|
|
442
|
+
// lifecycle subscription would keep observing the OLD namespace's provider
|
|
443
|
+
// and label its events with the new session's routing. Re-evaluate it.
|
|
444
|
+
const nextNamespace = this.sessionManager.getSession().activeNetwork?.namespace;
|
|
445
|
+
if (nextNamespace !== undefined && nextNamespace !== previousNamespace) {
|
|
446
|
+
this.connectionService.reattachLifecycle();
|
|
447
|
+
}
|
|
336
448
|
}
|
|
337
449
|
catch (error) {
|
|
338
|
-
this.emitError(error, 'switchNetwork');
|
|
450
|
+
this.emitError(error, 'switchNetwork', options?.signal);
|
|
339
451
|
throw error;
|
|
340
452
|
}
|
|
341
453
|
}
|
|
@@ -349,34 +461,13 @@ export class UniversalWalletConnector {
|
|
|
349
461
|
* @returns A promise that resolves to the signature
|
|
350
462
|
*/
|
|
351
463
|
async signMessage(message, options) {
|
|
352
|
-
const session = this.sessionManager.getSession();
|
|
353
|
-
if (!session.activeWallet) {
|
|
354
|
-
throw new Error('No active wallet');
|
|
355
|
-
}
|
|
356
|
-
if (!session.connectionMode) {
|
|
357
|
-
throw new Error('No active connection');
|
|
358
|
-
}
|
|
359
464
|
try {
|
|
360
|
-
//
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
provider = this.usingIntegratedBrowser
|
|
364
|
-
? session.activeWallet.integratedBrowserInjectedProvider
|
|
365
|
-
: session.activeWallet.extensionInjectedProvider;
|
|
366
|
-
}
|
|
367
|
-
else if (session.connectionMode === 'walletConnect') {
|
|
368
|
-
provider = session.activeWallet.walletConnectProvider;
|
|
369
|
-
}
|
|
370
|
-
else if (session.connectionMode === 'tonConnect') {
|
|
371
|
-
return await this.signatureService.signMessage(message, undefined, options);
|
|
372
|
-
}
|
|
373
|
-
if (!provider) {
|
|
374
|
-
throw new Error('No provider available for the active wallet');
|
|
375
|
-
}
|
|
376
|
-
return await this.signatureService.signMessage(message, provider, options);
|
|
465
|
+
// Validation + funnel instrumentation live in SignatureService (after
|
|
466
|
+
// validation, at the real wallet boundary) — same layering as connect.
|
|
467
|
+
return await this.signatureService.signMessage(message, options);
|
|
377
468
|
}
|
|
378
469
|
catch (error) {
|
|
379
|
-
this.emitError(error, 'signMessage');
|
|
470
|
+
this.emitError(error, 'signMessage', options?.signal);
|
|
380
471
|
throw error;
|
|
381
472
|
}
|
|
382
473
|
}
|
|
@@ -389,28 +480,14 @@ export class UniversalWalletConnector {
|
|
|
389
480
|
* @returns A promise that resolves to the 65-byte hex signature (0x-prefixed)
|
|
390
481
|
*/
|
|
391
482
|
async signTypedData(typedData) {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
if (session.connectionMode === 'tonConnect') {
|
|
400
|
-
throw new Error('signTypedData is not supported for TON wallets');
|
|
401
|
-
}
|
|
402
|
-
// Resolve the injected provider from the active wallet. WalletConnect
|
|
403
|
-
// resolves its own provider inside the connector, so it stays undefined here.
|
|
404
|
-
let provider;
|
|
405
|
-
if (session.connectionMode === 'injected') {
|
|
406
|
-
provider = this.usingIntegratedBrowser
|
|
407
|
-
? session.activeWallet.integratedBrowserInjectedProvider
|
|
408
|
-
: session.activeWallet.extensionInjectedProvider;
|
|
409
|
-
if (!provider) {
|
|
410
|
-
throw new Error('No provider available for the active wallet');
|
|
411
|
-
}
|
|
483
|
+
try {
|
|
484
|
+
// Validation + funnel instrumentation live in SignatureService.
|
|
485
|
+
return await this.signatureService.signTypedData(typedData);
|
|
486
|
+
}
|
|
487
|
+
catch (error) {
|
|
488
|
+
this.emitError(error, 'signTypedData');
|
|
489
|
+
throw error;
|
|
412
490
|
}
|
|
413
|
-
return await this.signatureService.signTypedData(typedData, provider);
|
|
414
491
|
}
|
|
415
492
|
/**
|
|
416
493
|
* Send a transaction with the connected wallet
|
|
@@ -419,34 +496,13 @@ export class UniversalWalletConnector {
|
|
|
419
496
|
* @returns A promise that resolves to the transaction result
|
|
420
497
|
*/
|
|
421
498
|
async sendTransaction(request, options) {
|
|
422
|
-
const session = this.sessionManager.getSession();
|
|
423
|
-
if (!session.activeWallet) {
|
|
424
|
-
throw new Error('No active wallet');
|
|
425
|
-
}
|
|
426
|
-
if (!session.connectionMode) {
|
|
427
|
-
throw new Error('No active connection');
|
|
428
|
-
}
|
|
429
499
|
try {
|
|
430
|
-
//
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
provider = this.usingIntegratedBrowser
|
|
434
|
-
? session.activeWallet.integratedBrowserInjectedProvider
|
|
435
|
-
: session.activeWallet.extensionInjectedProvider;
|
|
436
|
-
}
|
|
437
|
-
else if (session.connectionMode === 'walletConnect') {
|
|
438
|
-
provider = session.activeWallet.walletConnectProvider;
|
|
439
|
-
}
|
|
440
|
-
else if (session.connectionMode === 'tonConnect') {
|
|
441
|
-
return await this.transactionService.sendTransaction(request, undefined, options);
|
|
442
|
-
}
|
|
443
|
-
if (!provider) {
|
|
444
|
-
throw new Error('No provider available for the active wallet');
|
|
445
|
-
}
|
|
446
|
-
return await this.transactionService.sendTransaction(request, provider, options);
|
|
500
|
+
// Validation + funnel instrumentation live in TransactionService (after
|
|
501
|
+
// validation, at the real wallet boundary) — same layering as connect.
|
|
502
|
+
return await this.transactionService.sendTransaction(request, options);
|
|
447
503
|
}
|
|
448
504
|
catch (error) {
|
|
449
|
-
this.emitError(error, 'sendTransaction');
|
|
505
|
+
this.emitError(error, 'sendTransaction', options?.signal);
|
|
450
506
|
throw error;
|
|
451
507
|
}
|
|
452
508
|
}
|
|
@@ -456,19 +512,14 @@ export class UniversalWalletConnector {
|
|
|
456
512
|
* tonConnect doesn't implement it.
|
|
457
513
|
*/
|
|
458
514
|
async signSolanaTransaction(serializedTx) {
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
}
|
|
463
|
-
if (!session.connectionMode) {
|
|
464
|
-
throw new Error('No active connection');
|
|
515
|
+
try {
|
|
516
|
+
// Validation + funnel instrumentation live in TransactionService.
|
|
517
|
+
return await this.transactionService.signSolanaTransactionBytes(serializedTx);
|
|
465
518
|
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
throw new Error(`signSolanaTransaction is not supported for connection mode "${session.connectionMode}"`);
|
|
519
|
+
catch (error) {
|
|
520
|
+
this.emitError(error, 'signSolanaTransaction');
|
|
521
|
+
throw error;
|
|
470
522
|
}
|
|
471
|
-
return await connector.signSolanaTransactionBytes(serializedTx);
|
|
472
523
|
}
|
|
473
524
|
/**
|
|
474
525
|
* Fetch wallet capabilities for the connected wallet
|
|
@@ -482,7 +533,7 @@ export class UniversalWalletConnector {
|
|
|
482
533
|
return await this.walletCapabilitiesService.getWalletCapabilities(address, activeNetwork, options);
|
|
483
534
|
}
|
|
484
535
|
catch (error) {
|
|
485
|
-
this.emitError(error, 'getWalletCapabilities');
|
|
536
|
+
this.emitError(error, 'getWalletCapabilities', options?.signal);
|
|
486
537
|
throw error;
|
|
487
538
|
}
|
|
488
539
|
}
|
|
@@ -528,21 +579,67 @@ export class UniversalWalletConnector {
|
|
|
528
579
|
const session = this.sessionManager.getSession();
|
|
529
580
|
return session.activeWalletCapabilities;
|
|
530
581
|
}
|
|
582
|
+
/**
|
|
583
|
+
* Set the console log threshold at runtime (e.g. from a support toggle). The
|
|
584
|
+
* global `window.UWC_DEBUG` override still takes precedence for ad-hoc triage.
|
|
585
|
+
*/
|
|
586
|
+
setLogLevel(level) {
|
|
587
|
+
this.logger.setLevel(level);
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Release observer subscriptions and clear all event listeners. Call on full
|
|
591
|
+
* teardown / logout to avoid leaking listeners across connector lifecycles.
|
|
592
|
+
*/
|
|
593
|
+
dispose() {
|
|
594
|
+
this.observerTeardown?.();
|
|
595
|
+
this.observerTeardown = undefined;
|
|
596
|
+
// Release any live provider-lifecycle listeners on a connected session —
|
|
597
|
+
// `dispose()` can be called without a prior `disconnect()`, and leaving the
|
|
598
|
+
// EIP-1193/adapter `.on` handlers attached is the zombie-listener leak this
|
|
599
|
+
// method's contract promises to prevent.
|
|
600
|
+
this.connectionService.teardownLifecycle();
|
|
601
|
+
this.eventManager.clearAllListeners();
|
|
602
|
+
// Full teardown: if this was the shared singleton, clear the static refs too
|
|
603
|
+
// so a later getInstance()/new starts clean — otherwise getInstance() would
|
|
604
|
+
// hand back this now-listener-less instance, and the instance-count warning
|
|
605
|
+
// would mis-fire on the next construction.
|
|
606
|
+
if (UniversalWalletConnector.instance === this) {
|
|
607
|
+
UniversalWalletConnector.resetInstance();
|
|
608
|
+
}
|
|
609
|
+
}
|
|
531
610
|
// ---- private helpers ----
|
|
532
|
-
emitError(error, operation) {
|
|
611
|
+
emitError(error, operation, signal) {
|
|
533
612
|
// Intentional cancellations (AbortSignal.throwIfAborted, fetch abort,
|
|
534
613
|
// DOMException) should NOT surface as wallet errors — the caller already
|
|
535
|
-
// knows it asked to abort.
|
|
536
|
-
|
|
614
|
+
// knows it asked to abort. Uses the same name+signal check as
|
|
615
|
+
// `instrumentHandoff`, so both a DOMException abort (not an `Error`
|
|
616
|
+
// subclass in every runtime) AND a custom `abort(reason)` — whose rejection
|
|
617
|
+
// value carries the caller's own name — are skipped consistently.
|
|
618
|
+
if (isAbortError(error) || signal?.aborted) {
|
|
537
619
|
return;
|
|
538
620
|
}
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
621
|
+
// Classify here too so a PRE-wallet validation failure — which never enters
|
|
622
|
+
// the handoff funnel (no awaitingWallet/terminal) — still carries
|
|
623
|
+
// failureKind/source/errorCode in telemetry. The #1 prod connection error,
|
|
624
|
+
// `no_common_network`, lands here; forward its two CAIP-2 id lists.
|
|
625
|
+
const { errorCode, failureKind, source } = classifyError(error);
|
|
626
|
+
this.eventManager.emit('error', {
|
|
627
|
+
error: toWalletError(error),
|
|
628
|
+
operation,
|
|
629
|
+
errorCode,
|
|
630
|
+
failureKind,
|
|
631
|
+
source,
|
|
632
|
+
// A handoff terminal already reported this failure — mark this record as
|
|
633
|
+
// the back-compat duplicate so metrics can count terminals + uncovered
|
|
634
|
+
// errors without double-counting.
|
|
635
|
+
...(hasHandoffTerminal(error) && { handoffCovered: true }),
|
|
636
|
+
...(error instanceof NoCommonNetworkError && {
|
|
637
|
+
networkMismatch: {
|
|
638
|
+
walletNetworkIds: error.walletNetworkIds,
|
|
639
|
+
configuredNetworkIds: error.configuredNetworkIds
|
|
640
|
+
}
|
|
641
|
+
})
|
|
642
|
+
});
|
|
546
643
|
}
|
|
547
644
|
}
|
|
548
645
|
//# sourceMappingURL=universal-wallet-connector.js.map
|