@meshconnect/uwc-react 0.9.4 → 0.10.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.
Files changed (65) hide show
  1. package/dist/hooks/useConnection.d.ts.map +1 -1
  2. package/dist/hooks/useConnection.js +15 -6
  3. package/dist/hooks/useConnection.js.map +1 -1
  4. package/dist/hooks/useConnectionContext.d.ts +15 -0
  5. package/dist/hooks/useConnectionContext.d.ts.map +1 -0
  6. package/dist/hooks/useConnectionContext.js +22 -0
  7. package/dist/hooks/useConnectionContext.js.map +1 -0
  8. package/dist/hooks/useDetectedWallets.d.ts.map +1 -1
  9. package/dist/hooks/useDetectedWallets.js +6 -6
  10. package/dist/hooks/useDetectedWallets.js.map +1 -1
  11. package/dist/hooks/useDisconnect.d.ts.map +1 -1
  12. package/dist/hooks/useDisconnect.js +6 -6
  13. package/dist/hooks/useDisconnect.js.map +1 -1
  14. package/dist/hooks/useNetworks.d.ts.map +1 -1
  15. package/dist/hooks/useNetworks.js +2 -6
  16. package/dist/hooks/useNetworks.js.map +1 -1
  17. package/dist/hooks/useSession.d.ts.map +1 -1
  18. package/dist/hooks/useSession.js +2 -6
  19. package/dist/hooks/useSession.js.map +1 -1
  20. package/dist/hooks/useSignMessage.d.ts.map +1 -1
  21. package/dist/hooks/useSignMessage.js +4 -7
  22. package/dist/hooks/useSignMessage.js.map +1 -1
  23. package/dist/hooks/useSignSolanaTransaction.d.ts.map +1 -1
  24. package/dist/hooks/useSignSolanaTransaction.js +4 -7
  25. package/dist/hooks/useSignSolanaTransaction.js.map +1 -1
  26. package/dist/hooks/useSignTypedData.d.ts.map +1 -1
  27. package/dist/hooks/useSignTypedData.js +4 -7
  28. package/dist/hooks/useSignTypedData.js.map +1 -1
  29. package/dist/hooks/useSwitchNetwork.d.ts.map +1 -1
  30. package/dist/hooks/useSwitchNetwork.js +9 -6
  31. package/dist/hooks/useSwitchNetwork.js.map +1 -1
  32. package/dist/hooks/useTransaction.d.ts.map +1 -1
  33. package/dist/hooks/useTransaction.js +4 -7
  34. package/dist/hooks/useTransaction.js.map +1 -1
  35. package/dist/hooks/useWallet.d.ts.map +1 -1
  36. package/dist/hooks/useWallet.js +2 -6
  37. package/dist/hooks/useWallet.js.map +1 -1
  38. package/dist/hooks/useWalletCapabilities.d.ts.map +1 -1
  39. package/dist/hooks/useWalletCapabilities.js +6 -8
  40. package/dist/hooks/useWalletCapabilities.js.map +1 -1
  41. package/dist/hooks/useWallets.d.ts.map +1 -1
  42. package/dist/hooks/useWallets.js +2 -6
  43. package/dist/hooks/useWallets.js.map +1 -1
  44. package/dist/providers/ConnectionProvider.d.ts +10 -2
  45. package/dist/providers/ConnectionProvider.d.ts.map +1 -1
  46. package/dist/providers/ConnectionProvider.js +32 -5
  47. package/dist/providers/ConnectionProvider.js.map +1 -1
  48. package/package.json +3 -3
  49. package/src/hooks/useConnection.ts +18 -8
  50. package/src/hooks/useConnectionContext.ts +25 -0
  51. package/src/hooks/useDetectedWallets.ts +6 -10
  52. package/src/hooks/useDisconnect.ts +6 -8
  53. package/src/hooks/useNetworks.ts +2 -8
  54. package/src/hooks/useSession.ts +2 -8
  55. package/src/hooks/useSignMessage.ts +4 -9
  56. package/src/hooks/useSignSolanaTransaction.ts +4 -11
  57. package/src/hooks/useSignTypedData.ts +4 -9
  58. package/src/hooks/useSwitchNetwork.ts +10 -8
  59. package/src/hooks/useTransaction.ts +4 -9
  60. package/src/hooks/useWallet.ts +2 -8
  61. package/src/hooks/useWalletCapabilities.ts +6 -12
  62. package/src/hooks/useWallets.ts +2 -8
  63. package/src/providers/ConnectionProvider.emptyWallets.test.tsx +105 -0
  64. package/src/providers/ConnectionProvider.singleton.test.tsx +18 -7
  65. package/src/providers/ConnectionProvider.tsx +46 -7
@@ -1,7 +1,17 @@
1
1
  import { useContext, act } from 'react'
2
2
  import { describe, it, expect, beforeEach, vi } from 'vitest'
3
3
  import { createRoot } from 'react-dom/client'
4
- import type { TronConnectorConfig } from '@meshconnect/uwc-types'
4
+ import type {
5
+ TronConnectorConfig,
6
+ WalletMetadata
7
+ } from '@meshconnect/uwc-types'
8
+
9
+ // The provider only constructs a connector when at least one wallet is present
10
+ // (core rejects an empty wallet list), so these construction-focused tests pass
11
+ // a minimal wallet.
12
+ const TEST_WALLETS: WalletMetadata[] = [
13
+ { id: 'metamask', name: 'MetaMask', metadata: {} }
14
+ ]
5
15
 
