@interchain-kit/react 0.3.23 → 0.3.25

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,3 +3,4 @@ export * from './useChain';
3
3
  export * from './useChainWallet';
4
4
  export * from './useSigningClient';
5
5
  export * from './useAsync';
6
+ export * from './useWalletModal';
@@ -1,15 +1,15 @@
1
- import { useWalletModal } from "../modal";
2
1
  import { useWalletManager } from './useWalletManager';
3
2
  import { ChainNameNotExist } from '@interchain-kit/core';
4
3
  import { useSigningClient } from './useSigningClient';
4
+ import { useWalletModal } from './useWalletModal';
5
5
  export const useChain = (chainName) => {
6
- const { assetLists, currentWalletName, disconnect, setCurrentChainName, getChainByName, getWalletByName, getChainWalletState, getChainLogoUrl, connect, getSigningClient, getRpcEndpoint, getAccount } = useWalletManager();
6
+ const { assetLists, currentWalletName, disconnect, setCurrentChainName, getChainByName, getWalletByName, getChainWalletState, getChainLogoUrl, connect, getSigningClient, getRpcEndpoint, getAccount, getStatefulWalletByName } = useWalletManager();
7
7
  const chain = getChainByName(chainName);
8
8
  if (!chain) {
9
9
  throw new ChainNameNotExist(chainName);
10
10
  }
11
11
  const assetList = assetLists.find(a => a.chainName === chainName);
12
- const wallet = getWalletByName(currentWalletName);
12
+ const wallet = getStatefulWalletByName(currentWalletName);
13
13
  const chainWalletStateToShow = getChainWalletState(currentWalletName, chainName);
14
14
  const { open, close } = useWalletModal();
15
15
  const { signingClient, isLoading: isSigningClientLoading, error: signingClientError } = useSigningClient(chainName, currentWalletName);
@@ -1,9 +1,9 @@
1
1
  import { useWalletManager } from "./useWalletManager";
2
2
  import { useSigningClient } from "./useSigningClient";
3
3
  export const useChainWallet = (chainName, walletName) => {
4
- const { assetLists, disconnect, setCurrentChainName, setCurrentWalletName, getChainByName, getWalletByName, getChainWalletState, getChainLogoUrl, connect, getSigningClient, getRpcEndpoint, getAccount } = useWalletManager();
4
+ const { assetLists, disconnect, setCurrentChainName, setCurrentWalletName, getChainByName, getWalletByName, getChainWalletState, getChainLogoUrl, connect, getSigningClient, getRpcEndpoint, getAccount, getStatefulWalletByName } = useWalletManager();
5
5
  const chain = getChainByName(chainName);
6
- const wallet = getWalletByName(walletName);
6
+ const wallet = getStatefulWalletByName(walletName);
7
7
  const assetList = assetLists.find(a => a.chainName === chainName);
8
8
  const chainWalletStateToShow = getChainWalletState(walletName, chainName);
9
9
  const { signingClient, isLoading: isSigningClientLoading, error: signingClientError } = useSigningClient(chainName, walletName);
@@ -0,0 +1,7 @@
1
+ import { useWalletManager } from "./useWalletManager";
2
+ export const useWalletModal = () => {
3
+ const { modalIsOpen, openModal, closeModal } = useWalletManager();
4
+ return {
5
+ modalIsOpen, open: openModal, close: closeModal
6
+ };
7
+ };
@@ -1,2 +1 @@
1
1
  export * from './modal';
2
- export * from './provider';
@@ -1,15 +1,51 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { ConnectedContent, ConnectedHeader, ConnectingContent, ConnectingHeader, NotExistContent, NotExistHeader, QRCodeContent, QRCodeHeader, RejectContent, RejectHeader, WalletListContent, WalletListHeader, } from "./views";
3
- import { useMemo } from "react";
2
+ import { ConnectedContent, ConnectedHeader, ConnectingContent, ConnectingHeader, ErrorContent, ErrorHeader, NotExistContent, NotExistHeader, QRCodeContent, QRCodeHeader, RejectContent, RejectHeader, WalletListContent, WalletListHeader, } from "./views";
3
+ import { useMemo, useState } from "react";
4
+ import { WalletState } from "@interchain-kit/core";
4
5
  import { ConnectModal, } from "@interchain-ui/react";
6
+ import { useWalletManager } from "../hooks";
7
+ import { transferToWalletUISchema } from "../utils";
8
+ export const InterchainWalletModal = () => {
9
+ const [shouldShowList, setShouldShowList] = useState(false);
10
+ const { modalIsOpen: isOpen, walletConnectQRCodeUri, wallets: statefulWallets, getChainWalletState, currentWalletName, currentChainName, openModal: open, closeModal: close, chains, setCurrentWalletName, getDownloadLink, getEnv, } = useWalletManager();
11
+ const walletsForUI = statefulWallets.map((w) => transferToWalletUISchema(w));
12
+ const chainNameToConnect = currentChainName || chains[0].chainName;
13
+ const chainToConnect = chains.find((chain) => chain.chainName === chainNameToConnect);
14
+ const currentWallet = statefulWallets.find((w) => w.info.name === currentWalletName);
15
+ const { account, errorMessage } = getChainWalletState(currentWalletName, currentChainName) ||
16
+ {};
17
+ const disconnect = () => {
18
+ currentWallet.disconnect(chainToConnect.chainId);
19
+ };
20
+ const onSelectWallet = (wallet) => {
21
+ setShouldShowList(false);
22
+ return wallet.connect(chainToConnect.chainId);
23
+ };
24
+ const onBack = () => setShouldShowList(true);
25
+ const handleCloseModal = () => {
26
+ close();
27
+ setShouldShowList(false);
28
+ };
29
+ const onReconnect = () => {
30
+ currentWallet.connect(chainToConnect.chainId);
31
+ };
32
+ return (_jsx(WalletModal, { shouldShowList: shouldShowList, username: account?.username, address: account?.address, disconnect: disconnect, isOpen: isOpen, open: open, close: handleCloseModal, wallets: walletsForUI, walletConnectQRCodeUri: walletConnectQRCodeUri, currentWallet: currentWallet, isConnecting: currentWallet?.walletState === WalletState.Connecting, isConnected: currentWallet?.walletState === WalletState.Connected, isRejected: currentWallet?.walletState === WalletState.Rejected, isDisconnected: currentWallet?.walletState === WalletState.Disconnected, isNotExist: currentWallet?.walletState === WalletState.NotExist, errorMessage: errorMessage, onSelectWallet: (w) => onSelectWallet(w), onBack: () => setShouldShowList(true), onReconnect: () => onSelectWallet(currentWallet), getDownloadLink: () => getDownloadLink(currentWallet?.info.name), getEnv: getEnv }));
33
+ };
5
34
  export const WalletModal = ({ shouldShowList, isOpen, walletConnectQRCodeUri, wallets, username, address, currentWallet, isConnecting, isConnected, isRejected, isDisconnected, isNotExist, errorMessage, open, close, disconnect, onSelectWallet, onBack, onReconnect, getDownloadLink, getEnv, }) => {
6
35
  const { header, content } = useMemo(() => {
7
- if (shouldShowList || isDisconnected) {
36
+ if (shouldShowList ||
37
+ (isDisconnected && currentWallet.errorMessage === "")) {
8
38
  return {
9
39
  header: _jsx(WalletListHeader, { close: close }),
10
40
  content: (_jsx(WalletListContent, { onSelectWallet: onSelectWallet, wallets: wallets })),
11
41
  };
12
42
  }
43
+ if (currentWallet && currentWallet.errorMessage) {
44
+ return {
45
+ header: (_jsx(ErrorHeader, { wallet: currentWallet, close: close, onBack: onBack })),
46
+ content: _jsx(ErrorContent, { wallet: currentWallet, onBack: onBack }),
47
+ };
48
+ }
13
49
  if (currentWallet &&
14
50
  walletConnectQRCodeUri &&
15
51
  currentWallet.info.name === "WalletConnect") {
@@ -57,3 +93,11 @@ export const WalletModal = ({ shouldShowList, isOpen, walletConnectQRCodeUri, wa
57
93
  ]);
58
94
  return (_jsx(ConnectModal, { isOpen: isOpen, header: header, onOpen: open, onClose: close, children: content }));
59
95
  };
96
+ export const ModalRenderer = ({ walletModal: ProvidedWalletModal, }) => {
97
+ if (!ProvidedWalletModal) {
98
+ throw new Error(`InterchainWalletProvider: walletModal is required. Please provide a wallet modal component. or use InterchainkitWalletModal/n
99
+ Example: <ChainProvider chains={chains} assetLists={assetLists} wallets={wallets} walletModal={InterchainKitWalletModal} />`);
100
+ }
101
+ const { modalIsOpen, openModal, closeModal, wallets, currentWalletName } = useWalletManager();
102
+ return (_jsx(ProvidedWalletModal, { wallets: wallets, isOpen: modalIsOpen, open: openModal, close: closeModal, currentWallet: wallets.find((w) => w.info.name === currentWalletName) }));
103
+ };
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { createContext, useContext, useEffect, useRef, useState } from "react";
3
- import { WalletModal } from "./modal";
4
3
  import { WalletState } from "@interchain-kit/core";
5
4
  import { useChainWallet, useWalletManager } from "../hooks";
6
5
  import { transferToWalletUISchema } from "../utils";
6
+ import { InterchainWalletModal } from "./modal";
7
7
  const WalletModalContext = createContext(null);
8
8
  export const WalletModalProvider = ({ children, }) => {
9
9
  const [modalIsOpen, setModalIsOpen] = useState(false);
@@ -27,7 +27,7 @@ export const WalletModalProvider = ({ children, }) => {
27
27
  setCurrentWalletName(walletName);
28
28
  await connect(walletName, chainToConnect);
29
29
  };
30
- return (_jsxs(WalletModalContext.Provider, { value: { modalIsOpen, open, close }, children: [children, _jsx(WalletModal, { shouldShowList: shouldShowList, username: username, address: address, disconnect: disconnect, isOpen: modalIsOpen, open: open, close: handleCloseModal, wallets: walletsForUI, walletConnectQRCodeUri: walletConnectQRCodeUri, currentWallet: wallet, isConnecting: status === WalletState.Connecting, isConnected: status === WalletState.Connected, isRejected: status === WalletState.Rejected, isDisconnected: status === WalletState.Disconnected, isNotExist: status === WalletState.NotExist, errorMessage: message, onSelectWallet: (w) => handleConnectWallet(w.info.name), onBack: () => setShouldShowList(true), onReconnect: () => handleConnectWallet(currentWalletName), getDownloadLink: () => getDownloadLink(wallet?.info.name), getEnv: getEnv })] }));
30
+ return (_jsxs(WalletModalContext.Provider, { value: { modalIsOpen, open, close }, children: [children, _jsx(InterchainWalletModal, { shouldShowList: shouldShowList, username: username, address: address, disconnect: disconnect, isOpen: modalIsOpen, open: open, close: handleCloseModal, wallets: walletsForUI, walletConnectQRCodeUri: walletConnectQRCodeUri, currentWallet: wallet, isConnecting: status === WalletState.Connecting, isConnected: status === WalletState.Connected, isRejected: status === WalletState.Rejected, isDisconnected: status === WalletState.Disconnected, isNotExist: status === WalletState.NotExist, errorMessage: message, onSelectWallet: (w) => handleConnectWallet(w.info.name), onBack: () => setShouldShowList(true), onReconnect: () => handleConnectWallet(currentWalletName), getDownloadLink: () => getDownloadLink(wallet?.info.name), getEnv: getEnv })] }));
31
31
  };
32
32
  export const useWalletModal = () => {
33
33
  const context = useContext(WalletModalContext);
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { ConnectModalHead, ConnectModalStatus } from "@interchain-ui/react";
3
+ import { getWalletInfo } from "../../utils";
4
+ export const ErrorHeader = ({ wallet, close, onBack, }) => {
5
+ return (_jsx(ConnectModalHead, { title: wallet.info.prettyName, hasBackButton: true, onClose: close, onBack: onBack, closeButtonProps: { onClick: close } }));
6
+ };
7
+ export const ErrorContent = ({ wallet, onBack, }) => {
8
+ return (_jsx(ConnectModalStatus, { status: "Error", wallet: getWalletInfo(wallet), contentHeader: "Oops! Something wrong...", contentDesc: wallet.errorMessage, onChangeWallet: onBack }));
9
+ };
@@ -4,3 +4,4 @@ export * from './Connected';
4
4
  export * from './Reject';
5
5
  export * from './QRCode';
6
6
  export * from './NotExist';
7
+ export * from './Error';
package/esm/provider.js CHANGED
@@ -1,11 +1,11 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useRef } from "react";
3
3
  import { createContext, useContext } from "react";
4
4
  import { WalletManager, } from "@interchain-kit/core";
5
- import { WalletModalProvider } from "./modal";
5
+ import { ModalRenderer } from "./modal";
6
6
  import { createInterchainStore } from "./store";
7
7
  const InterchainWalletContext = createContext(null);
8
- export const ChainProvider = ({ chains, assetLists, wallets, signerOptions, endpointOptions, children, }) => {
8
+ export const ChainProvider = ({ chains, assetLists, wallets, signerOptions, endpointOptions, children, walletModal: ProviderWalletModal, }) => {
9
9
  // const [_, forceRender] = useState({});
10
10
  const walletManager = new WalletManager(chains, assetLists, wallets, signerOptions, endpointOptions);
11
11
  const store = useRef(createInterchainStore(walletManager));
@@ -13,7 +13,7 @@ export const ChainProvider = ({ chains, assetLists, wallets, signerOptions, endp
13
13
  // walletManager.init();
14
14
  store.current.getState().init();
15
15
  }, []);
16
- return (_jsx(InterchainWalletContext.Provider, { value: store.current, children: _jsx(WalletModalProvider, { children: children }) }));
16
+ return (_jsxs(InterchainWalletContext.Provider, { value: store.current, children: [children, _jsx(ModalRenderer, { walletModal: ProviderWalletModal })] }));
17
17
  };
18
18
  export const useInterchainWalletContext = () => {
19
19
  const context = useContext(InterchainWalletContext);
@@ -0,0 +1,117 @@
1
+ import { BaseWallet, WalletState, WCWallet } from "@interchain-kit/core";
2
+ export class StatefulWallet extends BaseWallet {
3
+ originalWallet;
4
+ walletName;
5
+ walletSet;
6
+ walletGet;
7
+ set;
8
+ get;
9
+ constructor(wallet, walletSet, walletGet, set, get) {
10
+ super(wallet.info);
11
+ this.originalWallet = wallet;
12
+ this.walletName = wallet.info.name;
13
+ this.walletState = WalletState.Disconnected;
14
+ this.errorMessage = "";
15
+ this.walletSet = walletSet;
16
+ this.walletGet = walletGet;
17
+ this.set = set;
18
+ this.get = get;
19
+ }
20
+ getChainToConnect(chainId) {
21
+ const { currentChainName, chains } = this.get();
22
+ const lastChainName = currentChainName;
23
+ const lastChain = chains.find((chain) => chain.chainName === lastChainName);
24
+ return chainId ? this.originalWallet.getChainById(chainId) : lastChain;
25
+ }
26
+ async init() {
27
+ return this.originalWallet.init();
28
+ }
29
+ async connect(chainId) {
30
+ const { get, set, walletName, walletGet, walletSet, originalWallet } = this;
31
+ const chainToConnect = this.getChainToConnect(chainId);
32
+ const state = get().getChainWalletState(walletName, chainToConnect.chainName)?.walletState;
33
+ if (state === WalletState.NotExist) {
34
+ return;
35
+ }
36
+ if (walletName === 'WalletConnect' && state === WalletState.Connected) {
37
+ return;
38
+ }
39
+ set(draft => {
40
+ draft.currentChainName = chainToConnect.chainName;
41
+ draft.currentWalletName = walletName;
42
+ draft.walletConnectQRCodeUri = '';
43
+ });
44
+ walletSet(draft => {
45
+ draft.walletState = WalletState.Connecting;
46
+ });
47
+ get().updateChainWalletState(walletName, chainToConnect.chainName, { walletState: WalletState.Connecting, errorMessage: '' });
48
+ try {
49
+ if (originalWallet instanceof WCWallet) {
50
+ originalWallet.setOnPairingUriCreatedCallback((uri) => {
51
+ set(draft => {
52
+ draft.walletConnectQRCodeUri = uri;
53
+ });
54
+ });
55
+ }
56
+ await originalWallet.connect(chainToConnect.chainId);
57
+ get().updateChainWalletState(walletName, chainToConnect.chainName, { walletState: WalletState.Connected });
58
+ walletSet(draft => {
59
+ draft.walletState = WalletState.Connected;
60
+ });
61
+ await walletGet().getAccount(chainToConnect.chainId);
62
+ }
63
+ catch (error) {
64
+ if (error.message === 'Request rejected') {
65
+ get().updateChainWalletState(walletName, chainToConnect.chainName, { walletState: WalletState.Rejected, errorMessage: error.message });
66
+ walletSet(draft => {
67
+ draft.walletState = WalletState.Rejected;
68
+ draft.errorMessage = error.message;
69
+ });
70
+ return;
71
+ }
72
+ get().updateChainWalletState(walletName, chainToConnect.chainName, { walletState: WalletState.Disconnected, errorMessage: error.message });
73
+ walletSet(draft => {
74
+ draft.walletState = WalletState.Disconnected;
75
+ draft.errorMessage = error.message;
76
+ });
77
+ }
78
+ }
79
+ async disconnect(chainId) {
80
+ const { get, walletName, walletSet, originalWallet } = this;
81
+ const chainToConnect = this.getChainToConnect(chainId);
82
+ try {
83
+ await originalWallet.disconnect(chainToConnect.chainId);
84
+ get().updateChainWalletState(walletName, chainToConnect.chainName, { walletState: WalletState.Disconnected, account: null });
85
+ walletSet(draft => {
86
+ draft.walletState = WalletState.Disconnected;
87
+ draft.errorMessage = "";
88
+ });
89
+ }
90
+ catch (error) {
91
+ }
92
+ }
93
+ async getAccount(chainId) {
94
+ const chainToConnect = this.getChainToConnect(chainId);
95
+ const { get, walletName, originalWallet } = this;
96
+ try {
97
+ const account = await originalWallet.getAccount(chainToConnect.chainId);
98
+ get().updateChainWalletState(walletName, chainToConnect.chainName, { account });
99
+ return account;
100
+ }
101
+ catch (error) {
102
+ console.log(error);
103
+ }
104
+ }
105
+ getOfflineSigner(chainId) {
106
+ return this.originalWallet.getOfflineSigner(chainId);
107
+ }
108
+ addSuggestChain(chainId) {
109
+ return this.originalWallet.addSuggestChain(chainId);
110
+ }
111
+ getProvider(chainId) {
112
+ return this.originalWallet.getProvider(chainId);
113
+ }
114
+ getChainById(chainId) {
115
+ return this.originalWallet.getChainById(chainId);
116
+ }
117
+ }
@@ -1,9 +1,9 @@
1
- import { clientNotExistError, WalletState, WCWallet } from "@interchain-kit/core";
1
+ 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
5
  import { dedupeAsync } from '../utils';
6
- import { decorateWallet } from '../utils/decorateWallet';
6
+ import { StatefulWallet } from './stateful-wallet';
7
7
  const immerSyncUp = (newWalletManager) => {
8
8
  return (draft) => {
9
9
  draft.chains = newWalletManager.chains;
@@ -17,15 +17,18 @@ const immerSyncUp = (newWalletManager) => {
17
17
  };
18
18
  };
19
19
  export const createInterchainStore = (walletManager) => {
20
- const { chains, assetLists, wallets, signerOptions, endpointOptions } = walletManager;
21
- // const walletManager = new WalletManager(chains, assetLists, wallets, signerOptions, endpointOptions)
22
20
  return createStore(persist(immer((set, get) => ({
23
21
  chainWalletState: [],
24
22
  currentWalletName: '',
25
23
  currentChainName: '',
26
24
  chains: [...walletManager.chains],
27
25
  assetLists: [...walletManager.assetLists],
28
- wallets: [],
26
+ wallets: walletManager.wallets.map(wallet => {
27
+ const walletSet = (fn) => {
28
+ set((draft) => fn(draft.wallets.find(w => w.info.name === wallet.info.name)));
29
+ };
30
+ return new StatefulWallet(wallet, walletSet, () => get().wallets.find(w => w.info.name === wallet.info.name), set, get);
31
+ }),
29
32
  signerOptions: walletManager.signerOptions,
30
33
  endpointOptions: walletManager.endpointOptions,
31
34
  preferredSignTypeMap: { ...walletManager.preferredSignTypeMap },
@@ -33,151 +36,49 @@ export const createInterchainStore = (walletManager) => {
33
36
  endpointOptionsMap: { ...walletManager.endpointOptionsMap },
34
37
  walletConnectQRCodeUri: '',
35
38
  isReady: false,
36
- updateWalletState: (walletName, data) => {
39
+ modalIsOpen: false,
40
+ openModal: () => {
37
41
  set(draft => {
38
- let targetWalletIndex = draft.wallets.findIndex(w => w.info.name === walletName);
39
- draft.wallets[targetWalletIndex].walletState = data.walletState;
42
+ draft.modalIsOpen = true;
43
+ });
44
+ },
45
+ closeModal: () => {
46
+ set(draft => {
47
+ draft.modalIsOpen = false;
48
+ draft.walletConnectQRCodeUri = ''; // reset the QR code uri when modal is closed
40
49
  });
41
50
  },
42
51
  updateChainWalletState: (walletName, chainName, data) => {
43
52
  set(draft => {
44
53
  let targetIndex = draft.chainWalletState.findIndex(cws => cws.walletName === walletName && cws.chainName === chainName);
45
54
  draft.chainWalletState[targetIndex] = { ...draft.chainWalletState[targetIndex], ...data };
46
- if (data.walletState) {
47
- get().updateWalletState(walletName, data);
48
- }
49
55
  });
50
56
  },
51
57
  createStatefulWallet: () => {
52
58
  const wallets = walletManager.wallets.map(wallet => {
53
- // safeStrictBatchPatch(wallet, {
54
- // connect: async (original, chainId) => {
55
- // const walletName = wallet.info.name
56
- // const chainName = get().chains.find(chain => chain.chainId === chainId)?.chainName
57
- // const state = get().getChainWalletState(walletName, chainName)?.walletState
58
- // if (state === WalletState.NotExist) {
59
- // return
60
- // }
61
- // if (walletName === 'WalletConnect' && state === WalletState.Connected) {
62
- // return
63
- // }
64
- // set(draft => {
65
- // draft.currentChainName = chainName
66
- // draft.currentWalletName = walletName
67
- // draft.walletConnectQRCodeUri = ''
68
- // })
69
- // get().updateChainWalletState(walletName, chainName, { walletState: WalletState.Connecting, errorMessage: '' })
70
- // try {
71
- // if (wallet instanceof WCWallet) {
72
- // wallet.setOnPairingUriCreatedCallback((uri) => {
73
- // set(draft => {
74
- // draft.walletConnectQRCodeUri = uri
75
- // })
76
- // })
77
- // }
78
- // await original(chainId)
79
- // get().updateChainWalletState(walletName, chainName, { walletState: WalletState.Connected })
80
- // await get().getAccount(walletName, chainName)
81
- // } catch (error) {
82
- // if ((error as any).message === 'Request rejected') {
83
- // get().updateChainWalletState(walletName, chainName, { walletState: WalletState.Rejected, errorMessage: (error as any).message })
84
- // return
85
- // }
86
- // get().updateChainWalletState(walletName, chainName, { walletState: WalletState.Disconnected, errorMessage: (error as any).message })
87
- // }
88
- // },
89
- // disconnect: async (original, chainId) => {
90
- // const walletName = wallet.info.name
91
- // const chainName = get().chains.find(chain => chain.chainId === chainId)?.chainName
92
- // try {
93
- // await original(chainId)
94
- // get().updateChainWalletState(walletName, chainName, { walletState: WalletState.Disconnected, account: null })
95
- // } catch (error) {
96
- // }
97
- // },
98
- // getAccount: async (original, chainId) => {
99
- // const walletName = wallet.info.name
100
- // const chainName = get().chains.find(chain => chain.chainId === chainId)?.chainName
101
- // try {
102
- // const account = await original(chainId)
103
- // get().updateChainWalletState(walletName, chainName, { account })
104
- // return account
105
- // } catch (error) {
106
- // console.log(error)
107
- // }
108
- // },
109
- // walletState: get().getChainWalletState(wallet.info.name, walletManager.chains?.[0].chainName)?.walletState || WalletState.Disconnected
110
- // })
111
- // return wallet
112
- return decorateWallet(wallet, {
113
- connect: async (chainId) => {
114
- const walletName = wallet.info.name;
115
- const chainName = get().chains.find(chain => chain.chainId === chainId)?.chainName;
116
- const state = get().getChainWalletState(walletName, chainName)?.walletState;
117
- if (state === WalletState.NotExist) {
118
- return;
119
- }
120
- if (walletName === 'WalletConnect' && state === WalletState.Connected) {
121
- return;
122
- }
123
- set(draft => {
124
- draft.currentChainName = chainName;
125
- draft.currentWalletName = walletName;
126
- draft.walletConnectQRCodeUri = '';
127
- });
128
- get().updateChainWalletState(walletName, chainName, { walletState: WalletState.Connecting, errorMessage: '' });
129
- try {
130
- if (wallet instanceof WCWallet) {
131
- wallet.setOnPairingUriCreatedCallback((uri) => {
132
- set(draft => {
133
- draft.walletConnectQRCodeUri = uri;
134
- });
135
- });
136
- }
137
- await wallet.connect(chainId);
138
- get().updateChainWalletState(walletName, chainName, { walletState: WalletState.Connected });
139
- await get().getAccount(walletName, chainName);
140
- }
141
- catch (error) {
142
- if (error.message === 'Request rejected') {
143
- get().updateChainWalletState(walletName, chainName, { walletState: WalletState.Rejected, errorMessage: error.message });
144
- return;
145
- }
146
- get().updateChainWalletState(walletName, chainName, { walletState: WalletState.Disconnected, errorMessage: error.message });
147
- }
148
- },
149
- disconnect: async (chainId) => {
150
- const walletName = wallet.info.name;
151
- const chainName = get().chains.find(chain => chain.chainId === chainId)?.chainName;
152
- try {
153
- await wallet.disconnect(chainId);
154
- get().updateChainWalletState(walletName, chainName, { walletState: WalletState.Disconnected, account: null });
155
- }
156
- catch (error) {
157
- }
158
- },
159
- getAccount: async (chainId) => {
160
- const walletName = wallet.info.name;
161
- const chainName = get().chains.find(chain => chain.chainId === chainId)?.chainName;
162
- try {
163
- const account = await wallet.getAccount(chainId);
164
- get().updateChainWalletState(walletName, chainName, { account });
165
- return account;
166
- }
167
- catch (error) {
168
- console.log(error);
169
- }
170
- },
171
- walletState: get().getChainWalletState(wallet.info.name, walletManager.chains?.[0].chainName)?.walletState || WalletState.Disconnected
172
- });
59
+ const walletSet = (fn) => {
60
+ set((draft) => fn(draft.wallets.find(w => w.info.name === wallet.info.name)));
61
+ };
62
+ return new StatefulWallet(wallet, walletSet, () => get().wallets.find(w => w.info.name === wallet.info.name), set, get);
173
63
  });
174
64
  set(draft => {
175
65
  draft.wallets = wallets;
176
66
  });
67
+ const defaultWalletStates = get().chainWalletState.reduce((acc, cws) => {
68
+ if (acc[cws.walletName] && cws.walletState === WalletState.Connected) {
69
+ return acc;
70
+ }
71
+ return { ...acc, [cws.walletName]: cws.walletState };
72
+ }, {});
73
+ set(draft => {
74
+ draft.wallets.forEach(wallet => {
75
+ wallet.walletState = defaultWalletStates[wallet.info.name];
76
+ });
77
+ });
177
78
  },
178
79
  init: async () => {
179
80
  const oldChainWalletStatesMap = new Map(get().chainWalletState.map(cws => [cws.walletName + cws.chainName, cws]));
180
- get().createStatefulWallet();
81
+ // get().createStatefulWallet()
181
82
  // should remove wallet that already disconnected ,for hydrain back from localstorage
182
83
  // const oldChainWalletStateMap = new Map()
183
84
  // get().chainWalletState.forEach(cws => {
@@ -217,7 +118,6 @@ export const createInterchainStore = (walletManager) => {
217
118
  set(draft => {
218
119
  draft.chainWalletState = draft.chainWalletState.map(cws => {
219
120
  if (NotExistWallets.includes(cws.walletName)) {
220
- get().updateWalletState(cws.walletName, { walletState: WalletState.NotExist });
221
121
  return { ...cws, walletState: WalletState.NotExist };
222
122
  }
223
123
  return cws;
@@ -225,7 +125,6 @@ export const createInterchainStore = (walletManager) => {
225
125
  draft.chainWalletState = draft.chainWalletState.map(cws => {
226
126
  if (ExistWallets.includes(cws.walletName)) {
227
127
  const newState = cws.walletState === WalletState.NotExist ? WalletState.Disconnected : cws.walletState;
228
- get().updateWalletState(cws.walletName, { walletState: newState });
229
128
  return { ...cws, walletState: newState };
230
129
  }
231
130
  return cws;
@@ -295,53 +194,37 @@ export const createInterchainStore = (walletManager) => {
295
194
  });
296
195
  },
297
196
  connect: async (walletName, chainName) => {
298
- const state = get().getChainWalletState(walletName, chainName)?.walletState;
299
- if (state === WalletState.NotExist) {
300
- return;
301
- }
302
- if (walletName === 'WalletConnect' && state === WalletState.Connected) {
303
- return;
304
- }
305
- set(draft => {
306
- draft.currentChainName = chainName;
307
- draft.currentWalletName = walletName;
308
- draft.walletConnectQRCodeUri = '';
309
- });
310
- get().updateChainWalletState(walletName, chainName, { walletState: WalletState.Connecting, errorMessage: '' });
311
- try {
312
- await walletManager.connect(walletName, chainName, (uri) => {
313
- set(draft => {
314
- draft.walletConnectQRCodeUri = uri;
315
- });
316
- });
317
- get().updateChainWalletState(walletName, chainName, { walletState: WalletState.Connected });
318
- await get().getAccount(walletName, chainName);
197
+ const wallet = get().wallets.find(w => w.info.name === walletName);
198
+ const chain = get().chains.find(c => c.chainName === chainName);
199
+ if (!wallet) {
200
+ throw new Error(`Wallet ${walletName} not found`);
319
201
  }
320
- catch (error) {
321
- if (error.message === 'Request rejected') {
322
- get().updateChainWalletState(walletName, chainName, { walletState: WalletState.Rejected, errorMessage: error.message });
323
- return;
324
- }
325
- get().updateChainWalletState(walletName, chainName, { walletState: WalletState.Disconnected, errorMessage: error.message });
202
+ if (!chain) {
203
+ throw new Error(`Chain ${chainName} not found`);
326
204
  }
205
+ return wallet.connect(chain.chainId);
327
206
  },
328
207
  disconnect: async (walletName, chainName) => {
329
- try {
330
- await walletManager.disconnect(walletName, chainName);
331
- get().updateChainWalletState(walletName, chainName, { walletState: WalletState.Disconnected, account: null });
208
+ const wallet = get().wallets.find(w => w.info.name === walletName);
209
+ const chain = get().chains.find(c => c.chainName === chainName);
210
+ if (!wallet) {
211
+ throw new Error(`Wallet ${walletName} not found`);
332
212
  }
333
- catch (error) {
213
+ if (!chain) {
214
+ throw new Error(`Chain ${chainName} not found`);
334
215
  }
216
+ return wallet.disconnect(chain.chainId);
335
217
  },
336
218
  getAccount: async (walletName, chainName) => {
337
- try {
338
- const account = await walletManager.getAccount(walletName, chainName);
339
- get().updateChainWalletState(walletName, chainName, { account });
340
- return account;
219
+ const wallet = get().wallets.find(w => w.info.name === walletName);
220
+ const chain = get().chains.find(c => c.chainName === chainName);
221
+ if (!wallet) {
222
+ throw new Error(`Wallet ${walletName} not found`);
341
223
  }
342
- catch (error) {
343
- console.log(error);
224
+ if (!chain) {
225
+ throw new Error(`Chain ${chainName} not found`);
344
226
  }
227
+ return wallet.getAccount(chain.chainId);
345
228
  },
346
229
  getRpcEndpoint: async (walletName, chainName) => {
347
230
  return dedupeAsync(`${chainName}-rpcEndpoint`, async () => {
@@ -380,6 +263,9 @@ export const createInterchainStore = (walletManager) => {
380
263
  getWalletByName(walletName) {
381
264
  return walletManager.getWalletByName(walletName);
382
265
  },
266
+ getStatefulWalletByName(walletName) {
267
+ return get().wallets.find(w => w.info.name === walletName);
268
+ },
383
269
  async getSigningClient(walletName, chainName) {
384
270
  return walletManager.getSigningClient(walletName, chainName);
385
271
  },
package/hooks/index.d.ts CHANGED
@@ -3,3 +3,4 @@ export * from './useChain';
3
3
  export * from './useChainWallet';
4
4
  export * from './useSigningClient';
5
5
  export * from './useAsync';
6
+ export * from './useWalletModal';
package/hooks/index.js CHANGED
@@ -19,3 +19,4 @@ __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("./useWalletModal"), exports);