@meshconnect/uwc-core 1.2.3 → 1.3.0-snapshot.3412d21

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.
Files changed (40) hide show
  1. package/README.md +5 -0
  2. package/dist/events.d.ts +39 -0
  3. package/dist/events.d.ts.map +1 -1
  4. package/dist/events.js +4 -0
  5. package/dist/events.js.map +1 -1
  6. package/dist/observability/focus-tracker.d.ts +30 -11
  7. package/dist/observability/focus-tracker.d.ts.map +1 -1
  8. package/dist/observability/focus-tracker.js +54 -18
  9. package/dist/observability/focus-tracker.js.map +1 -1
  10. package/dist/observability/instrument-handoff.d.ts.map +1 -1
  11. package/dist/observability/instrument-handoff.js +25 -6
  12. package/dist/observability/instrument-handoff.js.map +1 -1
  13. package/dist/observability/relay-drop-tracker.d.ts +37 -0
  14. package/dist/observability/relay-drop-tracker.d.ts.map +1 -0
  15. package/dist/observability/relay-drop-tracker.js +30 -0
  16. package/dist/observability/relay-drop-tracker.js.map +1 -0
  17. package/dist/observability/telemetry.d.ts +8 -0
  18. package/dist/observability/telemetry.d.ts.map +1 -1
  19. package/dist/observability/telemetry.js +32 -5
  20. package/dist/observability/telemetry.js.map +1 -1
  21. package/dist/universal-wallet-connector.d.ts +11 -0
  22. package/dist/universal-wallet-connector.d.ts.map +1 -1
  23. package/dist/universal-wallet-connector.js +47 -11
  24. package/dist/universal-wallet-connector.js.map +1 -1
  25. package/dist/version.d.ts +1 -1
  26. package/dist/version.js +1 -1
  27. package/package.json +5 -5
  28. package/src/events.ts +48 -1
  29. package/src/observability/focus-tracker.test.ts +95 -8
  30. package/src/observability/focus-tracker.ts +72 -22
  31. package/src/observability/instrument-handoff.test.ts +62 -0
  32. package/src/observability/instrument-handoff.ts +37 -6
  33. package/src/observability/relay-drop-tracker.test.ts +84 -0
  34. package/src/observability/relay-drop-tracker.ts +53 -0
  35. package/src/observability/telemetry.test.ts +18 -0
  36. package/src/observability/telemetry.ts +41 -6
  37. package/src/universal-wallet-connector.observability.test.ts +54 -8
  38. package/src/universal-wallet-connector.test.ts +78 -1
  39. package/src/universal-wallet-connector.ts +57 -12
  40. package/src/version.ts +1 -1
@@ -14,7 +14,8 @@ const mockInjectedConnector = {
14
14
 
15
15
  const mockWalletConnectConnector = {
16
16
  getAvailableWallets: vi.fn().mockResolvedValue([]),
17
- signSolanaTransactionBytes: vi.fn()
17
+ signSolanaTransactionBytes: vi.fn(),
18
+ beginPairing: vi.fn()
18
19
  }
19
20
 
20
21
  // tonConnect deliberately omits signSolanaTransactionBytes so the router's
@@ -695,4 +696,80 @@ describe('UniversalWalletConnector', () => {
695
696
  ).rejects.toThrow('No active wallet')
696
697
  })
697
698
  })
699
+
700
+ describe('beginPairing (WalletConnect pre-warm)', () => {
701
+ // Wallets exposing a WalletConnect provider, so the union of their networks
702
+ // is non-empty and beginPairing has something to pair.
703
+ const walletsWithWc: WalletMetadata[] = [
704
+ {
705
+ id: 'rainbow',
706
+ name: 'Rainbow',
707
+ metadata: {},
708
+ walletConnectProvider: {
709
+ supportedNetworkIds: ['eip155:1', 'eip155:137'],
710
+ deeplinks: { universal: 'https://rnbwapp.com', native: 'rainbow://' }
711
+ }
712
+ },
713
+ {
714
+ id: 'trust',
715
+ name: 'Trust',
716
+ metadata: {},
717
+ walletConnectProvider: {
718
+ supportedNetworkIds: ['eip155:137', 'eip155:8453'],
719
+ deeplinks: {
720
+ universal: 'https://link.trustwallet.com',
721
+ native: 'trust://'
722
+ }
723
+ }
724
+ }
725
+ ]
726
+
727
+ it('returns undefined when WalletConnect is not configured', async () => {
728
+ const uwc = new UniversalWalletConnector(mockNetworks, walletsWithWc)
729
+ await expect(uwc.beginPairing()).resolves.toBeUndefined()
730
+ expect(mockWalletConnectConnector.beginPairing).not.toHaveBeenCalled()
731
+ })
732
+
733
+ it('returns undefined when no wallet exposes a WalletConnect provider', async () => {
734
+ // WC configured, but mockWallets carries only an injected provider — nothing to pair.
735
+ const uwc = new UniversalWalletConnector(
736
+ mockNetworks,
737
+ mockWallets,
738
+ false,
739
+ mockWalletConnectConfig
740
+ )
741
+ await expect(uwc.beginPairing()).resolves.toBeUndefined()
742
+ expect(mockWalletConnectConnector.beginPairing).not.toHaveBeenCalled()
743
+ })
744
+
745
+ it('delegates to the connector with the deduped union of wallet networks', async () => {
746
+ mockWalletConnectConnector.beginPairing.mockResolvedValueOnce(
747
+ 'wc:union@2'
748
+ )
749
+ const uwc = new UniversalWalletConnector(
750
+ mockNetworks,
751
+ walletsWithWc,
752
+ false,
753
+ mockWalletConnectConfig
754
+ )
755
+ const uri = await uwc.beginPairing()
756
+ expect(uri).toBe('wc:union@2')
757
+ expect(mockWalletConnectConnector.beginPairing).toHaveBeenCalledWith({
758
+ supportedNetworkIds: ['eip155:1', 'eip155:137', 'eip155:8453']
759
+ })
760
+ })
761
+
762
+ it('never throws: resolves undefined if the connector rejects', async () => {
763
+ mockWalletConnectConnector.beginPairing.mockRejectedValueOnce(
764
+ new Error('relay down')
765
+ )
766
+ const uwc = new UniversalWalletConnector(
767
+ mockNetworks,
768
+ walletsWithWc,
769
+ false,
770
+ mockWalletConnectConfig
771
+ )
772
+ await expect(uwc.beginPairing()).resolves.toBeUndefined()
773
+ })
774
+ })
698
775
  })
