Skip to content

Commit

Permalink
wip: wc pairing list and slices
Browse files Browse the repository at this point in the history
  • Loading branch information
dianasavvatina committed Oct 2, 2024
1 parent 6ff0ebf commit f5056e3
Show file tree
Hide file tree
Showing 22 changed files with 447 additions and 51 deletions.
13 changes: 10 additions & 3 deletions apps/desktop/src/Router.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
/* istanbul ignore file */
import { DynamicModalContext, useDynamicModal } from "@umami/components";
import { useDataPolling } from "@umami/data-polling";
import { WalletClient, useImplicitAccounts, useResetConnections } from "@umami/state";
import {
WalletClient,
useImplicitAccounts,
useResetBeaconConnections,
useResetWcConnections,
} from "@umami/state";
import { noop } from "lodash";
import { useEffect } from "react";
import { HashRouter, Navigate, Route, Routes } from "react-router-dom";
Expand Down Expand Up @@ -59,11 +64,13 @@ const LoggedInRouterWithPolling = () => {
};

const LoggedOutRouter = () => {
const resetBeaconConnections = useResetConnections();
const resetBeaconConnections = useResetBeaconConnections();
const resetWcConnections = useResetWcConnections();

useEffect(() => {
WalletClient.destroy().then(resetBeaconConnections).catch(noop);
}, [resetBeaconConnections]);
resetWcConnections();
}, [resetBeaconConnections, resetWcConnections]);

