@meshconnect/uwc-core 0.7.5-snapshot.c90b3e8 → 0.7.6

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 (50) hide show
  1. package/dist/index.d.ts +3 -2
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +3 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/managers/event-manager.d.ts +3 -22
  6. package/dist/managers/event-manager.d.ts.map +1 -1
  7. package/dist/managers/event-manager.js +7 -63
  8. package/dist/managers/event-manager.js.map +1 -1
  9. package/dist/services/connection-service.d.ts +2 -5
  10. package/dist/services/connection-service.d.ts.map +1 -1
  11. package/dist/services/connection-service.js +7 -19
  12. package/dist/services/connection-service.js.map +1 -1
  13. package/dist/services/network-switch-service.d.ts +1 -2
  14. package/dist/services/network-switch-service.d.ts.map +1 -1
  15. package/dist/services/network-switch-service.js +3 -15
  16. package/dist/services/network-switch-service.js.map +1 -1
  17. package/dist/services/signature-service.d.ts +1 -3
  18. package/dist/services/signature-service.d.ts.map +1 -1
  19. package/dist/services/signature-service.js +5 -10
  20. package/dist/services/signature-service.js.map +1 -1
  21. package/dist/services/transaction-service.d.ts +1 -3
  22. package/dist/services/transaction-service.d.ts.map +1 -1
  23. package/dist/services/transaction-service.js +5 -10
  24. package/dist/services/transaction-service.js.map +1 -1
  25. package/dist/services/wallet-capabilities-service.d.ts +1 -2
  26. package/dist/services/wallet-capabilities-service.d.ts.map +1 -1
  27. package/dist/services/wallet-capabilities-service.js +2 -9
  28. package/dist/services/wallet-capabilities-service.js.map +1 -1
  29. package/dist/universal-wallet-connector.d.ts +6 -52
  30. package/dist/universal-wallet-connector.d.ts.map +1 -1
  31. package/dist/universal-wallet-connector.js +177 -271
  32. package/dist/universal-wallet-connector.js.map +1 -1
  33. package/package.json +5 -5
  34. package/src/index.ts +3 -11
  35. package/src/managers/event-manager.test.ts +0 -70
  36. package/src/managers/event-manager.ts +9 -80
  37. package/src/services/connection-service.test.ts +3 -11
  38. package/src/services/connection-service.ts +7 -34
  39. package/src/services/network-switch-service.ts +3 -22
  40. package/src/services/signature-service.ts +5 -13
  41. package/src/services/transaction-service.ts +5 -13
  42. package/src/services/wallet-capabilities-service.ts +2 -14
  43. package/src/universal-wallet-connector.test.ts +3 -87
  44. package/src/universal-wallet-connector.ts +204 -395
  45. package/README.md +0 -924
  46. package/dist/events.d.ts +0 -71
  47. package/dist/events.d.ts.map +0 -1
  48. package/dist/events.js +0 -2
  49. package/dist/events.js.map +0 -1
  50. package/src/events.ts +0 -73
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meshconnect/uwc-core",
3
- "version": "0.7.5-snapshot.c90b3e8",
3
+ "version": "0.7.6",
4
4
  "description": "Core functionality for Universal Wallet Connector",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -16,10 +16,10 @@
16
16
  "src"
17
17
  ],
18
18
  "dependencies": {
19
- "@meshconnect/uwc-wallet-connect-connector": "0.4.13-snapshot.c90b3e8",
20
- "@meshconnect/uwc-injected-connector": "0.10.5-snapshot.c90b3e8",
21
- "@meshconnect/uwc-ton-connector": "0.5.3-snapshot.c90b3e8",
22
- "@meshconnect/uwc-types": "0.11.1-snapshot.c90b3e8"
19
+ "@meshconnect/uwc-injected-connector": "0.10.5",
20
+ "@meshconnect/uwc-ton-connector": "0.5.3",
21
+ "@meshconnect/uwc-types": "0.11.1",
22
+ "@meshconnect/uwc-wallet-connect-connector": "0.4.14"
23
23
  },
