bridge_ui: WalletConnect support for EVM chains
Updated ethers dependency
This commit is contained in:
parent
a2917095a9
commit
62968c3535
File diff suppressed because it is too large
Load Diff
|
@ -19,6 +19,7 @@
|
|||
"@solana/wallet-adapter-wallets": "^0.16.1",
|
||||
"@solana/web3.js": "^1.35.1",
|
||||
"@terra-money/wallet-provider": "^3.8.0",
|
||||
"@walletconnect/web3-provider": "^1.7.8",
|
||||
"algosdk": "^1.15.0",
|
||||
"axios": "^0.21.1",
|
||||
"bech32": "^1.1.4",
|
||||
|
@ -26,7 +27,7 @@
|
|||
"borsh": "^0.4.0",
|
||||
"bs58": "^4.0.1",
|
||||
"clsx": "^1.1.1",
|
||||
"ethers": "^5.4.1",
|
||||
"ethers": "^5.6.8",
|
||||
"js-base64": "^3.6.1",
|
||||
"luxon": "^2.3.1",
|
||||
"notistack": "^1.0.10",
|
||||
|
|
|
@ -1,18 +1,36 @@
|
|||
import { useCallback, useState } from "react";
|
||||
import { Typography } from "@material-ui/core";
|
||||
import { useEthereumProvider } from "../contexts/EthereumProviderContext";
|
||||
import ToggleConnectedButton from "./ToggleConnectedButton";
|
||||
import EvmConnectWalletDialog from "./EvmConnectWalletDialog";
|
||||
import { ChainId } from "@certusone/wormhole-sdk";
|
||||
|
||||
const EthereumSignerKey = ({ chainId }: { chainId: ChainId }) => {
|
||||
const { disconnect, signerAddress, providerError } = useEthereumProvider();
|
||||
|
||||
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
||||
|
||||
const openDialog = useCallback(() => {
|
||||
setIsDialogOpen(true);
|
||||
}, [setIsDialogOpen]);
|
||||
|
||||
const closeDialog = useCallback(() => {
|
||||
setIsDialogOpen(false);
|
||||
}, [setIsDialogOpen]);
|
||||
|
||||
const EthereumSignerKey = () => {
|
||||
const { connect, disconnect, signerAddress, providerError } =
|
||||
useEthereumProvider();
|
||||
return (
|
||||
<>
|
||||
<ToggleConnectedButton
|
||||
connect={connect}
|
||||
connect={openDialog}
|
||||
disconnect={disconnect}
|
||||
connected={!!signerAddress}
|
||||
pk={signerAddress || ""}
|
||||
/>
|
||||
<EvmConnectWalletDialog
|
||||
isOpen={isDialogOpen}
|
||||
onClose={closeDialog}
|
||||
chainId={chainId}
|
||||
/>
|
||||
{providerError ? (
|
||||
<Typography variant="body2" color="error">
|
||||
{providerError}
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
import { ChainId } from "@certusone/wormhole-sdk";
|
||||
import {
|
||||
Dialog,
|
||||
DialogTitle,
|
||||
IconButton,
|
||||
List,
|
||||
ListItem,
|
||||
ListItemIcon,
|
||||
ListItemText,
|
||||
makeStyles,
|
||||
} from "@material-ui/core";
|
||||
import CloseIcon from "@material-ui/icons/Close";
|
||||
import { useCallback } from "react";
|
||||
import {
|
||||
Connection,
|
||||
ConnectType,
|
||||
useEthereumProvider,
|
||||
} from "../contexts/EthereumProviderContext";
|
||||
import { getEvmChainId } from "../utils/consts";
|
||||
import { EVM_RPC_MAP } from "../utils/metaMaskChainParameters";
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
flexTitle: {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
"& > div": {
|
||||
flexGrow: 1,
|
||||
marginRight: theme.spacing(4),
|
||||
},
|
||||
"& > button": {
|
||||
marginRight: theme.spacing(-1),
|
||||
},
|
||||
},
|
||||
icon: {
|
||||
height: 24,
|
||||
width: 24,
|
||||
},
|
||||
}));
|
||||
|
||||
const WalletOptions = ({
|
||||
connection,
|
||||
connect,
|
||||
onClose,
|
||||
}: {
|
||||
connection: Connection;
|
||||
connect: (connectType: ConnectType) => void;
|
||||
onClose: () => void;
|
||||
}) => {
|
||||
const classes = useStyles();
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
connect(connection.connectType);
|
||||
onClose();
|
||||
}, [connect, connection, onClose]);
|
||||
|
||||
return (
|
||||
<ListItem button onClick={handleClick}>
|
||||
<ListItemIcon>
|
||||
<img
|
||||
src={connection.icon}
|
||||
alt={connection.name}
|
||||
className={classes.icon}
|
||||
/>
|
||||
</ListItemIcon>
|
||||
<ListItemText>{connection.name}</ListItemText>
|
||||
</ListItem>
|
||||
);
|
||||
};
|
||||
|
||||
const EvmConnectWalletDialog = ({
|
||||
isOpen,
|
||||
onClose,
|
||||
chainId,
|
||||
}: {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
chainId: ChainId;
|
||||
}) => {
|
||||
const { availableConnections, connect } = useEthereumProvider();
|
||||
const classes = useStyles();
|
||||
|
||||
const availableWallets = availableConnections
|
||||
.filter((connection) => {
|
||||
if (connection.connectType === ConnectType.METAMASK) {
|
||||
return true;
|
||||
} else if (connection.connectType === ConnectType.WALLETCONNECT) {
|
||||
const evmChainId = getEvmChainId(chainId);
|
||||
// WalletConnect requires a rpc provider
|
||||
return (
|
||||
evmChainId !== undefined && EVM_RPC_MAP[evmChainId] !== undefined
|
||||
);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.map((connection) => (
|
||||
<WalletOptions
|
||||
connection={connection}
|
||||
connect={connect}
|
||||
onClose={onClose}
|
||||
key={connection.name}
|
||||
/>
|
||||
));
|
||||
|
||||
return (
|
||||
<Dialog open={isOpen} onClose={onClose}>
|
||||
<DialogTitle>
|
||||
<div className={classes.flexTitle}>
|
||||
<div>Select your wallet</div>
|
||||
<IconButton onClick={onClose}>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
</div>
|
||||
</DialogTitle>
|
||||
<List>{availableWallets}</List>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default EvmConnectWalletDialog;
|
|
@ -12,7 +12,7 @@ import TerraWalletKey from "./TerraWalletKey";
|
|||
|
||||
function KeyAndBalance({ chainId }: { chainId: ChainId }) {
|
||||
if (isEVMChain(chainId)) {
|
||||
return <EthereumSignerKey />;
|
||||
return <EthereumSignerKey chainId={chainId} />;
|
||||
}
|
||||
if (chainId === CHAIN_ID_SOLANA) {
|
||||
return <SolanaWalletKey />;
|
||||
|
|
|
@ -345,7 +345,7 @@ export default function EvmQuickMigrate({ chainId }: { chainId: ChainId }) {
|
|||
} into
|
||||
Wormhole V2 tokens.`}
|
||||
</Typography>
|
||||
<EthereumSignerKey />
|
||||
<EthereumSignerKey chainId={chainId} />
|
||||
{!isReady ? (
|
||||
<Typography variant="body1">Please connect your wallet.</Typography>
|
||||
) : migratorsError ? (
|
||||
|
|
|
@ -231,7 +231,7 @@ export default function EvmWorkflow({
|
|||
|
||||
return (
|
||||
<div className={classes.containerDiv}>
|
||||
<EthereumSignerKey />
|
||||
<EthereumSignerKey chainId={chainId} />
|
||||
{!isReady ? (
|
||||
<Typography variant="body1">Please connect your wallet.</Typography>
|
||||
) : poolInfo.isLoading ? (
|
||||
|
|
|
@ -218,7 +218,7 @@ function UnwrapNative() {
|
|||
Unwrap (withdraw) native tokens from their wrapped form (e.g. WETH
|
||||
→ ETH)
|
||||
</Typography>
|
||||
<EthereumSignerKey />
|
||||
<EthereumSignerKey chainId={selectedChainId} />
|
||||
<TextField
|
||||
select
|
||||
value={selectedChainId}
|
||||
|
|
|
@ -1,35 +1,57 @@
|
|||
import detectEthereumProvider from "@metamask/detect-provider";
|
||||
import WalletConnectProvider from "@walletconnect/web3-provider";
|
||||
import { BigNumber, ethers } from "ethers";
|
||||
import React, {
|
||||
ReactChildren,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from "react";
|
||||
import metamaskIcon from "../icons/metamask-fox.svg";
|
||||
import walletconnectIcon from "../icons/walletconnect.svg";
|
||||
import { EVM_RPC_MAP } from "../utils/metaMaskChainParameters";
|
||||
const CacheSubprovider = require("web3-provider-engine/subproviders/cache");
|
||||
|
||||
export type Provider = ethers.providers.Web3Provider | undefined;
|
||||
export type Signer = ethers.Signer | undefined;
|
||||
|
||||
export enum ConnectType {
|
||||
METAMASK,
|
||||
WALLETCONNECT,
|
||||
}
|
||||
|
||||
export interface Connection {
|
||||
connectType: ConnectType;
|
||||
name: string;
|
||||
icon: string;
|
||||
}
|
||||
|
||||
interface IEthereumProviderContext {
|
||||
connect(): void;
|
||||
connect(connectType: ConnectType): void;
|
||||
disconnect(): void;
|
||||
provider: Provider;
|
||||
chainId: number | undefined;
|
||||
signer: Signer;
|
||||
signerAddress: string | undefined;
|
||||
providerError: string | null;
|
||||
availableConnections: Connection[];
|
||||
connectType: ConnectType | undefined;
|
||||
}
|
||||
|
||||
const EthereumProviderContext = React.createContext<IEthereumProviderContext>({
|
||||
connect: () => {},
|
||||
connect: (connectType: ConnectType) => {},
|
||||
disconnect: () => {},
|
||||
provider: undefined,
|
||||
chainId: undefined,
|
||||
signer: undefined,
|
||||
signerAddress: undefined,
|
||||
providerError: null,
|
||||
availableConnections: [],
|
||||
connectType: undefined,
|
||||
});
|
||||
|
||||
export const EthereumProviderProvider = ({
|
||||
children,
|
||||
}: {
|
||||
|
@ -42,91 +64,239 @@ export const EthereumProviderProvider = ({
|
|||
const [signerAddress, setSignerAddress] = useState<string | undefined>(
|
||||
undefined
|
||||
);
|
||||
const connect = useCallback(() => {
|
||||
setProviderError(null);
|
||||
detectEthereumProvider()
|
||||
.then((detectedProvider) => {
|
||||
const [availableConnections, setAvailableConnections] = useState<
|
||||
Connection[]
|
||||
>([]);
|
||||
const [connectType, setConnectType] = useState<ConnectType | undefined>(
|
||||
undefined
|
||||
);
|
||||
const [ethereumProvider, setEthereumProvider] = useState<any>(undefined);
|
||||
const [walletConnectProvider, setWalletConnectProvider] = useState<
|
||||
WalletConnectProvider | undefined
|
||||
>(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
(async () => {
|
||||
const connections: Connection[] = [];
|
||||
try {
|
||||
const detectedProvider = await detectEthereumProvider();
|
||||
if (detectedProvider) {
|
||||
const provider = new ethers.providers.Web3Provider(
|
||||
// @ts-ignore
|
||||
detectedProvider,
|
||||
"any"
|
||||
);
|
||||
provider
|
||||
.send("eth_requestAccounts", [])
|
||||
.then(() => {
|
||||
setProviderError(null);
|
||||
setProvider(provider);
|
||||
provider
|
||||
.getNetwork()
|
||||
.then((network) => {
|
||||
setChainId(network.chainId);
|
||||
})
|
||||
.catch(() => {
|
||||
setProviderError(
|
||||
"An error occurred while getting the network"
|
||||
);
|
||||
});
|
||||
const signer = provider.getSigner();
|
||||
setSigner(signer);
|
||||
signer
|
||||
.getAddress()
|
||||
.then((address) => {
|
||||
setSignerAddress(address);
|
||||
})
|
||||
.catch(() => {
|
||||
setProviderError(
|
||||
"An error occurred while getting the signer address"
|
||||
);
|
||||
});
|
||||
// TODO: try using ethers directly
|
||||
// @ts-ignore
|
||||
if (detectedProvider && detectedProvider.on) {
|
||||
// @ts-ignore
|
||||
detectedProvider.on("chainChanged", (chainId) => {
|
||||
try {
|
||||
setChainId(BigNumber.from(chainId).toNumber());
|
||||
} catch (e) {}
|
||||
});
|
||||
// @ts-ignore
|
||||
detectedProvider.on("accountsChanged", (accounts) => {
|
||||
try {
|
||||
const signer = provider.getSigner();
|
||||
setSigner(signer);
|
||||
signer
|
||||
.getAddress()
|
||||
.then((address) => {
|
||||
setSignerAddress(address);
|
||||
})
|
||||
.catch(() => {
|
||||
setProviderError(
|
||||
"An error occurred while getting the signer address"
|
||||
);
|
||||
});
|
||||
} catch (e) {}
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
setProviderError(
|
||||
"An error occurred while requesting eth accounts"
|
||||
);
|
||||
});
|
||||
} else {
|
||||
setProviderError("Please install MetaMask");
|
||||
connections.push({
|
||||
connectType: ConnectType.METAMASK,
|
||||
name: "MetaMask",
|
||||
icon: metamaskIcon,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
setProviderError("Please install MetaMask");
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
connections.push({
|
||||
connectType: ConnectType.WALLETCONNECT,
|
||||
name: "Wallet Connect",
|
||||
icon: walletconnectIcon,
|
||||
});
|
||||
if (!cancelled) {
|
||||
setAvailableConnections(connections);
|
||||
}
|
||||
})();
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, []);
|
||||
|
||||
const disconnect = useCallback(() => {
|
||||
setProviderError(null);
|
||||
setProvider(undefined);
|
||||
setChainId(undefined);
|
||||
setSigner(undefined);
|
||||
setSignerAddress(undefined);
|
||||
}, []);
|
||||
setConnectType(undefined);
|
||||
if (ethereumProvider && ethereumProvider.removeAllListeners) {
|
||||
ethereumProvider.removeAllListeners();
|
||||
setEthereumProvider(undefined);
|
||||
}
|
||||
if (walletConnectProvider) {
|
||||
walletConnectProvider
|
||||
.disconnect()
|
||||
.catch((error: any) => console.error(error));
|
||||
setWalletConnectProvider(undefined);
|
||||
}
|
||||
}, [ethereumProvider, walletConnectProvider]);
|
||||
|
||||
const connect = useCallback(
|
||||
(connectType: ConnectType) => {
|
||||
setConnectType(connectType);
|
||||
if (connectType === ConnectType.METAMASK) {
|
||||
detectEthereumProvider()
|
||||
.then((detectedProvider) => {
|
||||
if (detectedProvider) {
|
||||
setEthereumProvider(detectedProvider);
|
||||
const provider = new ethers.providers.Web3Provider(
|
||||
// @ts-ignore
|
||||
detectedProvider,
|
||||
"any"
|
||||
);
|
||||
provider
|
||||
.send("eth_requestAccounts", [])
|
||||
.then(() => {
|
||||
setProviderError(null);
|
||||
setProvider(provider);
|
||||
provider
|
||||
.getNetwork()
|
||||
.then((network) => {
|
||||
setChainId(network.chainId);
|
||||
})
|
||||
.catch(() => {
|
||||
setProviderError(
|
||||
"An error occurred while getting the network"
|
||||
);
|
||||
});
|
||||
const signer = provider.getSigner();
|
||||
setSigner(signer);
|
||||
signer
|
||||
.getAddress()
|
||||
.then((address) => {
|
||||
setSignerAddress(address);
|
||||
})
|
||||
.catch(() => {
|
||||
setProviderError(
|
||||
"An error occurred while getting the signer address"
|
||||
);
|
||||
});
|
||||
// TODO: try using ethers directly
|
||||
// @ts-ignore
|
||||
if (detectedProvider && detectedProvider.on) {
|
||||
// @ts-ignore
|
||||
detectedProvider.on("chainChanged", (chainId) => {
|
||||
try {
|
||||
setChainId(BigNumber.from(chainId).toNumber());
|
||||
} catch (e) {}
|
||||
});
|
||||
// @ts-ignore
|
||||
detectedProvider.on("accountsChanged", (accounts) => {
|
||||
try {
|
||||
const signer = provider.getSigner();
|
||||
setSigner(signer);
|
||||
signer
|
||||
.getAddress()
|
||||
.then((address) => {
|
||||
setSignerAddress(address);
|
||||
})
|
||||
.catch(() => {
|
||||
setProviderError(
|
||||
"An error occurred while getting the signer address"
|
||||
);
|
||||
});
|
||||
} catch (e) {}
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
setProviderError(
|
||||
"An error occurred while requesting eth accounts"
|
||||
);
|
||||
});
|
||||
} else {
|
||||
setProviderError("Please install MetaMask");
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
setProviderError("Please install MetaMask");
|
||||
});
|
||||
} else if (connectType === ConnectType.WALLETCONNECT) {
|
||||
const walletConnectProvider = new WalletConnectProvider({
|
||||
rpc: EVM_RPC_MAP,
|
||||
storageId: "walletconnect-evm",
|
||||
});
|
||||
setWalletConnectProvider(walletConnectProvider);
|
||||
walletConnectProvider
|
||||
.enable()
|
||||
.then(() => {
|
||||
setProviderError(null);
|
||||
const provider = new ethers.providers.Web3Provider(
|
||||
walletConnectProvider,
|
||||
"any"
|
||||
);
|
||||
provider
|
||||
.getNetwork()
|
||||
.then((network) => {
|
||||
setChainId(network.chainId);
|
||||
})
|
||||
.catch(() => {
|
||||
setProviderError("An error occurred while getting the network");
|
||||
});
|
||||
walletConnectProvider.on("chainChanged", (chainId: number) => {
|
||||
setChainId(chainId);
|
||||
// HACK: clear the block-cache when switching chains by creating a new CacheSubprovider
|
||||
// Otherwise ethers may not resolve transaction receipts/waits
|
||||
const index = walletConnectProvider._providers.findIndex(
|
||||
(subprovider: any) => subprovider instanceof CacheSubprovider
|
||||
);
|
||||
if (index >= 0) {
|
||||
const subprovider = walletConnectProvider._providers[index];
|
||||
walletConnectProvider.removeProvider(subprovider);
|
||||
walletConnectProvider.addProvider(
|
||||
new CacheSubprovider(),
|
||||
index
|
||||
);
|
||||
// also reset the latest block
|
||||
walletConnectProvider._blockTracker._resetCurrentBlock();
|
||||
}
|
||||
});
|
||||
walletConnectProvider.on(
|
||||
"accountsChanged",
|
||||
(accounts: string[]) => {
|
||||
try {
|
||||
const signer = provider.getSigner();
|
||||
setSigner(signer);
|
||||
signer
|
||||
.getAddress()
|
||||
.then((address) => {
|
||||
setSignerAddress(address);
|
||||
})
|
||||
.catch(() => {
|
||||
setProviderError(
|
||||
"An error occurred while getting the signer address"
|
||||
);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
);
|
||||
walletConnectProvider.on(
|
||||
"disconnect",
|
||||
(code: number, reason: string) => {
|
||||
disconnect();
|
||||
}
|
||||
);
|
||||
setProvider(provider);
|
||||
const signer = provider.getSigner();
|
||||
setSigner(signer);
|
||||
signer
|
||||
.getAddress()
|
||||
.then((address) => {
|
||||
setSignerAddress(address);
|
||||
})
|
||||
.catch((error) => {
|
||||
setProviderError(
|
||||
"An error occurred while getting the signer address"
|
||||
);
|
||||
console.error(error);
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.message !== "User closed modal") {
|
||||
setProviderError("Error enabling WalletConnect session");
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
[disconnect]
|
||||
);
|
||||
|
||||
const contextValue = useMemo(
|
||||
() => ({
|
||||
connect,
|
||||
|
@ -136,6 +306,8 @@ export const EthereumProviderProvider = ({
|
|||
signer,
|
||||
signerAddress,
|
||||
providerError,
|
||||
availableConnections,
|
||||
connectType,
|
||||
}),
|
||||
[
|
||||
connect,
|
||||
|
@ -145,6 +317,8 @@ export const EthereumProviderProvider = ({
|
|||
signer,
|
||||
signerAddress,
|
||||
providerError,
|
||||
availableConnections,
|
||||
connectType,
|
||||
]
|
||||
);
|
||||
return (
|
||||
|
|
|
@ -9,10 +9,16 @@ import { hexlify, hexStripZeros } from "@ethersproject/bytes";
|
|||
import { useConnectedWallet } from "@terra-money/wallet-provider";
|
||||
import { useCallback, useMemo } from "react";
|
||||
import { useAlgorandContext } from "../contexts/AlgorandWalletContext";
|
||||
import { useEthereumProvider } from "../contexts/EthereumProviderContext";
|
||||
import {
|
||||
ConnectType,
|
||||
useEthereumProvider,
|
||||
} from "../contexts/EthereumProviderContext";
|
||||
import { useSolanaWallet } from "../contexts/SolanaWalletContext";
|
||||
import { CLUSTER, getEvmChainId } from "../utils/consts";
|
||||
import { METAMASK_CHAIN_PARAMETERS } from "../utils/metaMaskChainParameters";
|
||||
import {
|
||||
EVM_RPC_MAP,
|
||||
METAMASK_CHAIN_PARAMETERS,
|
||||
} from "../utils/metaMaskChainParameters";
|
||||
|
||||
const createWalletStatus = (
|
||||
isReady: boolean,
|
||||
|
@ -44,6 +50,8 @@ function useIsWalletReady(
|
|||
provider,
|
||||
signerAddress,
|
||||
chainId: evmChainId,
|
||||
connectType,
|
||||
disconnect,
|
||||
} = useEthereumProvider();
|
||||
const hasEthInfo = !!provider && !!signerAddress;
|
||||
const correctEvmNetwork = getEvmChainId(chainId);
|
||||
|
@ -56,6 +64,16 @@ function useIsWalletReady(
|
|||
if (!isEVMChain(chainId)) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
connectType === ConnectType.WALLETCONNECT &&
|
||||
EVM_RPC_MAP[correctEvmNetwork] === undefined
|
||||
) {
|
||||
// WalletConnect requires a rpc url for this chain
|
||||
// Force user to switch connect type
|
||||
disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await provider.send("wallet_switchEthereumChain", [
|
||||
{ chainId: hexStripZeros(hexlify(correctEvmNetwork)) },
|
||||
|
@ -77,7 +95,7 @@ function useIsWalletReady(
|
|||
}
|
||||
}
|
||||
}
|
||||
}, [provider, correctEvmNetwork, chainId]);
|
||||
}, [provider, correctEvmNetwork, chainId, connectType, disconnect]);
|
||||
|
||||
return useMemo(() => {
|
||||
if (
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 318.6 318.6" style="enable-background:new 0 0 318.6 318.6" xml:space="preserve"><style>.st1,.st2,.st3,.st4,.st5,.st6,.st9{fill:#e4761b;stroke:#e4761b;stroke-linecap:round;stroke-linejoin:round}.st2,.st3,.st4,.st5,.st6,.st9{fill:#d7c1b3;stroke:#d7c1b3}.st3,.st4,.st5,.st6,.st9{fill:#233447;stroke:#233447}.st4,.st5,.st6,.st9{fill:#cd6116;stroke:#cd6116}.st5,.st6,.st9{fill:#e4751f;stroke:#e4751f}.st6,.st9{fill:#f6851b;stroke:#f6851b}.st9{fill:#763d16;stroke:#763d16}</style><path style="fill:#e2761b;stroke:#e2761b;stroke-linecap:round;stroke-linejoin:round" d="m274.1 35.5-99.5 73.9L193 65.8z"/><path class="st1" d="m44.4 35.5 98.7 74.6-17.5-44.3zM238.3 206.8l-26.5 40.6 56.7 15.6 16.3-55.3zM33.9 207.7 50.1 263l56.7-15.6-26.5-40.6z"/><path class="st1" d="m103.6 138.2-15.8 23.9 56.3 2.5-2-60.5zM214.9 138.2l-39-34.8-1.3 61.2 56.2-2.5zM106.8 247.4l33.8-16.5-29.2-22.8zM177.9 230.9l33.9 16.5-4.7-39.3z"/><path class="st2" d="m211.8 247.4-33.9-16.5 2.7 22.1-.3 9.3zM106.8 247.4l31.5 14.9-.2-9.3 2.5-22.1z"/><path class="st3" d="m138.8 193.5-28.2-8.3 19.9-9.1zM179.7 193.5l8.3-17.4 20 9.1z"/><path class="st4" d="m106.8 247.4 4.8-40.6-31.3.9zM207 206.8l4.8 40.6 26.5-39.7zM230.8 162.1l-56.2 2.5 5.2 28.9 8.3-17.4 20 9.1zM110.6 185.2l20-9.1 8.2 17.4 5.3-28.9-56.3-2.5z"/><path class="st5" d="m87.8 162.1 23.6 46-.8-22.9zM208.1 185.2l-1 22.9 23.7-46zM144.1 164.6l-5.3 28.9 6.6 34.1 1.5-44.9zM174.6 164.6l-2.7 18 1.2 45 6.7-34.1z"/><path class="st6" d="m179.8 193.5-6.7 34.1 4.8 3.3 29.2-22.8 1-22.9zM110.6 185.2l.8 22.9 29.2 22.8 4.8-3.3-6.6-34.1z"/><path style="fill:#c0ad9e;stroke:#c0ad9e;stroke-linecap:round;stroke-linejoin:round" d="m180.3 262.3.3-9.3-2.5-2.2h-37.7l-2.3 2.2.2 9.3-31.5-14.9 11 9 22.3 15.5h38.3l22.4-15.5 11-9z"/><path style="fill:#161616;stroke:#161616;stroke-linecap:round;stroke-linejoin:round" d="m177.9 230.9-4.8-3.3h-27.7l-4.8 3.3-2.5 22.1 2.3-2.2h37.7l2.5 2.2z"/><path class="st9" d="m278.3 114.2 8.5-40.8-12.7-37.9-96.2 71.4 37 31.3 52.3 15.3 11.6-13.5-5-3.6 8-7.3-6.2-4.8 8-6.1zM31.8 73.4l8.5 40.8-5.4 4 8 6.1-6.1 4.8 8 7.3-5 3.6 11.5 13.5 52.3-15.3 37-31.3-96.2-71.4z"/><path class="st6" d="m267.2 153.5-52.3-15.3 15.9 23.9-23.7 46 31.2-.4h46.5zM103.6 138.2l-52.3 15.3-17.4 54.2h46.4l31.1.4-23.6-46zM174.6 164.6l3.3-57.7 15.2-41.1h-67.5l15 41.1 3.5 57.7 1.2 18.2.1 44.8h27.7l.2-44.8z"/></svg>
|
After Width: | Height: | Size: 2.4 KiB |
|
@ -0,0 +1 @@
|
|||
<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2"><g transform="translate(1.682 1.682) scale(1.7897)"><clipPath id="a"><path d="M0 0h16v16H0z"/></clipPath><g clip-path="url(#a)"><path d="M12.725 4.927c-2.594-2.588-6.856-2.588-9.45 0l-.344.345a.334.334 0 0 0 0 .471l1.074 1.073a.167.167 0 0 0 .236 0l.463-.462c1.809-1.806 4.783-1.806 6.592 0l.432.431a.167.167 0 0 0 .236 0l1.075-1.072a.33.33 0 0 0 0-.472l-.314-.314ZM15.902 8.1l-.956-.955a.336.336 0 0 0-.472 0l-3.06 3.055a.085.085 0 0 1-.118 0l-3.06-3.055a.336.336 0 0 0-.472 0L4.704 10.2a.085.085 0 0 1-.118 0l-3.06-3.055a.336.336 0 0 0-.472 0L.098 8.1a.33.33 0 0 0 0 .472l4.31 4.304c.131.13.343.13.473 0l3.06-3.055a.085.085 0 0 1 .118 0l3.06 3.055c.13.13.342.13.472 0l4.311-4.304a.33.33 0 0 0 0-.472Z" style="fill:#3b99fc;fill-rule:nonzero"/></g></g></svg>
|
After Width: | Height: | Size: 925 B |
|
@ -27,14 +27,14 @@ export const METAMASK_CHAIN_PARAMETERS: {
|
|||
chainId: "0x3",
|
||||
chainName: "Ropsten",
|
||||
nativeCurrency: { name: "Ropsten Ether", symbol: "ROP", decimals: 18 },
|
||||
rpcUrls: ["https://ropsten.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161"],
|
||||
rpcUrls: ["https://rpc.ankr.com/eth_ropsten"],
|
||||
blockExplorerUrls: ["https://ropsten.etherscan.io"],
|
||||
},
|
||||
5: {
|
||||
chainId: "0x5",
|
||||
chainName: "Görli",
|
||||
nativeCurrency: { name: "Görli Ether", symbol: "GOR", decimals: 18 },
|
||||
rpcUrls: ["https://goerli.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161"],
|
||||
rpcUrls: ["https://rpc.ankr.com/eth_goerli"],
|
||||
blockExplorerUrls: ["https://goerli.etherscan.io"],
|
||||
},
|
||||
56: {
|
||||
|
@ -172,3 +172,17 @@ export const METAMASK_CHAIN_PARAMETERS: {
|
|||
blockExplorerUrls: ["https://testnet.aurorascan.dev"],
|
||||
},
|
||||
};
|
||||
|
||||
export interface EvmRpcMap {
|
||||
[chainId: string]: string;
|
||||
}
|
||||
|
||||
export const EVM_RPC_MAP = Object.entries(METAMASK_CHAIN_PARAMETERS).reduce(
|
||||
(evmRpcMap, [evmChainId, { rpcUrls }]) => {
|
||||
if (rpcUrls.length > 0) {
|
||||
evmRpcMap[evmChainId] = rpcUrls[0];
|
||||
}
|
||||
return evmRpcMap;
|
||||
},
|
||||
{} as EvmRpcMap
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue