diff --git a/bridge_ui/package-lock.json b/bridge_ui/package-lock.json
index ef425c91b..b0e1c89fb 100644
--- a/bridge_ui/package-lock.json
+++ b/bridge_ui/package-lock.json
@@ -8,7 +8,7 @@
"name": "test_ui",
"version": "0.1.0",
"dependencies": {
- "@certusone/wormhole-sdk": "^0.2.0",
+ "@certusone/wormhole-sdk": "^0.2.1",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.11.2",
"@material-ui/lab": "^4.0.0-alpha.60",
@@ -67,15 +67,14 @@
},
"../sdk/js": {
"name": "@certusone/wormhole-sdk",
- "version": "0.1.5",
+ "version": "0.2.1",
"extraneous": true,
"license": "Apache-2.0",
"dependencies": {
"@improbable-eng/grpc-web": "^0.14.0",
"@solana/spl-token": "^0.1.8",
"@solana/web3.js": "^1.24.0",
- "@terra-money/terra.js": "^2.0.14",
- "@terra-money/wallet-provider": "^2.2.0",
+ "@terra-money/terra.js": "^3.0.7",
"axios": "^0.24.0",
"bech32": "^2.0.0",
"js-base64": "^3.6.1",
@@ -97,7 +96,8 @@
"ts-jest": "^27.0.7",
"tslint": "^6.1.3",
"tslint-config-prettier": "^1.18.0",
- "typescript": "^4.3.5"
+ "typescript": "^4.3.5",
+ "web3": "^1.6.1"
}
},
"node_modules/@apollo/client": {
@@ -2006,9 +2006,9 @@
}
},
"node_modules/@certusone/wormhole-sdk": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.2.0.tgz",
- "integrity": "sha512-M5DnyPbt8Wm2gSG596yH3Fw1cXulQSzJ/4b1wVeQBrZ4g2s0ztSLgSctUGTGwR4wacK5R1IeGo9jfn29KBmdwA==",
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.2.1.tgz",
+ "integrity": "sha512-L85tiUHwnH4nbUEDgQtS2hNm3Q0IsUP29Z/DGbN2zggdvR0KTC6nLQ+LufCM6IcdUQYpYuwXjOYKD1Et8qc0mw==",
"dependencies": {
"@improbable-eng/grpc-web": "^0.14.0",
"@solana/spl-token": "^0.1.8",
@@ -2046,9 +2046,9 @@
"integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg=="
},
"node_modules/@certusone/wormhole-sdk/node_modules/rxjs": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.4.tgz",
- "integrity": "sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ==",
+ "version": "7.5.5",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz",
+ "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==",
"dependencies": {
"tslib": "^2.1.0"
}
@@ -46140,9 +46140,9 @@
}
},
"@certusone/wormhole-sdk": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.2.0.tgz",
- "integrity": "sha512-M5DnyPbt8Wm2gSG596yH3Fw1cXulQSzJ/4b1wVeQBrZ4g2s0ztSLgSctUGTGwR4wacK5R1IeGo9jfn29KBmdwA==",
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.2.1.tgz",
+ "integrity": "sha512-L85tiUHwnH4nbUEDgQtS2hNm3Q0IsUP29Z/DGbN2zggdvR0KTC6nLQ+LufCM6IcdUQYpYuwXjOYKD1Et8qc0mw==",
"requires": {
"@improbable-eng/grpc-web": "^0.14.0",
"@solana/spl-token": "^0.1.8",
@@ -46177,9 +46177,9 @@
"integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg=="
},
"rxjs": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.4.tgz",
- "integrity": "sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ==",
+ "version": "7.5.5",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz",
+ "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==",
"requires": {
"tslib": "^2.1.0"
}
diff --git a/bridge_ui/package.json b/bridge_ui/package.json
index 3b42ef99f..9b75ee0d3 100644
--- a/bridge_ui/package.json
+++ b/bridge_ui/package.json
@@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
- "@certusone/wormhole-sdk": "^0.2.0",
+ "@certusone/wormhole-sdk": "^0.2.1",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.11.2",
"@material-ui/lab": "^4.0.0-alpha.60",
diff --git a/bridge_ui/src/components/Attest/Create.tsx b/bridge_ui/src/components/Attest/Create.tsx
index 65912a2f1..84ca24510 100644
--- a/bridge_ui/src/components/Attest/Create.tsx
+++ b/bridge_ui/src/components/Attest/Create.tsx
@@ -42,8 +42,6 @@ function Create() {
shouldUpdate || false
);
- console.log("foreign asset info", foreignAssetInfo);
-
return (
<>
diff --git a/bridge_ui/src/hooks/useHandleCreateWrapped.tsx b/bridge_ui/src/hooks/useHandleCreateWrapped.tsx
index 79054b305..b23719d87 100644
--- a/bridge_ui/src/hooks/useHandleCreateWrapped.tsx
+++ b/bridge_ui/src/hooks/useHandleCreateWrapped.tsx
@@ -1,16 +1,19 @@
import {
ChainId,
+ CHAIN_ID_ACALA,
+ CHAIN_ID_KARURA,
CHAIN_ID_SOLANA,
CHAIN_ID_TERRA,
createWrappedOnEth,
createWrappedOnSolana,
createWrappedOnTerra,
- updateWrappedOnEth,
- updateWrappedOnTerra,
- updateWrappedOnSolana,
- postVaaSolanaWithRetry,
isEVMChain,
+ postVaaSolanaWithRetry,
+ updateWrappedOnEth,
+ updateWrappedOnSolana,
+ updateWrappedOnTerra,
} from "@certusone/wormhole-sdk";
+import { Alert } from "@material-ui/lab";
import { WalletContextState } from "@solana/wallet-adapter-react";
import { Connection } from "@solana/web3.js";
import {
@@ -23,7 +26,6 @@ import { useCallback, useMemo } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useEthereumProvider } from "../contexts/EthereumProviderContext";
import { useSolanaWallet } from "../contexts/SolanaWalletContext";
-import useAttestSignedVAA from "./useAttestSignedVAA";
import { setCreateTx, setIsCreating } from "../store/attestSlice";
import {
selectAttestIsCreating,
@@ -31,17 +33,20 @@ import {
selectTerraFeeDenom,
} from "../store/selectors";
import {
+ ACALA_HOST,
getTokenBridgeAddressForChain,
+ KARURA_HOST,
MAX_VAA_UPLOAD_RETRIES_SOLANA,
SOLANA_HOST,
SOL_BRIDGE_ADDRESS,
SOL_TOKEN_BRIDGE_ADDRESS,
TERRA_TOKEN_BRIDGE_ADDRESS,
} from "../utils/consts";
+import { getKaruraGasParams } from "../utils/karura";
import parseError from "../utils/parseError";
import { signSendAndConfirm } from "../utils/solana";
-import { Alert } from "@material-ui/lab";
import { postWithFees } from "../utils/terra";
+import useAttestSignedVAA from "./useAttestSignedVAA";
async function evm(
dispatch: any,
@@ -53,16 +58,25 @@ async function evm(
) {
dispatch(setIsCreating(true));
try {
+ // Karura and Acala need gas params for contract deploys
+ const overrides =
+ chainId === CHAIN_ID_KARURA
+ ? await getKaruraGasParams(KARURA_HOST)
+ : chainId === CHAIN_ID_ACALA
+ ? await getKaruraGasParams(ACALA_HOST)
+ : {};
const receipt = shouldUpdate
? await updateWrappedOnEth(
getTokenBridgeAddressForChain(chainId),
signer,
- signedVAA
+ signedVAA,
+ overrides
)
: await createWrappedOnEth(
getTokenBridgeAddressForChain(chainId),
signer,
- signedVAA
+ signedVAA,
+ overrides
);
dispatch(
setCreateTx({ id: receipt.transactionHash, block: receipt.blockNumber })
diff --git a/bridge_ui/src/icons/acala.svg b/bridge_ui/src/icons/acala.svg
new file mode 100644
index 000000000..3cd2abb99
--- /dev/null
+++ b/bridge_ui/src/icons/acala.svg
@@ -0,0 +1,162 @@
+
+
diff --git a/bridge_ui/src/icons/karura.svg b/bridge_ui/src/icons/karura.svg
new file mode 100644
index 000000000..7eaa7809d
--- /dev/null
+++ b/bridge_ui/src/icons/karura.svg
@@ -0,0 +1,28 @@
+
+
+
diff --git a/bridge_ui/src/utils/consts.ts b/bridge_ui/src/utils/consts.ts
index 7e8692ce8..a1e547fea 100644
--- a/bridge_ui/src/utils/consts.ts
+++ b/bridge_ui/src/utils/consts.ts
@@ -1,10 +1,12 @@
import {
ChainId,
+ CHAIN_ID_ACALA,
CHAIN_ID_AVAX,
CHAIN_ID_BSC,
CHAIN_ID_ETH,
CHAIN_ID_ETHEREUM_ROPSTEN,
CHAIN_ID_FANTOM,
+ CHAIN_ID_KARURA,
CHAIN_ID_OASIS,
CHAIN_ID_POLYGON,
CHAIN_ID_SOLANA,
@@ -13,10 +15,12 @@ import {
} from "@certusone/wormhole-sdk";
import { clusterApiUrl } from "@solana/web3.js";
import { getAddress } from "ethers/lib/utils";
+import acalaIcon from "../icons/acala.svg";
import avaxIcon from "../icons/avax.svg";
import bscIcon from "../icons/bsc.svg";
import ethIcon from "../icons/eth.svg";
import fantomIcon from "../icons/fantom.svg";
+import karuraIcon from "../icons/karura.svg";
import oasisIcon from "../icons/oasis-network-rose-logo.svg";
import polygonIcon from "../icons/polygon.svg";
import solanaIcon from "../icons/solana.svg";
@@ -80,6 +84,11 @@ export const CHAINS: ChainInfo[] =
]
: CLUSTER === "testnet"
? [
+ {
+ id: CHAIN_ID_ACALA,
+ name: "Acala",
+ logo: acalaIcon,
+ },
{
id: CHAIN_ID_AVAX,
name: "Avalanche",
@@ -105,6 +114,11 @@ export const CHAINS: ChainInfo[] =
name: "Fantom",
logo: fantomIcon,
},
+ {
+ id: CHAIN_ID_KARURA,
+ name: "Karura",
+ logo: karuraIcon,
+ },
{
id: CHAIN_ID_OASIS,
name: "Oasis",
@@ -158,7 +172,9 @@ export const CHAINS_WITH_NFT_SUPPORT = CHAINS.filter(
id === CHAIN_ID_POLYGON ||
id === CHAIN_ID_OASIS ||
id === CHAIN_ID_SOLANA ||
- id === CHAIN_ID_FANTOM
+ id === CHAIN_ID_FANTOM ||
+ id === CHAIN_ID_KARURA ||
+ id === CHAIN_ID_ACALA
);
export type ChainsById = { [key in ChainId]: ChainInfo };
export const CHAINS_BY_ID: ChainsById = CHAINS.reduce((obj, chain) => {
@@ -184,6 +200,10 @@ export const getDefaultNativeCurrencySymbol = (chainId: ChainId) =>
? "ROSE"
: chainId === CHAIN_ID_FANTOM
? "FTM"
+ : chainId === CHAIN_ID_KARURA
+ ? "KAR"
+ : chainId === CHAIN_ID_ACALA
+ ? "ACA"
: "";
export const getExplorerName = (chainId: ChainId) =>
chainId === CHAIN_ID_ETH || chainId === CHAIN_ID_ETHEREUM_ROPSTEN
@@ -226,6 +246,10 @@ export const OASIS_NETWORK_CHAIN_ID =
CLUSTER === "mainnet" ? 42262 : CLUSTER === "testnet" ? 42261 : 1381;
export const FANTOM_NETWORK_CHAIN_ID =
CLUSTER === "mainnet" ? 250 : CLUSTER === "testnet" ? 4002 : 1381;
+export const KARURA_NETWORK_CHAIN_ID =
+ CLUSTER === "mainnet" ? 686 : CLUSTER === "testnet" ? 686 : 1381;
+export const ACALA_NETWORK_CHAIN_ID =
+ CLUSTER === "mainnet" ? 787 : CLUSTER === "testnet" ? 787 : 1381;
export const getEvmChainId = (chainId: ChainId) =>
chainId === CHAIN_ID_ETH
? ETH_NETWORK_CHAIN_ID
@@ -241,6 +265,10 @@ export const getEvmChainId = (chainId: ChainId) =>
? OASIS_NETWORK_CHAIN_ID
: chainId === CHAIN_ID_FANTOM
? FANTOM_NETWORK_CHAIN_ID
+ : chainId === CHAIN_ID_KARURA
+ ? KARURA_NETWORK_CHAIN_ID
+ : chainId === CHAIN_ID_ACALA
+ ? ACALA_NETWORK_CHAIN_ID
: undefined;
export const SOLANA_HOST = process.env.REACT_APP_SOLANA_API_URL
? process.env.REACT_APP_SOLANA_API_URL
@@ -268,6 +296,18 @@ export const TERRA_HOST =
chainID: "columbus-5",
name: "localterra",
};
+export const KARURA_HOST =
+ CLUSTER === "mainnet"
+ ? ""
+ : CLUSTER === "testnet"
+ ? "http://103.253.145.222:8545"
+ : "";
+export const ACALA_HOST =
+ CLUSTER === "mainnet"
+ ? ""
+ : CLUSTER === "testnet"
+ ? "http://157.245.252.103:8545"
+ : "";
export const ETH_BRIDGE_ADDRESS = getAddress(
CLUSTER === "mainnet"
? "0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B"
@@ -394,6 +434,48 @@ export const FANTOM_TOKEN_BRIDGE_ADDRESS = getAddress(
? "0x599CEa2204B4FaECd584Ab1F2b6aCA137a0afbE8"
: "0x0290FB167208Af455bB137780163b7B7a9a10C16"
);
+export const KARURA_BRIDGE_ADDRESS = getAddress(
+ CLUSTER === "mainnet"
+ ? "0x0000000000000000000000000000000000000000"
+ : CLUSTER === "testnet"
+ ? "0xE4eacc10990ba3308DdCC72d985f2a27D20c7d03"
+ : "0xC89Ce4735882C9F0f0FE26686c53074E09B0D550"
+);
+export const KARURA_NFT_BRIDGE_ADDRESS = getAddress(
+ CLUSTER === "mainnet"
+ ? "0x0000000000000000000000000000000000000000"
+ : CLUSTER === "testnet"
+ ? "0x0A693c2D594292B6Eb89Cb50EFe4B0b63Dd2760D"
+ : "0x26b4afb60d6c903165150c6f0aa14f8016be4aec"
+);
+export const KARURA_TOKEN_BRIDGE_ADDRESS = getAddress(
+ CLUSTER === "mainnet"
+ ? "0x0000000000000000000000000000000000000000"
+ : CLUSTER === "testnet"
+ ? "0xd11De1f930eA1F7Dd0290Fe3a2e35b9C91AEFb37"
+ : "0x0290FB167208Af455bB137780163b7B7a9a10C16"
+);
+export const ACALA_BRIDGE_ADDRESS = getAddress(
+ CLUSTER === "mainnet"
+ ? "0x0000000000000000000000000000000000000000"
+ : CLUSTER === "testnet"
+ ? "0x4377B49d559c0a9466477195C6AdC3D433e265c0"
+ : "0xC89Ce4735882C9F0f0FE26686c53074E09B0D550"
+);
+export const ACALA_NFT_BRIDGE_ADDRESS = getAddress(
+ CLUSTER === "mainnet"
+ ? "0x0000000000000000000000000000000000000000"
+ : CLUSTER === "testnet"
+ ? "0x96f1335e0AcAB3cfd9899B30b2374e25a2148a6E"
+ : "0x26b4afb60d6c903165150c6f0aa14f8016be4aec"
+);
+export const ACALA_TOKEN_BRIDGE_ADDRESS = getAddress(
+ CLUSTER === "mainnet"
+ ? "0x0000000000000000000000000000000000000000"
+ : CLUSTER === "testnet"
+ ? "0xebA00cbe08992EdD08ed7793E07ad6063c807004"
+ : "0x0290FB167208Af455bB137780163b7B7a9a10C16"
+);
export const SOL_BRIDGE_ADDRESS =
CLUSTER === "mainnet"
? "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth"
@@ -472,6 +554,10 @@ export const getBridgeAddressForChain = (chainId: ChainId) =>
? OASIS_BRIDGE_ADDRESS
: chainId === CHAIN_ID_FANTOM
? FANTOM_BRIDGE_ADDRESS
+ : chainId === CHAIN_ID_KARURA
+ ? KARURA_BRIDGE_ADDRESS
+ : chainId === CHAIN_ID_ACALA
+ ? ACALA_BRIDGE_ADDRESS
: "";
export const getNFTBridgeAddressForChain = (chainId: ChainId) =>
chainId === CHAIN_ID_SOLANA
@@ -490,6 +576,10 @@ export const getNFTBridgeAddressForChain = (chainId: ChainId) =>
? OASIS_NFT_BRIDGE_ADDRESS
: chainId === CHAIN_ID_FANTOM
? FANTOM_NFT_BRIDGE_ADDRESS
+ : chainId === CHAIN_ID_KARURA
+ ? KARURA_NFT_BRIDGE_ADDRESS
+ : chainId === CHAIN_ID_ACALA
+ ? ACALA_NFT_BRIDGE_ADDRESS
: "";
export const getTokenBridgeAddressForChain = (chainId: ChainId) =>
chainId === CHAIN_ID_SOLANA
@@ -510,6 +600,10 @@ export const getTokenBridgeAddressForChain = (chainId: ChainId) =>
? OASIS_TOKEN_BRIDGE_ADDRESS
: chainId === CHAIN_ID_FANTOM
? FANTOM_TOKEN_BRIDGE_ADDRESS
+ : chainId === CHAIN_ID_KARURA
+ ? KARURA_TOKEN_BRIDGE_ADDRESS
+ : chainId === CHAIN_ID_ACALA
+ ? ACALA_TOKEN_BRIDGE_ADDRESS
: "";
export const COVALENT_API_KEY = process.env.REACT_APP_COVALENT_API_KEY
@@ -524,6 +618,8 @@ export const COVALENT_AVAX = CLUSTER === "devnet" ? 137 : AVAX_NETWORK_CHAIN_ID;
export const COVALENT_OASIS = CLUSTER === "devnet" ? null : null;
export const COVALENT_FANTOM =
CLUSTER === "devnet" ? 250 : FANTOM_NETWORK_CHAIN_ID;
+export const COVALENT_KARURA = CLUSTER === "devnet" ? null : null;
+export const COVALENT_ACALA = CLUSTER === "devnet" ? null : null;
export const COVALENT_GET_TOKENS_URL = (
chainId: ChainId,
walletAddress: string,
@@ -543,6 +639,10 @@ export const COVALENT_GET_TOKENS_URL = (
? COVALENT_OASIS
: chainId === CHAIN_ID_FANTOM
? COVALENT_FANTOM
+ : chainId === CHAIN_ID_KARURA
+ ? COVALENT_KARURA
+ : chainId === CHAIN_ID_ACALA
+ ? COVALENT_ACALA
: "";
// 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}${
diff --git a/bridge_ui/src/utils/karura.ts b/bridge_ui/src/utils/karura.ts
new file mode 100644
index 000000000..bbca10ac6
--- /dev/null
+++ b/bridge_ui/src/utils/karura.ts
@@ -0,0 +1,22 @@
+import axios from "axios";
+
+export async function getKaruraGasParams(rpc: string): Promise<{
+ gasPrice: number;
+ gasLimit: number;
+}> {
+ const gasLimit = 21000000;
+ const storageLimit = 64001;
+ const res = (
+ await axios.post(rpc, {
+ id: 0,
+ jsonrpc: "2.0",
+ method: "eth_getEthGas",
+ params: [gasLimit, storageLimit],
+ })
+ ).data.result;
+
+ return {
+ gasLimit: parseInt(res.gasLimit, 16),
+ gasPrice: parseInt(res.gasPrice, 16),
+ };
+}