Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
hellno committed Sep 16, 2024
1 parent 7d84e00 commit ca58883
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 66 deletions.
2 changes: 1 addition & 1 deletion pages/accounts/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ export default function Accounts() {
<Card>
<CardHeader>
<CardTitle className="text-2xl">Create a shared Farcaster account</CardTitle>
<CardDescription className="text-lg">
<CardDescription className="text-md leading-tight">
Follow these steps to create a shared Farcaster account. Shared accounts are powered by Hats Protocol
🧢.
</CardDescription>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ const ConnectFarcasterAccountViaHatsProtocol = () => {
<Card>
<CardHeader>
<CardTitle className="text-2xl">Connect to a shared account</CardTitle>
<CardDescription className="text-lg">{state.description}</CardDescription>
<CardDescription className="text-md leading-tight">{state.description}</CardDescription>
</CardHeader>
<CardContent className="w-full max-w-lg">
{getCardContent()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,26 +72,12 @@ export const SharedAccountOwnershipSetup = ({
setDelegatorContractAddress={setDelegatorContractAddress}
/>
</div>
<div className="mt-4 lg:w-1/2 lg:mt-0">
<div className="mx-0 max-w-2xl">
<h3 className="text-lg font-semibold tracking-tight text-foreground">How to get your Hats IDs</h3>
<p className="mt-2 text-md leading-8 text-foreground/70">
Go to the{' '}
<a href="https://app.hatsprotocol.xyz" className="underline" target="_blank" rel="noreferrer">
Hats app
</a>{' '}
and click on the tree you want to use. In the top right corner, you will see the tree ID and the Hats ID.
You will need to use the Hats ID for the admin role and for the caster role.
</p>
</div>
<WarpcastImage url="https://i.imgur.com/pgl0n75.gif" />
</div>
</div>
);

const renderGoBack = () =>
state !== OwnershipSetupSteps.unknown && (
<Button className="mt-8" variant="default" onClick={() => setState(OwnershipSetupSteps.unknown)}>
<Button className="mt-8" variant="outline" onClick={() => setState(OwnershipSetupSteps.unknown)}>
Go back
</Button>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import SwitchWalletButton from '../SwitchWalletButton';
import { Label } from '@/components/ui/label';
import { User } from '@neynar/nodejs-sdk/build/neynar-api/v2';
import { optimism } from 'viem/chains';
import includes from 'lodash.includes';
import ClickToCopyText from '../ClickToCopyText';

const readNonces = async (account: `0x${string}`) => {
if (!account) return BigInt(0);
Expand All @@ -31,7 +33,7 @@ const readNonces = async (account: `0x${string}`) => {

enum TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS {
'CONNECT_WALLET',
'EXECUTE_PREPARE_TO_RECEIVE',
'PENDING_USER_SET_WARPCAST_RECOVERY_ADDRESS',
'PENDING_PREPARE_TO_RECEIVE_CONFIRMATION',
'GENERATE_SIGNATURE',
'PENDING_SIGNATURE_CONFIRMATION',
Expand All @@ -56,9 +58,9 @@ const TransferAccountToHatsDelegatorSteps: TransferAccountToHatsDelegatorStepTyp
idx: 0,
},
{
state: TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS.EXECUTE_PREPARE_TO_RECEIVE,
title: 'Prepare to receive',
description: 'Prepare your Hats Protocol Delegator contract instance to receive the Farcaster account',
state: TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS.PENDING_USER_SET_WARPCAST_RECOVERY_ADDRESS,
title: 'Set your recovery address in Warpcast',
description: '',
idx: 1,
},
{
Expand Down Expand Up @@ -122,6 +124,7 @@ const TransferAccountToHatsDelegator = ({
const [deadline, setDeadline] = useState<bigint>(BigInt(0));
const [nonce, setNonce] = useState<bigint>(BigInt(0));
const [onchainTransactionHash, setOnchainTransactionHash] = useState<`0x${string}`>('0x');
const [isRecoveryAddressSet, setIsRecoveryAddressSet] = useState(false);

const { signTypedDataAsync } = useSignTypedData();
const fid = BigInt(user.fid);
Expand All @@ -142,6 +145,19 @@ const TransferAccountToHatsDelegator = ({
hash: onchainTransactionHash,
});

const {
data: recoveryAddress,
error: recoveryAddressError,
status: recoveryAddressStatus,
} = useReadContract({
abi: idRegistryABI,
address: ID_REGISTRY_ADDRESS,
functionName: 'recoveryOf',
args: [fid],
});

console.log('recoveryAddress', recoveryAddress, recoveryAddressError, recoveryAddressStatus);

const {
data: isFidReceivable,
error,
Expand Down Expand Up @@ -303,8 +319,8 @@ const TransferAccountToHatsDelegator = ({
switch (step.state) {
case TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS.CONNECT_WALLET:
return 'Connect wallet';
case TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS.EXECUTE_PREPARE_TO_RECEIVE:
return 'Prepare for transfer';
case TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS.PENDING_USER_SET_WARPCAST_RECOVERY_ADDRESS:
return isRecoveryAddressSet ? 'Next step' : 'Waiting...';
case TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS.GENERATE_SIGNATURE:
return `Generate signature`;
case TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS.PENDING_PREPARE_TO_RECEIVE_CONFIRMATION:
Expand Down Expand Up @@ -332,8 +348,7 @@ const TransferAccountToHatsDelegator = ({

const onClick = () => {
switch (step.state) {
case TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS.EXECUTE_PREPARE_TO_RECEIVE:
onExecutePrepareToReceive();
case TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS.PENDING_USER_SET_WARPCAST_RECOVERY_ADDRESS:
break;
case TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS.GENERATE_SIGNATURE:
if (!address) return;
Expand All @@ -353,7 +368,7 @@ const TransferAccountToHatsDelegator = ({
break;
case TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS.ERROR:
setErrorMessage('');
setStepToKey(TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS.EXECUTE_PREPARE_TO_RECEIVE);
setStepToKey(TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS.PENDING_USER_SET_WARPCAST_RECOVERY_ADDRESS);
break;
default:
break;
Expand All @@ -362,30 +377,19 @@ const TransferAccountToHatsDelegator = ({

const getCardContent = () => {
switch (step.state) {
case TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS.EXECUTE_PREPARE_TO_RECEIVE:
case TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS.PENDING_USER_SET_WARPCAST_RECOVERY_ADDRESS:
return (
<>
<div className="flex flex-col">
<span>
Prepare delegator contract{' '}
<a
className="underline"
href={`https://optimistic.etherscan.io/address/${toAddress}`}
target="_blank"
rel="noopener noreferrer"
>
{toAddress}
</a>{' '}
to receive your Farcaster account.
Got to Warpcast and set the recovery address to your wallet address.
<br />
<br />
<span className="flex flex-col text-center">
{address}
<ClickToCopyText className="w-20" text={address!} size="sm" />
</span>
<Button
className="mt-8 w-1/2"
variant="outline"
onClick={() => setStepToKey(TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS.GENERATE_SIGNATURE)}
>
Skip
</Button>
<Label className="mt-2">Skip if you already prepared the contract.</Label>
<br />
<p>recovery address is {recoveryAddress}</p>
</div>
</>
);
Expand Down Expand Up @@ -450,14 +454,22 @@ const TransferAccountToHatsDelegator = ({
)}
</div>
)}
{step.state !== TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS.CONFIRMED && <SwitchWalletButton className="w-1/2" />}
{!includes(
[
TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS.PENDING_USER_SET_WARPCAST_RECOVERY_ADDRESS,
TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS.CONFIRMED,
],
step.state
) && <SwitchWalletButton className="w-1/2" />}
<Button
className="w-1/2"
variant="default"
disabled={
!toAddress ||
!address ||
!fid ||
(step.state === TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS.PENDING_USER_SET_WARPCAST_RECOVERY_ADDRESS &&
!isRecoveryAddressSet) ||
(step.state === TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS.EXECUTE_ONCHAIN &&
!connectedAddressOwnsFarcasterAccount) ||
step.state === TRANSFER_ACCOUNT_TO_HATS_DELEGATOR_STEPS.PENDING_SIGNATURE_CONFIRMATION ||
Expand Down
9 changes: 1 addition & 8 deletions src/common/components/SwitchWalletButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ import React, { useEffect, useState } from 'react';

import { Button } from '@/components/ui/button';
import { useAccountModal, useConnectModal } from '@rainbow-me/rainbowkit';
import { useAccount, useDisconnect } from 'wagmi';
import { useAccount } from 'wagmi';
import { cn } from '@/lib/utils';

type SwitchWalletButtonProps = {
className?: string;
};

const SwitchWalletButton = ({ className }: SwitchWalletButtonProps) => {
const { disconnect } = useDisconnect();
const { openConnectModal } = useConnectModal();
const { openAccountModal } = useAccountModal();

Expand All @@ -23,12 +22,6 @@ const SwitchWalletButton = ({ className }: SwitchWalletButtonProps) => {

return (
<div className={cn('flex flex-col', className)}>
{isClient && isConnected && (
<Button variant="outline" className="border-red-700" onClick={() => disconnect()}>
Disconnect
</Button>
)}

<Button
type="button"
variant="outline"
Expand Down
18 changes: 9 additions & 9 deletions src/common/helpers/farcaster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ type PublishReactionParams = {
reaction: {
type: 'like' | 'recast';
target:
| CastId
| {
url: string;
};
| CastId
| {
url: string;
};
};
};

Expand All @@ -52,10 +52,10 @@ type RemoveReactionParams = {
reaction: {
type: 'like' | 'recast';
target:
| CastId
| {
url: string;
};
| CastId
| {
url: string;
};
};
};

Expand Down Expand Up @@ -444,4 +444,4 @@ export const getSignatureForUsernameProof = async (
return signature;
};

export const updateBio = async () => {};
export const updateBio = async () => { };
4 changes: 2 additions & 2 deletions src/common/helpers/hats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ export async function createInitialTree(
],
});

if (res.status === 'success') {
if (res?.status === 'success') {
return { casterHat: casterHatId, adminHat: casterAdminHatId };
} else {
throw new Error('Tree creation failed');
throw new Error(`Tree creation failed`);
}
}

0 comments on commit ca58883

Please sign in to comment.