@interchain-kit/react 0.2.222 → 0.3.1

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.
@@ -3,4 +3,3 @@ export * from './useChain';
3
3
  export * from './useChainWallet';
4
4
  export * from './useSigningClient';
5
5
  export * from './useAsync';
6
- export * from './useRpcEndpoint';
@@ -1,7 +1,7 @@
1
1
  import { useState, useEffect, useRef } from 'react';
2
2
  export const cache = new Map();
3
3
  export const activeRequests = new Map();
4
- export function useAsync({ queryKey, queryFn, enabled = true }) {
4
+ export function useAsync({ queryKey, queryFn, enabled = true, disableCache = false, }) {
5
5
  const [state, setState] = useState({
6
6
  data: null,
7
7
  isLoading: false,
@@ -23,7 +23,7 @@ export function useAsync({ queryKey, queryFn, enabled = true }) {
23
23
  useEffect(() => {
24
24
  if (!enabled)
25
25
  return;
26
- if (cache.has(cacheKey)) {
26
+ if (!disableCache && cache.has(cacheKey)) {
27
27
  setState(prev => ({
28
28
  ...prev,
29
29
  data: cache.get(cacheKey),
@@ -55,7 +55,9 @@ export function useAsync({ queryKey, queryFn, enabled = true }) {
55
55
  setState(prev => ({ ...prev, isLoading: true, error: null }));
56
56
  const requestPromise = queryFnRef.current()
57
57
  .then((data) => {
58
- cache.set(cacheKey, data);
58
+ if (!disableCache) {
59
+ cache.set(cacheKey, data);
60
+ }
59
61
  if (mountedRef.current) {
60
62
  setState({
61
63
  data,
@@ -73,18 +75,19 @@ export function useAsync({ queryKey, queryFn, enabled = true }) {
73
75
  error,
74
76
  });
75
77
  }
76
- // throw error;
77
78
  })
78
79
  .finally(() => {
79
80
  activeRequests.delete(cacheKey);
80
81
  });
81
82
  activeRequests.set(cacheKey, requestPromise);
82
- }, [cacheKey, enabled]); // 不再依赖 queryFn
83
+ }, [cacheKey, enabled, disableCache]);
83
84
  const refetch = async () => {
84
85
  try {
85
86
  setState(prev => ({ ...prev, isLoading: true, error: null }));
86
87
  const data = await queryFnRef.current();
87
- cache.set(cacheKey, data);
88
+ if (!disableCache) {
89
+ cache.set(cacheKey, data);
90
+ }
88
91
  if (mountedRef.current) {
89
92
  setState({
90
93
  data,
@@ -1,16 +1,17 @@
1
1
  import { useWalletManager } from "./useWalletManager";
2
- import { useRpcEndpoint } from "./useRpcEndpoint";
3
2
  import { useAsync } from "./useAsync";
4
3
  import { WalletState } from "@interchain-kit/core";
5
4
  export const useSigningClient = (chainName, walletName) => {
6
- const { getSigningClient, getChainWalletState, getWalletByName } = useWalletManager();
7
- const { rpcEndpoint } = useRpcEndpoint(chainName, walletName);
5
+ const { getSigningClient, getChainWalletState, getRpcEndpoint } = useWalletManager();
8
6
  const chainWalletState = getChainWalletState(walletName, chainName);
9
- const wallet = getWalletByName(walletName);
10
7
  const { data, isLoading, error } = useAsync({
11
8
  queryKey: `signing-client-${chainName}-${walletName}`,
12
- queryFn: () => getSigningClient(walletName, chainName),
13
- enabled: !!rpcEndpoint && chainWalletState?.walletState === WalletState.Connected
9
+ queryFn: async () => {
10
+ await getRpcEndpoint(walletName, chainName);
11
+ return getSigningClient(walletName, chainName);
12
+ },
13
+ enabled: chainWalletState?.walletState === WalletState.Connected,
14
+ disableCache: true,
14
15
  });
15
16
  return {
16
17
  signingClient: data,
@@ -2,6 +2,7 @@ import { clientNotExistError, WalletState } from "@interchain-kit/core";
2
2
  import { createStore } from "zustand";
3
3
  import { immer } from "zustand/middleware/immer";
4
4
  import { persist, createJSONStorage } from 'zustand/middleware';
5
+ import { dedupeAsync } from '../utils';
5
6
  const immerSyncUp = (newWalletManager) => {
6
7
  return (draft) => {
7
8
  draft.chains = newWalletManager.chains;
@@ -38,16 +39,17 @@ export const createInterchainStore = (walletManager) => {
38
39
  },
39
40
  init: async () => {
40
41
  const oldChainWalletStatesMap = new Map(get().chainWalletState.map(cws => [cws.walletName + cws.chainName, cws]));
41
- set(draft => {
42
- draft.chainWalletState = [];
43
- });
44
- wallets.forEach(wallet => {
45
- chains.forEach(chain => {
42
+ // should remove wallet that already disconnected ,for hydrain back from localstorage
43
+ // const oldChainWalletStateMap = new Map()
44
+ // get().chainWalletState.forEach(cws => {
45
+ // if(cws.walletState === WalletState.Connected) {
46
+ // oldChainWalletStateMap.set(cws.walletName + cws.chainName, cws)
47
+ // }
48
+ // })
49
+ get().wallets.forEach(wallet => {
50
+ get().chains.forEach(chain => {
46
51
  set(draft => {
47
- if (oldChainWalletStatesMap.has(wallet.info.name + chain.chainName)) {
48
- draft.chainWalletState.push(oldChainWalletStatesMap.get(wallet.info.name + chain.chainName));
49
- }
50
- else {
52
+ if (!oldChainWalletStatesMap.has(wallet.info.name + chain.chainName)) {
51
53
  draft.chainWalletState.push({
52
54
  chainName: chain.chainName,
53
55
  walletName: wallet.info.name,
@@ -144,6 +146,9 @@ export const createInterchainStore = (walletManager) => {
144
146
  }
145
147
  });
146
148
  });
149
+ draft.chainWalletState = draft.chainWalletState.map(cws => {
150
+ return { ...cws, rpcEndpoint: newEndpointOptions?.endpoints?.[cws.chainName]?.rpc?.[0] || cws.rpcEndpoint };
151
+ });
147
152
  });
148
153
  },
149
154
  connect: async (walletName, chainName) => {
@@ -196,7 +201,13 @@ export const createInterchainStore = (walletManager) => {
196
201
  }
197
202
  },
198
203
  getRpcEndpoint: async (walletName, chainName) => {
199
- return walletManager.getRpcEndpoint(walletName, chainName);
204
+ return dedupeAsync(`${chainName}-rpcEndpoint`, async () => {
205
+ const rpcEndpoint = await walletManager.getRpcEndpoint(walletName, chainName);
206
+ get().wallets.map(wallet => {
207
+ get().updateChainWalletState(wallet.info.name, chainName, { rpcEndpoint });
208
+ });
209
+ return rpcEndpoint;
210
+ });
200
211
  },
201
212
  getChainLogoUrl(chainName) {
202
213
  return walletManager.getChainLogoUrl(chainName);
@@ -0,0 +1,18 @@
1
+ const pendingRequests = new Map();
2
+ /**
3
+ * Deduplicate async calls to avoid multiple identical requests.
4
+ * @param key - A unique key representing the request.
5
+ * @param asyncFn - A function that returns a Promise.
6
+ * @returns A Promise resolving to the result of the async function.
7
+ */
8
+ export async function dedupeAsync(key, asyncFn) {
9
+ if (pendingRequests.has(key)) {
10
+ return pendingRequests.get(key);
11
+ }
12
+ const promise = asyncFn()
13
+ .finally(() => {
14
+ pendingRequests.delete(key);
15
+ });
16
+ pendingRequests.set(key, promise);
17
+ return promise;
18
+ }
@@ -1 +1,2 @@
1
1
  export * from './wallet';
2
+ export * from './dedupeAsync';
package/hooks/index.d.ts CHANGED
@@ -3,4 +3,3 @@ export * from './useChain';
3
3
  export * from './useChainWallet';
4
4
  export * from './useSigningClient';
5
5
  export * from './useAsync';
6
- export * from './useRpcEndpoint';
package/hooks/index.js CHANGED
@@ -19,4 +19,3 @@ __exportStar(require("./useChain"), exports);
19
19
  __exportStar(require("./useChainWallet"), exports);
20
20
  __exportStar(require("./useSigningClient"), exports);
21
21
  __exportStar(require("./useAsync"), exports);
22
- __exportStar(require("./useRpcEndpoint"), exports);
@@ -17,8 +17,13 @@ type UseAsyncRequestOptions<T> = {
17
17
  * @default true
18
18
  */
19
19
  enabled?: boolean;
20
+ /**
21
+ * Whether to disable caching
22
+ * @default false
23
+ */
24
+ disableCache?: boolean;
20
25
  };
21
- export declare function useAsync<T>({ queryKey, queryFn, enabled }: UseAsyncRequestOptions<T>): {
26
+ export declare function useAsync<T>({ queryKey, queryFn, enabled, disableCache, }: UseAsyncRequestOptions<T>): {
22
27
  data: T;
23
28
  isLoading: boolean;
24
29
  error: Error;
package/hooks/useAsync.js CHANGED
@@ -5,7 +5,7 @@ exports.useAsync = useAsync;
5
5
  const react_1 = require("react");
6
6
  exports.cache = new Map();
7
7
  exports.activeRequests = new Map();
8
- function useAsync({ queryKey, queryFn, enabled = true }) {
8
+ function useAsync({ queryKey, queryFn, enabled = true, disableCache = false, }) {
9
9
  const [state, setState] = (0, react_1.useState)({
10
10
  data: null,
11
11
  isLoading: false,
@@ -27,7 +27,7 @@ function useAsync({ queryKey, queryFn, enabled = true }) {
27
27
  (0, react_1.useEffect)(() => {
28
28
  if (!enabled)
29
29
  return;
30
- if (exports.cache.has(cacheKey)) {
30
+ if (!disableCache && exports.cache.has(cacheKey)) {
31
31
  setState(prev => ({
32
32
  ...prev,
33
33
  data: exports.cache.get(cacheKey),
@@ -59,7 +59,9 @@ function useAsync({ queryKey, queryFn, enabled = true }) {
59
59
  setState(prev => ({ ...prev, isLoading: true, error: null }));
60
60
  const requestPromise = queryFnRef.current()
61
61
  .then((data) => {
62
- exports.cache.set(cacheKey, data);
62
+ if (!disableCache) {
63
+ exports.cache.set(cacheKey, data);
64
+ }
63
65
  if (mountedRef.current) {
64
66
  setState({
65
67
  data,
@@ -77,18 +79,19 @@ function useAsync({ queryKey, queryFn, enabled = true }) {
77
79
  error,
78
80
  });
79
81
  }
80
- // throw error;
81
82
  })
82
83
  .finally(() => {
83
84
  exports.activeRequests.delete(cacheKey);
84
85
  });
85
86
  exports.activeRequests.set(cacheKey, requestPromise);
86
- }, [cacheKey, enabled]); // 不再依赖 queryFn
87
+ }, [cacheKey, enabled, disableCache]);
87
88
  const refetch = async () => {
88
89
  try {
89
90
  setState(prev => ({ ...prev, isLoading: true, error: null }));
90
91
  const data = await queryFnRef.current();
91
- exports.cache.set(cacheKey, data);
92
+ if (!disableCache) {
93
+ exports.cache.set(cacheKey, data);
94
+ }
92
95
  if (mountedRef.current) {
93
96
  setState({
94
97
  data,
@@ -2,18 +2,19 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useSigningClient = void 0;
4
4
  const useWalletManager_1 = require("./useWalletManager");
5
- const useRpcEndpoint_1 = require("./useRpcEndpoint");
6
5
  const useAsync_1 = require("./useAsync");
7
6
  const core_1 = require("@interchain-kit/core");
8
7
  const useSigningClient = (chainName, walletName) => {
9
- const { getSigningClient, getChainWalletState, getWalletByName } = (0, useWalletManager_1.useWalletManager)();
10
- const { rpcEndpoint } = (0, useRpcEndpoint_1.useRpcEndpoint)(chainName, walletName);
8
+ const { getSigningClient, getChainWalletState, getRpcEndpoint } = (0, useWalletManager_1.useWalletManager)();
11
9
  const chainWalletState = getChainWalletState(walletName, chainName);
12
- const wallet = getWalletByName(walletName);
13
10
  const { data, isLoading, error } = (0, useAsync_1.useAsync)({
14
11
  queryKey: `signing-client-${chainName}-${walletName}`,
15
- queryFn: () => getSigningClient(walletName, chainName),
16
- enabled: !!rpcEndpoint && chainWalletState?.walletState === core_1.WalletState.Connected
12
+ queryFn: async () => {
13
+ await getRpcEndpoint(walletName, chainName);
14
+ return getSigningClient(walletName, chainName);
15
+ },
16
+ enabled: chainWalletState?.walletState === core_1.WalletState.Connected,
17
+ disableCache: true,
17
18
  });
18
19
  return {
19
20
  signingClient: data,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@interchain-kit/react",
3
- "version": "0.2.222",
3
+ "version": "0.3.1",
4
4
  "author": "Hyperweb <developers@hyperweb.io>",
5
5
  "description": "interchain-kit wallet connector react package",
6
6
  "main": "index.js",
@@ -34,17 +34,13 @@
34
34
  "keywords": [],
35
35
  "dependencies": {
36
36
  "@chain-registry/v2-types": "^0.53.40",
37
- "@interchain-kit/core": "0.2.222",
37
+ "@interchain-kit/core": "0.3.1",
38
38
  "@interchain-ui/react": "1.26.1",
39
- "@interchainjs/cosmos": "1.10.1",
40
- "@interchainjs/cosmos-types": "1.10.1",
39
+ "@interchainjs/cosmos": "1.11.2",
40
+ "@interchainjs/cosmos-types": "1.11.2",
41
41
  "@react-icons/all-files": "^4.1.0",
42
- "@types/react": "^18.3.3",
43
- "@types/react-dom": "^18.3.0",
44
42
  "@walletconnect/types": "^2.17.3",
45
- "interchainjs": "1.10.1",
46
- "react": "^18.3.1",
47
- "react-dom": "^18.3.1",
43
+ "interchainjs": "1.11.2",
48
44
  "zustand": "^5.0.3"
49
45
  },
50
46
  "devDependencies": {
@@ -61,5 +57,11 @@
61
57
  "jest-environment-jsdom": "^29.7.0",
62
58
  "ts-jest": "^29.3.0"
63
59
  },
64
- "gitHead": "fa6f119bb50e3044e2de4a21e370ecec33937459"
60
+ "peerDependencies": {
61
+ "@types/react": "^19.0.0",
62
+ "@types/react-dom": "^19.0.0",
63
+ "react": "^19.0.0",
64
+ "react-dom": "^19.0.0"
65
+ },
66
+ "gitHead": "d0add33b6b238d50dfd9c20ba44fd558a738eea8"
65
67
  }
package/store/store.js CHANGED
@@ -5,6 +5,7 @@ const core_1 = require("@interchain-kit/core");
5
5
  const zustand_1 = require("zustand");
6
6
  const immer_1 = require("zustand/middleware/immer");
7
7
  const middleware_1 = require("zustand/middleware");
8
+ const utils_1 = require("../utils");
8
9
  const immerSyncUp = (newWalletManager) => {
9
10
  return (draft) => {
10
11
  draft.chains = newWalletManager.chains;
@@ -41,16 +42,17 @@ const createInterchainStore = (walletManager) => {
41
42
  },
42
43
  init: async () => {
43
44
  const oldChainWalletStatesMap = new Map(get().chainWalletState.map(cws => [cws.walletName + cws.chainName, cws]));
44
- set(draft => {
45
- draft.chainWalletState = [];
46
- });
47
- wallets.forEach(wallet => {
48
- chains.forEach(chain => {
45
+ // should remove wallet that already disconnected ,for hydrain back from localstorage
46
+ // const oldChainWalletStateMap = new Map()
47
+ // get().chainWalletState.forEach(cws => {
48
+ // if(cws.walletState === WalletState.Connected) {
49
+ // oldChainWalletStateMap.set(cws.walletName + cws.chainName, cws)
50
+ // }
51
+ // })
52
+ get().wallets.forEach(wallet => {
53
+ get().chains.forEach(chain => {
49
54
  set(draft => {
50
- if (oldChainWalletStatesMap.has(wallet.info.name + chain.chainName)) {
51
- draft.chainWalletState.push(oldChainWalletStatesMap.get(wallet.info.name + chain.chainName));
52
- }
53
- else {
55
+ if (!oldChainWalletStatesMap.has(wallet.info.name + chain.chainName)) {
54
56
  draft.chainWalletState.push({
55
57
  chainName: chain.chainName,
56
58
  walletName: wallet.info.name,
@@ -147,6 +149,9 @@ const createInterchainStore = (walletManager) => {
147
149
  }
148
150
  });
149
151
  });
152
+ draft.chainWalletState = draft.chainWalletState.map(cws => {
153
+ return { ...cws, rpcEndpoint: newEndpointOptions?.endpoints?.[cws.chainName]?.rpc?.[0] || cws.rpcEndpoint };
154
+ });
150
155
  });
151
156
  },
152
157
  connect: async (walletName, chainName) => {
@@ -199,7 +204,13 @@ const createInterchainStore = (walletManager) => {
199
204
  }
200
205
  },
201
206
  getRpcEndpoint: async (walletName, chainName) => {
202
- return walletManager.getRpcEndpoint(walletName, chainName);
207
+ return (0, utils_1.dedupeAsync)(`${chainName}-rpcEndpoint`, async () => {
208
+ const rpcEndpoint = await walletManager.getRpcEndpoint(walletName, chainName);
209
+ get().wallets.map(wallet => {
210
+ get().updateChainWalletState(wallet.info.name, chainName, { rpcEndpoint });
211
+ });
212
+ return rpcEndpoint;
213
+ });
203
214
  },
204
215
  getChainLogoUrl(chainName) {
205
216
  return walletManager.getChainLogoUrl(chainName);
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Deduplicate async calls to avoid multiple identical requests.
3
+ * @param key - A unique key representing the request.
4
+ * @param asyncFn - A function that returns a Promise.
5
+ * @returns A Promise resolving to the result of the async function.
6
+ */
7
+ export declare function dedupeAsync<T>(key: string, asyncFn: () => Promise<T>): Promise<T>;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dedupeAsync = dedupeAsync;
4
+ const pendingRequests = new Map();
5
+ /**
6
+ * Deduplicate async calls to avoid multiple identical requests.
7
+ * @param key - A unique key representing the request.
8
+ * @param asyncFn - A function that returns a Promise.
9
+ * @returns A Promise resolving to the result of the async function.
10
+ */
11
+ async function dedupeAsync(key, asyncFn) {
12
+ if (pendingRequests.has(key)) {
13
+ return pendingRequests.get(key);
14
+ }
15
+ const promise = asyncFn()
16
+ .finally(() => {
17
+ pendingRequests.delete(key);
18
+ });
19
+ pendingRequests.set(key, promise);
20
+ return promise;
21
+ }
package/utils/index.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export * from './wallet';
2
+ export * from './dedupeAsync';
package/utils/index.js CHANGED
@@ -15,3 +15,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./wallet"), exports);
18
+ __exportStar(require("./dedupeAsync"), exports);
@@ -1,22 +0,0 @@
1
- import { useAsync } from "./useAsync";
2
- import { useWalletManager } from "./useWalletManager";
3
- export const useRpcEndpoint = (chainName, walletName) => {
4
- const { getRpcEndpoint, updateChainWalletState, wallets } = useWalletManager();
5
- const { data, error, isLoading } = useAsync({
6
- queryKey: `rpc-endpoint-${chainName}`,
7
- queryFn: async () => {
8
- const rpc = await getRpcEndpoint(walletName, chainName);
9
- wallets.forEach(wallet => {
10
- updateChainWalletState(wallet.info.name, chainName, {
11
- rpcEndpoint: rpc
12
- });
13
- });
14
- return rpc;
15
- }
16
- });
17
- return {
18
- rpcEndpoint: data,
19
- error,
20
- isLoading
21
- };
22
- };
@@ -1,5 +0,0 @@
1
- export declare const useRpcEndpoint: (chainName: string, walletName: string) => {
2
- rpcEndpoint: string | import("@interchainjs/types").HttpEndpoint;
3
- error: Error;
4
- isLoading: boolean;
5
- };
@@ -1,26 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useRpcEndpoint = void 0;
4
- const useAsync_1 = require("./useAsync");
5
- const useWalletManager_1 = require("./useWalletManager");
6
- const useRpcEndpoint = (chainName, walletName) => {
7
- const { getRpcEndpoint, updateChainWalletState, wallets } = (0, useWalletManager_1.useWalletManager)();
8
- const { data, error, isLoading } = (0, useAsync_1.useAsync)({
9
- queryKey: `rpc-endpoint-${chainName}`,
10
- queryFn: async () => {
11
- const rpc = await getRpcEndpoint(walletName, chainName);
12
- wallets.forEach(wallet => {
13
- updateChainWalletState(wallet.info.name, chainName, {
14
- rpcEndpoint: rpc
15
- });
16
- });
17
- return rpc;
18
- }
19
- });
20
- return {
21
- rpcEndpoint: data,
22
- error,
23
- isLoading
24
- };
25
- };
26
- exports.useRpcEndpoint = useRpcEndpoint;