6
16
  describe('ConnectionProvider singleton behavior', () => {
7
17
  beforeEach(async () => {
@@ -68,14 +78,14 @@ describe('ConnectionProvider singleton behavior', () => {
68
78
  <>
69
79
  <ConnectionProvider
70
80
  networks={[]}
71
- wallets={[]}
81
+ wallets={TEST_WALLETS}
72
82
  usingIntegratedBrowser={false}
73
83
  >
74
84
  <Capture />
75
85
  </ConnectionProvider>
76
86
  <ConnectionProvider
77
87
  networks={[]}
78
- wallets={[]}
88
+ wallets={TEST_WALLETS}
79
89
  usingIntegratedBrowser={false}
80
90
  >
81
91
  <Capture />
@@ -88,9 +98,10 @@ describe('ConnectionProvider singleton behavior', () => {
88
98
  // @ts-expect-error test-only property
89
99
  expect(UniversalWalletConnector.calls).toBe(1)
90
100
 
91
- // Both providers should expose the same connector instance
92
- expect(connectors.length).toBe(2)
93
- expect(connectors[0]).toBe(connectors[1])
101
+ // Both providers should expose the same connector instance (render count is
102
+ // an implementation detail — assert the singleton invariant, not the count).
103
+ expect(connectors.length).toBeGreaterThanOrEqual(2)
104
+ expect(connectors.every(c => c === connectors[0])).toBe(true)
94
105
 
95
106
  await act(async () => {
96
107
  root.unmount()
@@ -140,7 +151,7 @@ describe('ConnectionProvider singleton behavior', () => {
140
151
  root.render(
141
152
  <ConnectionProvider
142
153
  networks={[]}
143
- wallets={[]}
154
+ wallets={TEST_WALLETS}
144
155
  tronConnectorConfig={tronConnectorConfig}
145
156
  >
146
157
  <div />
@@ -12,8 +12,35 @@ import type {
12
12
  // Guard against double initialization
13
13
  let sharedConnector: UniversalWalletConnector | null = null
14
14
 
15
- interface ConnectionContextValue {
16
- connector: UniversalWalletConnector
15
+ /**
16
+ * Session served before any wallet is connected — and while the provider is
17
+ * mounted without wallets (a wallet-less session; see `connector` below). Every
18
+ * field is at its natural empty per the `Session` type, so the read-only hooks
19
+ * (`useSession`/`useNetworks`/`useWallets`) work unchanged and the sign/transfer
20
+ * hooks short-circuit on their existing `activeAddress` guard.
21
+ */
22
+ const EMPTY_SESSION: Session = {
23
+ connectionMode: null,
24
+ activeNetwork: null,
25
+ activeWalletCapabilities: null,
26
+ activeNetworkWalletCapabilities: null,
27
+ activeAddress: null,
28
+ publicKey: null,
29
+ availableNetworks: [],
30
+ activeWallet: null,
31
+ availableAddresses: []
32
+ }
33
+
34
+ export interface ConnectionContextValue {
35
+ /**
36
+ * `null` when the provider is mounted without wallets. `@meshconnect/uwc-core`
37
+ * requires at least one wallet to construct a connector, so a wallet-less
38
+ * session (e.g. a CEX-only catalog) legitimately has none. Hooks treat a null
39
+ * connector as "no wallet session" and return inert values instead of
40
+ * throwing, so a host that mounts this provider for every session — wallet or
41
+ * not — does not crash.
42
+ */
43
+ connector: UniversalWalletConnector | null
17
44
  session: Session
18
45
  wallets: WalletMetadata[]
19
46
  networks: Network[]
@@ -41,7 +68,10 @@ export function ConnectionProvider({
41
68
  tonConnectConfig,
42
69
  tronConnectorConfig
43
70
  }: ConnectionProviderProps) {
44
- if (!sharedConnector) {
71
+ // Core rejects an empty wallet list, so only construct once there is at least
72
+ // one wallet. A wallet-less session keeps `connector` null; the effect below
73
+ // adopts the connector if wallets arrive later (async catalog population).
74
+ if (!sharedConnector && wallets.length > 0) {
45
75
  sharedConnector = new UniversalWalletConnector(
46
76
  networks,
47
77
  wallets,
@@ -54,10 +84,19 @@ export function ConnectionProvider({
54
84
 
55
85
  const connector = sharedConnector
56
86
 
57
- const [session, setSession] = useState<Session>(() => connector.getSession())
58
- const [isReady, setIsReady] = useState(() => connector.isReady())
87
+ const [session, setSession] = useState<Session>(
88
+ () => connector?.getSession() ?? EMPTY_SESSION
89
+ )
90
+ const [isReady, setIsReady] = useState(() => connector?.isReady() ?? false)
59
91
 
60
92
  useEffect(() => {
93
+ if (!connector) return
94
+
95
+ // Sync once on adoption — covers the case where the connector was created
96
+ // after the first render (wallets populated asynchronously).
97
+ setSession(connector.getSession())
98
+ setIsReady(connector.isReady())
99
+
61
100
  const unsubscribe = connector.subscribe(() => {
62
101
  setSession(connector.getSession())
63
102
  setIsReady(connector.isReady())
@@ -69,8 +108,8 @@ export function ConnectionProvider({
69
108
  const value: ConnectionContextValue = {
70
109
  connector,
71
110
  session,
72
- wallets: connector.getWallets(),
73
- networks: connector.getNetworks(),
111
+ wallets: connector ? connector.getWallets() : wallets,
112
+ networks: connector ? connector.getNetworks() : networks,
74
113
  isReady
75
114
  }
76
115