Compare commits

...

1 Commits

Author SHA1 Message Date
jaredvu
5a91e56ac3
🚧 WAGMI 2 2024-01-09 13:28:21 -08:00
15 changed files with 4558 additions and 793 deletions

View File

@ -72,6 +72,7 @@
"@reduxjs/toolkit": "^1.9.5",
"@scure/bip32": "^1.3.0",
"@scure/bip39": "^1.2.0",
"@tanstack/react-query": "^5.17.9",
"@types/lodash": "^4.14.195",
"@types/styled-components": "^5.1.26",
"@visx/axis": "^3.1.0",
@ -104,15 +105,15 @@
"react-aria": "^3.25.0",
"react-dom": "^18.2.0",
"react-number-format": "^5.2.2",
"react-query": "^3.39.3",
"react-redux": "^8.1.1",
"react-router-dom": "^6.14.0",
"react-stately": "^3.23.0",
"reselect": "^4.1.8",
"stream-browserify": "^3.0.0",
"styled-components": "^5.3.11",
"use-latest": "^1.2.1",
"viem": "^1.12.2",
"wagmi": "^1.4.12"
"viem": "^2.0.0",
"wagmi": "^2.0.3"
},
"devDependencies": {
"@babel/core": "^7.22.5",

4884
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -39,7 +39,7 @@
"environments": {
"dydxprotocol-dev": {
"name": "v4 Dev",
"ethereumChainId": "5",
"ethereumChainId": "11155111",
"dydxChainId": "dydxprotocol-testnet",
"chainName": "dYdX Chain",
"chainLogo": "/dydx-chain.png",
@ -113,7 +113,7 @@
},
"dydxprotocol-dev-2": {
"name": "v4 Dev 2",
"ethereumChainId": "5",
"ethereumChainId": "11155111",
"dydxChainId": "dydxprotocol-testnet",
"chainName": "dYdX Chain",
"chainLogo": "/dydx-chain.png",
@ -186,7 +186,7 @@
},
"dydxprotocol-dev-4": {
"name": "v4 Dev 4",
"ethereumChainId": "5",
"ethereumChainId": "11155111",
"dydxChainId": "dydxprotocol-testnet",
"chainName": "dYdX Chain",
"chainLogo": "/dydx-chain.png",
@ -259,7 +259,7 @@
},
"dydxprotocol-dev-5": {
"name": "v4 Dev 5",
"ethereumChainId": "5",
"ethereumChainId": "11155111",
"dydxChainId": "dydxprotocol-testnet",
"chainName": "dYdX Chain",
"chainLogo": "/dydx-chain.png",
@ -332,7 +332,7 @@
},
"dydxprotocol-staging": {
"name": "v4 Staging",
"ethereumChainId": "5",
"ethereumChainId": "11155111",
"dydxChainId": "dydxprotocol-testnet",
"chainName": "dYdX Chain",
"chainLogo": "/dydx-chain.png",
@ -407,7 +407,7 @@
},
"dydxprotocol-staging-forced-update": {
"name": "v4 Staging Forced Update",
"ethereumChainId": "5",
"ethereumChainId": "11155111",
"dydxChainId": "dydxprotocol-testnet",
"chainName": "dYdX Chain",
"chainLogo": "/dydx-chain.png",
@ -480,7 +480,7 @@
},
"dydxprotocol-staging-west": {
"name": "v4 Staging West",
"ethereumChainId": "5",
"ethereumChainId": "11155111",
"dydxChainId": "dydxprotocol-testnet",
"chainName": "dYdX Chain",
"chainLogo": "/dydx-chain.png",
@ -555,7 +555,7 @@
},
"dydxprotocol-testnet": {
"name": "v4 Public Testnet",
"ethereumChainId": "5",
"ethereumChainId": "11155111",
"dydxChainId": "dydx-testnet-4",
"chainName": "dYdX Chain",
"chainLogo": "/dydx-chain.png",
@ -634,7 +634,7 @@
},
"dydxprotocol-testnet-dydx": {
"name": "v4 Public Testnet/dYdX",
"ethereumChainId": "5",
"ethereumChainId": "11155111",
"dydxChainId": "dydx-testnet-4",
"chainName": "dYdX Chain",
"chainLogo": "/dydx-chain.png",
@ -710,7 +710,7 @@
},
"dydxprotocol-testnet-nodefleet": {
"name": "v4 Public Testnet/nodefleet",
"ethereumChainId": "5",
"ethereumChainId": "11155111",
"dydxChainId": "dydx-testnet-4",
"chainName": "dYdX Chain",
"chainLogo": "/dydx-chain.png",
@ -786,7 +786,7 @@
},
"dydxprotocol-testnet-kingnodes": {
"name": "v4 Public Testnet/KingNodes",
"ethereumChainId": "5",
"ethereumChainId": "11155111",
"dydxChainId": "dydx-testnet-4",
"chainName": "dYdX Chain",
"chainLogo": "/dydx-chain.png",
@ -862,7 +862,7 @@
},
"dydxprotocol-testnet-liquify": {
"name": "v4 Public Testnet/Liquify",
"ethereumChainId": "5",
"ethereumChainId": "11155111",
"dydxChainId": "dydx-testnet-4",
"chainName": "dYdX Chain",
"chainLogo": "/dydx-chain.png",
@ -938,7 +938,7 @@
},
"dydxprotocol-testnet-polkachu": {
"name": "v4 Public Testnet/Polkahcu",
"ethereumChainId": "5",
"ethereumChainId": "11155111",
"dydxChainId": "dydx-testnet-4",
"chainName": "dYdX Chain",
"chainLogo": "/dydx-chain.png",
@ -1005,7 +1005,7 @@
},
"dydxprotocol-testnet-bware": {
"name": "v4 Public Testnet/BWare",
"ethereumChainId": "5",
"ethereumChainId": "11155111",
"dydxChainId": "dydx-testnet-4",
"chainName": "dYdX Chain",
"chainLogo": "/dydx-chain.png",

View File

@ -1,8 +1,8 @@
import { lazy, Suspense } from 'react';
import { Navigate, Route, Routes } from 'react-router-dom';
import styled, { AnyStyledComponent, css } from 'styled-components';
import { WagmiConfig } from 'wagmi';
import { QueryClient, QueryClientProvider } from 'react-query';
import { WagmiProvider } from 'wagmi';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { GrazProvider } from 'graz';
import { AppRoute, DEFAULT_TRADE_ROUTE } from '@/constants/routes';
@ -120,9 +120,9 @@ const wrapProvider = (Component: React.ComponentType<any>, props?: any) => {
};
const providers = [
wrapProvider(WagmiProvider, { config }),
wrapProvider(QueryClientProvider, { client: queryClient }),
wrapProvider(GrazProvider),
wrapProvider(WagmiConfig, { config }),
wrapProvider(LocaleProvider),
wrapProvider(RestrictionProvider),
wrapProvider(DydxProvider),

5
src/constants/queries.ts Normal file
View File

@ -0,0 +1,5 @@
export enum QueryKeys {
ACCOUNT_BALANCE = 'ACCOUNT_BALANCE',
LAUNCH_INCENTIVES = 'LAUNCH_INCENTIVES',
TRANSACTION_STATUS = 'TRANSACTION_STATUS',
}

View File

@ -52,7 +52,7 @@ type WalletConnectionTypeConfig = {
wagmiConnectorId?: string;
};
export const walletConnectionTypes: Record<WalletConnectionType, WalletConnectionTypeConfig> = {
export const WALLET_CONNECTION_TYPES: Record<WalletConnectionType, WalletConnectionTypeConfig> = {
[WalletConnectionType.CoinbaseWalletSdk]: {
name: 'Coinbase Wallet SDK',
wagmiConnectorId: 'coinbaseWallet',
@ -110,7 +110,7 @@ export const WALLET_CONNECT_EXPLORER_RECOMMENDED_IDS = Object.values(
WALLET_CONNECT_EXPLORER_RECOMMENDED_WALLETS
);
type WalletConfig = {
export type WalletConfig = {
type: WalletType;
stringKey: string;
icon: string;
@ -274,6 +274,17 @@ export type WalletConnection = {
provider?: ExternalProvider;
};
export type WalletConnectConfig = {
client: {
name: string;
description: string;
iconUrl: string;
};
v2: {
projectId: string;
};
};
// dYdX Chain wallets
export const COSMOS_DERIVATION_PATH = "m/44'/118'/0'/0/0";

View File

@ -1,11 +1,12 @@
import { useCallback } from 'react';
import { useCallback, useEffect } from 'react';
import { shallowEqual, useSelector } from 'react-redux';
import { useBalance } from 'wagmi';
import { useBalance, useBlockNumber } from 'wagmi';
import { StargateClient } from '@cosmjs/stargate';
import { useQuery } from 'react-query';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { formatUnits } from 'viem';
import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
import { QueryKeys } from '@/constants/queries';
import { EvmAddress } from '@/constants/wallets';
import { convertBech32Address } from '@/lib/addressUtils';
@ -52,15 +53,27 @@ export const useAccountBalance = ({
const evmChainId = Number(ENVIRONMENT_CONFIG_MAP[selectedNetwork].ethereumChainId);
const stakingBalances = useSelector(getStakingBalances, shallowEqual);
const evmQuery = useBalance({
enabled: Boolean(!isCosmosChain && addressOrDenom?.startsWith('0x')),
const queryClient = useQueryClient();
const { data: blockNumber } = useBlockNumber({ watch: true });
const {
data: evmQuery,
status: evmBalanceStatus,
fetchStatus: evmBalanceFetchStatus,
queryKey,
} = useBalance({
query: {
enabled: Boolean(!isCosmosChain && addressOrDenom?.startsWith('0x')),
},
address: evmAddress,
chainId: typeof chainId === 'number' ? chainId : Number(evmChainId),
token:
addressOrDenom === CHAIN_DEFAULT_TOKEN_ADDRESS ? undefined : (addressOrDenom as EvmAddress),
watch: true,
});
useEffect(() => {
queryClient.invalidateQueries({ queryKey });
}, [blockNumber]);
const cosmosQueryFn = useCallback(async () => {
if (dydxAddress && bech32AddrPrefix && rpc && addressOrDenom) {
const address = convertBech32Address({
@ -78,7 +91,7 @@ export const useAccountBalance = ({
const cosmosQuery = useQuery({
enabled: Boolean(isCosmosChain && dydxAddress && bech32AddrPrefix && rpc && addressOrDenom),
queryKey: `accountBalances_${chainId}_${addressOrDenom}`,
queryKey: [QueryKeys.ACCOUNT_BALANCE, chainId, addressOrDenom],
queryFn: cosmosQueryFn,
refetchOnWindowFocus: false,
refetchOnMount: false,
@ -87,8 +100,11 @@ export const useAccountBalance = ({
staleTime: 10_000,
});
const { formatted: evmBalance } = evmQuery.data || {};
const balance = isCosmosChain ? cosmosQuery.data : evmBalance;
const balance = isCosmosChain
? cosmosQuery.data
: evmQuery
? formatUnits(evmQuery?.value, evmQuery?.decimals)
: undefined;
const nativeTokenCoinBalance = balances?.[chainTokenDenom];
const nativeTokenBalance = MustBigNumber(nativeTokenCoinBalance?.amount);
@ -104,7 +120,7 @@ export const useAccountBalance = ({
nativeTokenBalance,
nativeStakingBalance,
usdcBalance,
queryStatus: isCosmosChain ? cosmosQuery.status : evmQuery.status,
isQueryFetching: isCosmosChain ? cosmosQuery.isFetching : evmQuery.fetchStatus === 'fetching',
queryStatus: isCosmosChain ? cosmosQuery.status : evmBalanceStatus,
isQueryFetching: isCosmosChain ? cosmosQuery.isFetching : evmBalanceFetchStatus === 'fetching',
};
};

View File

@ -39,7 +39,6 @@ const useAccountsContext = () => {
walletConnectionType,
selectWalletType,
selectedWalletType,
selectedWalletError,
evmAddress,
signerWagmi,
publicClientWagmi,
@ -300,9 +299,7 @@ const useAccountsContext = () => {
walletConnectionType,
// Wallet selection
selectWalletType,
selectedWalletType,
selectedWalletError,
// Wallet connection (EVM)
evmAddress,

View File

@ -1,8 +1,9 @@
import { createContext, useContext, useCallback, useEffect, useMemo } from 'react';
import { useQuery } from 'react-query';
import { useQuery } from '@tanstack/react-query';
import { LOCAL_STORAGE_VERSIONS, LocalStorageKey } from '@/constants/localStorage';
import { type TransferNotifcation } from '@/constants/notifications';
import { QueryKeys } from '@/constants/queries';
import { useAccounts } from '@/hooks/useAccounts';
import { fetchSquidStatus, STATUS_ERROR_GRACE_PERIOD } from '@/lib/squid';
@ -68,8 +69,8 @@ const useLocalNotificationsContext = () => {
[transferNotifications]
);
useQuery({
queryKey: 'getTransactionStatus',
const { data: newTransferNotifications } = useQuery({
queryKey: [QueryKeys.TRANSACTION_STATUS],
queryFn: async () => {
const processTransferNotifications = async (transferNotifications: TransferNotifcation[]) => {
const newTransferNotifications = await Promise.all(
@ -84,10 +85,11 @@ const useLocalNotificationsContext = () => {
status: currentStatus,
} = transferNotification;
// @ts-ignore status.errors is not in the type definition but can be returned
// also error can some time come back as an empty object so we need to ignore for that
const hasErrors = !!currentStatus?.errors ||
(currentStatus?.error && Object.keys(currentStatus.error).length !== 0);
const hasErrors =
// @ts-ignore status.errors is not in the type definition but can be returned
// also error can some time come back as an empty object so we need to ignore for that
!!currentStatus?.errors ||
(currentStatus?.error && Object.keys(currentStatus.error).length !== 0);
if (
!hasErrors &&
@ -95,11 +97,14 @@ const useLocalNotificationsContext = () => {
currentStatus?.squidTransactionStatus === 'ongoing')
) {
try {
const status = await fetchSquidStatus({
transactionId: txHash,
toChainId,
fromChainId,
}, isCctp);
const status = await fetchSquidStatus(
{
transactionId: txHash,
toChainId,
fromChainId,
},
isCctp
);
if (status) {
transferNotification.status = status;
@ -121,12 +126,18 @@ const useLocalNotificationsContext = () => {
return newTransferNotifications;
};
const newTransferNotifications = await processTransferNotifications(transferNotifications);
setTransferNotifications(newTransferNotifications);
return newTransferNotifications;
},
refetchInterval: TRANSFER_STATUS_FETCH_INTERVAL,
});
useEffect(() => {
if (!newTransferNotifications) return;
setTransferNotifications(newTransferNotifications);
}, [newTransferNotifications]);
return {
transferNotifications,
addTransferNotification,

View File

@ -1,5 +1,5 @@
import { useCallback, useEffect, useMemo } from 'react';
import { useNetwork, useSwitchNetwork } from 'wagmi';
import { UseSwitchChainReturnType, useAccount, useSwitchChain } from 'wagmi';
export const useMatchingEvmNetwork = ({
chainId,
@ -8,10 +8,10 @@ export const useMatchingEvmNetwork = ({
}: {
chainId?: string | number;
switchAutomatically?: boolean;
onError?: (error: Error) => void;
onError?: Parameters<UseSwitchChainReturnType['switchChainAsync']>[1]['onError'];
}) => {
const { chain } = useNetwork();
const { isLoading, switchNetworkAsync } = useSwitchNetwork({ onError });
const { chain } = useAccount();
const { switchChainAsync, isPending } = useSwitchChain();
// If chainId is not a number, we can assume it is a non EVM compatible chain
const isMatchingNetwork = useMemo(
@ -21,7 +21,14 @@ export const useMatchingEvmNetwork = ({
const matchNetwork = useCallback(async () => {
if (!isMatchingNetwork) {
await switchNetworkAsync?.(Number(chainId));
await switchChainAsync?.(
{
chainId: Number(chainId),
},
{
onError,
}
);
}
}, [chainId, chain]);
@ -34,6 +41,6 @@ export const useMatchingEvmNetwork = ({
return {
isMatchingNetwork,
matchNetwork,
isSwitchingNetwork: isLoading,
isSwitchingNetwork: isPending,
};
};

View File

@ -104,12 +104,13 @@ export const useWalletConnection = () => {
[walletConnectConfig, walletType, walletConnectionType]
);
const { connectAsync: connectWagmi } = useConnectWagmi({ connector: wagmiConnector })
const { connectAsync: connectWagmi } = useConnectWagmi();
const { suggestAndConnect: connectGraz } = useConnectGraz();
const connectWallet = useCallback(
async ({ walletType }: { walletType: WalletType }) => {
const walletConnection = getWalletConnection({ walletType });
console.log({ walletConnection });
try {
if (!walletConnection) {
@ -133,13 +134,17 @@ export const useWalletConnection = () => {
}
} else {
if (!isConnectedWagmi) {
await connectWagmi({
connector: resolveWagmiConnector({
walletType,
walletConnection,
walletConnectConfig,
}),
const connector = resolveWagmiConnector({
walletType,
walletConnection,
walletConnectConfig,
});
if (connector) {
await connectWagmi({
connector,
});
}
}
}
} catch (error) {
@ -156,7 +161,7 @@ export const useWalletConnection = () => {
walletConnectionType: walletConnection.type,
};
},
[isConnectedGraz, signerGraz, isConnectedWagmi, signerWagmi]
[isConnectedGraz, signerGraz, isConnectedWagmi, signerWagmi, walletConnectConfig]
);
const disconnectWallet = useCallback(async () => {
@ -204,10 +209,9 @@ export const useWalletConnection = () => {
})();
}, [selectedWalletType, signerWagmi, signerGraz]);
const selectWalletType = async (walletType: WalletType | undefined) => {
const selectWalletType = (walletType: WalletType | undefined) => {
if (selectedWalletType) {
setSelectedWalletType(undefined);
await new Promise(requestAnimationFrame);
}
setSelectedWalletType(walletType);

View File

@ -1,7 +1,6 @@
import { createConfig, configureChains, mainnet, Chain, Connector, usePublicClient } from 'wagmi';
import { goerli } from 'wagmi/chains';
import { createConfig, createConnector, http, usePublicClient } from 'wagmi';
import {
type Chain,
arbitrum,
arbitrumGoerli,
avalanche,
@ -26,34 +25,33 @@ import {
fantomTestnet,
celo,
celoAlfajores,
} from 'viem/chains';
mainnet,
goerli,
sepolia,
} from 'wagmi/chains';
import { alchemyProvider } from 'wagmi/providers/alchemy';
import { jsonRpcProvider } from 'wagmi/providers/jsonRpc';
import { publicProvider } from 'wagmi/providers/public';
import { CoinbaseWalletConnector } from 'wagmi/connectors/coinbaseWallet';
import { InjectedConnector } from 'wagmi/connectors/injected';
import { MetaMaskConnector } from 'wagmi/connectors/metaMask';
import { WalletConnectConnector } from 'wagmi/connectors/walletConnect';
import { coinbaseWallet, injected, metaMask, walletConnect } from 'wagmi/connectors';
import type { ExternalProvider } from '@ethersproject/providers';
import {
type WalletConnectConfig,
type WalletConnection,
WalletConnectionType,
type WalletType,
walletConnectionTypes,
WalletType,
WALLET_CONNECTION_TYPES,
wallets,
WALLET_CONNECT_EXPLORER_RECOMMENDED_IDS,
WalletConfig,
} from '@/constants/wallets';
import { isTruthy } from './isTruthy';
import { log } from './telemetry';
// Config
export const WAGMI_SUPPORTED_CHAINS: Chain[] = [
const WAGMI_SUPPORTED_CHAINS: Parameters<typeof createConfig>[0]['chains'] = [
mainnet,
goerli,
sepolia,
arbitrum,
arbitrumGoerli,
avalanche,
@ -80,118 +78,104 @@ export const WAGMI_SUPPORTED_CHAINS: Chain[] = [
celoAlfajores,
];
const { chains, publicClient, webSocketPublicClient } = configureChains(
WAGMI_SUPPORTED_CHAINS,
[
import.meta.env.VITE_ALCHEMY_API_KEY &&
alchemyProvider({ apiKey: import.meta.env.VITE_ALCHEMY_API_KEY }),
jsonRpcProvider({
rpc: (chain) => ({ http: chain.rpcUrls.default.http[0] }),
}),
publicProvider(),
].filter(isTruthy)
);
export const config = createConfig({
chains: WAGMI_SUPPORTED_CHAINS,
transports: Object.fromEntries(
Object.values(WAGMI_SUPPORTED_CHAINS).map(({ id }) => [id, http()])
),
});
const injectedConnectorOptions = {
chains,
options: {
name: 'Injected',
const createdInjectedConnectorWithProvider = ({ provider }: { provider: ExternalProvider }) => {
console.log(provider);
return injected({
target() {
return {
id: 'windowProvider',
name: 'Injected',
provider,
};
},
shimDisconnect: true,
shimChainChangedDisconnect: false,
},
});
};
type WalletConnectConfig = {
client: {
name: string;
description: string;
iconUrl: string;
};
v2: {
projectId: string;
};
const getConnector = ({
walletConnectionType,
walletConnectConfig,
}: {
walletConnectionType: WalletConnectionType;
walletConnectConfig: WalletConnectConfig;
}) => {
console.log(walletConnectionType);
switch (walletConnectionType) {
case WalletConnectionType.WalletConnect2:
return [
walletConnect(
getConnectorInfoForWc2({
walletConnectConfig,
})
),
];
case WalletConnectionType.CoinbaseWalletSdk:
return [
coinbaseWallet({
appName: 'dYdX',
appLogoUrl: walletConnectConfig.client.iconUrl,
reloadOnDisconnect: false,
darkMode: true,
}),
];
case WalletConnectionType.InjectedEip1193:
return injected({
target() {
return {
id: 'windowProvider',
name: 'Injected',
provider: window.ethereum,
};
},
shimDisconnect: true,
});
case WalletConnectionType.CosmosSigner:
default: {
return undefined;
}
}
};
const getWalletconnect2ConnectorOptions = (
config: WalletConnectConfig
): ConstructorParameters<typeof WalletConnectConnector>[0] => ({
chains,
options: {
projectId: config.v2.projectId,
const getConnectorInfoForWc2 = ({
walletConnectId,
walletConnectConfig,
}: {
walletConnectId?: string;
walletConnectConfig: WalletConnectConfig;
}) => {
const explorerRecommendedWalletIds = walletConnectId
? [walletConnectId]
: WALLET_CONNECT_EXPLORER_RECOMMENDED_IDS;
return {
projectId: walletConnectConfig.v2.projectId,
metadata: {
name: config.client.name,
description: config.client.description,
name: walletConnectConfig.client.name,
description: walletConnectConfig.client.description,
url: import.meta.env.VITE_BASE_URL,
icons: [config.client.iconUrl],
icons: [walletConnectConfig.client.iconUrl],
},
showQrModal: true,
qrModalOptions: {
themeMode: 'dark' as const,
themeVariables: {
'--wcm-accent-color': '#5973fe',
'--wcm-accent-color': 'var(--color-accent)',
'--wcm-font-family': 'var(--fontFamily-base)',
'--wcm-background-color': 'var(--color-accent)',
},
explorerRecommendedWalletIds: WALLET_CONNECT_EXPLORER_RECOMMENDED_IDS,
explorerRecommendedWalletIds,
},
},
});
const getConnectors = (walletConnectConfig: WalletConnectConfig) => [
new MetaMaskConnector({
chains,
options: {
shimDisconnect: true,
},
}),
new CoinbaseWalletConnector({
chains,
options: {
appName: 'dYdX',
reloadOnDisconnect: false,
},
}),
new WalletConnectConnector(getWalletconnect2ConnectorOptions(walletConnectConfig)),
new InjectedConnector(injectedConnectorOptions),
];
export const config = createConfig({
autoConnect: true,
// connectors,
publicClient,
webSocketPublicClient,
});
// Custom connectors
import type { ExternalProvider } from '@ethersproject/providers';
// Create a custom wagmi InjectedConnector using a specific injected EIP-1193 provider (instead of wagmi's default detection logic)
const createInjectedConnectorWithProvider = (provider: ExternalProvider) =>
new (class extends InjectedConnector {
getProvider = async () =>
provider as unknown as Awaited<ReturnType<InjectedConnector['getProvider']>>;
})(injectedConnectorOptions) as InjectedConnector;
const createWalletConnect2ConnectorWithId = (
walletconnectId: string,
walletConnectConfig: WalletConnectConfig
) => {
const walletconnect2ConnectorOptions = getWalletconnect2ConnectorOptions(walletConnectConfig);
return new WalletConnectConnector({
...walletconnect2ConnectorOptions,
options: {
...walletconnect2ConnectorOptions.options,
qrModalOptions: {
...walletconnect2ConnectorOptions.options.qrModalOptions,
explorerRecommendedWalletIds: [walletconnectId],
explorerExcludedWalletIds: 'ALL',
},
},
});
};
};
// Custom connector from wallet selection
export const resolveWagmiConnector = ({
walletType,
walletConnection,
@ -202,13 +186,23 @@ export const resolveWagmiConnector = ({
walletConnectConfig: WalletConnectConfig;
}) => {
const walletConfig = wallets[walletType];
const walletConnectionConfig = walletConnectionTypes[walletConnection.type];
return walletConnection.type === WalletConnectionType.InjectedEip1193 && walletConnection.provider
? createInjectedConnectorWithProvider(walletConnection.provider)
: walletConnection.type === WalletConnectionType.WalletConnect2 && walletConfig.walletconnect2Id
? createWalletConnect2ConnectorWithId(walletConfig.walletconnect2Id, walletConnectConfig)
: getConnectors(walletConnectConfig).find(
({ id }: { id: string }) => id === walletConnectionConfig.wagmiConnectorId
);
if (walletConnection.type === WalletConnectionType.InjectedEip1193 && walletConnection.provider) {
if (walletType === WalletType.MetaMask) {
return metaMask();
}
return createdInjectedConnectorWithProvider({ provider: walletConnection.provider });
} else if (
walletConnection.type === WalletConnectionType.WalletConnect2 &&
walletConfig.walletconnect2Id
) {
return walletConnect(
getConnectorInfoForWc2({
walletConnectId: walletConfig.walletconnect2Id,
walletConnectConfig,
})
);
} else {
return getConnector({ walletConnectionType: walletConnection.type, walletConnectConfig });
}
};

View File

@ -1,11 +1,12 @@
import { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { useQuery } from 'react-query';
import { useQuery } from '@tanstack/react-query';
import styled, { AnyStyledComponent } from 'styled-components';
import { STRING_KEYS } from '@/constants/localization';
import { ButtonAction } from '@/constants/buttons';
import { DialogTypes } from '@/constants/dialogs';
import { QueryKeys } from '@/constants/queries';
import breakpoints from '@/styles/breakpoints';
import { useAccounts, useBreakpoints, useStringGetter } from '@/hooks';
@ -68,17 +69,24 @@ const EstimatedRewards = () => {
const stringGetter = useStringGetter();
const { dydxAddress } = useAccounts();
const { data, isLoading } = useQuery({
const { data, isLoading, status, error } = useQuery({
enabled: !!dydxAddress,
queryKey: `launch_incentives_rewards_${dydxAddress ?? ''}`,
queryKey: [QueryKeys.LAUNCH_INCENTIVES, dydxAddress, SEASON_NUMBER],
queryFn: async () => {
if (!dydxAddress) return undefined;
const resp = await fetch(`https://cloud.chaoslabs.co/query/api/dydx/points/${dydxAddress}?n=${SEASON_NUMBER}`);
const resp = await fetch(
`https://cloud.chaoslabs.co/query/api/dydx/points/${dydxAddress}?n=${SEASON_NUMBER}`
);
return (await resp.json())?.incentivePoints;
},
onError: (error: Error) => log('LaunchIncentives/fetchPoints', error),
});
useEffect(() => {
if (status === 'error') {
log('LaunchIncentives/fetchPoints', error);
}
}, [status]);
return (
<Styled.EstimatedRewardsCard>
<Styled.EstimatedRewardsCardContent>

View File

@ -3,19 +3,18 @@ import styled, { AnyStyledComponent } from 'styled-components';
import { useDispatch } from 'react-redux';
import { AlertType } from '@/constants/alerts';
import { STRING_KEYS } from '@/constants/localization';
import { WalletType, wallets } from '@/constants/wallets';
import { ButtonAction, ButtonSize } from '@/constants/buttons';
import { STRING_KEYS } from '@/constants/localization';
import { WalletType, wallets } from '@/constants/wallets';
import { useStringGetter, useURLConfigs } from '@/hooks';
import { useDisplayedWallets } from '@/hooks/useDisplayedWallets';
import { useWalletConnection } from '@/hooks/useWalletConnection';
import { AlertMessage } from '@/components/AlertMessage';
import { Button } from '@/components/Button';
import { Icon } from '@/components/Icon';
import { Link } from '@/components/Link';
import { useAccounts, useStringGetter, useURLConfigs } from '@/hooks';
import { useDisplayedWallets } from '@/hooks/useDisplayedWallets';
import { breakpoints } from '@/styles';
import { layoutMixins } from '@/styles/layoutMixins';
@ -25,7 +24,7 @@ export const ChooseWallet = () => {
const displayedWallets = useDisplayedWallets();
const { selectWalletType, selectedWalletType, selectedWalletError } = useAccounts();
const { selectWalletType, selectedWalletType, selectedWalletError } = useWalletConnection();
return (
<>

View File

@ -86,13 +86,7 @@ export const GenerateKeys = ({
].includes(status);
const signTypedData = getSignTypedData(selectedNetwork);
const { signTypedDataAsync } = useSignTypedData({
...signTypedData,
domain: {
...signTypedData.domain,
chainId,
},
});
const { signTypedDataAsync } = useSignTypedData();
const staticEncryptionKey = import.meta.env.VITE_PK_ENCRYPTION_KEY;
@ -103,7 +97,13 @@ export const GenerateKeys = ({
// 1. First signature
setStatus(EvmDerivedAccountStatus.Deriving);
const signature = await signTypedDataAsync();
const signature = await signTypedDataAsync({
...signTypedData,
domain: {
...signTypedData.domain,
chainId,
},
});
const { wallet: dydxWallet } = await getWalletFromEvmSignature({ signature });
// 2. Ensure signature is deterministic
@ -121,7 +121,13 @@ export const GenerateKeys = ({
setStatus(EvmDerivedAccountStatus.EnsuringDeterminism);
// Second signature
const additionalSignature = await signTypedDataAsync();
const additionalSignature = await signTypedDataAsync({
...signTypedData,
domain: {
...signTypedData.domain,
chainId,
},
});
if (signature !== additionalSignature) {
throw new Error(