{
status: string;
message: string;
@@ -29,7 +31,7 @@ export async function queryExplorer(
throw new Error(`No URL found for explorer for chain ${chainName}`);
let url = `${baseUrl}/${path}`;
- console.debug('Querying explorer url:', url);
+ widgetLogger.debug('Querying explorer url:', url);
if (apiKey) {
url += `&apikey=${apiKey}`;
@@ -76,7 +78,7 @@ export async function queryExplorerForBlock(
);
if (!block?.number || parseInt(block.number.toString()) < 0) {
const msg = 'Invalid block result';
- console.error(msg, JSON.stringify(block), path);
+ widgetLogger.error(msg, JSON.stringify(block), path);
throw new Error(msg);
}
return block;
diff --git a/typescript/widgets/src/utils/useChainConnectionTest.ts b/typescript/widgets/src/utils/useChainConnectionTest.ts
index 920b2e7dd..6892fb83b 100644
--- a/typescript/widgets/src/utils/useChainConnectionTest.ts
+++ b/typescript/widgets/src/utils/useChainConnectionTest.ts
@@ -26,7 +26,7 @@ export function useConnectionHealthTest(
timeout(tester(chainMetadata, index), HEALTH_TEST_TIMEOUT)
.then((result) => setIsHealthy(result))
.catch(() => setIsHealthy(false));
- }, [chainMetadata, index, tester]);
+ }, [chainMetadata, index, type, tester]);
return isHealthy;
}
diff --git a/typescript/widgets/src/walletIntegrations/AccountList.tsx b/typescript/widgets/src/walletIntegrations/AccountList.tsx
new file mode 100644
index 000000000..db99a33a4
--- /dev/null
+++ b/typescript/widgets/src/walletIntegrations/AccountList.tsx
@@ -0,0 +1,143 @@
+import clsx from 'clsx';
+import React, { ButtonHTMLAttributes } from 'react';
+
+import { MultiProtocolProvider } from '@hyperlane-xyz/sdk';
+import { ProtocolType, objKeys } from '@hyperlane-xyz/utils';
+
+import { Button } from '../components/Button.js';
+import { IconButton } from '../components/IconButton.js';
+import { LogoutIcon } from '../icons/Logout.js';
+import { WalletIcon } from '../icons/Wallet.js';
+import { XCircleIcon } from '../icons/XCircle.js';
+import { widgetLogger } from '../logger.js';
+import { tryClipboardSet } from '../utils/clipboard.js';
+import { WalletLogo } from '../walletIntegrations/WalletLogo.js';
+import {
+ useAccounts,
+ useDisconnectFns,
+ useWalletDetails,
+} from '../walletIntegrations/multiProtocol.js';
+
+import { AccountInfo, WalletDetails } from './types.js';
+
+const logger = widgetLogger.child({ module: 'walletIntegrations/AccountList' });
+
+export function AccountList({
+ multiProvider,
+ onClickConnectWallet,
+ onCopySuccess,
+ className,
+}: {
+ multiProvider: MultiProtocolProvider;
+ onClickConnectWallet: () => void;
+ onCopySuccess?: () => void;
+ className?: string;
+}) {
+ const { readyAccounts } = useAccounts(multiProvider);
+ const disconnectFns = useDisconnectFns();
+ const walletDetails = useWalletDetails();
+
+ const onClickDisconnect = async (protocol: ProtocolType) => {
+ try {
+ const disconnectFn = disconnectFns[protocol];
+ if (disconnectFn) await disconnectFn();
+ } catch (error) {
+ logger.error('Error disconnecting wallet', error);
+ }
+ };
+
+ const onClickDisconnectAll = async () => {
+ for (const protocol of objKeys(disconnectFns)) {
+ await onClickDisconnect(protocol);
+ }
+ };
+
+ return (
+
+ {readyAccounts.map((acc, i) => (
+
onClickDisconnect(acc.protocol)}
+ />
+ ))}
+