24
24
  "devDependencies": {
25
25
  "typescript": "^5.9.3"
package/src/index.ts CHANGED
@@ -1,11 +1,3 @@
1
- export {
2
- UniversalWalletConnector,
3
- type UWCConfig,
4
- type OperationOptions
5
- } from './universal-wallet-connector'
6
- export type {
7
- UWCEventMap,
8
- UWCEventName,
9
- UWCEventListener,
10
- UWCOperation
11
- } from './events'
1
+ export * from './universal-wallet-connector'
2
+ export * from './managers'
3
+ export * from './services'
@@ -71,74 +71,4 @@ describe('EventManager', () => {
71
71
  eventManager.clearAllListeners()
72
72
  expect(eventManager.getListenerCount()).toBe(0)
73
73
  })
74
-
75
- describe('typed events', () => {
76
- it('dispatches typed event data only to on() listeners of that event', () => {
77
- const disconnected: unknown[] = []
78
- const networkSwitched: unknown[] = []
79
-
80
- eventManager.on('disconnected', data => disconnected.push(data))
81
- eventManager.on('networkSwitched', data => networkSwitched.push(data))
82
-
83
- eventManager.emit('disconnected', undefined)
84
-
85
- expect(disconnected).toHaveLength(1)
86
- expect(networkSwitched).toHaveLength(0)
87
- })
88
-
89
- it('cascades every typed event to the legacy change channel', () => {
90
- let changeCount = 0
91
- eventManager.subscribe(() => {
92
- changeCount++
93
- })
94
-
95
- eventManager.emit('connectionUri', {
96
- uri: 'wc://x',
97
- connectionMode: 'walletConnect'
98
- })
99
- eventManager.emit('disconnected', undefined)
100
-
101
- expect(changeCount).toBe(2)
102
- })
103
-
104
- it('off() removes a listener from the typed set', () => {
105
- const calls: unknown[] = []
106
- const listener = (d: unknown) => calls.push(d)
107
- eventManager.on('ready', listener)
108
- eventManager.off('ready', listener)
109
- eventManager.emit('ready', undefined)
110
- expect(calls).toHaveLength(0)
111
- })
112
-
113
- it('once() removes the listener after a single dispatch', () => {
114
- let calls = 0
115
- eventManager.once('ready', () => {
116
- calls++
117
- })
118
- eventManager.emit('ready', undefined)
119
- eventManager.emit('ready', undefined)
120
- expect(calls).toBe(1)
121
- })
122
-
123
- it('a throwing listener does not stop other listeners', () => {
124
- const calls: string[] = []
125
- eventManager.on('ready', () => {
126
- throw new Error('boom')
127
- })
128
- eventManager.on('ready', () => {
129
- calls.push('second')
130
- })
131
- eventManager.emit('ready', undefined)
132
- expect(calls).toEqual(['second'])
133
- })
134
-
135
- it('emit("change") does not recurse into itself', () => {
136
- let count = 0
137
- eventManager.on('change', () => {
138
- count++
139
- })
140
- eventManager.emit('change', undefined)
141
- expect(count).toBe(1)
142
- })
143
- })
144
74
  })
@@ -1,93 +1,22 @@
1
- import type { UWCEventMap, UWCEventName, UWCEventListener } from '../events'
1
+ type Listener = () => void
2
+ type Unsubscribe = () => void
2
3
 
