Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: ui demo user card reflects 7702 delegation status #1294

Merged
merged 7 commits into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,54 @@ import DialogMenu from "@/components/shared/user-connection-avatar/UserConnectio
import { UserConnectionAvatar } from "./UserConnectionAvatar";
import { UserConnectionDetails } from "./UserConnectionDetails";
import React, { useEffect, useState } from "react";
import { useAccount } from "@account-kit/react";
import { useAccount, useSigner } from "@account-kit/react";
import { useQuery } from "@tanstack/react-query";
import { useConfigStore } from "@/state";
import { WalletTypes } from "@/app/config";
import { createPublicClient, Hex, http } from "viem";
import { odysseyTestnet } from "viem/chains";

type RenderAvatarMenuProps = {
deploymentStatus: boolean;
delegationAddress?: Hex;
};
export const RenderUserConnectionAvatar = (
props: React.HTMLAttributes<HTMLDivElement>
) => {
const { account } = useAccount({
type: "LightAccount",
});
const { walletType } = useConfigStore();

const publicClient = createPublicClient({
chain: odysseyTestnet,
transport: http(),
});

const signer = useSigner();

const { nftTransferred } = useConfigStore(({ nftTransferred }) => ({
nftTransferred,
}));

const { data: deploymentStatus = false, refetch } = useQuery({
queryKey: ["deploymentStatus"],
const { data: hybridAccount, refetch: refetch7702 } = useQuery({
queryKey: ["deploymentStatus7702"],
queryFn: async () => {
const delegationAddress = signer
? await publicClient.getCode({
address: await signer?.getAddress(),
})
: "0x";
const delegationStatus = delegationAddress !== "0x";
return {
delegationAddress,
delegationStatus,
};
},
});

const { data: deploymentStatusSCA = false, refetch: refetchSCA } = useQuery({
queryKey: ["deploymentStatusSCA"],
queryFn: async () => {
const initCode = await account?.getInitCode();
return initCode && initCode === "0x";
Expand All @@ -33,10 +61,20 @@ export const RenderUserConnectionAvatar = (
useEffect(() => {
// Refetch the deployment status if the NFT transferred state changes.
// Only refetch if this is a user's first NFT Transfer...
if (nftTransferred && !deploymentStatus) {
refetch();
if (nftTransferred && !deploymentStatusSCA) {
refetchSCA();
}
}, [nftTransferred, deploymentStatus, refetch]);

if (nftTransferred && !hybridAccount?.delegationStatus) {
refetch7702();
}
}, [
nftTransferred,
deploymentStatusSCA,
refetchSCA,
hybridAccount?.delegationStatus,
refetch7702,
]);

return (
<div
Expand All @@ -45,17 +83,42 @@ export const RenderUserConnectionAvatar = (
>
{/* Popover - Visible on desktop screens */}
<div className="hidden lg:block overflow-hidden">
<RenderPopoverMenu deploymentStatus={deploymentStatus} />
<RenderPopoverMenu
deploymentStatus={
walletType === WalletTypes.hybrid7702
? hybridAccount
? hybridAccount.delegationStatus
: false
: deploymentStatusSCA
}
delegationAddress={
hybridAccount ? hybridAccount.delegationAddress : "0x"
}
/>
</div>
{/* Dialog - Visible on mobile screens */}
<div className="block lg:hidden">
<RenderDialogMenu deploymentStatus={deploymentStatus} />
<RenderDialogMenu
deploymentStatus={
walletType === WalletTypes.hybrid7702
? hybridAccount
? hybridAccount.delegationStatus
: false
: deploymentStatusSCA
}
delegationAddress={
hybridAccount ? hybridAccount.delegationAddress : "0x"
}
/>
</div>
</div>
);
};

const RenderPopoverMenu = ({ deploymentStatus }: RenderAvatarMenuProps) => {
const RenderPopoverMenu = ({
deploymentStatus,
delegationAddress,
}: RenderAvatarMenuProps) => {
const [popoverOpen, setPopoverOpen] = useState(false);

return (
Expand All @@ -67,13 +130,19 @@ const RenderPopoverMenu = ({ deploymentStatus }: RenderAvatarMenuProps) => {
/>
</PopoverMenu.Trigger>
<PopoverMenu.Content>
<UserConnectionDetails deploymentStatus={deploymentStatus} />
<UserConnectionDetails
deploymentStatus={deploymentStatus}
delegationAddress={delegationAddress}
/>
</PopoverMenu.Content>
</PopoverMenu>
);
};

const RenderDialogMenu = ({ deploymentStatus }: RenderAvatarMenuProps) => {
const RenderDialogMenu = ({
deploymentStatus,
delegationAddress,
}: RenderAvatarMenuProps) => {
const [dialogOpen, setDialogOpen] = useState(false);

return (
Expand All @@ -90,7 +159,10 @@ const RenderDialogMenu = ({ deploymentStatus }: RenderAvatarMenuProps) => {
<DialogMenu isOpen={dialogOpen} onClose={() => setDialogOpen(false)}>
<DialogMenu.Content>
<p className="text-lg font-semibold text-fg-primary mb-5">Profile</p>
<UserConnectionDetails deploymentStatus={deploymentStatus} />
<UserConnectionDetails
deploymentStatus={deploymentStatus}
delegationAddress={delegationAddress}
/>
</DialogMenu.Content>
</DialogMenu>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@ import { ExternalLinkIcon } from "@/components/icons/external-link";
import { LogoutIcon } from "@/components/icons/logout";
import { DeploymentStatusIndicator } from "@/components/shared/DeploymentStatusIndicator";
import { UserAddressLink } from "@/components/shared/user-connection-avatar/UserAddressLink";
import { ODYSSEY_EXPLORER_URL } from "@/hooks/7702/constants";
import { useConfigStore } from "@/state";
import { useAccount, useLogout, useSigner, useUser } from "@account-kit/react";
import { useQuery } from "@tanstack/react-query";
import { Hex } from "viem";

type UserConnectionDetailsProps = {
deploymentStatus: boolean;
delegationAddress?: Hex;
};
export function UserConnectionDetails({
deploymentStatus,
delegationAddress,
}: UserConnectionDetailsProps) {
const user = useUser();
const signer = useSigner();
Expand Down Expand Up @@ -119,11 +123,23 @@ export function UserConnectionDetails({
</span>
<div className="flex flex-row items-center">
<DeploymentStatusIndicator
isDeployed={false}
isDeployed={deploymentStatus}
className="w-[12px] h-[12px]"
/>
<span className="text-fg-primary block ml-1 text-md md:text-sm">
None
{deploymentStatus && delegationAddress ? (
<a
href={`${ODYSSEY_EXPLORER_URL}/address/0x${delegationAddress.slice(
8
)}`}
target="_blank"
className="underline"
>
Modular Account
</a>
) : (
"None"
)}
</span>
</div>
</div>
Expand Down
Loading