diff --git a/apps/web/package.json b/apps/web/package.json index 928a69e0a3..5a35f71f5e 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -21,7 +21,6 @@ "@headlessui/react": "^1.7.19", "@heroicons/react": "^2.1.3", "@lottiefiles/dotlottie-react": "^0.8.10", - "@noble/ed25519": "^2.1.0", "@radix-ui/react-accordion": "^1.2.0", "@radix-ui/react-popover": "^1.1.1", "@radix-ui/react-tooltip": "^1.1.2", diff --git a/apps/web/src/components/Basenames/UsernameProfileSectionFrames/Context.tsx b/apps/web/src/components/Basenames/UsernameProfileSectionFrames/Context.tsx index ee66606904..8c3667acce 100644 --- a/apps/web/src/components/Basenames/UsernameProfileSectionFrames/Context.tsx +++ b/apps/web/src/components/Basenames/UsernameProfileSectionFrames/Context.tsx @@ -162,8 +162,6 @@ export function FramesProvider({ children }: FramesProviderProps) { async ({ signatureData }) => { if (!address) { openConnectModal?.(); - console.info('Opened connect modal because the account address is not set'); - return null; } @@ -189,12 +187,12 @@ export function FramesProvider({ children }: FramesProviderProps) { setFrameInteractionError('Error signing data'); } - console.error(error); + logError(error, 'failed to sign frame data'); return null; } }, - [address, openConnectModal, currentChainId, config], + [address, openConnectModal, currentChainId, config, logError], ); const { writeContractAsync, isPending: pendingFrameChange } = useWriteContract(); @@ -222,20 +220,21 @@ export function FramesProvider({ children }: FramesProviderProps) { args: [nameHash, UsernameTextRecordKeys.Frames, frameUrl.trim()], functionName: 'setText', }); - refetchExistingTextRecords().catch(console.warn); + refetchExistingTextRecords().catch((e) => logError(e, 'failed to refetch text records')); return result; } return doTransaction(); }, [ address, + currentChainId, profileUsername, - basenameChain, writeContractAsync, - config, - currentChainId, - openConnectModal, + basenameChain.id, refetchExistingTextRecords, + openConnectModal, + config, + logError, ], ); diff --git a/apps/web/src/hooks/useStorage.ts b/apps/web/src/hooks/useStorage.ts deleted file mode 100644 index 8f511fdd80..0000000000 --- a/apps/web/src/hooks/useStorage.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { WebStorage } from '@frames.js/render/identity/storage'; -import type { WebStorage as Storage } from '@frames.js/render/identity/storage'; -import { useCallback, useEffect, useRef, useState } from 'react'; - -type Primitives = string | number | boolean | null; -type Arr = AllowedValue[]; -type Obj = { [key in string]: AllowedValue } & { - [key in string]?: AllowedValue | undefined; -}; -export type AllowedValue = Primitives | Arr | Obj; - -type SharedOptions = { - key: string; - preprocessValue?: (value: Exclude) => TValue; - /** - * @defaultValue WebStorage - */ - storage?: Storage; -}; - -type UseStorageWithoutInitialValue = { - initialValue?: never; -} & SharedOptions; - -type UseStorageOptionsWithInitialValue = { - initialValue: TValue; -} & SharedOptions; - -type UseStorageOptions = { - initialValue?: TValue; -} & SharedOptions; - -type Setter = ( - value: TValue | ((prevState: TValue) => TValue), -) => Promise; - -const defaultStorage = new WebStorage(); - -export function useStorage( - options: UseStorageWithoutInitialValue, -): [TValue | undefined, Setter]; - -export function useStorage( - options: UseStorageOptionsWithInitialValue, -): [TValue, Setter]; - -export function useStorage({ - key, - initialValue, - preprocessValue, - storage = defaultStorage, -}: UseStorageOptions): [TValue | undefined, Setter] { - const storageRef = useRef(storage); - const preprocessValueRef = useRef(preprocessValue); - preprocessValueRef.current = preprocessValue; - const initialValueRef = useRef(initialValue); - const [value, setValue] = useState(initialValueRef.current); - - useEffect(() => { - function isValueNotUndefined( - newValue: TNewValue, - ): newValue is Exclude { - return newValue !== undefined; - } - - const listener = (newValue: TValue | undefined): void => { - if (!isValueNotUndefined(newValue)) { - /** - * If new value is undefined, use initial value. - * - * This can happen when you load the app for first time and there is no value - * in the storage or when you remove the value from the storage. - */ - setValue(initialValueRef.current); - return; - } - - setValue(preprocessValueRef.current ? preprocessValueRef.current(newValue) : newValue); - }; - - const unsubscribe = storageRef.current.watch(key, listener); - - return () => { - unsubscribe(); - }; - }, [key]); - - const setState: Setter = useCallback( - async (setter) => { - await storageRef.current.set(key, (currentState) => { - if (typeof setter !== 'function') { - return setter; - } - - return setter(currentState ?? initialValueRef.current); - }); - }, - [key], - ); - - return [value, setState]; -} diff --git a/apps/web/src/utils/farcaster/crypto.ts b/apps/web/src/utils/farcaster/crypto.ts deleted file mode 100644 index c990824569..0000000000 --- a/apps/web/src/utils/farcaster/crypto.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { getPublicKeyAsync, utils } from '@noble/ed25519'; - -export function convertKeypairToHex({ - privateKeyBytes, - publicKeyBytes, -}: { - privateKeyBytes: Uint8Array; - publicKeyBytes: Uint8Array; -}): { - publicKey: string; - privateKey: string; -} { - return { - publicKey: `0x${Buffer.from(publicKeyBytes).toString('hex')}`, - privateKey: `0x${Buffer.from(privateKeyBytes).toString('hex')}`, - }; -} - -export async function createKeypairEDDSA(): Promise<{ - publicKeyBytes: Uint8Array; - privateKeyBytes: Uint8Array; -}> { - const privateKeyBytes = utils.randomPrivateKey(); - const publicKeyBytes = await getPublicKeyAsync(privateKeyBytes); - - return { - privateKeyBytes, - publicKeyBytes, - }; -} diff --git a/apps/web/src/utils/farcaster/identityPoller.ts b/apps/web/src/utils/farcaster/identityPoller.ts deleted file mode 100644 index 2b7da6f1c0..0000000000 --- a/apps/web/src/utils/farcaster/identityPoller.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { AllowedValue } from 'apps/web/src/hooks/useStorage'; - -type SignedKeyRequest = { - deeplinkUrl: string; - isSponsored: boolean; - key: string; - requestFid: number; - state: string; - token: string; - userFid: number; - signerUser?: Record; - signerUserMetadata?: Record; -}; - -const POLL_INTERVAL = 2000; - -export class IdentityPoller { - private controller: AbortController; - - private polling = false; - - constructor() { - this.controller = new AbortController(); - } - - isPolling = (): boolean => { - return this.polling; - }; - - start = async (token: string): Promise => { - this.controller = new AbortController(); - this.polling = true; - - while (true) { - if (this.controller.signal.aborted) { - this.polling = false; - return false; - } - - try { - const fcSignerRequestResponse = await fetch( - `https://api.warpcast.com/v2/signed-key-request?token=${token}`, - { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - }, - }, - ); - - if (fcSignerRequestResponse.ok) { - const responseBody = (await fcSignerRequestResponse.json()) as { - result: { signedKeyRequest: SignedKeyRequest }; - }; - - if (responseBody.result.signedKeyRequest.state === 'completed') { - return responseBody.result.signedKeyRequest; - } - } else { - throw new Error( - `Warpcast API returned an error response with status code: ${fcSignerRequestResponse.status}`, - ); - } - } catch (error) { - console.error('Error while polling for the signer approval status', error); - } - - await new Promise((r) => { - setTimeout(r, POLL_INTERVAL); - }); - } - }; - - stop = (): void => { - if (this.controller.signal.aborted) { - return; - } - - this.controller.abort(); - }; -} diff --git a/yarn.lock b/yarn.lock index aef27f64b1..9473e347df 100644 --- a/yarn.lock +++ b/yarn.lock @@ -362,7 +362,6 @@ __metadata: "@headlessui/react": ^1.7.19 "@heroicons/react": ^2.1.3 "@lottiefiles/dotlottie-react": ^0.8.10 - "@noble/ed25519": ^2.1.0 "@radix-ui/react-accordion": ^1.2.0 "@radix-ui/react-popover": ^1.1.1 "@radix-ui/react-tooltip": ^1.1.2 @@ -5492,7 +5491,7 @@ __metadata: languageName: node linkType: hard -"@noble/ed25519@npm:^2.0.0, @noble/ed25519@npm:^2.1.0": +"@noble/ed25519@npm:^2.0.0": version: 2.1.0 resolution: "@noble/ed25519@npm:2.1.0" checksum: f9638d5daaaadaecf33cb09675668bde144cecb9a4467f78cda2a7fbd96a1b975a1f8d00e99599f840de52adc64e723333c7c8e52cdf85e3ef160d01b95c408c