@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.
- package/esm/hooks/index.js +0 -1
- package/esm/hooks/useAsync.js +9 -6
- package/esm/hooks/useSigningClient.js +7 -6
- package/esm/store/store.js +11 -1
- package/esm/utils/dedupeAsync.js +18 -0
- package/esm/utils/index.js +1 -0
- package/hooks/index.d.ts +0 -1
- package/hooks/index.js +0 -1
- package/hooks/useAsync.d.ts +6 -1
- package/hooks/useAsync.js +9 -6
- package/hooks/useSigningClient.js +7 -6
- package/package.json +12 -10
- package/store/store.js +11 -1
- package/utils/dedupeAsync.d.ts +7 -0
- package/utils/dedupeAsync.js +21 -0
- package/utils/index.d.ts +1 -0
- package/utils/index.js +1 -0
- package/esm/hooks/useRpcEndpoint.js +0 -22
- package/hooks/useRpcEndpoint.d.ts +0 -5
- package/hooks/useRpcEndpoint.js +0 -26
package/esm/hooks/index.js
CHANGED
package/esm/hooks/useAsync.js
CHANGED
|
@@ -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
|
-
|
|
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]);
|
|
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
|
-
|
|
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,
|
|
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: () =>
|
|
13
|
-
|
|
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,
|
package/esm/store/store.js
CHANGED
|
@@ -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
|
|
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
|
+
}
|
package/esm/utils/index.js
CHANGED
package/hooks/index.d.ts
CHANGED
package/hooks/index.js
CHANGED
package/hooks/useAsync.d.ts
CHANGED
|
@@ -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
|
-
|
|
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]);
|
|
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
|
-
|
|
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,
|
|
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: () =>
|
|
16
|
-
|
|
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.
|
|
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.
|
|
37
|
+
"@interchain-kit/core": "0.3.0",
|
|
38
38
|
"@interchain-ui/react": "1.26.1",
|
|
39
|
-
"@interchainjs/cosmos": "1.
|
|
40
|
-
"@interchainjs/cosmos-types": "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.
|
|
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
|
-
"
|
|
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
|
|
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
package/utils/index.js
CHANGED
|
@@ -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
|
-
};
|
package/hooks/useRpcEndpoint.js
DELETED
|
@@ -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;
|