3
- type LegacyListener = () => void
4
- type UntypedListener = (data: unknown) => void
5
-
6
- /**
7
- * Typed event emitter used by UniversalWalletConnector.
8
- *
9
- * Each event has its own listener set. Emitting any typed event also
10
- * dispatches the legacy `change` event, so `subscribe()` callers keep
11
- * receiving a notification on every state change.
12
- */
13
4
  export class EventManager {
14
- private listeners: Map<UWCEventName, Set<UntypedListener>> = new Map()
15
-
16
- /** Subscribe to a typed event. Returns an unsubscribe function. */
17
- on<K extends UWCEventName>(
18
- event: K,
19
- listener: UWCEventListener<K>
20
- ): () => void {
21
- let set = this.listeners.get(event)
22
- if (!set) {
23
- set = new Set()
24
- this.listeners.set(event, set)
25
- }
26
- set.add(listener as UntypedListener)
27
- return () => this.off(event, listener)
28
- }
29
-
30
- /** Subscribe once; the listener is removed after the first dispatch. */
31
- once<K extends UWCEventName>(
32
- event: K,
33
- listener: UWCEventListener<K>
34
- ): () => void {
35
- const wrapper: UWCEventListener<K> = data => {
36
- this.off(event, wrapper)
37
- listener(data)
38
- }
39
- return this.on(event, wrapper)
40
- }
41
-
42
- off<K extends UWCEventName>(event: K, listener: UWCEventListener<K>): void {
43
- const set = this.listeners.get(event)
44
- set?.delete(listener as UntypedListener)
45
- }
46
-
47
- emit<K extends UWCEventName>(event: K, data: UWCEventMap[K]): void {
48
- this.dispatch(event, data)
49
- if (event !== 'change') {
50
- this.dispatch('change', undefined as UWCEventMap['change'])
51
- }
52
- }
5
+ private listeners: Set<Listener> = new Set()
53
6
 
54
- private dispatch<K extends UWCEventName>(
55
- event: K,
56
- data: UWCEventMap[K]
57
- ): void {
58
- const set = this.listeners.get(event)
59
- if (!set || set.size === 0) return
60
- // Clone to guard against mutation during dispatch.
61
- for (const listener of [...set]) {
62
- try {
63
- listener(data)
64
- } catch {
65
- // A bad listener shouldn't break the rest of the dispatch chain.
66
- }
7
+ subscribe(listener: Listener): Unsubscribe {
8
+ this.listeners.add(listener)
9
+ return () => {
10
+ this.listeners.delete(listener)
67
11
  }
68
12
  }
69
13
 
70
- // ---- legacy API (still used by the React ConnectionProvider) ----
71
-
72
- /**
73
- * @deprecated Prefer `on(eventName, listener)` for targeted updates.
74
- * Subscribes to the catch-all `change` event.
75
- */
76
- subscribe(listener: LegacyListener): () => void {
77
- return this.on('change', listener)
78
- }
79
-
80
- /** @deprecated Prefer `emit(eventName, data)`. Emits `change` with no payload. */
81
14
  notify(): void {
82
- this.dispatch('change', undefined as UWCEventMap['change'])
15
+ this.listeners.forEach(listener => listener())
83
16
  }
84
17
 
85
18
  getListenerCount(): number {
86
- let count = 0
87
- for (const set of this.listeners.values()) {
88
- count += set.size
89
- }
90
- return count
19
+ return this.listeners.size
91
20
  }
92
21
 
93
22
  clearAllListeners(): void {
@@ -249,12 +249,8 @@ describe('ConnectionService', () => {
249
249
  })
250
250
  })
251
251
 
252
- it('emits connectionUri and change events when URI becomes available', async () => {
253
- const uriListener = vi.fn()
254
- const changeListener = vi.fn()
255
- eventManager.on('connectionUri', uriListener)
256
- eventManager.on('change', changeListener)
257
-
252
+ it('polls for URI and notifies eventManager when available', async () => {
253
+ const notifySpy = vi.spyOn(eventManager, 'notify')
258
254
  let connectResolve: (v: any) => void
259
255
 
260
256
  tonConnector.connect = vi.fn().mockReturnValue(
@@ -279,11 +275,7 @@ describe('ConnectionService', () => {
279
275
  // Wait for polling to detect URI
280
276
  await new Promise(r => setTimeout(r, 250))
281
277
 
282
- expect(uriListener).toHaveBeenCalledWith({
283
- uri: 'tc://some-uri',
284
- connectionMode: 'tonConnect'
285
- })
286
- expect(changeListener).toHaveBeenCalled()
278
+ expect(notifySpy).toHaveBeenCalled()
287
279
 
288
280
  // Resolve the connection to let the test finish
289
281
  connectResolve!({
@@ -13,10 +13,6 @@ import type {
13
13
  import type { SessionManager } from '../managers/session-manager'
14
14
  import type { EventManager } from '../managers/event-manager'
15
15
 
16
- export interface ServiceOptions {
17
- signal?: AbortSignal
18
- }
19
-
20
16
  export class ConnectionService {
21
17
  private activeConnector: Connector | null = null
22
18
 
@@ -32,13 +28,8 @@ export class ConnectionService {
32
28
  async connect(
33
29
  connectionMode: ConnectionMode,
34
30
  walletId: string,
35
- networkId?: NetworkId,
36
- options?: ServiceOptions
31
+ networkId?: NetworkId
37
32
  ): Promise<void> {
38
- options?.signal?.throwIfAborted()
39
-
40
- this.eventManager.emit('connecting', { connectionMode, walletId })
41
-
42
33
  // Find the wallet
43
34
  const wallet = this.findWallet(walletId)
44
35
 
@@ -68,12 +59,7 @@ export class ConnectionService {
68
59
  connectionMode === 'tonConnect' ||
69
60
  connectionMode === 'walletConnect'
70
61
  ) {
71
- result = await this.connectWithURIPoll(
72
- connector,
73
- network,
74
- provider,
75
- connectionMode
76
- )
62
+ result = await this.connectWithURIPoll(connector, network, provider)
77
63
  } else {
78
64
  throw new Error(`Unsupported connection mode: ${connectionMode}`)
79
65
  }
@@ -82,9 +68,6 @@ export class ConnectionService {
82
68
  throw error
83
69
  }
84
70
 
85
- // If the caller aborted during the await, bail before mutating session
86
- options?.signal?.throwIfAborted()
87
-
88
71
  // Filter available addresses to only include those for configured networks
89
72
  const filteredAvailableAddresses = result.availableAddresses.filter(addr =>
90
73
  this.networks.some(n => n.id === addr.networkId)
@@ -101,26 +84,20 @@ export class ConnectionService {
101
84
  ),
102
85
  availableAddresses: filteredAvailableAddresses
103
86
  })
104
-
105
- const session = this.sessionManager.getSession()
106
- this.eventManager.emit('connected', { session })
107
- this.eventManager.emit('sessionChanged', { session })
108
87
  }
109
88
 
110
89
  private async connectWithURIPoll(
111
90
  connector: Connector,
112
91
  network: Network,
113
- provider: SupportedProvider,
114
- connectionMode: ConnectionMode
92
+ provider: SupportedProvider
115
93
  ): Promise<ConnectorResult> {
116
94
  const connectPromise = connector.connect(network, provider)
117
95
 
118
- let emittedUri: string | undefined
119
96
  const pollForURI = setInterval(() => {
120
97
  const uri = this.getConnectionURI()
121
- if (uri && uri !== emittedUri) {
122
- emittedUri = uri
123
- this.eventManager.emit('connectionUri', { uri, connectionMode })
98
+ if (uri) {
99
+ clearInterval(pollForURI)
100
+ this.eventManager.notify()
124
101
  }
125
102
  }, 100)
126
103
 
@@ -242,8 +219,7 @@ export class ConnectionService {
242
219
  return network
243
220
  }
244
221
 
245
- async disconnect(options?: ServiceOptions): Promise<void> {
246
- options?.signal?.throwIfAborted()
222
+ async disconnect(): Promise<void> {
247
223
  try {
248
224
  if (
249
225
  this.activeConnector &&
@@ -254,9 +230,6 @@ export class ConnectionService {
254
230
  } finally {
255
231
  this.activeConnector = null
256
232
  this.sessionManager.clearSession()
257
- const session = this.sessionManager.getSession()
258
- this.eventManager.emit('disconnected', undefined)
259
- this.eventManager.emit('sessionChanged', { session })
260
233
  }
261
234
  }
262
235
 
@@ -11,7 +11,6 @@ import type {
11
11
  } from '@meshconnect/uwc-types'
12
12
  import type { SessionManager } from '../managers/session-manager'
13
13
  import type { EventManager } from '../managers/event-manager'
14
- import type { ServiceOptions } from './connection-service'
15
14
 
16
15
  export class NetworkSwitchService {
17
16
  private isLoading = false
@@ -32,12 +31,7 @@ export class NetworkSwitchService {
32
31
  }
33
32
  }
34
33
 
35
- async switchNetwork(
36
- networkId: NetworkId,
37
- options?: ServiceOptions
38
- ): Promise<void> {
39
- options?.signal?.throwIfAborted()
40
-
34
+ async switchNetwork(networkId: NetworkId): Promise<void> {
41
35
  // Check if there's an active connection
42
36
  const session = this.sessionManager.getSession()
43
37
  if (!session) {
@@ -110,10 +104,7 @@ export class NetworkSwitchService {
110
104
  // Set loading states
111
105
  this.isLoading = true
112
106
  this.isWaitingForUserApproval = requiresApproval
113
- this.eventManager.emit('networkSwitching', {
114
- isLoading: true,
115
- isWaitingForUserApproval: requiresApproval
116
- })
107
+ this.eventManager.notify()
117
108
 
118
109
  // Perform the network switch and get the new address
119
110
  // Pass the appropriate provider based on connection mode
@@ -138,8 +129,6 @@ export class NetworkSwitchService {
138
129
  result = await activeConnector.switchNetwork(network)
139
130
  }
140
131
 
141
- options?.signal?.throwIfAborted()
142
-
143
132
  // Filter available addresses to only include those for configured networks
144
133
  const filteredAvailableAddresses = result.availableAddresses
145
134
  ? result.availableAddresses.filter(addr =>
@@ -155,19 +144,11 @@ export class NetworkSwitchService {
155
144
  availableAddresses: filteredAvailableAddresses
156
145
  })
157
146
  })
158
-
159
- this.eventManager.emit('networkSwitched', { network })
160
- this.eventManager.emit('sessionChanged', {
161
- session: this.sessionManager.getSession()
162
- })
163
147
  } finally {
164
148
  // Clear loading states
165
149
  this.isLoading = false
166
150
  this.isWaitingForUserApproval = false
167
- this.eventManager.emit('networkSwitching', {
168
- isLoading: false,
169
- isWaitingForUserApproval: false
170
- })
151
+ this.eventManager.notify()
171
152
  }
172
153
  }
173
154
 
@@ -8,7 +8,6 @@ import type {
8
8
  SignatureType
9
9
  } from '@meshconnect/uwc-types'
10
10
  import type { SessionManager } from '../managers/session-manager'
11
- import type { ServiceOptions } from './connection-service'
12
11
 
13
12
  /**
14
13
  * Service for handling signature operations across different connector types
@@ -23,15 +22,12 @@ export class SignatureService {
23
22
  * Sign a message with the currently connected wallet
24
23
  * @param message The message to sign
25
24
  * @param provider The wallet provider to use for signing (required for injected connector)
26
- * @param options Optional cancellation signal
27
25
  * @returns A promise that resolves to the signature
28
26
  */
29
27
  async signMessage(
30
28
  message: string,
31
- provider?: SupportedProvider,
32
- options?: ServiceOptions
29
+ provider?: SupportedProvider
33
30
  ): Promise<SignatureType> {
34
- options?.signal?.throwIfAborted()
35
31
  const session = this.sessionManager.getSession()
36
32
 
37
33
  if (!session.connectionMode) {
@@ -56,33 +52,29 @@ export class SignatureService {
56
52
  }
57
53
 
58
54
  // Call the connector's signMessage method with the appropriate provider
59
- let signature: SignatureType
60
55
  if (session.connectionMode === 'injected') {
61
56
  if (!provider) {
62
57
  throw new Error('Provider is required for injected connector')
63
58
  }
64
- signature = await connector.signMessage(
59
+ return await connector.signMessage(
65
60
  message,
66
61
  provider as
67
62
  | ExtensionInjectedProvider
68
63
  | IntegratedBrowserInjectedProvider
69
64
  )
70
65
  } else if (session.connectionMode === 'tonConnect') {
71
- signature = await connector.signMessage(message)
66
+ return await connector.signMessage(message)
72
67
  } else if (session.connectionMode === 'walletConnect') {
73
68
  if (!provider) {
74
69
  throw new Error('Provider is required for WalletConnect connector')
75
70
  }
76
- signature = await connector.signMessage(
71
+ return await connector.signMessage(
77
72
  message,
78
73
  provider as WalletConnectProvider
79
74
  )
80
75
  } else {
81
76
  // For other connectors that might not need the provider
82
- signature = await connector.signMessage(message)
77
+ return await connector.signMessage(message)
83
78
  }
84
-
85
- options?.signal?.throwIfAborted()
86
- return signature
87
79
  }
88
80
  }
@@ -9,7 +9,6 @@ import type {
9
9
  TransactionResult
10
10
  } from '@meshconnect/uwc-types'
11
11
  import type { SessionManager } from '../managers/session-manager'
12
- import type { ServiceOptions } from './connection-service'
13
12
 
14
13
  /**
15
14
  * Service for handling transaction operations across different connector types
@@ -24,15 +23,12 @@ export class TransactionService {
24
23
  * Send a transaction with the currently connected wallet
25
24
  * @param request The transaction request parameters
26
25
  * @param provider The wallet provider to use for sending (required for injected connector)
27
- * @param options Optional cancellation signal
28
26
  * @returns A promise that resolves to the transaction result
29
27
  */
30
28
  async sendTransaction(
31
29
  request: TransactionRequest,
32
- provider?: SupportedProvider,
33
- options?: ServiceOptions
30
+ provider?: SupportedProvider
34
31
  ): Promise<TransactionResult> {
35
- options?.signal?.throwIfAborted()
36
32
  const session = this.sessionManager.getSession()
37
33
 
38
34
  if (!session.connectionMode) {
@@ -57,33 +53,29 @@ export class TransactionService {
57
53
  }
58
54
 
59
55
  // Call the connector's sendTransaction method with the appropriate provider
60
- let result: TransactionResult
61
56
  if (session.connectionMode === 'injected') {
62
57
  if (!provider) {
63
58
  throw new Error('Provider is required for injected connector')
64
59
  }
65
- result = await connector.sendTransaction(
60
+ return await connector.sendTransaction(
66
61
  request,
67
62
  provider as
68
63
  | ExtensionInjectedProvider
69
64
  | IntegratedBrowserInjectedProvider
70
65
  )
71
66
  } else if (session.connectionMode === 'tonConnect') {
72
- result = await connector.sendTransaction(request)
67
+ return await connector.sendTransaction(request)
73
68
  } else if (session.connectionMode === 'walletConnect') {
74
69
  if (!provider) {
75
70
  throw new Error('Provider is required for WalletConnect connector')
76
71
  }
77
- result = await connector.sendTransaction(
72
+ return await connector.sendTransaction(
78
73
  request,
79
74
  provider as WalletConnectProvider
80
75
  )
81
76
  } else {
82
77
  // For other connectors that might not need the provider
83
- result = await connector.sendTransaction(request)
78
+ return await connector.sendTransaction(request)
84
79
  }
85
-
86
- options?.signal?.throwIfAborted()
87
- return result
88
80
  }
89
81
  }
@@ -6,7 +6,6 @@ import type {
6
6
  } from '@meshconnect/uwc-types'
7
7
  import type { SessionManager } from '../managers/session-manager'
8
8
  import type { EventManager } from '../managers/event-manager'
9
- import type { ServiceOptions } from './connection-service'
10
9
 
11
10
  export class WalletCapabilitiesService {
12
11
  constructor(
@@ -18,11 +17,8 @@ export class WalletCapabilitiesService {
18
17
 
19
18
  async getWalletCapabilities(
20
19
  address: string,
21
- activeNetwork?: Network,
22
- options?: ServiceOptions
20
+ activeNetwork?: Network
23
21
  ): Promise<void> {
24
- options?.signal?.throwIfAborted()
25
-
26
22
  let activeWalletCapabilities: Record<string, EVMCapabilities> = {}
27
23
  let activeNetworkWalletCapabilities: EVMCapabilities = {}
28
24
 
@@ -53,8 +49,6 @@ export class WalletCapabilitiesService {
53
49
  capabilities = {}
54
50
  }
55
51
 
56
- options?.signal?.throwIfAborted()
57
-
58
52
  // keep only supported networks
59
53
  activeWalletCapabilities = Object.fromEntries(
60
54
  Object.entries(capabilities).filter(([networkId, _]) =>
@@ -77,13 +71,7 @@ export class WalletCapabilitiesService {
77
71
  activeNetworkWalletCapabilities: null
78
72
  })
79
73
  }
80
-
81
- this.eventManager.emit('capabilitiesUpdated', {
82
- capabilities: activeWalletCapabilities
83
- })
84
- this.eventManager.emit('sessionChanged', {
85
- session: this.sessionManager.getSession()
86
- })
74
+ this.eventManager.notify()
87
75
  }
88
76
  }
89
77
  }
@@ -29,11 +29,7 @@ const mockSessionManager = {
29
29
 
30
30
  const mockEventManager = {
31
31
  subscribe: vi.fn().mockReturnValue(() => {}),
32
- notify: vi.fn(),
33
- emit: vi.fn(),
34
- on: vi.fn().mockReturnValue(() => {}),
35
- off: vi.fn(),
36
- once: vi.fn().mockReturnValue(() => {})
32
+ notify: vi.fn()
37
33
  }
38
34
 
39
35
  const mockConnectionService = {
@@ -121,7 +117,8 @@ describe('UniversalWalletConnector', () => {
121
117
  let mockWalletConnectConfig: WalletConnectConfig
122
118
 
123
119
  beforeEach(() => {
124
- UniversalWalletConnector.resetInstance()
120
+ ;(UniversalWalletConnector as any).instanceCount = 0
121
+ ;(UniversalWalletConnector as any).hasWarnedAboutMultipleInstances = false
125
122
 
126
123
  mockNetworks = [
127
124
  {
@@ -405,87 +402,6 @@ describe('UniversalWalletConnector', () => {
405
402
  expect(typeof connector.sendTransaction).toBe('function')
406
403
  expect(typeof connector.isConnectionModeAvailable).toBe('function')
407
404
  expect(typeof connector.getActiveWalletCapabilities).toBe('function')
408
- expect(typeof connector.on).toBe('function')
409
- expect(typeof connector.once).toBe('function')
410
- expect(typeof connector.off).toBe('function')
411
- })
412
- })
413
-
414
- describe('getInstance singleton factory', () => {
415
- it('creates an instance on first call and reuses it afterwards', () => {
416
- const a = UniversalWalletConnector.getInstance({
417
- networks: mockNetworks,
418
- wallets: mockWallets
419
- })
420
- const b = UniversalWalletConnector.getInstance({
421
- networks: mockNetworks,
422
- wallets: mockWallets
423
- })
424
- expect(a).toBe(b)
425
- })
426
-
427
- it('throws when called before any instance exists and no config is given', () => {
428
- expect(() => UniversalWalletConnector.getInstance()).toThrow(
429
- /getInstance.*before an instance existed/
430
- )
431
- })
432
-
433
- it('resetInstance() clears the shared reference', () => {
434
- const first = UniversalWalletConnector.getInstance({
435
- networks: mockNetworks,
436
- wallets: mockWallets
437
- })
438
- UniversalWalletConnector.resetInstance()
439
- const second = UniversalWalletConnector.getInstance({
440
- networks: mockNetworks,
441
- wallets: mockWallets
442
- })
443
- expect(second).not.toBe(first)
444
- })
445
-
446
- it('adopts a `new`-constructed instance as the singleton', () => {
447
- const created = new UniversalWalletConnector(mockNetworks, mockWallets)
448
- expect(UniversalWalletConnector.getInstance()).toBe(created)
449
- })
450
- })
451
-
452
- describe('config-object constructor', () => {
453
- it('accepts the { networks, wallets, ... } form', () => {
454
- const connector = new UniversalWalletConnector({
455
- networks: mockNetworks,
456
- wallets: mockWallets,
457
- walletConnectConfig: mockWalletConnectConfig
458
- })
459
- expect(connector).toBeInstanceOf(UniversalWalletConnector)
460
- })
461
- })
462
-
463
- describe('AbortSignal support', () => {
464
- it('connect rejects immediately when signal is already aborted', async () => {
465
- const connector = new UniversalWalletConnector(mockNetworks, mockWallets)
466
- const controller = new AbortController()
467
- controller.abort()
468
-
469
- // ConnectionService.connect is mocked to return undefined by default,
470
- // so the abort check is what surfaces the error.
471
- mockConnectionService.connect = vi.fn().mockImplementation(
472
- async (
473
- _m: unknown,
474
- _w: unknown,
475
- _n: unknown,
476
- options?: {
477
- signal?: AbortSignal
478
- }
479
- ) => {
480
- options?.signal?.throwIfAborted()
481
- }
482
- )
483
-
484
- await expect(
485
- connector.connect('injected', 'metamask', undefined, {
486
- signal: controller.signal
487
- })
488
- ).rejects.toThrow()
489
405
  })
490
406
  })
491
407