bridge_ui: terra, terra transfers
Change-Id: I9a615bd69ed2cf82c9eccee304b1211fd0c9a96c
This commit is contained in:
parent
d09abac78f
commit
3795cb15fb
|
@ -12,7 +12,9 @@
|
||||||
"@solana/spl-token": "^0.1.6",
|
"@solana/spl-token": "^0.1.6",
|
||||||
"@solana/wallet-base": "^0.0.1",
|
"@solana/wallet-base": "^0.0.1",
|
||||||
"@solana/web3.js": "^1.22.0",
|
"@solana/web3.js": "^1.22.0",
|
||||||
|
"@terra-money/wallet-provider": "^1.4.0-alpha.1",
|
||||||
"ethers": "^5.4.1",
|
"ethers": "^5.4.1",
|
||||||
|
"js-base64": "^3.6.1",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-redux": "^7.2.4",
|
"react-redux": "^7.2.4",
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { CHAIN_ID_ETH, CHAIN_ID_SOLANA } from "@certusone/wormhole-sdk";
|
import { CHAIN_ID_TERRA, CHAIN_ID_ETH, CHAIN_ID_SOLANA } from "@certusone/wormhole-sdk";
|
||||||
import { Button, CircularProgress, makeStyles } from "@material-ui/core";
|
import { Button, CircularProgress, makeStyles } from "@material-ui/core";
|
||||||
import { useCallback } from "react";
|
import { useCallback } from "react";
|
||||||
|
import { useConnectedWallet } from "@terra-money/wallet-provider";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { useEthereumProvider } from "../../contexts/EthereumProviderContext";
|
import { useEthereumProvider } from "../../contexts/EthereumProviderContext";
|
||||||
import { useSolanaWallet } from "../../contexts/SolanaWalletContext";
|
import { useSolanaWallet } from "../../contexts/SolanaWalletContext";
|
||||||
|
@ -13,6 +14,7 @@ import {
|
||||||
import {
|
import {
|
||||||
createWrappedOnEth,
|
createWrappedOnEth,
|
||||||
createWrappedOnSolana,
|
createWrappedOnSolana,
|
||||||
|
createWrappedOnTerra,
|
||||||
} from "../../utils/createWrappedOn";
|
} from "../../utils/createWrappedOn";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
|
@ -32,6 +34,7 @@ function Create() {
|
||||||
const signedVAA = useAttestSignedVAA();
|
const signedVAA = useAttestSignedVAA();
|
||||||
const isCreating = useSelector(selectAttestIsCreating);
|
const isCreating = useSelector(selectAttestIsCreating);
|
||||||
const { signer } = useEthereumProvider();
|
const { signer } = useEthereumProvider();
|
||||||
|
const terraWallet = useConnectedWallet();
|
||||||
const handleCreateClick = useCallback(() => {
|
const handleCreateClick = useCallback(() => {
|
||||||
if (targetChain === CHAIN_ID_SOLANA && signedVAA) {
|
if (targetChain === CHAIN_ID_SOLANA && signedVAA) {
|
||||||
(async () => {
|
(async () => {
|
||||||
|
@ -47,6 +50,12 @@ function Create() {
|
||||||
dispatch(reset());
|
dispatch(reset());
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
if (targetChain === CHAIN_ID_TERRA && signedVAA) {
|
||||||
|
(async () => {
|
||||||
|
dispatch(setIsCreating(true));
|
||||||
|
createWrappedOnTerra(terraWallet, signedVAA);
|
||||||
|
})();
|
||||||
|
}
|
||||||
}, [dispatch, targetChain, wallet, solPK, signedVAA, signer]);
|
}, [dispatch, targetChain, wallet, solPK, signedVAA, signer]);
|
||||||
return (
|
return (
|
||||||
<div style={{ position: "relative" }}>
|
<div style={{ position: "relative" }}>
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { CHAIN_ID_ETH, CHAIN_ID_SOLANA } from "@certusone/wormhole-sdk";
|
import { CHAIN_ID_TERRA, CHAIN_ID_ETH, CHAIN_ID_SOLANA } from "@certusone/wormhole-sdk";
|
||||||
import { Button, CircularProgress, makeStyles } from "@material-ui/core";
|
import { Button, CircularProgress, makeStyles } from "@material-ui/core";
|
||||||
import { useCallback } from "react";
|
import { useCallback } from "react";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { useEthereumProvider } from "../../contexts/EthereumProviderContext";
|
import { useEthereumProvider } from "../../contexts/EthereumProviderContext";
|
||||||
import { useSolanaWallet } from "../../contexts/SolanaWalletContext";
|
import { useSolanaWallet } from "../../contexts/SolanaWalletContext";
|
||||||
|
import { useConnectedWallet } from "@terra-money/wallet-provider";
|
||||||
import { setIsSending, setSignedVAAHex } from "../../store/attestSlice";
|
import { setIsSending, setSignedVAAHex } from "../../store/attestSlice";
|
||||||
import {
|
import {
|
||||||
selectAttestIsSendComplete,
|
selectAttestIsSendComplete,
|
||||||
|
@ -13,7 +14,11 @@ import {
|
||||||
selectAttestSourceChain,
|
selectAttestSourceChain,
|
||||||
} from "../../store/selectors";
|
} from "../../store/selectors";
|
||||||
import { uint8ArrayToHex } from "../../utils/array";
|
import { uint8ArrayToHex } from "../../utils/array";
|
||||||
import { attestFromEth, attestFromSolana } from "../../utils/attestFrom";
|
import {
|
||||||
|
attestFromEth,
|
||||||
|
attestFromSolana,
|
||||||
|
attestFromTerra,
|
||||||
|
} from "../../utils/attestFrom";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
transferButton: {
|
transferButton: {
|
||||||
|
@ -35,6 +40,7 @@ function Send() {
|
||||||
const isSendComplete = useSelector(selectAttestIsSendComplete);
|
const isSendComplete = useSelector(selectAttestIsSendComplete);
|
||||||
const { signer } = useEthereumProvider();
|
const { signer } = useEthereumProvider();
|
||||||
const { wallet } = useSolanaWallet();
|
const { wallet } = useSolanaWallet();
|
||||||
|
const terraWallet = useConnectedWallet();
|
||||||
const solPK = wallet?.publicKey;
|
const solPK = wallet?.publicKey;
|
||||||
// TODO: dynamically get "to" wallet
|
// TODO: dynamically get "to" wallet
|
||||||
const handleAttestClick = useCallback(() => {
|
const handleAttestClick = useCallback(() => {
|
||||||
|
@ -68,7 +74,20 @@ function Send() {
|
||||||
dispatch(setIsSending(false));
|
dispatch(setIsSending(false));
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
}
|
} else if (sourceChain === CHAIN_ID_TERRA) {
|
||||||
|
//TODO: just for testing, this should eventually use the store to communicate between steps
|
||||||
|
(async () => {
|
||||||
|
dispatch(setIsSending(true));
|
||||||
|
try {
|
||||||
|
const vaaBytes = await attestFromTerra(terraWallet, sourceAsset);
|
||||||
|
console.log("bytes in attest", vaaBytes);
|
||||||
|
vaaBytes && dispatch(setSignedVAAHex(uint8ArrayToHex(vaaBytes)));
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
dispatch(setIsSending(false));
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
}, [dispatch, sourceChain, signer, wallet, solPK, sourceAsset]);
|
}, [dispatch, sourceChain, signer, wallet, solPK, sourceAsset]);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -2,10 +2,12 @@ import {
|
||||||
ChainId,
|
ChainId,
|
||||||
CHAIN_ID_ETH,
|
CHAIN_ID_ETH,
|
||||||
CHAIN_ID_SOLANA,
|
CHAIN_ID_SOLANA,
|
||||||
|
CHAIN_ID_TERRA,
|
||||||
} from "@certusone/wormhole-sdk";
|
} from "@certusone/wormhole-sdk";
|
||||||
import { Typography } from "@material-ui/core";
|
import { Typography } from "@material-ui/core";
|
||||||
import EthereumSignerKey from "./EthereumSignerKey";
|
import EthereumSignerKey from "./EthereumSignerKey";
|
||||||
import SolanaWalletKey from "./SolanaWalletKey";
|
import SolanaWalletKey from "./SolanaWalletKey";
|
||||||
|
import TerraWalletKey from "./TerraWalletKey";
|
||||||
|
|
||||||
function KeyAndBalance({
|
function KeyAndBalance({
|
||||||
chainId,
|
chainId,
|
||||||
|
@ -30,6 +32,14 @@ function KeyAndBalance({
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (chainId === CHAIN_ID_TERRA) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<TerraWalletKey />
|
||||||
|
<Typography>{balance}</Typography>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { useTerraWallet } from "../contexts/TerraWalletContext";
|
||||||
|
import ToggleConnectedButton from "./ToggleConnectedButton";
|
||||||
|
|
||||||
|
const TerraWalletKey = () => {
|
||||||
|
const { connect, disconnect, connected, wallet } = useTerraWallet();
|
||||||
|
const pk =
|
||||||
|
(wallet &&
|
||||||
|
wallet.wallets &&
|
||||||
|
wallet.wallets.length > 0 &&
|
||||||
|
wallet.wallets[0].terraAddress) ||
|
||||||
|
"";
|
||||||
|
return (
|
||||||
|
<ToggleConnectedButton
|
||||||
|
connect={connect}
|
||||||
|
disconnect={disconnect}
|
||||||
|
connected={connected}
|
||||||
|
pk={pk}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TerraWalletKey;
|
|
@ -1,7 +1,12 @@
|
||||||
import { CHAIN_ID_ETH, CHAIN_ID_SOLANA } from "@certusone/wormhole-sdk";
|
import {
|
||||||
|
CHAIN_ID_TERRA,
|
||||||
|
CHAIN_ID_ETH,
|
||||||
|
CHAIN_ID_SOLANA,
|
||||||
|
} from "@certusone/wormhole-sdk";
|
||||||
import { Button, CircularProgress, makeStyles } from "@material-ui/core";
|
import { Button, CircularProgress, makeStyles } from "@material-ui/core";
|
||||||
import { useCallback } from "react";
|
import { useCallback } from "react";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
import { useConnectedWallet } from "@terra-money/wallet-provider";
|
||||||
import { useEthereumProvider } from "../../contexts/EthereumProviderContext";
|
import { useEthereumProvider } from "../../contexts/EthereumProviderContext";
|
||||||
import { useSolanaWallet } from "../../contexts/SolanaWalletContext";
|
import { useSolanaWallet } from "../../contexts/SolanaWalletContext";
|
||||||
import useTransferSignedVAA from "../../hooks/useTransferSignedVAA";
|
import useTransferSignedVAA from "../../hooks/useTransferSignedVAA";
|
||||||
|
@ -13,7 +18,11 @@ import {
|
||||||
selectTransferTargetChain,
|
selectTransferTargetChain,
|
||||||
} from "../../store/selectors";
|
} from "../../store/selectors";
|
||||||
import { reset, setIsRedeeming } from "../../store/transferSlice";
|
import { reset, setIsRedeeming } from "../../store/transferSlice";
|
||||||
import { redeemOnEth, redeemOnSolana } from "../../utils/redeemOn";
|
import {
|
||||||
|
redeemOnEth,
|
||||||
|
redeemOnSolana,
|
||||||
|
redeemOnTerra,
|
||||||
|
} from "../../utils/redeemOn";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
transferButton: {
|
transferButton: {
|
||||||
|
@ -35,6 +44,7 @@ function Redeem() {
|
||||||
const { wallet } = useSolanaWallet();
|
const { wallet } = useSolanaWallet();
|
||||||
const solPK = wallet?.publicKey;
|
const solPK = wallet?.publicKey;
|
||||||
const { signer } = useEthereumProvider();
|
const { signer } = useEthereumProvider();
|
||||||
|
const terraWallet = useConnectedWallet();
|
||||||
const signedVAA = useTransferSignedVAA();
|
const signedVAA = useTransferSignedVAA();
|
||||||
const isRedeeming = useSelector(selectTransferIsRedeeming);
|
const isRedeeming = useSelector(selectTransferIsRedeeming);
|
||||||
const handleRedeemClick = useCallback(() => {
|
const handleRedeemClick = useCallback(() => {
|
||||||
|
@ -58,8 +68,13 @@ function Redeem() {
|
||||||
dispatch(reset());
|
dispatch(reset());
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
if (targetChain === CHAIN_ID_TERRA && signedVAA) {
|
||||||
|
dispatch(setIsRedeeming(true));
|
||||||
|
redeemOnTerra(terraWallet, signedVAA);
|
||||||
|
}
|
||||||
}, [
|
}, [
|
||||||
dispatch,
|
dispatch,
|
||||||
|
terraWallet,
|
||||||
targetChain,
|
targetChain,
|
||||||
signer,
|
signer,
|
||||||
signedVAA,
|
signedVAA,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { CHAIN_ID_ETH, CHAIN_ID_SOLANA } from "@certusone/wormhole-sdk";
|
import { CHAIN_ID_TERRA, CHAIN_ID_ETH, CHAIN_ID_SOLANA } from "@certusone/wormhole-sdk";
|
||||||
import { Button, CircularProgress, makeStyles } from "@material-ui/core";
|
import { Button, CircularProgress, makeStyles } from "@material-ui/core";
|
||||||
import {
|
import {
|
||||||
ASSOCIATED_TOKEN_PROGRAM_ID,
|
ASSOCIATED_TOKEN_PROGRAM_ID,
|
||||||
|
@ -27,7 +27,11 @@ import {
|
||||||
} from "../../store/selectors";
|
} from "../../store/selectors";
|
||||||
import { setIsSending, setSignedVAAHex } from "../../store/transferSlice";
|
import { setIsSending, setSignedVAAHex } from "../../store/transferSlice";
|
||||||
import { uint8ArrayToHex } from "../../utils/array";
|
import { uint8ArrayToHex } from "../../utils/array";
|
||||||
import { transferFromEth, transferFromSolana } from "../../utils/transferFrom";
|
import {
|
||||||
|
transferFromEth,
|
||||||
|
transferFromSolana,
|
||||||
|
transferFromTerra,
|
||||||
|
} from "../../utils/transferFrom";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
transferButton: {
|
transferButton: {
|
||||||
|
@ -146,6 +150,19 @@ function Send() {
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
if (sourceChain === CHAIN_ID_TERRA && decimals) {
|
||||||
|
(async () => {
|
||||||
|
dispatch(setIsSending(true));
|
||||||
|
try {
|
||||||
|
const vaaBytes = await transferFromTerra(undefined);
|
||||||
|
console.log("bytes in transfer", vaaBytes);
|
||||||
|
vaaBytes && dispatch(setSignedVAAHex(uint8ArrayToHex(vaaBytes)));
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
dispatch(setIsSending(false));
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
}, [
|
}, [
|
||||||
dispatch,
|
dispatch,
|
||||||
sourceChain,
|
sourceChain,
|
||||||
|
|
|
@ -29,9 +29,11 @@ function Transfer() {
|
||||||
useCheckIfWormholeWrapped();
|
useCheckIfWormholeWrapped();
|
||||||
useFetchTargetAsset();
|
useFetchTargetAsset();
|
||||||
useGetBalanceEffect("target");
|
useGetBalanceEffect("target");
|
||||||
|
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const activeStep = useSelector(selectTransferActiveStep);
|
const activeStep = useSelector(selectTransferActiveStep);
|
||||||
const signedVAAHex = useSelector(selectTransferSignedVAAHex);
|
const signedVAAHex = useSelector(selectTransferSignedVAAHex);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container maxWidth="md">
|
<Container maxWidth="md">
|
||||||
<Stepper activeStep={activeStep} orientation="vertical">
|
<Stepper activeStep={activeStep} orientation="vertical">
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
import {
|
||||||
|
NetworkInfo,
|
||||||
|
Wallet,
|
||||||
|
WalletProvider,
|
||||||
|
useWallet,
|
||||||
|
} from "@terra-money/wallet-provider";
|
||||||
|
import React, {
|
||||||
|
ReactChildren,
|
||||||
|
useCallback,
|
||||||
|
useContext,
|
||||||
|
useMemo,
|
||||||
|
useState,
|
||||||
|
} from "react";
|
||||||
|
import { TERRA_HOST } from "../utils/consts";
|
||||||
|
|
||||||
|
const mainnet = {
|
||||||
|
name: "mainnet",
|
||||||
|
chainID: "columbus-4",
|
||||||
|
lcd: "https://lcd.terra.dev",
|
||||||
|
};
|
||||||
|
|
||||||
|
const localnet = {
|
||||||
|
name: "localnet",
|
||||||
|
chainID: "localnet",
|
||||||
|
lcd: TERRA_HOST,
|
||||||
|
};
|
||||||
|
|
||||||
|
const walletConnectChainIds: Record<number, NetworkInfo> = {
|
||||||
|
0: localnet,
|
||||||
|
1: mainnet,
|
||||||
|
};
|
||||||
|
|
||||||
|
interface ITerraWalletContext {
|
||||||
|
connect(): void;
|
||||||
|
disconnect(): void;
|
||||||
|
connected: boolean;
|
||||||
|
wallet: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TerraWalletContext = React.createContext<ITerraWalletContext>({
|
||||||
|
connect: () => {},
|
||||||
|
disconnect: () => {},
|
||||||
|
connected: false,
|
||||||
|
wallet: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const TerraWalletWrapper = ({
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
children: ReactChildren;
|
||||||
|
}) => {
|
||||||
|
// TODO: Use wallet instead of useConnectedWallet.
|
||||||
|
const terraWallet = useWallet();
|
||||||
|
const [wallet, setWallet] = useState<Wallet | undefined>(undefined);
|
||||||
|
const [connected, setConnected] = useState(false);
|
||||||
|
|
||||||
|
const connect = useCallback(() => {
|
||||||
|
const CHROME_EXTENSION = 1;
|
||||||
|
if (terraWallet) {
|
||||||
|
terraWallet.connect(terraWallet.availableConnectTypes[CHROME_EXTENSION]);
|
||||||
|
setWallet(terraWallet);
|
||||||
|
setConnected(true);
|
||||||
|
}
|
||||||
|
}, [terraWallet]);
|
||||||
|
|
||||||
|
const disconnect = useCallback(() => {
|
||||||
|
setConnected(false);
|
||||||
|
setWallet(undefined);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const contextValue = useMemo(
|
||||||
|
() => ({
|
||||||
|
connect,
|
||||||
|
disconnect,
|
||||||
|
connected,
|
||||||
|
wallet: terraWallet,
|
||||||
|
}),
|
||||||
|
[connect, disconnect, connected, terraWallet]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TerraWalletContext.Provider value={contextValue}>
|
||||||
|
{children}
|
||||||
|
</TerraWalletContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TerraWalletProvider = ({
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
children: ReactChildren;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<WalletProvider
|
||||||
|
defaultNetwork={localnet}
|
||||||
|
walletConnectChainIds={walletConnectChainIds}
|
||||||
|
>
|
||||||
|
<TerraWalletWrapper>{children}</TerraWalletWrapper>
|
||||||
|
</WalletProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useTerraWallet = () => {
|
||||||
|
return useContext(TerraWalletContext);
|
||||||
|
};
|
|
@ -1,4 +1,4 @@
|
||||||
import { CHAIN_ID_ETH, CHAIN_ID_SOLANA } from "@certusone/wormhole-sdk";
|
import { CHAIN_ID_ETH, CHAIN_ID_SOLANA, CHAIN_ID_TERRA } from "@certusone/wormhole-sdk";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { useEthereumProvider } from "../contexts/EthereumProviderContext";
|
import { useEthereumProvider } from "../contexts/EthereumProviderContext";
|
||||||
|
@ -10,8 +10,12 @@ import { setSourceWormholeWrappedInfo } from "../store/transferSlice";
|
||||||
import {
|
import {
|
||||||
getOriginalAssetEth,
|
getOriginalAssetEth,
|
||||||
getOriginalAssetSol,
|
getOriginalAssetSol,
|
||||||
|
getOriginalAssetTerra,
|
||||||
} from "../utils/getOriginalAsset";
|
} from "../utils/getOriginalAsset";
|
||||||
|
|
||||||
|
// Check if the tokens in the configured source chain/address are wrapped
|
||||||
|
// tokens. Wrapped tokens are tokens that are non-native, I.E, are locked up on
|
||||||
|
// a different chain than this one.
|
||||||
function useCheckIfWormholeWrapped() {
|
function useCheckIfWormholeWrapped() {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const sourceChain = useSelector(selectTransferSourceChain);
|
const sourceChain = useSelector(selectTransferSourceChain);
|
||||||
|
@ -27,7 +31,8 @@ function useCheckIfWormholeWrapped() {
|
||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
dispatch(setSourceWormholeWrappedInfo(wrappedInfo));
|
dispatch(setSourceWormholeWrappedInfo(wrappedInfo));
|
||||||
}
|
}
|
||||||
} else if (sourceChain === CHAIN_ID_SOLANA) {
|
}
|
||||||
|
if (sourceChain === CHAIN_ID_SOLANA) {
|
||||||
try {
|
try {
|
||||||
const wrappedInfo = await getOriginalAssetSol(sourceAsset);
|
const wrappedInfo = await getOriginalAssetSol(sourceAsset);
|
||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
|
@ -35,6 +40,14 @@ function useCheckIfWormholeWrapped() {
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
|
if (sourceChain === CHAIN_ID_TERRA) {
|
||||||
|
try {
|
||||||
|
const wrappedInfo = await getOriginalAssetTerra(sourceAsset);
|
||||||
|
if (!cancelled) {
|
||||||
|
dispatch(setSourceWormholeWrappedInfo(wrappedInfo));
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
return () => {
|
return () => {
|
||||||
cancelled = true;
|
cancelled = true;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { CHAIN_ID_ETH, CHAIN_ID_SOLANA } from "@certusone/wormhole-sdk";
|
import { CHAIN_ID_TERRA, CHAIN_ID_ETH, CHAIN_ID_SOLANA } from "@certusone/wormhole-sdk";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { useEthereumProvider } from "../contexts/EthereumProviderContext";
|
import { useEthereumProvider } from "../contexts/EthereumProviderContext";
|
||||||
|
@ -14,6 +14,7 @@ import { setTargetAsset } from "../store/transferSlice";
|
||||||
import {
|
import {
|
||||||
getForeignAssetEth,
|
getForeignAssetEth,
|
||||||
getForeignAssetSol,
|
getForeignAssetSol,
|
||||||
|
getForeignAssetTerra,
|
||||||
} from "../utils/getForeignAsset";
|
} from "../utils/getForeignAsset";
|
||||||
|
|
||||||
function useFetchTargetAsset() {
|
function useFetchTargetAsset() {
|
||||||
|
@ -51,7 +52,8 @@ function useFetchTargetAsset() {
|
||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
dispatch(setTargetAsset(asset));
|
dispatch(setTargetAsset(asset));
|
||||||
}
|
}
|
||||||
} else if (targetChain === CHAIN_ID_SOLANA) {
|
}
|
||||||
|
if (targetChain === CHAIN_ID_SOLANA) {
|
||||||
try {
|
try {
|
||||||
const asset = await getForeignAssetSol(sourceChain, sourceAsset);
|
const asset = await getForeignAssetSol(sourceChain, sourceAsset);
|
||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
|
@ -64,6 +66,19 @@ function useFetchTargetAsset() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (targetChain === CHAIN_ID_TERRA) {
|
||||||
|
try {
|
||||||
|
const asset = await getForeignAssetTerra(sourceChain, sourceAsset);
|
||||||
|
if (!cancelled) {
|
||||||
|
console.log("terra target asset", asset);
|
||||||
|
dispatch(setTargetAsset(asset));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (!cancelled) {
|
||||||
|
// TODO: warning for this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
return () => {
|
return () => {
|
||||||
cancelled = true;
|
cancelled = true;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import {
|
import {
|
||||||
CHAIN_ID_ETH,
|
CHAIN_ID_ETH,
|
||||||
CHAIN_ID_SOLANA,
|
CHAIN_ID_SOLANA,
|
||||||
|
CHAIN_ID_TERRA,
|
||||||
TokenImplementation__factory,
|
TokenImplementation__factory,
|
||||||
} from "@certusone/wormhole-sdk";
|
} from "@certusone/wormhole-sdk";
|
||||||
import { Connection, PublicKey } from "@solana/web3.js";
|
import { Connection, PublicKey } from "@solana/web3.js";
|
||||||
|
@ -68,6 +69,13 @@ function useGetBalanceEffect(sourceOrTarget: "source" | "target") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let cancelled = false;
|
let cancelled = false;
|
||||||
|
if (lookupChain === CHAIN_ID_TERRA && wallet) {
|
||||||
|
dispatch(
|
||||||
|
setSourceParsedTokenAccount(
|
||||||
|
createParsedTokenAccount(undefined, "0", 0, 0, "0")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
if (lookupChain === CHAIN_ID_SOLANA && solPK) {
|
if (lookupChain === CHAIN_ID_SOLANA && solPK) {
|
||||||
let mint;
|
let mint;
|
||||||
try {
|
try {
|
||||||
|
@ -143,6 +151,7 @@ function useGetBalanceEffect(sourceOrTarget: "source" | "target") {
|
||||||
};
|
};
|
||||||
}, [
|
}, [
|
||||||
dispatch,
|
dispatch,
|
||||||
|
wallet,
|
||||||
sourceOrTarget,
|
sourceOrTarget,
|
||||||
setAction,
|
setAction,
|
||||||
lookupChain,
|
lookupChain,
|
||||||
|
|
|
@ -7,6 +7,7 @@ import App from "./App";
|
||||||
import RadialGradient from "./components/RadialGradient";
|
import RadialGradient from "./components/RadialGradient";
|
||||||
import { EthereumProviderProvider } from "./contexts/EthereumProviderContext";
|
import { EthereumProviderProvider } from "./contexts/EthereumProviderContext";
|
||||||
import { SolanaWalletProvider } from "./contexts/SolanaWalletContext.tsx";
|
import { SolanaWalletProvider } from "./contexts/SolanaWalletContext.tsx";
|
||||||
|
import { TerraWalletProvider } from "./contexts/TerraWalletContext.tsx";
|
||||||
import { theme } from "./muiTheme";
|
import { theme } from "./muiTheme";
|
||||||
import { store } from "./store";
|
import { store } from "./store";
|
||||||
|
|
||||||
|
@ -17,9 +18,11 @@ ReactDOM.render(
|
||||||
<RadialGradient />
|
<RadialGradient />
|
||||||
<SolanaWalletProvider>
|
<SolanaWalletProvider>
|
||||||
<EthereumProviderProvider>
|
<EthereumProviderProvider>
|
||||||
<HashRouter>
|
<TerraWalletProvider>
|
||||||
<App />
|
<HashRouter>
|
||||||
</HashRouter>
|
<App />
|
||||||
|
</HashRouter>
|
||||||
|
</TerraWalletProvider>
|
||||||
</EthereumProviderProvider>
|
</EthereumProviderProvider>
|
||||||
</SolanaWalletProvider>
|
</SolanaWalletProvider>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
|
|
|
@ -2,11 +2,13 @@ import {
|
||||||
ChainId,
|
ChainId,
|
||||||
CHAIN_ID_ETH,
|
CHAIN_ID_ETH,
|
||||||
CHAIN_ID_SOLANA,
|
CHAIN_ID_SOLANA,
|
||||||
|
CHAIN_ID_TERRA,
|
||||||
} from "@certusone/wormhole-sdk";
|
} from "@certusone/wormhole-sdk";
|
||||||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||||
import {
|
import {
|
||||||
ETH_TEST_TOKEN_ADDRESS,
|
ETH_TEST_TOKEN_ADDRESS,
|
||||||
SOL_TEST_TOKEN_ADDRESS,
|
SOL_TEST_TOKEN_ADDRESS,
|
||||||
|
TERRA_TEST_TOKEN_ADDRESS,
|
||||||
} from "../utils/consts";
|
} from "../utils/consts";
|
||||||
|
|
||||||
const LAST_STEP = 3;
|
const LAST_STEP = 3;
|
||||||
|
@ -56,6 +58,9 @@ export const attestSlice = createSlice({
|
||||||
if (action.payload === CHAIN_ID_SOLANA) {
|
if (action.payload === CHAIN_ID_SOLANA) {
|
||||||
state.sourceAsset = SOL_TEST_TOKEN_ADDRESS;
|
state.sourceAsset = SOL_TEST_TOKEN_ADDRESS;
|
||||||
}
|
}
|
||||||
|
if (action.payload === CHAIN_ID_TERRA) {
|
||||||
|
state.sourceAsset = TERRA_TEST_TOKEN_ADDRESS;
|
||||||
|
}
|
||||||
if (state.targetChain === action.payload) {
|
if (state.targetChain === action.payload) {
|
||||||
state.targetChain = prevSourceChain;
|
state.targetChain = prevSourceChain;
|
||||||
}
|
}
|
||||||
|
@ -76,6 +81,9 @@ export const attestSlice = createSlice({
|
||||||
if (state.targetChain === CHAIN_ID_SOLANA) {
|
if (state.targetChain === CHAIN_ID_SOLANA) {
|
||||||
state.sourceAsset = SOL_TEST_TOKEN_ADDRESS;
|
state.sourceAsset = SOL_TEST_TOKEN_ADDRESS;
|
||||||
}
|
}
|
||||||
|
if (state.targetChain === CHAIN_ID_TERRA) {
|
||||||
|
state.sourceAsset = TERRA_TEST_TOKEN_ADDRESS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setSignedVAAHex: (state, action: PayloadAction<string>) => {
|
setSignedVAAHex: (state, action: PayloadAction<string>) => {
|
||||||
|
|
|
@ -2,11 +2,13 @@ import {
|
||||||
ChainId,
|
ChainId,
|
||||||
CHAIN_ID_ETH,
|
CHAIN_ID_ETH,
|
||||||
CHAIN_ID_SOLANA,
|
CHAIN_ID_SOLANA,
|
||||||
|
CHAIN_ID_TERRA,
|
||||||
} from "@certusone/wormhole-sdk";
|
} from "@certusone/wormhole-sdk";
|
||||||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||||
import {
|
import {
|
||||||
ETH_TEST_TOKEN_ADDRESS,
|
ETH_TEST_TOKEN_ADDRESS,
|
||||||
SOL_TEST_TOKEN_ADDRESS,
|
SOL_TEST_TOKEN_ADDRESS,
|
||||||
|
TERRA_TEST_TOKEN_ADDRESS,
|
||||||
} from "../utils/consts";
|
} from "../utils/consts";
|
||||||
import { StateSafeWormholeWrappedInfo } from "../utils/getOriginalAsset";
|
import { StateSafeWormholeWrappedInfo } from "../utils/getOriginalAsset";
|
||||||
|
|
||||||
|
@ -79,6 +81,9 @@ export const transferSlice = createSlice({
|
||||||
if (action.payload === CHAIN_ID_SOLANA) {
|
if (action.payload === CHAIN_ID_SOLANA) {
|
||||||
state.sourceAsset = SOL_TEST_TOKEN_ADDRESS;
|
state.sourceAsset = SOL_TEST_TOKEN_ADDRESS;
|
||||||
}
|
}
|
||||||
|
if (action.payload === CHAIN_ID_TERRA) {
|
||||||
|
state.sourceAsset = TERRA_TEST_TOKEN_ADDRESS;
|
||||||
|
}
|
||||||
if (state.targetChain === action.payload) {
|
if (state.targetChain === action.payload) {
|
||||||
state.targetChain = prevSourceChain;
|
state.targetChain = prevSourceChain;
|
||||||
}
|
}
|
||||||
|
@ -122,6 +127,9 @@ export const transferSlice = createSlice({
|
||||||
if (state.targetChain === CHAIN_ID_SOLANA) {
|
if (state.targetChain === CHAIN_ID_SOLANA) {
|
||||||
state.sourceAsset = SOL_TEST_TOKEN_ADDRESS;
|
state.sourceAsset = SOL_TEST_TOKEN_ADDRESS;
|
||||||
}
|
}
|
||||||
|
if (state.targetChain === CHAIN_ID_TERRA) {
|
||||||
|
state.sourceAsset = TERRA_TEST_TOKEN_ADDRESS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setTargetAsset: (
|
setTargetAsset: (
|
||||||
|
|
|
@ -3,6 +3,7 @@ import {
|
||||||
attestFromSolana as attestSolanaTx,
|
attestFromSolana as attestSolanaTx,
|
||||||
CHAIN_ID_ETH,
|
CHAIN_ID_ETH,
|
||||||
CHAIN_ID_SOLANA,
|
CHAIN_ID_SOLANA,
|
||||||
|
CHAIN_ID_TERRA,
|
||||||
getEmitterAddressEth,
|
getEmitterAddressEth,
|
||||||
getEmitterAddressSolana,
|
getEmitterAddressSolana,
|
||||||
parseSequenceFromLogEth,
|
parseSequenceFromLogEth,
|
||||||
|
@ -10,10 +11,13 @@ import {
|
||||||
} from "@certusone/wormhole-sdk";
|
} from "@certusone/wormhole-sdk";
|
||||||
import Wallet from "@project-serum/sol-wallet-adapter";
|
import Wallet from "@project-serum/sol-wallet-adapter";
|
||||||
import { Connection } from "@solana/web3.js";
|
import { Connection } from "@solana/web3.js";
|
||||||
|
import { MsgExecuteContract } from "@terra-money/terra.js";
|
||||||
|
import { ConnectedWallet as TerraConnectedWallet } from "@terra-money/wallet-provider";
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
import {
|
import {
|
||||||
ETH_BRIDGE_ADDRESS,
|
ETH_BRIDGE_ADDRESS,
|
||||||
ETH_TOKEN_BRIDGE_ADDRESS,
|
ETH_TOKEN_BRIDGE_ADDRESS,
|
||||||
|
TERRA_TOKEN_BRIDGE_ADDRESS,
|
||||||
SOLANA_HOST,
|
SOLANA_HOST,
|
||||||
SOL_BRIDGE_ADDRESS,
|
SOL_BRIDGE_ADDRESS,
|
||||||
SOL_TOKEN_BRIDGE_ADDRESS,
|
SOL_TOKEN_BRIDGE_ADDRESS,
|
||||||
|
@ -71,3 +75,29 @@ export async function attestFromSolana(
|
||||||
);
|
);
|
||||||
return vaaBytes;
|
return vaaBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function attestFromTerra(
|
||||||
|
wallet: TerraConnectedWallet | undefined,
|
||||||
|
asset: string | undefined
|
||||||
|
) {
|
||||||
|
const nonceConst = Math.random() * 100000;
|
||||||
|
const nonceBuffer = Buffer.alloc(4);
|
||||||
|
nonceBuffer.writeUInt32LE(nonceConst, 0);
|
||||||
|
wallet &&
|
||||||
|
(await wallet.post({
|
||||||
|
msgs: [
|
||||||
|
new MsgExecuteContract(
|
||||||
|
wallet.terraAddress,
|
||||||
|
TERRA_TOKEN_BRIDGE_ADDRESS,
|
||||||
|
{
|
||||||
|
register_asset_hook: {
|
||||||
|
asset_id: asset,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ uluna: 1000 }
|
||||||
|
),
|
||||||
|
],
|
||||||
|
memo: "Create Wrapped",
|
||||||
|
}));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ export const CHAINS_BY_ID: ChainsById = CHAINS.reduce((obj, chain) => {
|
||||||
}, {} as ChainsById);
|
}, {} as ChainsById);
|
||||||
export const WORMHOLE_RPC_HOST = "http://localhost:8080";
|
export const WORMHOLE_RPC_HOST = "http://localhost:8080";
|
||||||
export const SOLANA_HOST = "http://localhost:8899";
|
export const SOLANA_HOST = "http://localhost:8899";
|
||||||
|
export const TERRA_HOST = "http://localhost:1317";
|
||||||
export const ETH_TEST_TOKEN_ADDRESS = getAddress(
|
export const ETH_TEST_TOKEN_ADDRESS = getAddress(
|
||||||
"0x67B5656d60a809915323Bf2C40A8bEF15A152e3e"
|
"0x67B5656d60a809915323Bf2C40A8bEF15A152e3e"
|
||||||
);
|
);
|
||||||
|
@ -50,3 +51,9 @@ export const SOL_TEST_TOKEN_ADDRESS =
|
||||||
export const SOL_BRIDGE_ADDRESS = "Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o";
|
export const SOL_BRIDGE_ADDRESS = "Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o";
|
||||||
export const SOL_TOKEN_BRIDGE_ADDRESS =
|
export const SOL_TOKEN_BRIDGE_ADDRESS =
|
||||||
"B6RHG3mfcckmrYN1UhmJzyS1XX3fZKbkeUcpJe9Sy3FE";
|
"B6RHG3mfcckmrYN1UhmJzyS1XX3fZKbkeUcpJe9Sy3FE";
|
||||||
|
export const TERRA_TEST_TOKEN_ADDRESS =
|
||||||
|
"terra13nkgqrfymug724h8pprpexqj9h629sa3ncw7sh";
|
||||||
|
export const TERRA_BRIDGE_ADDRESS =
|
||||||
|
"terra18vd8fpwxzck93qlwghaj6arh4p7c5n896xzem5";
|
||||||
|
export const TERRA_TOKEN_BRIDGE_ADDRESS =
|
||||||
|
"terra10pyejy66429refv3g35g2t7am0was7ya7kz2a4";
|
||||||
|
|
|
@ -6,11 +6,16 @@ import {
|
||||||
import Wallet from "@project-serum/sol-wallet-adapter";
|
import Wallet from "@project-serum/sol-wallet-adapter";
|
||||||
import { Connection } from "@solana/web3.js";
|
import { Connection } from "@solana/web3.js";
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
|
import { fromUint8Array } from "js-base64";
|
||||||
|
import { MsgExecuteContract } from "@terra-money/terra.js";
|
||||||
|
import { ConnectedWallet as TerraConnectedWallet } from "@terra-money/wallet-provider";
|
||||||
import {
|
import {
|
||||||
ETH_TOKEN_BRIDGE_ADDRESS,
|
ETH_TOKEN_BRIDGE_ADDRESS,
|
||||||
SOLANA_HOST,
|
SOLANA_HOST,
|
||||||
SOL_BRIDGE_ADDRESS,
|
SOL_BRIDGE_ADDRESS,
|
||||||
SOL_TOKEN_BRIDGE_ADDRESS,
|
SOL_TOKEN_BRIDGE_ADDRESS,
|
||||||
|
TERRA_TOKEN_BRIDGE_ADDRESS,
|
||||||
|
TERRA_BRIDGE_ADDRESS,
|
||||||
} from "./consts";
|
} from "./consts";
|
||||||
import { signSendAndConfirm } from "./solana";
|
import { signSendAndConfirm } from "./solana";
|
||||||
|
|
||||||
|
@ -22,6 +27,32 @@ export async function createWrappedOnEth(
|
||||||
await createWrappedOnEthTx(ETH_TOKEN_BRIDGE_ADDRESS, signer, signedVAA);
|
await createWrappedOnEthTx(ETH_TOKEN_BRIDGE_ADDRESS, signer, signedVAA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function createWrappedOnTerra(
|
||||||
|
wallet: TerraConnectedWallet | undefined,
|
||||||
|
signedVAA: Uint8Array
|
||||||
|
) {
|
||||||
|
console.log("creating wrapped");
|
||||||
|
console.log("PROGRAM:", TERRA_TOKEN_BRIDGE_ADDRESS);
|
||||||
|
console.log("BRIDGE:", TERRA_BRIDGE_ADDRESS);
|
||||||
|
console.log("VAA:", signedVAA);
|
||||||
|
wallet &&
|
||||||
|
(await wallet.post({
|
||||||
|
msgs: [
|
||||||
|
new MsgExecuteContract(
|
||||||
|
wallet.terraAddress,
|
||||||
|
TERRA_TOKEN_BRIDGE_ADDRESS,
|
||||||
|
{
|
||||||
|
submit_vaa: {
|
||||||
|
data: fromUint8Array(signedVAA),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ uluna: 1000 }
|
||||||
|
),
|
||||||
|
],
|
||||||
|
memo: "Create Wrapped",
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
export async function createWrappedOnSolana(
|
export async function createWrappedOnSolana(
|
||||||
wallet: Wallet | undefined,
|
wallet: Wallet | undefined,
|
||||||
payerAddress: string | undefined, //TODO: we may not need this since we have wallet
|
payerAddress: string | undefined, //TODO: we may not need this since we have wallet
|
||||||
|
|
|
@ -56,3 +56,16 @@ export async function getForeignAssetSol(
|
||||||
originAssetBytes
|
originAssetBytes
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a foreign asset address on Terra for a provided native chain and asset address
|
||||||
|
* @param originChain
|
||||||
|
* @param originAsset
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getForeignAssetTerra(
|
||||||
|
originChain: ChainId,
|
||||||
|
originAsset: string
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
|
@ -52,3 +52,13 @@ export async function getOriginalAssetSol(
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getOriginalAssetTerra(
|
||||||
|
mintAddress: string
|
||||||
|
): Promise<StateSafeWormholeWrappedInfo> {
|
||||||
|
return {
|
||||||
|
assetAddress: "",
|
||||||
|
chainId: 3,
|
||||||
|
isWrapped: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -6,11 +6,15 @@ import {
|
||||||
import Wallet from "@project-serum/sol-wallet-adapter";
|
import Wallet from "@project-serum/sol-wallet-adapter";
|
||||||
import { Connection } from "@solana/web3.js";
|
import { Connection } from "@solana/web3.js";
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
|
import { fromUint8Array } from 'js-base64';
|
||||||
|
import { ConnectedWallet as TerraConnectedWallet } from "@terra-money/wallet-provider";
|
||||||
|
import { MsgExecuteContract } from "@terra-money/terra.js";
|
||||||
import {
|
import {
|
||||||
ETH_TOKEN_BRIDGE_ADDRESS,
|
ETH_TOKEN_BRIDGE_ADDRESS,
|
||||||
SOLANA_HOST,
|
SOLANA_HOST,
|
||||||
SOL_BRIDGE_ADDRESS,
|
SOL_BRIDGE_ADDRESS,
|
||||||
SOL_TOKEN_BRIDGE_ADDRESS,
|
SOL_TOKEN_BRIDGE_ADDRESS,
|
||||||
|
TERRA_TOKEN_BRIDGE_ADDRESS,
|
||||||
} from "./consts";
|
} from "./consts";
|
||||||
import { signSendAndConfirm } from "./solana";
|
import { signSendAndConfirm } from "./solana";
|
||||||
|
|
||||||
|
@ -50,3 +54,25 @@ export async function redeemOnSolana(
|
||||||
);
|
);
|
||||||
await signSendAndConfirm(wallet, connection, transaction);
|
await signSendAndConfirm(wallet, connection, transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function redeemOnTerra(
|
||||||
|
wallet: TerraConnectedWallet | undefined,
|
||||||
|
signedVAA: Uint8Array,
|
||||||
|
) {
|
||||||
|
if (!wallet) return;
|
||||||
|
wallet && await wallet.post({
|
||||||
|
msgs: [
|
||||||
|
new MsgExecuteContract(
|
||||||
|
wallet.terraAddress,
|
||||||
|
TERRA_TOKEN_BRIDGE_ADDRESS,
|
||||||
|
{
|
||||||
|
submit_vaa: {
|
||||||
|
data: fromUint8Array(signedVAA)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ uluna: 1000 }
|
||||||
|
),
|
||||||
|
],
|
||||||
|
memo: "Complete Transfer",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import {
|
import {
|
||||||
ChainId,
|
ChainId,
|
||||||
CHAIN_ID_ETH,
|
CHAIN_ID_ETH,
|
||||||
|
CHAIN_ID_TERRA,
|
||||||
CHAIN_ID_SOLANA,
|
CHAIN_ID_SOLANA,
|
||||||
getEmitterAddressEth,
|
getEmitterAddressEth,
|
||||||
getEmitterAddressSolana,
|
getEmitterAddressSolana,
|
||||||
|
@ -9,6 +10,7 @@ import {
|
||||||
transferFromEth as transferFromEthTx,
|
transferFromEth as transferFromEthTx,
|
||||||
transferFromSolana as transferFromSolanaTx,
|
transferFromSolana as transferFromSolanaTx,
|
||||||
} from "@certusone/wormhole-sdk";
|
} from "@certusone/wormhole-sdk";
|
||||||
|
import { Wallet as TerraWallet } from "@terra-money/wallet-provider";
|
||||||
import Wallet from "@project-serum/sol-wallet-adapter";
|
import Wallet from "@project-serum/sol-wallet-adapter";
|
||||||
import { Connection } from "@solana/web3.js";
|
import { Connection } from "@solana/web3.js";
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
|
@ -110,3 +112,9 @@ export async function transferFromSolana(
|
||||||
);
|
);
|
||||||
return vaaBytes;
|
return vaaBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function transferFromTerra(
|
||||||
|
wallet: TerraWallet | undefined,
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue