diff --git a/package.json b/package.json index ee61ba59b..fdbcab7fc 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,6 @@ "@scure/bip32": "^1.3.0", "@scure/bip39": "^1.2.0", "@skip-router/core": "^5.1.0", - "@solana/web3.js": "^1.93.0", "@statsig/js-client": "1.4.0", "@statsig/react-bindings": "1.4.0", "@tanstack/react-query": "^5.37.1", @@ -118,7 +117,6 @@ "crypto-js": "^4.1.1", "ethers": "^6.6.1", "export-to-csv": "^1.2.3", - "fast-json-stable-stringify": "^2.1.0", "graz": "^0.0.43", "jsdom": "^24.1.0", "lodash": "^4.17.21", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ba9d16e38..f78c80d8e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -146,9 +146,6 @@ dependencies: '@skip-router/core': specifier: ^5.1.0 version: 5.1.0(@types/react@18.3.3)(chain-registry@1.63.9)(react-dom@18.2.0)(react@18.2.0)(typescript@5.1.3) - '@solana/web3.js': - specifier: ^1.93.0 - version: 1.93.2 '@statsig/js-client': specifier: 1.4.0 version: 1.4.0 @@ -227,9 +224,6 @@ dependencies: export-to-csv: specifier: ^1.2.3 version: 1.2.3 - fast-json-stable-stringify: - specifier: ^2.1.0 - version: 2.1.0 graz: specifier: ^0.0.43 version: 0.0.43(@types/react@18.3.3)(react-dom@18.2.0)(react-native@0.74.3)(react@18.2.0) @@ -4439,26 +4433,26 @@ packages: /@internationalized/date@3.4.0: resolution: {integrity: sha512-QUDSGCsvrEVITVf+kv9VSAraAmCgjQmU5CiXtesUBBhBe374NmnEIIaOFBZ72t29dfGMBP0zF+v6toVnbcc6jg==} dependencies: - '@swc/helpers': 0.5.11 + '@swc/helpers': 0.5.1 dev: false /@internationalized/message@3.1.1: resolution: {integrity: sha512-ZgHxf5HAPIaR0th+w0RUD62yF6vxitjlprSxmLJ1tam7FOekqRSDELMg4Cr/DdszG5YLsp5BG3FgHgqquQZbqw==} dependencies: - '@swc/helpers': 0.5.11 + '@swc/helpers': 0.5.1 intl-messageformat: 10.5.0 dev: false /@internationalized/number@3.2.1: resolution: {integrity: sha512-hK30sfBlmB1aIe3/OwAPg9Ey0DjjXvHEiGVhNaOiBJl31G0B6wMaX8BN3ibzdlpyRNE9p7X+3EBONmxtJO9Yfg==} dependencies: - '@swc/helpers': 0.5.11 + '@swc/helpers': 0.5.1 dev: false /@internationalized/string@3.1.1: resolution: {integrity: sha512-fvSr6YRoVPgONiVIUhgCmIAlifMVCeej/snPZVzbzRPxGpHl3o1GRe+d/qh92D8KhgOciruDUH8I5mjdfdjzfA==} dependencies: - '@swc/helpers': 0.5.11 + '@swc/helpers': 0.5.1 dev: false /@ioredis/commands@1.2.0: @@ -7160,7 +7154,7 @@ packages: '@react-types/checkbox': 3.5.0(react@18.2.0) '@react-types/grid': 3.2.0(react@18.2.0) '@react-types/shared': 3.19.0(react@18.2.0) - '@swc/helpers': 0.5.11 + '@swc/helpers': 0.5.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false @@ -7260,7 +7254,7 @@ packages: /@react-aria/live-announcer@3.3.1: resolution: {integrity: sha512-hsc77U7S16trM86d+peqJCOCQ7/smO1cybgdpOuzXyiwcHQw8RQ4GrXrS37P4Ux/44E9nMZkOwATQRT2aK8+Ew==} dependencies: - '@swc/helpers': 0.5.11 + '@swc/helpers': 0.5.1 dev: false /@react-aria/menu@3.10.1(react-dom@18.2.0)(react@18.2.0): @@ -7469,7 +7463,7 @@ packages: '@react-aria/utils': 3.19.0(react@18.2.0) '@react-types/button': 3.7.4(react@18.2.0) '@react-types/shared': 3.19.0(react@18.2.0) - '@swc/helpers': 0.5.11 + '@swc/helpers': 0.5.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false @@ -7587,7 +7581,7 @@ packages: '@react-types/checkbox': 3.5.0(react@18.2.0) '@react-types/shared': 3.19.0(react@18.2.0) '@react-types/switch': 3.4.0(react@18.2.0) - '@swc/helpers': 0.5.11 + '@swc/helpers': 0.5.1 react: 18.2.0 dev: false @@ -8160,7 +8154,7 @@ packages: '@react-types/grid': 3.2.0(react@18.2.0) '@react-types/shared': 3.19.0(react@18.2.0) '@react-types/table': 3.8.0(react@18.2.0) - '@swc/helpers': 0.5.11 + '@swc/helpers': 0.5.1 react: 18.2.0 dev: false @@ -8363,7 +8357,7 @@ packages: dependencies: '@react-aria/utils': 3.19.0(react@18.2.0) '@react-types/shared': 3.19.0(react@18.2.0) - '@swc/helpers': 0.5.11 + '@swc/helpers': 0.5.1 react: 18.2.0 dev: false @@ -13545,7 +13539,7 @@ packages: resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} requiresBuild: true dependencies: - node-fetch: 2.7.0(encoding@0.1.13) + node-fetch: 2.6.12(encoding@0.1.13) transitivePeerDependencies: - encoding @@ -15502,6 +15496,7 @@ packages: /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} @@ -17001,7 +16996,7 @@ packages: merge-options: 3.0.4 nanoid: 3.3.7 native-fetch: 3.0.0(node-fetch@2.6.12) - node-fetch: 2.6.12 + node-fetch: 2.6.12(encoding@0.1.13) react-native-fetch-api: 3.0.0 stream-to-it: 0.2.4 transitivePeerDependencies: @@ -17435,7 +17430,7 @@ packages: /isomorphic-unfetch@3.1.0(encoding@0.1.13): resolution: {integrity: sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==} dependencies: - node-fetch: 2.7.0(encoding@0.1.13) + node-fetch: 2.6.12(encoding@0.1.13) unfetch: 4.2.0 transitivePeerDependencies: - encoding @@ -19701,7 +19696,7 @@ packages: peerDependencies: node-fetch: '*' dependencies: - node-fetch: 2.6.12 + node-fetch: 2.6.12(encoding@0.1.13) dev: true /native-fetch@3.0.0(node-fetch@3.3.2): @@ -19777,7 +19772,7 @@ packages: resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} dev: false - /node-fetch@2.6.12: + /node-fetch@2.6.12(encoding@0.1.13): resolution: {integrity: sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==} engines: {node: 4.x || >=6.0.0} peerDependencies: @@ -19786,8 +19781,8 @@ packages: encoding: optional: true dependencies: + encoding: 0.1.13 whatwg-url: 5.0.0 - dev: true /node-fetch@2.7.0(encoding@0.1.13): resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} @@ -19800,6 +19795,7 @@ packages: dependencies: encoding: 0.1.13 whatwg-url: 5.0.0 + dev: false /node-fetch@3.3.2: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} @@ -21025,7 +21021,7 @@ packages: bl: 5.1.0 debug: 4.3.4(supports-color@5.5.0) minimist: 1.2.8 - node-fetch: 2.7.0(encoding@0.1.13) + node-fetch: 2.6.12(encoding@0.1.13) readable-stream: 3.6.2 transitivePeerDependencies: - encoding diff --git a/src/constants/account.ts b/src/constants/account.ts index d0ba4e790..368074197 100644 --- a/src/constants/account.ts +++ b/src/constants/account.ts @@ -1,5 +1,4 @@ import type { DydxAddress, EvmAddress } from './wallets'; -import { SolAddress } from './wallets'; export enum OnboardingSteps { ChooseWallet = 'ChooseWallet', @@ -44,16 +43,6 @@ export type EvmDerivedAddresses = { }; }; -export type SolDerivedAddresses = { - version?: string; -} & Record< - SolAddress, - { - encryptedSignature?: string; - dydxAddress?: DydxAddress; - } ->; - export type Hdkey = { mnemonic: string; privateKey: Uint8Array | null; diff --git a/src/constants/localStorage.ts b/src/constants/localStorage.ts index 1cfd34c13..c74f0f575 100644 --- a/src/constants/localStorage.ts +++ b/src/constants/localStorage.ts @@ -1,13 +1,11 @@ export enum LocalStorageKey { // Onboarding / Accounts EvmAddress = 'dydx.EvmAddress', - SolAddress = 'dydx.SolAddress', DydxAddress = 'dydx.DydxAddress', OnboardingSelectedWalletType = 'dydx.OnboardingSelectedWalletType', WalletConnectionType = 'dydx.WalletConnectionType', OnboardingHasAcknowledgedTerms = 'dydx.OnboardingHasAcknowledgedTerms', EvmDerivedAddresses = 'dydx.EvmDerivedAddresses', - SolDerivedAddresses = 'dydx.SolDerivedAddresses', // Gas SelectedGasDenom = 'dydx.SelectedGasDenom', @@ -38,7 +36,6 @@ export enum LocalStorageKey { export const LOCAL_STORAGE_VERSIONS = { [LocalStorageKey.EvmDerivedAddresses]: 'v2', - [LocalStorageKey.SolDerivedAddresses]: 'v1', [LocalStorageKey.NotificationPreferences]: 'v2', [LocalStorageKey.TransferNotifications]: 'v1', [LocalStorageKey.Notifications]: 'v1', diff --git a/src/constants/wallets.ts b/src/constants/wallets.ts index 5234be492..4095b07fd 100644 --- a/src/constants/wallets.ts +++ b/src/constants/wallets.ts @@ -19,7 +19,6 @@ import { MathWalletIcon, MetaMaskIcon, OkxWalletIcon, - PhantomIcon, RainbowIcon, TokenPocketIcon, TrustWalletIcon, @@ -37,7 +36,6 @@ export enum WalletConnectionType { InjectedEip1193 = 'injectedEip1193', WalletConnect2 = 'walletConnect2', TestWallet = 'TestWallet', - Phantom = 'Phantom', } export enum WalletErrorType { @@ -71,9 +69,6 @@ export const walletConnectionTypes: Record = { icon: EmailIcon, connectionTypes: [WalletConnectionType.Privy], }, - [WalletType.Phantom]: { - type: WalletType.Phantom, - stringKey: STRING_KEYS.PHANTOM, - icon: PhantomIcon, - connectionTypes: [WalletConnectionType.Phantom], - }, }; // Injected EIP-1193 Providers @@ -344,7 +332,6 @@ export const getSignTypedData = (selectedDydxChainId: DydxChainId) => export type PrivateInformation = ReturnType; export type EvmAddress = `0x${string}`; -export type SolAddress = `${string}`; export type DydxAddress = `dydx${string}`; export const DYDX_CHAIN_INFO: Parameters[0] = { diff --git a/src/hooks/useAccounts.tsx b/src/hooks/useAccounts.tsx index a3d0e8c62..80c51d8f4 100644 --- a/src/hooks/useAccounts.tsx +++ b/src/hooks/useAccounts.tsx @@ -5,18 +5,12 @@ import { LocalWallet, NOBLE_BECH32_PREFIX, type Subaccount } from '@dydxprotocol import { usePrivy } from '@privy-io/react-auth'; import { AES, enc } from 'crypto-js'; -import { - EvmDerivedAddresses, - OnboardingGuard, - OnboardingState, - SolDerivedAddresses, -} from '@/constants/account'; +import { OnboardingGuard, OnboardingState, type EvmDerivedAddresses } from '@/constants/account'; import { LOCAL_STORAGE_VERSIONS, LocalStorageKey } from '@/constants/localStorage'; import { DydxAddress, EvmAddress, PrivateInformation, - SolAddress, TEST_WALLET_EVM_ADDRESS, WalletConnectionType, WalletType, @@ -61,7 +55,6 @@ const useAccountsContext = () => { selectedWalletType, selectedWalletError, evmAddress, - solAddress, signerWagmi, publicClientWagmi, dydxAddress: connectedDydxAddress, @@ -72,50 +65,61 @@ const useAccountsContext = () => { const [previousEvmAddress, setPreviousEvmAddress] = useState(evmAddress); const hasSubAccount = useAppSelector(getHasSubaccount); - const { ready, authenticated } = usePrivy(); + useEffect(() => { + // Wallet accounts switched + if (previousEvmAddress && evmAddress && evmAddress !== previousEvmAddress) { + // Disconnect local wallet + disconnectLocalDydxWallet(); + + // Forget EVM signature + forgetEvmSignature(previousEvmAddress); + } + + if (evmAddress) { + abacusStateManager.setTransfersSourceAddress(evmAddress); + } - const [previousSolAddress, setPreviousSolAddress] = useState(solAddress); + setPreviousEvmAddress(evmAddress); + }, [evmAddress, hasSubAccount]); + + const { ready, authenticated } = usePrivy(); // EVM → dYdX account derivation + const [evmDerivedAddresses, saveEvmDerivedAddresses] = useLocalStorage({ key: LocalStorageKey.EvmDerivedAddresses, - defaultValue: { version: 'v2' } as EvmDerivedAddresses, + defaultValue: {} as EvmDerivedAddresses, }); useEffect(() => { // Clear data stored with deprecated LocalStorageKey if (evmDerivedAddresses.version !== LOCAL_STORAGE_VERSIONS[LocalStorageKey.EvmDerivedAddresses]) - saveEvmDerivedAddresses({ - version: LOCAL_STORAGE_VERSIONS[LocalStorageKey.EvmDerivedAddresses], - }); - }, [evmDerivedAddresses.version, saveEvmDerivedAddresses]); - - const saveEvmDerivedAccount = useCallback( - ({ - evmAddressInner, - dydxAddress, - }: { - evmAddressInner: EvmAddress; - dydxAddress?: DydxAddress; - }) => { - saveEvmDerivedAddresses({ - ...evmDerivedAddresses, - version: LOCAL_STORAGE_VERSIONS[LocalStorageKey.EvmDerivedAddresses], - [evmAddressInner]: { - ...(evmDerivedAddresses as any)[evmAddressInner], - dydxAddress, - }, - }); - }, - [evmDerivedAddresses, saveEvmDerivedAddresses] - ); + saveEvmDerivedAddresses({}); + }, []); + + const saveEvmDerivedAccount = ({ + evmAddressInner, + dydxAddress, + }: { + evmAddressInner: EvmAddress; + dydxAddress?: DydxAddress; + }) => { + saveEvmDerivedAddresses({ + ...evmDerivedAddresses, + version: LOCAL_STORAGE_VERSIONS[LocalStorageKey.EvmDerivedAddresses], + [evmAddressInner]: { + ...evmDerivedAddresses[evmAddressInner], + dydxAddress, + }, + }); + }; const saveEvmSignature = useCallback( (encryptedSignature: string) => { evmDerivedAddresses[evmAddress!].encryptedSignature = encryptedSignature; saveEvmDerivedAddresses(evmDerivedAddresses); }, - [evmDerivedAddresses, evmAddress, saveEvmDerivedAddresses] + [evmDerivedAddresses, evmAddress] ); const forgetEvmSignature = useCallback( @@ -125,87 +129,9 @@ const useAccountsContext = () => { saveEvmDerivedAddresses(evmDerivedAddresses); } }, - [evmAddress, evmDerivedAddresses, saveEvmDerivedAddresses] - ); - - useEffect(() => { - // EVM Wallet accounts switched - if (previousEvmAddress && evmAddress && evmAddress !== previousEvmAddress) { - // Disconnect local wallet - disconnectLocalDydxWallet(); - - // Forget EVM signature - forgetEvmSignature(previousEvmAddress); - } - - if (evmAddress) { - abacusStateManager.setTransfersSourceAddress(evmAddress); - } - - setPreviousEvmAddress(evmAddress); - }, [evmAddress, forgetEvmSignature, hasSubAccount, previousEvmAddress]); - - // SOL → dYdX account derivation - const [solDerivedAddresses, saveSolDerivedAddresses] = useLocalStorage({ - key: LocalStorageKey.SolDerivedAddresses, - defaultValue: {} as SolDerivedAddresses, - }); - - const saveSolDerivedAccount = useCallback( - ({ - solAddressInner, - dydxAddress, - }: { - solAddressInner: SolAddress; - dydxAddress?: DydxAddress; - }) => { - saveSolDerivedAddresses({ - ...solDerivedAddresses, - version: LOCAL_STORAGE_VERSIONS[LocalStorageKey.SolDerivedAddresses], - [solAddressInner]: { - ...solDerivedAddresses[solAddressInner], - dydxAddress, - }, - }); - }, - [saveSolDerivedAddresses, solDerivedAddresses] - ); - - const saveSolSignature = useCallback( - (encryptedSignature: string) => { - solDerivedAddresses[solAddress!].encryptedSignature = encryptedSignature; - saveSolDerivedAddresses(solDerivedAddresses); - }, - [solDerivedAddresses, solAddress, saveSolDerivedAddresses] - ); - - const forgetSolSignature = useCallback( - (_solAddress = solAddress) => { - if (_solAddress) { - delete solDerivedAddresses[_solAddress]?.encryptedSignature; - saveSolDerivedAddresses(solDerivedAddresses); - } - }, - [solAddress, solDerivedAddresses, saveSolDerivedAddresses] + [evmDerivedAddresses, evmAddress] ); - useEffect(() => { - // SOL Wallet accounts switched - if (previousSolAddress && solAddress && solAddress !== previousSolAddress) { - // Disconnect local wallet - disconnectLocalDydxWallet(); - - // Forget SOL signature - forgetSolSignature(previousSolAddress); - } - - if (solAddress) { - abacusStateManager.setTransfersSourceAddress(solAddress); - } - - setPreviousSolAddress(solAddress); - }, [solAddress, forgetSolSignature, hasSubAccount, previousSolAddress]); - const decryptSignature = (encryptedSignature: string | undefined) => { const staticEncryptionKey = import.meta.env.VITE_PK_ENCRYPTION_KEY; @@ -218,7 +144,7 @@ const useAccountsContext = () => { }; // dYdXClient Onboarding & Account Helpers - const { indexerClient, getWalletFromSignature } = useDydxClient(); + const { indexerClient, getWalletFromEvmSignature } = useDydxClient(); // dYdX subaccounts const [dydxSubaccounts, setDydxSubaccounts] = useState(); @@ -251,30 +177,21 @@ const useAccountsContext = () => { const nobleAddress = useMemo(() => localNobleWallet?.address, [localNobleWallet]); - const setWalletFromSignature = useCallback( - async (signature: string) => { - const { wallet, mnemonic, privateKey, publicKey } = await getWalletFromSignature({ - signature, - }); - setLocalDydxWallet(wallet); - setHdKey({ mnemonic, privateKey, publicKey }); - }, - [getWalletFromSignature] - ); + const setWalletFromEvmSignature = async (signature: string) => { + const { wallet, mnemonic, privateKey, publicKey } = await getWalletFromEvmSignature({ + signature, + }); + setLocalDydxWallet(wallet); + setHdKey({ mnemonic, privateKey, publicKey }); + }; useEffect(() => { if (evmAddress) { saveEvmDerivedAccount({ evmAddressInner: evmAddress, dydxAddress }); } - }, [evmAddress, dydxAddress, saveEvmDerivedAccount]); - - useEffect(() => { - if (solAddress) { - saveSolDerivedAccount({ solAddressInner: solAddress, dydxAddress }); - } - }, [solAddress, dydxAddress, saveSolDerivedAccount]); + }, [evmAddress, dydxAddress]); - const signMessageAsync = useSignForWalletDerivation(walletType); + const signTypedDataAsync = useSignForWalletDerivation(); useEffect(() => { (async () => { @@ -316,9 +233,9 @@ const useAccountsContext = () => { try { // Give Privy a second to finish the auth flow before getting the signature await sleep(); - const signature = await signMessageAsync(); + const signature = await signTypedDataAsync(); - await setWalletFromSignature(signature); + await setWalletFromEvmSignature(signature); dispatch(setOnboardingState(OnboardingState.AccountConnected)); } catch (error) { log('useAccounts/decryptSignature', error); @@ -328,7 +245,7 @@ const useAccountsContext = () => { try { const signature = decryptSignature(evmDerivedAccount.encryptedSignature); - await setWalletFromSignature(signature); + await setWalletFromEvmSignature(signature); dispatch(setOnboardingState(OnboardingState.AccountConnected)); } catch (error) { log('useAccounts/decryptSignature', error); @@ -338,55 +255,18 @@ const useAccountsContext = () => { } else { dispatch(setOnboardingState(OnboardingState.AccountConnected)); } - } else if (solAddress) { - if (!localDydxWallet) { - dispatch(setOnboardingState(OnboardingState.WalletConnected)); - - const solDerivedAccount = solDerivedAddresses[solAddress]; - if (solDerivedAccount?.encryptedSignature) { - try { - const signature = decryptSignature(solDerivedAccount.encryptedSignature); - await setWalletFromSignature(signature); - dispatch(setOnboardingState(OnboardingState.AccountConnected)); - } catch (error) { - log('useAccounts/decryptSignature', error); - forgetSolSignature(); - } - } - } else { - dispatch(setOnboardingState(OnboardingState.AccountConnected)); - } } else { disconnectLocalDydxWallet(); dispatch(setOnboardingState(OnboardingState.Disconnected)); } })(); - }, [ - evmAddress, - evmDerivedAddresses, - solAddress, - solDerivedAddresses, - signerWagmi, - connectedDydxAddress, - signerGraz, - walletType, - dispatch, - saveEvmDerivedAccount, - localDydxWallet, - walletConnectionType, - authenticated, - ready, - signMessageAsync, - setWalletFromSignature, - forgetEvmSignature, - forgetSolSignature, - ]); + }, [evmAddress, evmDerivedAddresses, signerWagmi, connectedDydxAddress, signerGraz]); // abacus useEffect(() => { if (dydxAddress) abacusStateManager.setAccount(localDydxWallet, hdKey); else abacusStateManager.attemptDisconnectAccount(); - }, [localDydxWallet, hdKey, dydxAddress]); + }, [localDydxWallet, hdKey]); useEffect(() => { const setNobleWallet = async () => { @@ -470,22 +350,14 @@ const useAccountsContext = () => { signerWagmi, publicClientWagmi, - // Wallet connection (sol) - solAddress, - // Wallet connection (Cosmos) signerGraz, - setWalletFromSignature, - // EVM → dYdX account derivation + setWalletFromEvmSignature, saveEvmSignature, forgetEvmSignature, - // SOL → dYdX account derivation - saveSolSignature, - forgetSolSignature, - // dYdX accounts hdKey, localDydxWallet, diff --git a/src/hooks/useDisplayedWallets.ts b/src/hooks/useDisplayedWallets.ts index e803ae284..4c9a41d76 100644 --- a/src/hooks/useDisplayedWallets.ts +++ b/src/hooks/useDisplayedWallets.ts @@ -1,4 +1,4 @@ -import { isDev, isTestnet } from '@/constants/networks'; +import { isDev } from '@/constants/networks'; import { WalletType } from '@/constants/wallets'; import { isTruthy } from '@/lib/isTruthy'; @@ -7,8 +7,6 @@ export const useDisplayedWallets = () => { const displayedWallets = [ WalletType.MetaMask, - (isTestnet || isDev) && WalletType.Phantom, - isDev && WalletType.Keplr, WalletType.WalletConnect2, diff --git a/src/hooks/useDydxClient.tsx b/src/hooks/useDydxClient.tsx index 59244d72d..169b6c8d1 100644 --- a/src/hooks/useDydxClient.tsx +++ b/src/hooks/useDydxClient.tsx @@ -116,15 +116,7 @@ const useDydxClientContext = () => { setFaucetClient(undefined); } })(); - }, [ - chainTokenDecimals, - chainTokenDenom, - networkConfig, - selectedNetwork, - usdcDecimals, - usdcDenom, - usdcGasDenom, - ]); + }, [networkConfig]); // ------ Gas Denom ------ // @@ -152,9 +144,8 @@ const useDydxClientContext = () => { }, [compositeClient, setSelectedGasDenom]); // ------ Wallet Methods ------ // - const getWalletFromSignature = async ({ signature }: { signature: string }) => { + const getWalletFromEvmSignature = async ({ signature }: { signature: string }) => { const { mnemonic, privateKey, publicKey } = - // This method should be renamed to deriveHDKeyFromSignature as it is used for both solana and ethereum signatures onboarding.deriveHDKeyFromEthereumSignature(signature); return { @@ -434,7 +425,7 @@ const useDydxClientContext = () => { selectedGasDenom: gasDenom, // Wallet Methods - getWalletFromSignature, + getWalletFromEvmSignature, // Public Methods requestAllAccountTransfers, diff --git a/src/hooks/usePhantomWallet.ts b/src/hooks/usePhantomWallet.ts deleted file mode 100644 index d6df815dc..000000000 --- a/src/hooks/usePhantomWallet.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { useCallback, useEffect, useState } from 'react'; - -import { PublicKey } from '@solana/web3.js'; - -export function usePhantomWallet() { - const [solAddress, setSolAddress] = useState(''); - - const connect = useCallback(async (): Promise => { - const resp = await (window as any).phantom.solana.connect(); - const pubkey = resp.publicKey.toBase58(); - setSolAddress(pubkey); - return pubkey; - }, []); - - const disconnect = useCallback(() => { - setSolAddress(''); - }, []); - - useEffect(() => { - (window as any).phantom?.solana?.on('accountChanged', (publicKey: PublicKey) => { - if (publicKey) { - // Set new public key and continue as usual - setSolAddress(publicKey.toBase58()); - } else { - connect().then((address) => setSolAddress(address)); - } - }); - return () => { - (window as any).phantom?.solana?.off('accountChanged'); - }; - }, [connect]); - - const signMessage = useCallback(async (message: string): Promise => { - const resp: { - signature: Uint8Array; - } = await (window as any).phantom.solana.signMessage(new TextEncoder().encode(message)); - return resp.signature; - }, []); - - return { - solAddress, - connect, - disconnect, - signMessage, - }; -} diff --git a/src/hooks/useSignForWalletDerivation.tsx b/src/hooks/useSignForWalletDerivation.tsx index 46e16abb7..3b3f6492d 100644 --- a/src/hooks/useSignForWalletDerivation.tsx +++ b/src/hooks/useSignForWalletDerivation.tsx @@ -1,27 +1,23 @@ import { useCallback } from 'react'; -import stableStringify from 'fast-json-stable-stringify'; import { useSignTypedData } from 'wagmi'; -import { getSignTypedData, WalletType } from '@/constants/wallets'; - -import { usePhantomWallet } from '@/hooks/usePhantomWallet'; +import { getSignTypedData } from '@/constants/wallets'; import { getSelectedDydxChainId } from '@/state/appSelectors'; import { useAppSelector } from '@/state/appTypes'; import { useEnvConfig } from './useEnvConfig'; -export default function useSignForWalletDerivation(walletType: WalletType | undefined) { +export default function useSignForWalletDerivation() { const selectedDydxChainId = useAppSelector(getSelectedDydxChainId); const ethereumChainId = useEnvConfig('ethereumChainId'); const chainId = Number(ethereumChainId); const signTypedData = getSignTypedData(selectedDydxChainId); - const { signTypedDataAsync } = useSignTypedData(); - const signEvmMessage = useCallback( + const callSignTypedData = useCallback( () => signTypedDataAsync({ ...signTypedData, @@ -32,21 +28,5 @@ export default function useSignForWalletDerivation(walletType: WalletType | unde }), [signTypedData, signTypedDataAsync, chainId] ); - - const { signMessage: phantomSignMessage } = usePhantomWallet(); - - const signSolanaMessage = useCallback(async (): Promise => { - const signature = await phantomSignMessage(stableStringify(signTypedData)); - // Left pad the signature with a 0 byte so that the signature is 65 bytes long, a solana signature is 64 bytes by default. - return Buffer.from([0, ...signature]).toString('hex'); - }, [phantomSignMessage, signTypedData]); - - const signMessage = useCallback(async (): Promise => { - if (walletType === WalletType.Phantom) { - return signSolanaMessage(); - } - return signEvmMessage(); - }, [signEvmMessage, signSolanaMessage, walletType]); - - return signMessage; + return callSignTypedData; } diff --git a/src/hooks/useWalletConnection.ts b/src/hooks/useWalletConnection.ts index aa7187096..ab145790e 100644 --- a/src/hooks/useWalletConnection.ts +++ b/src/hooks/useWalletConnection.ts @@ -2,11 +2,11 @@ import { useCallback, useEffect, useState } from 'react'; import { useLogin, useLogout, useMfa, useMfaEnrollment, usePrivy } from '@privy-io/react-auth'; import { + WalletType as CosmosWalletType, useAccount as useAccountGraz, + useSuggestChainAndConnect as useConnectGraz, useDisconnect as useDisconnectGraz, useOfflineSigners as useOfflineSignersGraz, - useSuggestChainAndConnect as useConnectGraz, - WalletType as CosmosWalletType, } from 'graz'; import { useAccount as useAccountWagmi, @@ -23,16 +23,14 @@ import { STRING_KEYS } from '@/constants/localization'; import { WALLETS_CONFIG_MAP } from '@/constants/networks'; import { DYDX_CHAIN_INFO, - type DydxAddress, - type EvmAddress, - SolAddress, WalletConnectionType, - wallets, WalletType, + wallets, + type DydxAddress, + type EvmAddress, } from '@/constants/wallets'; import { useLocalStorage } from '@/hooks/useLocalStorage'; -import { usePhantomWallet } from '@/hooks/usePhantomWallet'; import { getSelectedDydxChainId } from '@/state/appSelectors'; import { useAppSelector } from '@/state/appTypes'; @@ -52,31 +50,15 @@ export const useWalletConnection = () => { key: LocalStorageKey.EvmAddress, defaultValue: undefined, }); - const { address: evmAddressWagmi, isConnected: isConnectedWagmi } = useAccountWagmi(); const publicClientWagmi = usePublicClientWagmi(); const { data: signerWagmi } = useWalletClientWagmi(); const { disconnectAsync: disconnectWagmi } = useDisconnectWagmi(); - const { - solAddress: solAddressPhantom, - connect: connectPhantom, - disconnect: disconnectPhantom, - } = usePhantomWallet(); - - // SOL wallet connection - const [solAddress, saveSolAddress] = useLocalStorage({ - key: LocalStorageKey.SolAddress, - defaultValue: undefined, - }); - useEffect(() => { + // Cache last connected address if (evmAddressWagmi) saveEvmAddress(evmAddressWagmi); - }, [evmAddressWagmi, saveEvmAddress]); - - useEffect(() => { - if (solAddressPhantom) saveSolAddress(solAddressPhantom); - }, [solAddressPhantom, saveSolAddress]); + }, [evmAddressWagmi]); // Cosmos wallet connection const [dydxAddress, saveDydxAddress] = useLocalStorage({ @@ -92,7 +74,7 @@ export const useWalletConnection = () => { useEffect(() => { // Cache last connected address if (dydxAddressGraz) saveDydxAddress(dydxAddressGraz as DydxAddress); - }, [dydxAddressGraz, saveDydxAddress]); + }, [dydxAddressGraz]); // Wallet connection @@ -144,11 +126,11 @@ export const useWalletConnection = () => { async ({ walletType: wType, forceConnect, - isEvmAccountConnected, + isAccountConnected, }: { walletType?: WalletType; forceConnect?: boolean; - isEvmAccountConnected?: boolean; + isAccountConnected?: boolean; }) => { if (!wType) return { walletType: wType, walletConnectionType }; @@ -178,11 +160,9 @@ export const useWalletConnection = () => { } } else if (walletConnection.type === WalletConnectionType.TestWallet) { saveEvmAddress(STRING_KEYS.TEST_WALLET as EvmAddress); - } else if (walletConnection.type === WalletConnectionType.Phantom) { - await connectPhantom(); } else { // if account connected (via remember me), do not show wagmi popup until forceConnect - if (!isConnectedWagmi && (!!forceConnect || !isEvmAccountConnected)) { + if (!isConnectedWagmi && (!!forceConnect || !isAccountConnected)) { await connectWagmi({ connector: resolveWagmiConnector({ walletType: wType, @@ -209,44 +189,17 @@ export const useWalletConnection = () => { walletConnectionType: walletConnection?.type, }; }, - [ - walletConnectionType, - isConnectedWagmi, - ready, - authenticated, - login, - isConnectedGraz, - stringGetter, - connectGraz, - saveEvmAddress, - connectPhantom, - connectWagmi, - walletConnectConfig, - ] + [isConnectedGraz, signerGraz, isConnectedWagmi, signerWagmi, ready, authenticated, login] ); const disconnectWallet = useCallback(async () => { saveEvmAddress(undefined); saveDydxAddress(undefined); - saveSolAddress(undefined); if (isConnectedWagmi) await disconnectWagmi(); if (isConnectedGraz) await disconnectGraz(); if (authenticated) await logout(); - if (solAddressPhantom) await disconnectPhantom(); - }, [ - saveEvmAddress, - saveDydxAddress, - saveSolAddress, - isConnectedWagmi, - disconnectWagmi, - isConnectedGraz, - disconnectGraz, - authenticated, - logout, - solAddressPhantom, - disconnectPhantom, - ]); + }, [isConnectedGraz, isConnectedWagmi, authenticated, logout]); // Wallet selection @@ -269,16 +222,15 @@ export const useWalletConnection = () => { const walletConnection = getWalletConnection({ walletType: selectedWalletType }); setWalletType(selectedWalletType); setWalletConnectionType(walletConnection?.type); - const isEvmAccountConnected = + const isAccountConnected = evmAddress && evmDerivedAddresses[evmAddress]?.encryptedSignature; if ( walletConnection && walletConnection.type !== WalletConnectionType.Privy && walletConnection.type !== WalletConnectionType.CosmosSigner && walletConnection.type !== WalletConnectionType.TestWallet && - walletConnection.type !== WalletConnectionType.Phantom && !isConnectedWagmi && - !isEvmAccountConnected + !isAccountConnected ) { await reconnectWagmi({ connectors: [ @@ -289,12 +241,6 @@ export const useWalletConnection = () => { }), ], }); - } else if ( - walletConnection && - walletConnection.type === WalletConnectionType.Phantom && - !solAddress - ) { - await connectPhantom(); } } })(); @@ -309,8 +255,6 @@ export const useWalletConnection = () => { setWalletConnectionType, isConnectedWagmi, walletConnectConfig, - connectPhantom, - solAddress, ]); const selectWalletType = useCallback( @@ -326,7 +270,7 @@ export const useWalletConnection = () => { try { const { walletConnectionType: wConnectionType } = await connectWallet({ walletType: wType, - isEvmAccountConnected: Boolean( + isAccountConnected: Boolean( evmAddress && evmDerivedAddresses[evmAddress]?.encryptedSignature ), }); @@ -390,8 +334,6 @@ export const useWalletConnection = () => { walletType: selectedWalletType, forceConnect: true, }), - // Wallet connection (sol) - solAddress, // Wallet connection (Cosmos) dydxAddress, diff --git a/src/icons/index.ts b/src/icons/index.ts index f101e82e5..a1bb48328 100644 --- a/src/icons/index.ts +++ b/src/icons/index.ts @@ -94,7 +94,6 @@ export { default as MagicIcon } from './wallets/magic.svg'; export { default as MathWalletIcon } from './wallets/mathwallet.svg'; export { default as MetaMaskIcon } from './wallets/metamask.svg'; export { default as OkxWalletIcon } from './wallets/okx-wallet.svg'; -export { default as PhantomIcon } from './wallets/phantom.svg'; export { default as RainbowIcon } from './wallets/rainbow-wallet.svg'; export { default as TestWalletIcon } from './wallets/test-wallet.svg'; export { default as TokenPocketIcon } from './wallets/tokenpocket.svg'; diff --git a/src/icons/wallets/phantom.svg b/src/icons/wallets/phantom.svg deleted file mode 100644 index 4aaa39c08..000000000 --- a/src/icons/wallets/phantom.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/lib/wallet/index.ts b/src/lib/wallet/index.ts index c9f1cc0df..b2b5f7351 100644 --- a/src/lib/wallet/index.ts +++ b/src/lib/wallet/index.ts @@ -69,11 +69,6 @@ export const getWalletConnection = ({ type: WalletConnectionType.Privy, }; } - case WalletConnectionType.Phantom: { - return { - type: WalletConnectionType.Phantom, - }; - } default: { continue; } diff --git a/src/views/dialogs/OnboardingDialog/GenerateKeys.tsx b/src/views/dialogs/OnboardingDialog/GenerateKeys.tsx index 8f756ac46..fe765bfb4 100644 --- a/src/views/dialogs/OnboardingDialog/GenerateKeys.tsx +++ b/src/views/dialogs/OnboardingDialog/GenerateKeys.tsx @@ -8,7 +8,7 @@ import { AlertType } from '@/constants/alerts'; import { AnalyticsEvents } from '@/constants/analytics'; import { ButtonAction } from '@/constants/buttons'; import { STRING_KEYS } from '@/constants/localization'; -import { DydxAddress, WalletType } from '@/constants/wallets'; +import { DydxAddress } from '@/constants/wallets'; import { useAccounts } from '@/hooks/useAccounts'; import { useDydxClient } from '@/hooks/useDydxClient'; @@ -42,7 +42,7 @@ export const GenerateKeys = ({ status, setStatus, onKeysDerived = () => {} }: El const stringGetter = useStringGetter(); const [shouldRememberMe, setShouldRememberMe] = useState(false); - const { setWalletFromSignature, saveEvmSignature, saveSolSignature, walletType } = useAccounts(); + const { setWalletFromEvmSignature, saveEvmSignature } = useAccounts(); const [error, setError] = useState(); @@ -84,7 +84,7 @@ export const GenerateKeys = ({ status, setStatus, onKeysDerived = () => {} }: El }; // 2. Derive keys from EVM account - const { getWalletFromSignature } = useDydxClient(); + const { getWalletFromEvmSignature } = useDydxClient(); const { getSubaccounts } = useAccounts(); const isDeriving = ![ @@ -92,7 +92,7 @@ export const GenerateKeys = ({ status, setStatus, onKeysDerived = () => {} }: El EvmDerivedAccountStatus.Derived, ].includes(status); - const signMessageAsync = useSignForWalletDerivation(walletType); + const signTypedDataAsync = useSignForWalletDerivation(); const staticEncryptionKey = import.meta.env.VITE_PK_ENCRYPTION_KEY; @@ -103,13 +103,13 @@ export const GenerateKeys = ({ status, setStatus, onKeysDerived = () => {} }: El // 1. First signature setStatus(EvmDerivedAccountStatus.Deriving); - const signature = await signMessageAsync(); + const signature = await signTypedDataAsync(); track( AnalyticsEvents.OnboardingDeriveKeysSignatureReceived({ signatureNumber: 1, }) ); - const { wallet: dydxWallet } = await getWalletFromSignature({ signature }); + const { wallet: dydxWallet } = await getWalletFromEvmSignature({ signature }); // 2. Ensure signature is deterministic // Check if subaccounts exist @@ -125,8 +125,8 @@ export const GenerateKeys = ({ status, setStatus, onKeysDerived = () => {} }: El if (!hasPreviousTransactions) { setStatus(EvmDerivedAccountStatus.EnsuringDeterminism); + const additionalSignature = await signTypedDataAsync(); // Second signature - const additionalSignature = await signMessageAsync(); track( AnalyticsEvents.OnboardingDeriveKeysSignatureReceived({ signatureNumber: 2, @@ -150,17 +150,13 @@ export const GenerateKeys = ({ status, setStatus, onKeysDerived = () => {} }: El return; } - await setWalletFromSignature(signature); + await setWalletFromEvmSignature(signature); // 3: Remember me (encrypt and store signature) if (shouldRememberMe && staticEncryptionKey) { const encryptedSignature = AES.encrypt(signature, staticEncryptionKey).toString(); - if (walletType === WalletType.Phantom) { - saveSolSignature(encryptedSignature); - } else { - saveEvmSignature(encryptedSignature); - } + saveEvmSignature(encryptedSignature); } // 4. Done @@ -261,7 +257,7 @@ export const GenerateKeys = ({ status, setStatus, onKeysDerived = () => {} }: El } tw="[--withReceipt-backgroundColor:--color-layer-2]" > - {!isMatchingNetwork && walletType !== WalletType.Phantom ? ( + {!isMatchingNetwork ? (