return (
<HashRouter>
Expand Down
12 changes: 6 additions & 6 deletions apps/desktop/src/utils/beacon/BeaconPeers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
Image,
Text,
} from "@chakra-ui/react";
import { useGetConnectionInfo, usePeers, useRemovePeer } from "@umami/state";
import { useBeaconPeers, useGetBeaconConnectionInfo, useRemoveBeaconPeer } from "@umami/state";
import { parsePkh } from "@umami/tezos";
import capitalize from "lodash/capitalize";
import { Fragment } from "react";
Expand All @@ -22,10 +22,10 @@ import colors from "../../style/colors";
/**
* Component displaying a list of connected dApps.
*
* Loads dApps data from {@link usePeers} hook & zips it with generated dAppIds.
* Loads dApps data from {@link useBeaconPeers} hook & zips it with generated dAppIds.
*/
export const BeaconPeers = () => {
const { peers } = usePeers();
const { peers } = useBeaconPeers();

if (peers.length === 0) {
return (
Expand Down Expand Up @@ -57,7 +57,7 @@ export const BeaconPeers = () => {
* @param onRemove - action for deleting dApp connection.
*/
const PeerRow = ({ peerInfo }: { peerInfo: ExtendedPeerInfo }) => {
const removePeer = useRemovePeer();
const removeBeaconPeer = useRemoveBeaconPeer();

return (
<Flex justifyContent="space-between" height="106px" data-testid="peer-row" paddingY="30px">
Expand All @@ -76,7 +76,7 @@ const PeerRow = ({ peerInfo }: { peerInfo: ExtendedPeerInfo }) => {
<IconButton
aria-label="Remove Peer"
icon={<TrashIcon />}
onClick={() => removePeer(peerInfo)}
onClick={() => removeBeaconPeer(peerInfo)}
size="xs"
variant="circle"
/>
Expand All @@ -94,7 +94,7 @@ const PeerRow = ({ peerInfo }: { peerInfo: ExtendedPeerInfo }) => {
* @param peerInfo - peerInfo provided by beacon Api + computed dAppId.
*/
const StoredPeerInfo = ({ peerInfo }: { peerInfo: ExtendedPeerInfo }) => {
const connectionInfo = useGetConnectionInfo(peerInfo.senderId);
const connectionInfo = useGetBeaconConnectionInfo(peerInfo.senderId);

if (!connectionInfo) {
return null;
Expand Down
4 changes: 2 additions & 2 deletions apps/desktop/src/utils/beacon/PermissionRequestModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
import { useDynamicModalContext } from "@umami/components";
import {
WalletClient,
useAddConnection,
useAddBeaconConnection,
useAsyncActionHandler,
useGetImplicitAccount,
} from "@umami/state";
Expand All @@ -38,7 +38,7 @@ import { OwnedImplicitAccountsAutocomplete } from "../../components/AddressAutoc
import colors from "../../style/colors";

export const PermissionRequestModal = ({ request }: { request: PermissionRequestOutput }) => {
const addConnectionToBeaconSlice = useAddConnection();
const addConnectionToBeaconSlice = useAddBeaconConnection();
const getAccount = useGetImplicitAccount();
const { onClose } = useDynamicModalContext();
const { handleAsyncAction } = useAsyncActionHandler();
Expand Down
6 changes: 3 additions & 3 deletions apps/desktop/src/utils/beacon/useHandleBeaconMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
useAsyncActionHandler,
useFindNetwork,
useGetOwnedAccountSafe,
useRemovePeerBySenderId,
useRemoveBeaconPeerBySenderId,
} from "@umami/state";
import { type Network } from "@umami/tezos";

Expand All @@ -23,15 +23,15 @@ import { BeaconSignPage } from "../../components/SendFlow/Beacon/BeaconSignPage"
/**
* @returns a function that handles a beacon message and opens a modal with the appropriate content
*
* For operation requests it will also try to convert the operation(s) to our {@link Operation} format,
* For operation requests it will also try to convert the operation(s)n to our {@link Operation} format,
* estimate the fee and open the BeaconSignPage only if it succeeds
*/
export const useHandleBeaconMessage = () => {
const { openWith } = useDynamicModalContext();
const { handleAsyncAction } = useAsyncActionHandler();
const getAccount = useGetOwnedAccountSafe();
const findNetwork = useFindNetwork();
const removePeer = useRemovePeerBySenderId();
const removePeer = useRemoveBeaconPeerBySenderId();

// we should confirm that we support the network that the beacon request is coming from
const checkNetwork = ({
Expand Down
3 changes: 2 additions & 1 deletion apps/web/src/components/Menu/AppsMenu/AppsMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Button, Divider, Text } from "@chakra-ui/react";
import { useAddPeer } from "@umami/state";

import { BeaconPeers } from "../../beacon";
import { onConnect } from "../../WalletConnect";
import { WcPeers, onConnect } from "../../WalletConnect";
import { DrawerContentWrapper } from "../DrawerContentWrapper";

export const AppsMenu = () => {
Expand All @@ -28,6 +28,7 @@ export const AppsMenu = () => {
</Button>
<Divider marginTop={{ base: "36px", md: "40px" }} />
<BeaconPeers />
<WcPeers />
</DrawerContentWrapper>
);
};
14 changes: 11 additions & 3 deletions apps/web/src/components/WalletConnect/SessionProposalModal.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { type NetworkType } from "@airgap/beacon-wallet";
import {
Box,
Card,
Expand All @@ -11,7 +12,13 @@ import {
} from "@chakra-ui/react";
import { type WalletKitTypes } from "@reown/walletkit";
import { useDynamicModalContext } from "@umami/components";
import { useAsyncActionHandler, useGetImplicitAccount, walletKit } from "@umami/state";
import {
useAddWcConnection,
useAsyncActionHandler,
useGetImplicitAccount,
walletKit,
} from "@umami/state";
import { type SessionTypes } from "@walletconnect/types";
import { buildApprovedNamespaces, getSdkError } from "@walletconnect/utils";
import { useState } from "react";
import { FormProvider, useForm } from "react-hook-form";
Expand Down Expand Up @@ -40,6 +47,7 @@ export default function SessionProposalModal({
proposal: WalletKitTypes.SessionProposal;
}) {
console.log("SessionProposalModal", proposal);
const addConnectionToWcSlice = useAddWcConnection();
const getAccount = useGetImplicitAccount();
const toast = useToast();

Expand Down Expand Up @@ -91,12 +99,12 @@ export default function SessionProposalModal({
console.log("approvedNamespaces", namespaces);

setIsLoadingApprove(true);
await walletKit.approveSession({
const session: SessionTypes.Struct = await walletKit.approveSession({
id: proposal.id,
namespaces,
sessionProperties: {},
});
onClose();
addConnectionToWcSlice(session, account.address.pkh, chain as NetworkType);
} catch (e) {
setIsLoadingApprove(false);
toast({ description: (e as Error).message, status: "error" });
Expand Down
199 changes: 199 additions & 0 deletions apps/web/src/components/WalletConnect/WcPeers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
import { Center, Divider, Flex, Heading, IconButton, Image, Text, VStack } from "@chakra-ui/react";
import { useGetWcConnectionInfo, useRemoveWcPeer, walletKit } from "@umami/state";
import { parsePkh } from "@umami/tezos";
import { type SessionTypes } from "@walletconnect/types";
import { getSdkError } from "@walletconnect/utils";
import capitalize from "lodash/capitalize";

import { CodeSandboxIcon, StubIcon as TrashIcon } from "../../assets/icons";
import { useColor } from "../../styles/useColor";
import { AddressPill } from "../AddressPill/AddressPill";
import { EmptyMessage } from "../EmptyMessage";

/**
* Component displaying a list of connected dApps.
*
* Loads dApps data from {@link useWcPeers} hook & zips it with generated dAppIds.
*/
export const WcPeers = () => {
const wcPeers: Record<string, SessionTypes.Struct> = walletKit.getActiveSessions();

console.log("wcPeers", wcPeers);

if (Object.keys(wcPeers).length === 0) {
return (
<EmptyMessage
alignItems="flex-start"
marginTop="40px"
data-testid="wc-peers-empty"
subtitle="No WalltConnect Apps to show"
title="Your WalletConnect Apps will appear here..."
/>
);
}

return (
<VStack
alignItems="flex-start"
gap="24px"
marginTop="24px"
data-testid="wc-peers"
divider={<Divider />}
spacing="0"
>
{
// loop peers and print PeerRow
Object.entries(wcPeers).map(([topic, peerInfo]) => (
<PeerRow key={topic} peerInfo={peerInfo} />
))
}
</VStack>
);
};

/*
interface Struct {
topic: string;
topic: string;
relay: RelayerTypes.ProtocolOptions;
expiry: Expiry;
acknowledged: boolean;
controller: string;
namespaces: Namespaces;
requiredNamespaces: ProposalTypes.RequiredNamespaces;
optionalNamespaces: ProposalTypes.OptionalNamespaces;
sessionProperties?: ProposalTypes.SessionProperties;
sessionConfig?: SessionConfig;
self: {
publicKey: string;
metadata: SignClientTypes.Metadata;
};
peer: {
publicKey: string;
metadata: SignClientTypes.Metadata;
};
authentication?: AuthTypes.Cacao[];
transportType?: RelayerTypes.TransportType;
}
*/

/**
* Component for displaying info about single connected dApp.
*
* @param peerInfo - peerInfo provided by wc Api + computed dAppId.
* @param onRemove - action for deleting dApp connection.
*/
const PeerRow = ({ peerInfo }: { peerInfo: SessionTypes.Struct }) => {
const color = useColor();
const removePeer = useRemoveWcPeer();

return (
<Center
alignItems="center"
justifyContent="space-between"
width="full"
height="60px"
data-testid="peer-row"
>
<Flex height="100%">
<Center width="60px" marginRight="12px">
<Image
objectFit="cover"
fallback={<CodeSandboxIcon width="36px" height="36px" />}
src={peerInfo.peer.metadata.icons[0]}
/>
</Center>
<Center alignItems="flex-start" flexDirection="column" gap="6px">
<Heading color={color("900")} size="lg">
{peerInfo.peer.metadata.name}
</Heading>
<StoredPeerInfo peerInfo={peerInfo} />
</Center>
</Flex>
<IconButton
color={color("500")}
aria-label="Remove Peer"
icon={<TrashIcon />}
onClick={() =>
removePeer({ topic: peerInfo.topic, reason: getSdkError("USER_DISCONNECTED") })
}
variant="iconButtonSolid"
/>
</Center>
);
};

/**
* Component for displaying additional info about connection with a dApp.
*
* Displays {@link AddressPill} with a connected account and network type,
* if information about the connection is stored in {@link wcSlice}.
*
* @param peerInfo - peerInfo provided by wc Api + computed dAppId.
*/
const StoredPeerInfo = ({ peerInfo }: { peerInfo: SessionTypes.Struct }) => {
const connectionInfo = useGetWcConnectionInfo(peerInfo.topic);

if (!connectionInfo) {
return null;
}

return (
<Flex>
<AddressPill marginRight="10px" address={parsePkh(connectionInfo.accountPkh)} />
<Divider marginRight="10px" orientation="vertical" />
<Text marginTop="2px" marginRight="4px" fontWeight={600} size="sm">
Network:
</Text>
<Text marginTop="2px" data-testid="dapp-connection-network" size="sm">
{capitalize(connectionInfo.networkType)}
</Text>
</Flex>
);
};

// import { Text } from "@chakra-ui/react";
// import { walletKit } from "@umami/state";
// import { type PairingTypes } from "@walletconnect/types";
// import { getSdkError } from "@walletconnect/utils";
// import { Fragment, useEffect } from "react";

// import PairingCard from "./PairingCard";

// export default function PairingsPage() {
// // const [walletPairings ] = useState(web3wallet.core.pairing.getPairings())

// async function onDelete(topic: string) {
// await walletKit.disconnectSession({ topic, reason: getSdkError("USER_DISCONNECTED") });
// const newPairings = pairings.filter(pairing => pairing.topic !== topic);
// SettingsStore.setPairings(newPairings as PairingTypes.Struct[]);
// }

// useEffect(() => {
// SettingsStore.setPairings(web3wallet.core.pairing.getPairings());
// }, []);

// // console.log("pairings", walletPairings)
// return (
// <Fragment>
// {pairings.length ? (
// pairings.map(pairing => {
// const { peerMetadata } = pairing;

// return (
// <PairingCard
// key={pairing.topic}
// data-testid={"pairing-" + pairing.topic}
// name={peerMetadata?.name}
// onDelete={() => onDelete(pairing.topic)}
// topic={pairing.topic}
// url={peerMetadata?.url}
// />
// );
// })
// ) : (
// <Text css={{ opacity: "0.5", textAlign: "center", marginTop: "$20" }}>No pairings</Text>
// )}
// </Fragment>
// );
// }
3 changes: 3 additions & 0 deletions apps/web/src/components/WalletConnect/WcProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ export const WalletConnectProvider = ({ children }: PropsWithChildren) => {
await createWalletKit();
walletKit.on("session_proposal", proposal => void onSessionProposal(proposal));
walletKit.on("session_request", request => void onSessionRequest(request));
walletKit.on("session_delete", ({ id, topic }) =>
console.log("Session deleted", id, topic)
);
} catch (error) {
console.error("Error initializing Web3Wallet:", error);
}
Expand Down
1 change: 1 addition & 0 deletions apps/web/src/components/WalletConnect/index.tsx
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./WcProvider";
export * from "./WcPeers";
Loading

0 comments on commit f5056e3

Please sign in to comment.