@txnlab/use-wallet 1.0.3 → 1.0.4

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 CHANGED
@@ -457,6 +457,12 @@ In the root of `use-wallet` directory, run:
457
457
  yarn link react
458
458
  ```
459
459
 
460
+ ## Used By
461
+
462
+ Are you using `@txnlab/use-wallet`? We'd love to include you here. Let us know! [Twitter](https://twitter.com/NFDomains) | [Discord](https://discord.gg/7XcuMTfeZP) | [Email](mailto:admin@txnlab.dev)
463
+
464
+ * [@algoscan/use-wallet-ui](https://github.com/algoscan/use-wallet-ui)
465
+
460
466
  ## License
461
467
 
462
468
  See the [LICENSE](https://github.com/TxnLab/use-wallet/blob/main/LICENSE.md) file for license rights and limitations (MIT)
@@ -1,5 +1,5 @@
1
1
  import type algosdk from "algosdk";
2
- import { PROVIDER_ID, TransactionsArray } from "../types";
2
+ import { PROVIDER_ID, TransactionsArray, Provider } from "../types";
3
3
  export { PROVIDER_ID };
4
4
  export default function useWallet(): {
5
5
  clients: Partial<{
@@ -11,112 +11,7 @@ export default function useWallet(): {
11
11
  exodus: Promise<import("../clients/base/base").default | null>;
12
12
  walletconnect: Promise<import("../clients/base/base").default | null>;
13
13
  }> | null;
14
- providers: ({
15
- accounts: import("../types").Account[];
16
- isActive: boolean;
17
- isConnected: boolean;
18
- connect: () => Promise<void>;
19
- disconnect: () => Promise<void>;
20
- reconnect: () => Promise<void>;
21
- setActiveProvider: () => Promise<void>;
22
- setActiveAccount: (account: string) => Promise<void>;
23
- metadata: {
24
- id: PROVIDER_ID;
25
- name: string;
26
- icon: string;
27
- isWalletConnect: boolean;
28
- };
29
- } | {
30
- accounts: import("../types").Account[];
31
- isActive: boolean;
32
- isConnected: boolean;
33
- connect: () => Promise<void>;
34
- disconnect: () => Promise<void>;
35
- reconnect: () => Promise<void>;
36
- setActiveProvider: () => Promise<void>;
37
- setActiveAccount: (account: string) => Promise<void>;
38
- metadata: {
39
- id: PROVIDER_ID;
40
- name: string;
41
- icon: string;
42
- isWalletConnect: boolean;
43
- };
44
- } | {
45
- accounts: import("../types").Account[];
46
- isActive: boolean;
47
- isConnected: boolean;
48
- connect: () => Promise<void>;
49
- disconnect: () => Promise<void>;
50
- reconnect: () => Promise<void>;
51
- setActiveProvider: () => Promise<void>;
52
- setActiveAccount: (account: string) => Promise<void>;
53
- metadata: {
54
- id: PROVIDER_ID;
55
- name: string;
56
- icon: string;
57
- isWalletConnect: boolean;
58
- };
59
- } | {
60
- accounts: import("../types").Account[];
61
- isActive: boolean;
62
- isConnected: boolean;
63
- connect: () => Promise<void>;
64
- disconnect: () => Promise<void>;
65
- reconnect: () => Promise<void>;
66
- setActiveProvider: () => Promise<void>;
67
- setActiveAccount: (account: string) => Promise<void>;
68
- metadata: {
69
- id: PROVIDER_ID;
70
- name: string;
71
- icon: string;
72
- isWalletConnect: boolean;
73
- };
74
- } | {
75
- accounts: import("../types").Account[];
76
- isActive: boolean;
77
- isConnected: boolean;
78
- connect: () => Promise<void>;
79
- disconnect: () => Promise<void>;
80
- reconnect: () => Promise<void>;
81
- setActiveProvider: () => Promise<void>;
82
- setActiveAccount: (account: string) => Promise<void>;
83
- metadata: {
84
- id: PROVIDER_ID;
85
- name: string;
86
- icon: string;
87
- isWalletConnect: boolean;
88
- };
89
- } | {
90
- accounts: import("../types").Account[];
91
- isActive: boolean;
92
- isConnected: boolean;
93
- connect: () => Promise<void>;
94
- disconnect: () => Promise<void>;
95
- reconnect: () => Promise<void>;
96
- setActiveProvider: () => Promise<void>;
97
- setActiveAccount: (account: string) => Promise<void>;
98
- metadata: {
99
- id: PROVIDER_ID;
100
- name: string;
101
- icon: string;
102
- isWalletConnect: boolean;
103
- };
104
- } | {
105
- accounts: import("../types").Account[];
106
- isActive: boolean;
107
- isConnected: boolean;
108
- connect: () => Promise<void>;
109
- disconnect: () => Promise<void>;
110
- reconnect: () => Promise<void>;
111
- setActiveProvider: () => Promise<void>;
112
- setActiveAccount: (account: string) => Promise<void>;
113
- metadata: {
114
- id: PROVIDER_ID;
115
- name: string;
116
- icon: string;
117
- isWalletConnect: boolean;
118
- };
119
- })[] | null;
14
+ providers: Provider[] | null;
120
15
  connectedAccounts: import("../types").Account[];
121
16
  connectedActiveAccounts: import("../types").Account[];
122
17
  activeAccount: import("../types").Account | null;
package/dist/cjs/index.js CHANGED
@@ -886,6 +886,14 @@ const walletStoreSelector = (state) => ({
886
886
  addAccounts: state.addAccounts,
887
887
  removeAccounts: state.removeAccounts,
888
888
  });
889
+ const emptyState = {
890
+ accounts: [],
891
+ activeAccount: null,
892
+ setActiveAccount: (account) => { },
893
+ clearActiveAccount: (id) => { },
894
+ addAccounts: (accounts) => { },
895
+ removeAccounts: (providerId) => { },
896
+ };
889
897
  const useWalletStore = create()(immer(persist(devtools((set, _get) => ({
890
898
  accounts: [],
891
899
  activeAccount: null,
@@ -919,8 +927,17 @@ const useWalletStore = create()(immer(persist(devtools((set, _get) => ({
919
927
  },
920
928
  })), {
921
929
  name: "txnlab-use-wallet",
922
- version: 0, // increment to deprecate stored data
923
- })));
930
+ version: 1, // increment to deprecate stored data
931
+ })));
932
+ // This a fix to ensure zustand never hydrates the store before React hydrates the page
933
+ // otherwise it causes a mismatch between SSR and client render
934
+ // see: https://github.com/pmndrs/zustand/issues/1145
935
+ const useHydratedWalletStore = ((selector, compare) => {
936
+ const store = useWalletStore(selector, compare);
937
+ const [hydrated, setHydrated] = require$$0.useState(false);
938
+ require$$0.useEffect(() => setHydrated(true), []);
939
+ return hydrated ? store : selector(emptyState);
940
+ });
924
941
 
925
942
  const ClientContext = require$$0.createContext(null);
926
943
  var clientStore = ClientContext.Provider;
@@ -1789,12 +1806,10 @@ class WalletConnectClient extends BaseClient {
1789
1806
  const QRCodeModal = modalStatic ||
1790
1807
  (await import('algorand-walletconnect-qrcode-modal')).default;
1791
1808
  const walletConnect = new WalletConnect({
1792
- ...(clientOptions
1793
- ? clientOptions
1794
- : {
1795
- bridge: "https://bridge.walletconnect.org",
1796
- qrcodeModal: QRCodeModal,
1797
- }),
1809
+ bridge: "https://bridge.walletconnect.org",
1810
+ qrcodeModal: QRCodeModal,
1811
+ storageId: 'walletconnect-generic',
1812
+ ...(clientOptions || {})
1798
1813
  });
1799
1814
  const algosdk = algosdkStatic || (await Algod.init(algodOptions)).algosdk;
1800
1815
  const algodClient = await getAlgodClient(algosdk, algodOptions);
@@ -2141,17 +2156,20 @@ function shallow(objA, objB) {
2141
2156
  }
2142
2157
 
2143
2158
  function useWallet() {
2159
+ const [providers, setProviders] = require$$0.useState(null);
2144
2160
  const clients = require$$0.useContext(ClientContext);
2145
- const { activeAccount, accounts: connectedAccounts, setActiveAccount: _setActiveAccount, addAccounts, } = useWalletStore(walletStoreSelector, shallow);
2161
+ const { activeAccount, accounts: connectedAccounts, setActiveAccount: _setActiveAccount, addAccounts, } = useHydratedWalletStore(walletStoreSelector, shallow);
2146
2162
  const getAccountsByProvider = (id) => {
2147
2163
  return connectedAccounts.filter((account) => account.providerId === id);
2148
2164
  };
2149
2165
  const connectedActiveAccounts = require$$0.useMemo(() => connectedAccounts.filter((account) => account.providerId === activeAccount?.providerId), [connectedAccounts, activeAccount]);
2150
- const providers = require$$0.useMemo(() => {
2151
- if (!clients)
2152
- return null;
2166
+ require$$0.useEffect(() => {
2167
+ if (!clients) {
2168
+ setProviders(null);
2169
+ return;
2170
+ }
2153
2171
  const supportedClients = Object.keys(clients);
2154
- return supportedClients.map((id) => {
2172
+ setProviders(supportedClients.map((id) => {
2155
2173
  return {
2156
2174
  ...allClients[id],
2157
2175
  accounts: getAccountsByProvider(id),
@@ -2163,7 +2181,7 @@ function useWallet() {
2163
2181
  setActiveProvider: () => setActive(id),
2164
2182
  setActiveAccount: (account) => selectActiveAccount(id, account),
2165
2183
  };
2166
- });
2184
+ }));
2167
2185
  }, [clients, connectedAccounts, connectedActiveAccounts, activeAccount]);
2168
2186
  const getClient = async (id) => {
2169
2187
  if (!id)
@@ -2173,27 +2191,12 @@ function useWallet() {
2173
2191
  throw new Error("Client not found for ID");
2174
2192
  return client;
2175
2193
  };
2176
- const disconnectWCSessions = async (id) => {
2177
- if (!allClients[id].metadata.isWalletConnect) {
2178
- return;
2179
- }
2180
- if (!providers) {
2181
- return;
2182
- }
2183
- const wcSessions = Object.values(providers).filter((p) => p.metadata.id !== id &&
2184
- p.metadata.isWalletConnect &&
2185
- (p.isConnected || p.isActive));
2186
- for (const session of wcSessions) {
2187
- await disconnect(session.metadata.id);
2188
- }
2189
- };
2190
2194
  const selectActiveAccount = async (providerId, address) => {
2191
2195
  try {
2192
2196
  const account = connectedActiveAccounts.find((acct) => acct.address === address && acct.providerId === providerId);
2193
2197
  if (!account) {
2194
2198
  throw new Error(`No accounts with address ${address} found.`);
2195
2199
  }
2196
- await disconnectWCSessions(account.providerId);
2197
2200
  _setActiveAccount(account);
2198
2201
  }
2199
2202
  catch (e) {
@@ -2202,7 +2205,6 @@ function useWallet() {
2202
2205
  };
2203
2206
  const connect = async (id) => {
2204
2207
  try {
2205
- await disconnectWCSessions(id);
2206
2208
  const walletClient = await getClient(id);
2207
2209
  const walletInfo = await walletClient?.connect(() => clearAccounts(id));
2208
2210
  if (!walletInfo || !walletInfo.accounts.length) {
@@ -2242,7 +2244,6 @@ function useWallet() {
2242
2244
  };
2243
2245
  const setActive = async (id) => {
2244
2246
  try {
2245
- await disconnectWCSessions(id);
2246
2247
  const accounts = getAccountsByProvider(id);
2247
2248
  _setActiveAccount(accounts[0]);
2248
2249
  }
@@ -2318,6 +2319,10 @@ function useWallet() {
2318
2319
 
2319
2320
  const initializeProviders = (providers, nodeConfig, algosdkStatic) => {
2320
2321
  const initializedProviders = {};
2322
+ if (typeof window === "undefined") {
2323
+ console.warn("Window object is not available, skipping initialization.");
2324
+ return initializedProviders;
2325
+ }
2321
2326
  const { network = DEFAULT_NETWORK$1, nodeServer = DEFAULT_NODE_BASEURL, nodePort = DEFAULT_NODE_PORT, nodeToken = DEFAULT_NODE_TOKEN, } = nodeConfig || {};
2322
2327
  if (!providers || providers.length === 0)
2323
2328
  for (const [id, client] of Object.entries(allClients)) {