bridge_ui: oasis support

This commit is contained in:
Chase Moran 2021-12-20 21:26:15 -05:00 committed by Evan Gray
parent 8a24b23a27
commit 195a61714e
9 changed files with 160 additions and 14 deletions

View File

@ -8,7 +8,7 @@
"name": "test_ui",
"version": "0.1.0",
"dependencies": {
"@certusone/wormhole-sdk": "^0.1.4",
"@certusone/wormhole-sdk": "^0.1.5",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.11.2",
"@material-ui/lab": "^4.0.0-alpha.60",
@ -63,7 +63,7 @@
},
"../sdk/js": {
"name": "@certusone/wormhole-sdk",
"version": "0.1.3",
"version": "0.1.5",
"extraneous": true,
"license": "Apache-2.0",
"dependencies": {
@ -2002,9 +2002,9 @@
}
},
"node_modules/@certusone/wormhole-sdk": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.1.4.tgz",
"integrity": "sha512-C9GXZJ3vjBDU1Ytk6Sk5SYS3oJFjUa7vEq1NlOwHCwt5CL0vFwdrBq3WER8h1+i+/4AaGreOyCpxct0tXeasXg==",
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.1.5.tgz",
"integrity": "sha512-xRRItdrIDNVA4S4krmkq2JwNCpkcqAjbTRhPGNLKx29v2TSiOZ3MEug31urPvdfcvPM7DerN+o0LnGy9LMmboA==",
"dependencies": {
"@improbable-eng/grpc-web": "^0.14.0",
"@solana/spl-token": "^0.1.8",
@ -45479,9 +45479,9 @@
}
},
"@certusone/wormhole-sdk": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.1.4.tgz",
"integrity": "sha512-C9GXZJ3vjBDU1Ytk6Sk5SYS3oJFjUa7vEq1NlOwHCwt5CL0vFwdrBq3WER8h1+i+/4AaGreOyCpxct0tXeasXg==",
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.1.5.tgz",
"integrity": "sha512-xRRItdrIDNVA4S4krmkq2JwNCpkcqAjbTRhPGNLKx29v2TSiOZ3MEug31urPvdfcvPM7DerN+o0LnGy9LMmboA==",
"requires": {
"@improbable-eng/grpc-web": "^0.14.0",
"@solana/spl-token": "^0.1.8",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@certusone/wormhole-sdk": "^0.1.4",
"@certusone/wormhole-sdk": "^0.1.5",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.11.2",
"@material-ui/lab": "^4.0.0-alpha.60",

View File

@ -4,6 +4,7 @@ import {
CHAIN_ID_ETH,
CHAIN_ID_POLYGON,
CHAIN_ID_SOLANA,
CHAIN_ID_OASIS,
hexToNativeString,
isEVMChain,
uint8ArrayToHex,
@ -342,7 +343,7 @@ export default function NFTOriginVerifier() {
>
View on Snowtrace
</Button>
) : (
) : originInfo.chainId === CHAIN_ID_OASIS ? null : (
<Button
href={`https://opensea.io/assets/${readableAddress}/${originInfo.tokenId}`}
target="_blank"

View File

@ -7,6 +7,7 @@ import {
CHAIN_ID_POLYGON,
CHAIN_ID_SOLANA,
CHAIN_ID_TERRA,
CHAIN_ID_OASIS,
} from "@certusone/wormhole-sdk";
import { Button, makeStyles, Typography } from "@material-ui/core";
import { Transaction } from "../store/transferSlice";
@ -56,6 +57,8 @@ export default function ShowTx({
? `https://${CLUSTER === "testnet" ? "testnet." : ""}snowtrace.io/tx/${
tx?.id
}`
: chainId === CHAIN_ID_OASIS
? undefined
: chainId === CHAIN_ID_SOLANA
? `https://explorer.solana.com/tx/${tx?.id}${
CLUSTER === "testnet"

View File

@ -7,6 +7,7 @@ import {
CHAIN_ID_POLYGON,
CHAIN_ID_SOLANA,
CHAIN_ID_TERRA,
CHAIN_ID_OASIS,
isNativeDenom,
} from "@certusone/wormhole-sdk";
import { Button, makeStyles, Tooltip, Typography } from "@material-ui/core";
@ -115,6 +116,8 @@ export default function SmartAddress({
? `https://${
CLUSTER === "testnet" ? "testnet." : ""
}snowtrace.io/address/${useableAddress}`
: chainId === CHAIN_ID_OASIS
? null
: chainId === CHAIN_ID_SOLANA
? `https://explorer.solana.com/address/${useableAddress}${
CLUSTER === "testnet"

View File

@ -19,6 +19,7 @@ import {
CHAIN_ID_ETHEREUM_ROPSTEN,
CHAIN_ID_POLYGON,
CHAIN_ID_SOLANA,
CHAIN_ID_OASIS,
} from "@certusone/wormhole-sdk";
import SmartAddress from "../SmartAddress";
import avaxIcon from "../../icons/avax.svg";
@ -26,6 +27,7 @@ import bscIcon from "../../icons/bsc.svg";
import ethIcon from "../../icons/eth.svg";
import solanaIcon from "../../icons/solana.svg";
import polygonIcon from "../../icons/polygon.svg";
import oasisIcon from "../../icons/oasis-network-rose-logo.svg";
import useCopyToClipboard from "../../hooks/useCopyToClipboard";
import { Skeleton } from "@material-ui/lab";
import Wormhole from "../../icons/wormhole-network.svg";
@ -99,6 +101,18 @@ const LogoIcon = ({ chainId }: { chainId: ChainId }) =>
src={avaxIcon}
alt="Avalanche"
/>
) : chainId === CHAIN_ID_OASIS ? (
<Avatar
style={{
backgroundColor: "black",
height: "1em",
width: "1em",
marginLeft: "4px",
padding: "3px",
}}
src={oasisIcon}
alt="Oasis"
/>
) : null;
const useStyles = makeStyles((theme) => ({
@ -400,7 +414,8 @@ export default function NFTViewer({
[classes.eth]:
chainId === CHAIN_ID_ETH ||
chainId === CHAIN_ID_ETHEREUM_ROPSTEN ||
chainId === CHAIN_ID_AVAX, //TODO: give avax it's own bg
chainId === CHAIN_ID_AVAX || //TODO: give avax it's own bg
chainId === CHAIN_ID_OASIS, //TODO: give oasis it's own bg
[classes.bsc]: chainId === CHAIN_ID_BSC,
[classes.solana]: chainId === CHAIN_ID_SOLANA,
[classes.polygon]: chainId === CHAIN_ID_POLYGON,
@ -427,6 +442,7 @@ export default function NFTViewer({
[classes.silverMediaBorder]:
chainId === CHAIN_ID_SOLANA ||
chainId === CHAIN_ID_POLYGON ||
chainId === CHAIN_ID_OASIS ||
chainId === CHAIN_ID_AVAX,
})}
>

View File

@ -3,6 +3,7 @@ import {
CHAIN_ID_BSC,
CHAIN_ID_ETH,
CHAIN_ID_ETHEREUM_ROPSTEN,
CHAIN_ID_OASIS,
CHAIN_ID_POLYGON,
CHAIN_ID_SOLANA,
isEVMChain,
@ -37,6 +38,7 @@ import {
WBNB_ADDRESS,
WETH_ADDRESS,
WMATIC_ADDRESS,
WROSE_ADDRESS,
} from "../../utils/consts";
import ButtonWithLoader from "../ButtonWithLoader";
import KeyAndBalance from "../KeyAndBalance";
@ -91,6 +93,10 @@ function Redeem() {
targetChain === CHAIN_ID_AVAX &&
targetAsset &&
targetAsset.toLowerCase() === WAVAX_ADDRESS.toLowerCase();
const isOasisNative =
targetChain === CHAIN_ID_OASIS &&
targetAsset &&
targetAsset.toLowerCase() === WROSE_ADDRESS.toLowerCase();
const isSolNative =
targetChain === CHAIN_ID_SOLANA &&
targetAsset &&
@ -101,6 +107,7 @@ function Redeem() {
isBscNative ||
isPolygonNative ||
isAvaxNative ||
isOasisNative ||
isSolNative;
const [useNativeRedeem, setUseNativeRedeem] = useState(true);
const toggleNativeRedeem = useCallback(() => {

View File

@ -7,6 +7,7 @@ import {
CHAIN_ID_POLYGON,
CHAIN_ID_SOLANA,
CHAIN_ID_TERRA,
CHAIN_ID_OASIS,
isEVMChain,
WSOL_ADDRESS,
WSOL_DECIMALS,
@ -70,6 +71,8 @@ import {
WETH_DECIMALS,
WMATIC_ADDRESS,
WMATIC_DECIMALS,
WROSE_ADDRESS,
WROSE_DECIMALS,
} from "../utils/consts";
import {
ExtractedMintInfo,
@ -80,6 +83,7 @@ import avaxIcon from "../icons/avax.svg";
import bnbIcon from "../icons/bnb.svg";
import ethIcon from "../icons/eth.svg";
import polygonIcon from "../icons/polygon.svg";
import oasisIcon from "../icons/oasis-network-rose-logo.svg";
export function createParsedTokenAccount(
publicKey: string,
@ -317,6 +321,29 @@ const createNativeAvaxParsedTokenAccount = (
});
};
const createNativeOasisParsedTokenAccount = (
provider: Provider,
signerAddress: string | undefined
) => {
return !(provider && signerAddress)
? Promise.reject()
: provider.getBalance(signerAddress).then((balanceInWei) => {
const balanceInEth = ethers.utils.formatEther(balanceInWei);
return createParsedTokenAccount(
signerAddress, //public key
WROSE_ADDRESS, //Mint key, On the other side this will be wavax, so this is hopefully a white lie.
balanceInWei.toString(), //amount, in wei
WROSE_DECIMALS,
parseFloat(balanceInEth), //This loses precision, but is a limitation of the current datamodel. This field is essentially deprecated
balanceInEth.toString(), //This is the actual display field, which has full precision.
"ROSE", //A white lie for display purposes
"Rose", //A white lie for display purposes
oasisIcon,
true //isNativeAsset
);
});
};
const createNFTParsedTokenAccountFromCovalent = (
walletAddress: string,
covalent: CovalentData,
@ -799,6 +826,39 @@ function useGetAvailableTokens(nft: boolean = false) {
};
}, [lookupChain, provider, signerAddress, nft, ethNativeAccount]);
useEffect(() => {
let cancelled = false;
if (
signerAddress &&
lookupChain === CHAIN_ID_OASIS &&
!ethNativeAccount &&
!nft
) {
setEthNativeAccountLoading(true);
createNativeOasisParsedTokenAccount(provider, signerAddress).then(
(result) => {
console.log("create native account returned with value", result);
if (!cancelled) {
setEthNativeAccount(result);
setEthNativeAccountLoading(false);
setEthNativeAccountError("");
}
},
(error) => {
if (!cancelled) {
setEthNativeAccount(undefined);
setEthNativeAccountLoading(false);
setEthNativeAccountError("Unable to retrieve your Oasis balance.");
}
}
);
}
return () => {
cancelled = true;
};
}, [lookupChain, provider, signerAddress, nft, ethNativeAccount]);
//Ethereum covalent accounts load
useEffect(() => {
//const testWallet = "0xf60c2ea62edbfe808163751dd0d8693dcb30019c";

View File

@ -7,6 +7,7 @@ import {
CHAIN_ID_POLYGON,
CHAIN_ID_SOLANA,
CHAIN_ID_TERRA,
CHAIN_ID_OASIS,
isEVMChain,
} from "@certusone/wormhole-sdk";
import { clusterApiUrl } from "@solana/web3.js";
@ -39,6 +40,11 @@ export const CHAINS =
name: "Avalanche",
logo: avaxIcon,
},
{
id: CHAIN_ID_OASIS,
name: "Oasis",
logo: oasisIcon,
},
{
id: CHAIN_ID_BSC,
name: "Binance Smart Chain",
@ -72,6 +78,11 @@ export const CHAINS =
name: "Avalanche",
logo: avaxIcon,
},
{
id: CHAIN_ID_OASIS,
name: "Oasis",
logo: oasisIcon,
},
{
id: CHAIN_ID_BSC,
name: "Binance Smart Chain",
@ -126,7 +137,7 @@ export const CHAINS =
},
];
export const BETA_CHAINS: ChainId[] =
CLUSTER === "mainnet" ? [CHAIN_ID_AVAX] : [];
CLUSTER === "mainnet" ? [CHAIN_ID_AVAX, CHAIN_ID_OASIS] : [];
export const CHAINS_WITH_NFT_SUPPORT = CHAINS.filter(
({ id }) =>
id === CHAIN_ID_AVAX ||
@ -134,6 +145,7 @@ export const CHAINS_WITH_NFT_SUPPORT = CHAINS.filter(
id === CHAIN_ID_ETH ||
id === CHAIN_ID_ETHEREUM_ROPSTEN ||
id === CHAIN_ID_POLYGON ||
id === CHAIN_ID_OASIS ||
id === CHAIN_ID_SOLANA
);
export type ChainsById = { [key in ChainId]: ChainInfo };
@ -144,12 +156,12 @@ export const CHAINS_BY_ID: ChainsById = CHAINS.reduce((obj, chain) => {
export const COMING_SOON_CHAINS = [
{
id: 0,
id: CHAIN_ID_OASIS,
name: "Oasis",
logo: oasisIcon,
},
{
id: 0,
id: CHAIN_ID_AVAX,
name: "Avalanche",
logo: avaxIcon,
},
@ -167,6 +179,8 @@ export const getDefaultNativeCurrencySymbol = (chainId: ChainId) =>
? "MATIC"
: chainId === CHAIN_ID_AVAX
? "AVAX"
: chainId === CHAIN_ID_OASIS
? "ROSE"
: "";
export const getExplorerName = (chainId: ChainId) =>
chainId === CHAIN_ID_ETH || chainId === CHAIN_ID_ETHEREUM_ROPSTEN
@ -203,6 +217,8 @@ export const POLYGON_NETWORK_CHAIN_ID =
CLUSTER === "mainnet" ? 137 : CLUSTER === "testnet" ? 80001 : 1381;
export const AVAX_NETWORK_CHAIN_ID =
CLUSTER === "mainnet" ? 43114 : CLUSTER === "testnet" ? 43113 : 1381;
export const OASIS_NETWORK_CHAIN_ID =
CLUSTER === "mainnet" ? 42262 : CLUSTER === "testnet" ? 42261 : 1381;
export const getEvmChainId = (chainId: ChainId) =>
chainId === CHAIN_ID_ETH
? ETH_NETWORK_CHAIN_ID
@ -214,6 +230,8 @@ export const getEvmChainId = (chainId: ChainId) =>
? POLYGON_NETWORK_CHAIN_ID
: chainId === CHAIN_ID_AVAX
? AVAX_NETWORK_CHAIN_ID
: chainId === CHAIN_ID_OASIS
? OASIS_NETWORK_CHAIN_ID
: undefined;
export const SOLANA_HOST = process.env.REACT_APP_SOLANA_API_URL
? process.env.REACT_APP_SOLANA_API_URL
@ -325,6 +343,27 @@ export const AVAX_TOKEN_BRIDGE_ADDRESS = getAddress(
? "0x61E44E506Ca5659E6c0bba9b678586fA2d729756"
: "0x0290FB167208Af455bB137780163b7B7a9a10C16"
);
export const OASIS_BRIDGE_ADDRESS = getAddress(
CLUSTER === "mainnet"
? "0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585"
: CLUSTER === "testnet"
? "0xc1C338397ffA53a2Eb12A7038b4eeb34791F8aCb"
: "0xC89Ce4735882C9F0f0FE26686c53074E09B0D550"
);
export const OASIS_NFT_BRIDGE_ADDRESS = getAddress(
CLUSTER === "mainnet"
? "0x04952D522Ff217f40B5Ef3cbF659EcA7b952a6c1"
: CLUSTER === "testnet"
? "0xC5c25B41AB0b797571620F5204Afa116A44c0ebA"
: "0x26b4afb60d6c903165150c6f0aa14f8016be4aec"
);
export const OASIS_TOKEN_BRIDGE_ADDRESS = getAddress(
CLUSTER === "mainnet"
? "0x5848C791e09901b40A9Ef749f2a6735b418d7564"
: CLUSTER === "testnet"
? "0x88d8004A9BdbfD9D28090A02010C19897a29605c"
: "0x0290FB167208Af455bB137780163b7B7a9a10C16"
);
export const SOL_BRIDGE_ADDRESS =
CLUSTER === "mainnet"
? "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth"
@ -399,6 +438,8 @@ export const getBridgeAddressForChain = (chainId: ChainId) =>
? ROPSTEN_ETH_BRIDGE_ADDRESS
: chainId === CHAIN_ID_AVAX
? AVAX_BRIDGE_ADDRESS
: chainId === CHAIN_ID_OASIS
? OASIS_BRIDGE_ADDRESS
: "";
export const getNFTBridgeAddressForChain = (chainId: ChainId) =>
chainId === CHAIN_ID_SOLANA
@ -413,6 +454,8 @@ export const getNFTBridgeAddressForChain = (chainId: ChainId) =>
? ROPSTEN_ETH_NFT_BRIDGE_ADDRESS
: chainId === CHAIN_ID_AVAX
? AVAX_NFT_BRIDGE_ADDRESS
: chainId === CHAIN_ID_OASIS
? OASIS_NFT_BRIDGE_ADDRESS
: "";
export const getTokenBridgeAddressForChain = (chainId: ChainId) =>
chainId === CHAIN_ID_SOLANA
@ -429,6 +472,8 @@ export const getTokenBridgeAddressForChain = (chainId: ChainId) =>
? ROPSTEN_ETH_TOKEN_BRIDGE_ADDRESS
: chainId === CHAIN_ID_AVAX
? AVAX_TOKEN_BRIDGE_ADDRESS
: chainId === CHAIN_ID_OASIS
? OASIS_TOKEN_BRIDGE_ADDRESS
: "";
export const COVALENT_API_KEY = process.env.REACT_APP_COVALENT_API_KEY
@ -440,6 +485,7 @@ export const COVALENT_BSC = CLUSTER === "devnet" ? 56 : BSC_NETWORK_CHAIN_ID;
export const COVALENT_POLYGON =
CLUSTER === "devnet" ? 137 : POLYGON_NETWORK_CHAIN_ID;
export const COVALENT_AVAX = CLUSTER === "devnet" ? 137 : AVAX_NETWORK_CHAIN_ID;
export const COVALENT_OASIS = CLUSTER === "devnet" ? null : null;
export const COVALENT_GET_TOKENS_URL = (
chainId: ChainId,
walletAddress: string,
@ -455,6 +501,8 @@ export const COVALENT_GET_TOKENS_URL = (
? COVALENT_POLYGON
: chainId === CHAIN_ID_AVAX
? COVALENT_AVAX
: chainId === CHAIN_ID_OASIS
? COVALENT_OASIS
: "";
// https://www.covalenthq.com/docs/api/#get-/v1/{chain_id}/address/{address}/balances_v2/
return `https://api.covalenthq.com/v1/${chainNum}/address/${walletAddress}/balances_v2/?key=${COVALENT_API_KEY}${
@ -504,6 +552,14 @@ export const WAVAX_ADDRESS =
: "0xDDb64fE46a91D46ee29420539FC25FD07c5FEa3E";
export const WAVAX_DECIMALS = 18;
export const WROSE_ADDRESS =
CLUSTER === "mainnet"
? "0xE4F5F5910b347A5AEFd12745a98eEEA97F69180e"
: CLUSTER === "testnet"
? "0x792296e2a15e6Ceb5f5039DecaE7A1f25b00B0B0"
: "0xDDb64fE46a91D46ee29420539FC25FD07c5FEa3E";
export const WROSE_DECIMALS = 18;
export const WORMHOLE_V1_ETH_ADDRESS =
CLUSTER === "mainnet"
? "0xf92cD566Ea4864356C5491c177A430C222d7e678"