Skip to content

Commit

Permalink
🚧 Update components to handle new session type
Browse files Browse the repository at this point in the history
  • Loading branch information
KONFeature committed Dec 18, 2024
1 parent f6a0d23 commit c189514
Show file tree
Hide file tree
Showing 18 changed files with 213 additions and 115 deletions.
4 changes: 1 addition & 3 deletions packages/wallet/app/context/wallet/smartWallet/connector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,7 @@ export function smartAccountConnector<
return (await signViaPrivy(
message,
{
title: "Action confirmation",
description:
"By signing the following hash, you will authorize the current frak action",
showWalletUIs: true,
},
address
)) as Hex;
Expand Down
6 changes: 5 additions & 1 deletion packages/wallet/app/i18n/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,11 @@
},
"wallet": {
"activateNotifications": "<strong>Enable notifications</strong> <br /> to be notified when your gains are paid",
"biometryInfos": "Biometry informations",
"settings": {
"biometryInfo": "Biometry informations",
"privyInfo": "Login informations",
"privyWallet": "Privy wallet"
},
"installWebApp": "<strong>Install wallet on home screen</strong> <br /> to find your gains at any time",
"interaction": {
"CREATE_REFERRAL_LINK": "Created share link",
Expand Down
6 changes: 5 additions & 1 deletion packages/wallet/app/i18n/locales/fr/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,11 @@
},
"wallet": {
"activateNotifications": "<strong>Activer les notifications</strong><br /> pour être prévenu du versement de vos gains",
"biometryInfos": "Informations biométriques",
"settings": {
"biometryInfo": "Informations biométriques",
"privyInfo": "Informations de connection",
"privyWallet": "Portefeuille privy"
},
"installWebApp": "<strong>Installer le wallet sur l'écran d'accueil</strong><br /> pour retrouver vos gains à tout moment",
"interaction": {
"CREATE_REFERRAL_LINK": "Lien de partage créé",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { sdkSessionAtom, sessionAtom } from "@/module/common/atoms/session";
import { Panel } from "@/module/common/component/Panel";
import { jotaiStore } from "@module/atoms/store";
import { Button } from "@module/component/Button";
import { useLogout } from "@privy-io/react-auth";
import { useQueryClient } from "@tanstack/react-query";
import { RESET } from "jotai/utils";
import { LogOut } from "lucide-react";
Expand Down Expand Up @@ -29,13 +30,18 @@ export function Logout() {
const { t } = useTranslation();
const navigate = useNavigate();
const queryClient = useQueryClient();
const { logout: privyLogout } = useLogout();
return (
<Panel size={"none"} variant={"invisible"}>
<Button
blur={"blur"}
width={"full"}
align={"left"}
onClick={async () => {
// Privy logout
privyLogout().catch(() => {
console.log("Privy logout failed");
});
// Session deletion
jotaiStore.set(sessionAtom, RESET);
jotaiStore.set(sdkSessionAtom, RESET);
Expand Down
60 changes: 38 additions & 22 deletions packages/wallet/app/module/authentication/component/Privy/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,38 @@ import {
useWallets,
} from "@privy-io/react-auth";
import { useMutation } from "@tanstack/react-query";
import { useState } from "react";
import { useEffect, useState } from "react";
import type { Address, Hex } from "viem";
import { generatePrivateKey } from "viem/accounts";

export function PrivyLogin() {
const { ready, authenticated } = usePrivy();
const { ready } = usePrivy();

if (!ready) {
return <Spinner />;
}

if (!authenticated) {
return <DoPrivyLogin />;
}

return <DoPrivyAuthentication />;
return (
<>
<DoPrivyLogin />
<br />
<br />
<DoPrivyAuthentication />
</>
);
}

function DoPrivyLogin() {
// todo: Maybe a fork session stuff for the SDK post SSO?
const { ready, login, authenticated } = usePrivy();

if (!ready || authenticated) {
return <Spinner />;
}
const { login, authenticated } = usePrivy();

return (
<Button type={"button"} onClick={() => login()}>
Login via socials
<Button
type={"button"}
onClick={() => login()}
disabled={authenticated}
>
Connect via socials
</Button>
);
}
Expand All @@ -47,8 +50,16 @@ function DoPrivyAuthentication() {
const { signMessage } = usePrivy();
const { wallets } = useWallets();
const [wallet, setWallet] = useState<ConnectedWallet | undefined>(
wallets.length > 2 ? undefined : wallets[0]
undefined
);

// Auto pick the first wallet
useEffect(() => {
if (wallets.length === 1) {
setWallet(wallets[0]);
}
}, [wallets]);

const { mutate: authenticate } = useMutation({
mutationKey: ["privy-login", wallet?.address],
async mutationFn() {
Expand Down Expand Up @@ -97,14 +108,19 @@ function DoPrivyAuthentication() {
},
});

if (!wallet) {
return <PickPrivyWallet wallets={wallets} onPick={setWallet} />;
}

return (
<Button type={"button"} onClick={() => authenticate()}>
Login via Privy
</Button>
<>
{!wallet && wallets.length > 0 && (
<PickPrivyWallet wallets={wallets} onPick={setWallet} />
)}
<Button
type={"button"}
onClick={() => authenticate()}
disabled={wallet === undefined}
>
Authenticate
</Button>
</>
);
}

Expand Down
13 changes: 13 additions & 0 deletions packages/wallet/app/module/common/atoms/session.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
import type { SdkSession, Session } from "@/types/Session";
import { atom } from "jotai";
import { atomWithStorage } from "jotai/utils";

export const sessionAtom = atomWithStorage<Session | null>(
"frak_session",
null
);

export const webauthnSessionAtom = atom((get) => {
const session = get(sessionAtom);
if (!session || typeof session.publicKey !== "object") return null;
return session;
});

export const privySessionAtom = atom((get) => {
const session = get(sessionAtom);
if (!session || typeof session.publicKey === "object") return null;
return session;
});

export const sdkSessionAtom = atomWithStorage<SdkSession | null>(
"frak_sdkSession",
null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {
type FrakWalletConnector,
smartAccountConnector,
} from "@/context/wallet/smartWallet/connector";
import { usePrivy } from "@privy-io/react-auth";
import { useSignMessage } from "@privy-io/react-auth";
import { useEffect, useMemo } from "react";
import { useConfig, useConnect } from "wagmi";

Expand Down Expand Up @@ -59,10 +59,9 @@ export function useEnforceWagmiConnection() {
}, [connect, frakConnector, isPending, state.current, state.status]);

/**
* Get the current privy wallets
* Synchronise the privy sign message with the frak connector
*/
const { signMessage } = usePrivy();

const { signMessage } = useSignMessage();
useEffect(() => {
if (!frakConnector) {
return;
Expand Down
34 changes: 34 additions & 0 deletions packages/wallet/app/module/common/hook/useSyncPrivySession.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {
privySessionAtom,
sdkSessionAtom,
sessionAtom,
} from "@/module/common/atoms/session";
import { jotaiStore } from "@module/atoms/store";
import { useWallets } from "@privy-io/react-auth";
import { useAtomValue } from "jotai";
import { RESET } from "jotai/utils";
import { useEffect } from "react";
import { type Address, isAddressEqual } from "viem";

/**
* Hook that synchronise the privy session
*/
export function useSyncPrivySession() {
const privySession = useAtomValue(privySessionAtom);
const { wallets: privyWallets, ready } = useWallets();

useEffect(() => {
if (!ready) return;
if (!privySession) return;

// Find a privy wallets that match the current session
const wallet = privyWallets.find((w) =>
isAddressEqual(w.address as Address, privySession.publicKey)
);
if (wallet) return;

// If no wallet match, we reset the current user session
jotaiStore.set(sessionAtom, RESET);
jotaiStore.set(sdkSessionAtom, RESET);
}, [privySession, privyWallets, ready]);
}
5 changes: 5 additions & 0 deletions packages/wallet/app/module/common/provider/RootProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { currentChain } from "@/context/blockchain/provider";
import { authenticatedBackendApi } from "@/context/common/backendClient";
import { smartAccountConnector } from "@/context/wallet/smartWallet/connector";
import { useEnforceWagmiConnection } from "@/module/common/hook/useEnforceWagmiConnection";
import { useSyncPrivySession } from "@/module/common/hook/useSyncPrivySession";
import { subscriptionAtom } from "@/module/notification/atom/subscriptionAtom";
import { getTransport } from "@frak-labs/app-essentials/blockchain";
import { jotaiStore } from "@module/atoms/store";
Expand Down Expand Up @@ -162,6 +163,7 @@ function WagmiProviderWithDynamicConfig({ children }: PropsWithChildren) {

function EnforceWagmiConnection() {
useEnforceWagmiConnection();
useSyncPrivySession();
return null;
}

Expand All @@ -175,11 +177,14 @@ function PrivyProviderWithConfig({ children }: PropsWithChildren) {
theme: "light",
accentColor: "#676FFF",
logo: "https://wallet.frak.id/icon-192.png",
walletChainType: "ethereum-only",
},
embeddedWallets: {
// Create wallet on login for user who don't have one
createOnLogin: "users-without-wallets",
},
supportedChains: [currentChain],
defaultChain: currentChain,
}}
>
{children}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { sessionAtom } from "@/module/common/atoms/session";
import { webauthnSessionAtom } from "@/module/common/atoms/session";
import { AccordionRecoveryItem } from "@/module/common/component/AccordionRecoveryItem";
import { useGenerateRecoveryOptions } from "@/module/recovery-setup/hook/useGenerateRecoveryOptions";
import {
Expand All @@ -21,7 +21,7 @@ export function Step2() {
const password = useAtomValue(recoveryPasswordAtom);

// Get the current session
const session = useAtomValue(sessionAtom);
const session = useAtomValue(webauthnSessionAtom);

// Set the recovery options
const setRecoveryOptions = useSetAtom(recoveryOptionsAtom);
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { webauthnSessionAtom } from "@/module/common/atoms/session";
import { Panel } from "@/module/common/component/Panel";
import { Title } from "@/module/common/component/Title";
import { CurrentRecoverySetupStatus } from "@/module/recovery-setup/component/CurrentSetupStatus";
import { useAtomValue } from "jotai";
import { Shield } from "lucide-react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router";
Expand All @@ -11,6 +13,12 @@ import { Link } from "react-router";
*/
export function RecoveryLink() {
const { t } = useTranslation();
const webauthnSession = useAtomValue(webauthnSessionAtom);

if (!webauthnSession) {
return null;
}

return (
<Panel size={"small"}>
<Title icon={<Shield size={32} />}>
Expand Down
Loading

0 comments on commit c189514

Please sign in to comment.