@reown/appkit-controllers
Version:
#### 🔗 [Website](https://reown.com/appkit)
153 lines • 6.84 kB
JavaScript
import { useCallback, useState } from 'react';
import { useSnapshot } from 'valtio';
import { ConstantsUtil } from '@reown/appkit-common';
import { AssetController } from '../src/controllers/AssetController.js';
import { ChainController } from '../src/controllers/ChainController.js';
import { ConnectionController } from '../src/controllers/ConnectionController.js';
import { ConnectorController } from '../src/controllers/ConnectorController.js';
import { ConnectionControllerUtil } from '../src/utils/ConnectionControllerUtil.js';
import { CoreHelperUtil } from '../src/utils/CoreHelperUtil.js';
import { AssetUtil, StorageUtil } from './utils.js';
// -- Hooks ------------------------------------------------------------
export function useAppKitNetworkCore() {
const { activeCaipNetwork } = useSnapshot(ChainController.state);
return {
caipNetwork: activeCaipNetwork,
chainId: activeCaipNetwork?.id,
caipNetworkId: activeCaipNetwork?.caipNetworkId
};
}
export function useAppKitAccount(options) {
const state = useSnapshot(ChainController.state);
const chainNamespace = options?.namespace || state.activeChain;
if (!chainNamespace) {
return {
allAccounts: [],
address: undefined,
caipAddress: undefined,
status: undefined,
isConnected: false,
embeddedWalletInfo: undefined
};
}
const chainAccountState = state.chains.get(chainNamespace)?.accountState;
const authConnector = ConnectorController.getAuthConnector(chainNamespace);
const activeConnectorId = StorageUtil.getConnectedConnectorId(chainNamespace);
return {
allAccounts: chainAccountState?.allAccounts || [],
caipAddress: chainAccountState?.caipAddress,
address: CoreHelperUtil.getPlainAddress(chainAccountState?.caipAddress),
isConnected: Boolean(chainAccountState?.caipAddress),
status: chainAccountState?.status,
embeddedWalletInfo: authConnector && activeConnectorId === ConstantsUtil.CONNECTOR_ID.AUTH
? {
user: chainAccountState?.user
? {
...chainAccountState.user,
/*
* Getting the username from the chain controller works well for social logins,
* but Farcaster uses a different connection flow and doesn’t emit the username via events.
* Since the username is stored in local storage before the chain controller updates,
* it’s safe to use the local storage value here.
*/
username: StorageUtil.getConnectedSocialUsername()
}
: undefined,
authProvider: chainAccountState?.socialProvider || 'email',
accountType: chainAccountState?.preferredAccountTypes?.[chainNamespace],
isSmartAccountDeployed: Boolean(chainAccountState?.smartAccountDeployed)
}
: undefined
};
}
export function useDisconnect() {
async function disconnect(props) {
await ConnectionController.disconnect(props);
}
return { disconnect };
}
export function useAppKitConnections(namespace) {
// Snapshots to trigger re-renders on state changes
useSnapshot(ConnectionController.state);
useSnapshot(ConnectorController.state);
useSnapshot(AssetController.state);
const { activeChain } = useSnapshot(ChainController.state);
const chainNamespace = namespace ?? activeChain;
if (!chainNamespace) {
throw new Error('No namespace found');
}
const { connections, recentConnections } = ConnectionControllerUtil.getConnectionsData(chainNamespace);
const formatConnection = useCallback((connection) => {
const connector = ConnectorController.getConnectorById(connection.connectorId);
const name = ConnectorController.getConnectorName(connector?.name);
const icon = AssetUtil.getConnectorImage(connector);
const networkImage = AssetUtil.getNetworkImage(connection.caipNetwork);
return {
name,
icon,
networkIcon: networkImage,
...connection
};
}, []);
return {
connections: connections.map(formatConnection),
recentConnections: recentConnections.map(formatConnection)
};
}
export function useAppKitConnection({ namespace, onSuccess, onError }) {
const [, forceUpdate] = useState(0);
const { connections, isSwitchingConnection } = useSnapshot(ConnectionController.state);
const { activeConnectorIds } = useSnapshot(ConnectorController.state);
const { activeChain } = useSnapshot(ChainController.state);
const chainNamespace = namespace ?? activeChain;
if (!chainNamespace) {
throw new Error('No namespace found');
}
const connectorId = activeConnectorIds[chainNamespace];
const connList = connections.get(chainNamespace);
const connection = connList?.find(c => c.connectorId.toLowerCase() === connectorId?.toLowerCase());
const switchConnection = useCallback(async ({ connection: _connection, address }) => {
try {
ConnectionController.setIsSwitchingConnection(true);
await ConnectionController.switchConnection({
connection: _connection,
address,
namespace: chainNamespace,
onChange({ address: newAddress, namespace: newNamespace, hasSwitchedAccount, hasSwitchedWallet }) {
onSuccess?.({
address: newAddress,
namespace: newNamespace,
hasSwitchedAccount,
hasSwitchedWallet,
hasDeletedWallet: false
});
}
});
}
catch (err) {
const error = err instanceof Error ? err : new Error('Something went wrong');
onError?.(error);
}
finally {
ConnectionController.setIsSwitchingConnection(false);
}
}, [chainNamespace, onSuccess, onError]);
const deleteConnection = useCallback(({ address, connectorId }) => {
StorageUtil.deleteAddressFromConnection({ connectorId, address, namespace: chainNamespace });
onSuccess?.({
address,
namespace: chainNamespace,
hasSwitchedAccount: false,
hasSwitchedWallet: false,
hasDeletedWallet: true
});
forceUpdate(prev => prev + 1);
}, [chainNamespace]);
return {
connection,
isPending: isSwitchingConnection,
switchConnection,
deleteConnection
};
}
//# sourceMappingURL=react.js.map