@interchain-kit/react 0.2.222 → 0.3.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.
@@ -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;
@@ -144,6 +145,9 @@ export const createInterchainStore = (walletManager) => {
144
145
  }
145
146
  });
146
147
  });
148
+ draft.chainWalletState = draft.chainWalletState.map(cws => {
149
+ return { ...cws, rpcEndpoint: newEndpointOptions?.endpoints?.[cws.chainName]?.rpc?.[0] || cws.rpcEndpoint };
150
+ });
147
151
  });
148
152
  },
149
153
  connect: async (walletName, chainName) => {
@@ -196,7 +200,13 @@ export const createInterchainStore = (walletManager) => {
196
200
  }
197
201
  },
198
202
  getRpcEndpoint: async (walletName, chainName) => {
199
- return walletManager.getRpcEndpoint(walletName, chainName);
203
+ return dedupeAsync(`${chainName}-rpcEndpoint`, async () => {
204
+ const rpcEndpoint = await walletManager.getRpcEndpoint(walletName, chainName);
205
+ get().wallets.map(wallet => {
206
+ get().updateChainWalletState(wallet.info.name, chainName, { rpcEndpoint });
207
+ });
208
+ return rpcEndpoint;
209
+ });
200
210
  },
201
211
  getChainLogoUrl(chainName) {
202
212
  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.0",
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.0",
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": "2fa62ae0dbeb2833b55d59c0cfe8446d1c7a7b06"
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;
@@ -147,6 +148,9 @@ const createInterchainStore = (walletManager) => {
147
148
  }
148
149
  });
149
150
  });
151
+ draft.chainWalletState = draft.chainWalletState.map(cws => {
152
+ return { ...cws, rpcEndpoint: newEndpointOptions?.endpoints?.[cws.chainName]?.rpc?.[0] || cws.rpcEndpoint };
153
+ });
150
154
  });
151
155
  },
152
156
  connect: async (walletName, chainName) => {
@@ -199,7 +203,13 @@ const createInterchainStore = (walletManager) => {
199
203
  }
200
204
  },
201
205
  getRpcEndpoint: async (walletName, chainName) => {
202
- return walletManager.getRpcEndpoint(walletName, chainName);
206
+ return (0, utils_1.dedupeAsync)(`${chainName}-rpcEndpoint`, async () => {
207
+ const rpcEndpoint = await walletManager.getRpcEndpoint(walletName, chainName);
208
+ get().wallets.map(wallet => {
209
+ get().updateChainWalletState(wallet.info.name, chainName, { rpcEndpoint });
210
+ });
211
+ return rpcEndpoint;
212
+ });
203
213
  },
204
214
  getChainLogoUrl(chainName) {
205
215
  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;