@@ -314,18 +314,28 @@ export class UniversalWalletConnector {
314
314
  new WalletConnectConnector(
315
315
  configuredWalletConnectConfig,
316
316
  this.networkRpcMap,
317
- // Surface relay-socket failures (e.g. code 3000 JWT clock skew) that are
318
- // detached from the connect handoff, as a telemetry event.
319
- (error: unknown) =>
320
- this.eventManager.emit('relayError', {
321
- error: toWalletError(error)
322
- }),
323
- // Surface a failed SignClient.init as its own signal — otherwise it has no
324
- // dedicated telemetry and only appears as a generic connect failure.
325
- (error: unknown) =>
326
- this.eventManager.emit('walletConnectInitError', {
327
- error: toWalletError(error)
328
- })
317
+ {
318
+ // Surface relay-socket failures (e.g. code 3000 JWT clock skew) that are
319
+ // detached from the connect handoff, as a telemetry event.
320
+ onRelayError: (error: unknown) =>
321
+ this.eventManager.emit('relayError', {
322
+ error: toWalletError(error)
323
+ }),
324
+ // Surface a failed SignClient.init as its own signal — otherwise it has no
325
+ // dedicated telemetry and only appears as a generic connect failure.
326
+ onInitError: (error: unknown) =>
327
+ this.eventManager.emit('walletConnectInitError', {
328
+ error: toWalletError(error)
329
+ }),
330
+ // Relay transport dropped (once per outage) — the FACT is the signal; the
331
+ // relayer carries no payload, so emit the bare event (CARE-263).
332
+ onRelayDisconnect: () =>
333
+ this.eventManager.emit('relayDisconnected', undefined),
334
+ // Relay transport recovered — pair with `relayDisconnected` (same
335
+ // sdkSessionId) to measure the dead window.
336
+ onRelayReconnect: () =>
337
+ this.eventManager.emit('relayReconnected', undefined)
338
+ }
329
339
  )
330
340
  )
331
341
  }
@@ -697,6 +707,41 @@ export class UniversalWalletConnector {
697
707
  }
698
708
  }
699
709
 
710
+ /**
711
+ * Pre-generate a WalletConnect pairing ahead of the user's tap. Warms the relay
712
+ * (opens the socket even on a cold, topic-less client) and returns a URI the app
713
+ * can deep-link inside the tap gesture, so the first tap opens the wallet
714
+ * reliably; a subsequent `connect()` adopts the same pairing. Built against the
715
+ * UNION of every WalletConnect wallet's networks so the single pairing serves
716
+ * whichever wallet the user picks (optionalNamespaces let a wallet approve only
717
+ * its supported subset). Best-effort: resolves `undefined` when WalletConnect is
718
+ * not configured or there is nothing to pair, and never throws into the caller.
719
+ */
720
+ async beginPairing(): Promise<string | undefined> {
721
+ try {
722
+ const connector = this.connectors.get('walletConnect')
723
+ if (!connector?.beginPairing) {
724
+ return undefined
725
+ }
726
+
727
+ const supportedNetworkIds = [
728
+ ...new Set(
729
+ this.wallets.flatMap(
730
+ wallet => wallet.walletConnectProvider?.supportedNetworkIds ?? []
731
+ )
732
+ )
733
+ ]
734
+ if (supportedNetworkIds.length === 0) {
735
+ return undefined
736
+ }
737
+
738
+ return await connector.beginPairing({ supportedNetworkIds })
739
+ } catch {
740
+ // Best-effort pre-warm — never surface a pairing failure to the caller.
741
+ return undefined
742
+ }
743
+ }
744
+
700
745
  getConnectionURI(): string | undefined {
701
746
  return this.connectionService.getConnectionURI()
702
747
  }
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated from package.json by scripts/generate-version.mjs — do not edit.
2
- export const UWC_CORE_VERSION = '1.2.3'
2
+ export const UWC_CORE_VERSION = '1.3.0'