@meshconnect/uwc-core 1.3.0 → 1.4.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.
- package/README.md +5 -0
- package/dist/events.d.ts +50 -0
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +6 -0
- package/dist/events.js.map +1 -1
- package/dist/observability/instrument-handoff.d.ts +6 -0
- package/dist/observability/instrument-handoff.d.ts.map +1 -1
- package/dist/observability/instrument-handoff.js +6 -3
- package/dist/observability/instrument-handoff.js.map +1 -1
- package/dist/observability/telemetry.d.ts +13 -0
- package/dist/observability/telemetry.d.ts.map +1 -1
- package/dist/observability/telemetry.js +55 -6
- package/dist/observability/telemetry.js.map +1 -1
- package/dist/services/connection-service.d.ts.map +1 -1
- package/dist/services/connection-service.js +12 -4
- package/dist/services/connection-service.js.map +1 -1
- package/dist/services/network-switch-service.d.ts.map +1 -1
- package/dist/services/network-switch-service.js +2 -1
- package/dist/services/network-switch-service.js.map +1 -1
- package/dist/universal-wallet-connector.d.ts +11 -0
- package/dist/universal-wallet-connector.d.ts.map +1 -1
- package/dist/universal-wallet-connector.js +40 -1
- package/dist/universal-wallet-connector.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -5
- package/src/events.ts +59 -0
- package/src/observability/instrument-handoff.test.ts +31 -0
- package/src/observability/instrument-handoff.ts +12 -3
- package/src/observability/telemetry.test.ts +71 -0
- package/src/observability/telemetry.ts +68 -6
- package/src/services/connection-service.test.ts +11 -5
- package/src/services/connection-service.ts +17 -4
- package/src/services/network-switch-service.ts +2 -1
- package/src/universal-wallet-connector.test.ts +78 -1
- package/src/universal-wallet-connector.ts +49 -1
- package/src/version.ts +1 -1
|
@@ -139,7 +139,8 @@ export class ConnectionService {
|
|
|
139
139
|
network,
|
|
140
140
|
provider,
|
|
141
141
|
connectionMode,
|
|
142
|
-
signal
|
|
142
|
+
signal,
|
|
143
|
+
wallet.name
|
|
143
144
|
),
|
|
144
145
|
signal
|
|
145
146
|
)
|
|
@@ -189,7 +190,11 @@ export class ConnectionService {
|
|
|
189
190
|
availableNetworks: this.networks.filter(n =>
|
|
190
191
|
provider.supportedNetworkIds.includes(n.id)
|
|
191
192
|
),
|
|
192
|
-
availableAddresses: filteredAvailableAddresses
|
|
193
|
+
availableAddresses: filteredAvailableAddresses,
|
|
194
|
+
// Connection provenance for observability — set definitively on every
|
|
195
|
+
// connect so a fresh pairing clears any prior reused flag (MFS-642). Rides
|
|
196
|
+
// `connected` + every later operation handoff via sessionHandoffContext.
|
|
197
|
+
reused: result.reused === true
|
|
193
198
|
})
|
|
194
199
|
|
|
195
200
|
const session = this.sessionManager.getSession()
|
|
@@ -295,9 +300,17 @@ export class ConnectionService {
|
|
|
295
300
|
network: Network,
|
|
296
301
|
provider: SupportedProvider,
|
|
297
302
|
connectionMode: ConnectionMode,
|
|
298
|
-
signal?: AbortSignal
|
|
303
|
+
signal?: AbortSignal,
|
|
304
|
+
// Passed to the connector as ConnectOptions.walletName so the WalletConnect
|
|
305
|
+
// connector can confirm a reused session belongs to the selected wallet
|
|
306
|
+
// (MFS-642). Ignored by connectors without session reuse.
|
|
307
|
+
walletName?: string
|
|
299
308
|
): Promise<ConnectorResult> {
|
|
300
|
-
const connectPromise = connector.connect(
|
|
309
|
+
const connectPromise = connector.connect(
|
|
310
|
+
network,
|
|
311
|
+
provider,
|
|
312
|
+
walletName ? { walletName } : undefined
|
|
313
|
+
)
|
|
301
314
|
|
|
302
315
|
let pollingStopped = false
|
|
303
316
|
let emittedUri: string | undefined
|
|
@@ -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
|
})
|
|
@@ -334,7 +334,20 @@ export class UniversalWalletConnector {
|
|
|
334
334
|
// Relay transport recovered — pair with `relayDisconnected` (same
|
|
335
335
|
// sdkSessionId) to measure the dead window.
|
|
336
336
|
onRelayReconnect: () =>
|
|
337
|
-
this.eventManager.emit('relayReconnected', undefined)
|
|
337
|
+
this.eventManager.emit('relayReconnected', undefined),
|
|
338
|
+
// Relay/subscription health captured just before a wallet request is
|
|
339
|
+
// published — the CARE-263 delivery signal for a reused session whose
|
|
340
|
+
// transport went stale (correlate with the sign terminal).
|
|
341
|
+
onRelayHealthProbe: probe =>
|
|
342
|
+
this.eventManager.emit('relayHealthProbe', probe),
|
|
343
|
+
// Outbound request handed to the relay, with its JSON-RPC id — the
|
|
344
|
+
// correlation key for wallet-side duplicate-prompt triage.
|
|
345
|
+
onRequestPublished: info =>
|
|
346
|
+
this.eventManager.emit('wcRequestPublished', info),
|
|
347
|
+
// A published request hit its WC TTL unanswered — the terminal
|
|
348
|
+
// counterpart to the probe ("wallet never surfaced the prompt").
|
|
349
|
+
onRequestExpired: info =>
|
|
350
|
+
this.eventManager.emit('wcRequestExpired', info)
|
|
338
351
|
}
|
|
339
352
|
)
|
|
340
353
|
)
|
|
@@ -707,6 +720,41 @@ export class UniversalWalletConnector {
|
|
|
707
720
|
}
|
|
708
721
|
}
|
|
709
722
|
|
|
723
|
+
/**
|
|
724
|
+
* Pre-generate a WalletConnect pairing ahead of the user's tap. Warms the relay
|
|
725
|
+
* (opens the socket even on a cold, topic-less client) and returns a URI the app
|
|
726
|
+
* can deep-link inside the tap gesture, so the first tap opens the wallet
|
|
727
|
+
* reliably; a subsequent `connect()` adopts the same pairing. Built against the
|
|
728
|
+
* UNION of every WalletConnect wallet's networks so the single pairing serves
|
|
729
|
+
* whichever wallet the user picks (optionalNamespaces let a wallet approve only
|
|
730
|
+
* its supported subset). Best-effort: resolves `undefined` when WalletConnect is
|
|
731
|
+
* not configured or there is nothing to pair, and never throws into the caller.
|
|
732
|
+
*/
|
|
733
|
+
async beginPairing(): Promise<string | undefined> {
|
|
734
|
+
try {
|
|
735
|
+
const connector = this.connectors.get('walletConnect')
|
|
736
|
+
if (!connector?.beginPairing) {
|
|
737
|
+
return undefined
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
const supportedNetworkIds = [
|
|
741
|
+
...new Set(
|
|
742
|
+
this.wallets.flatMap(
|
|
743
|
+
wallet => wallet.walletConnectProvider?.supportedNetworkIds ?? []
|
|
744
|
+
)
|
|
745
|
+
)
|
|
746
|
+
]
|
|
747
|
+
if (supportedNetworkIds.length === 0) {
|
|
748
|
+
return undefined
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
return await connector.beginPairing({ supportedNetworkIds })
|
|
752
|
+
} catch {
|
|
753
|
+
// Best-effort pre-warm — never surface a pairing failure to the caller.
|
|
754
|
+
return undefined
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
|
|
710
758
|
getConnectionURI(): string | undefined {
|
|
711
759
|
return this.connectionService.getConnectionURI()
|
|
712
760
|
}
|
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
|
+
export const UWC_CORE_VERSION = '1.4.0'
|