UI - terra support
This commit is contained in:
parent
0c50e93dc0
commit
1c3b6908a9
|
@ -14,6 +14,7 @@
|
||||||
"@material-ui/icons": "^4.11.2",
|
"@material-ui/icons": "^4.11.2",
|
||||||
"@material-ui/lab": "^4.0.0-alpha.60",
|
"@material-ui/lab": "^4.0.0-alpha.60",
|
||||||
"@metamask/detect-provider": "^1.2.0",
|
"@metamask/detect-provider": "^1.2.0",
|
||||||
|
"@terra-money/wallet-provider": "^2.2.0",
|
||||||
"@types/node": "^16.11.19",
|
"@types/node": "^16.11.19",
|
||||||
"@types/react": "^17.0.38",
|
"@types/react": "^17.0.38",
|
||||||
"@types/react-dom": "^17.0.11",
|
"@types/react-dom": "^17.0.11",
|
||||||
|
@ -4464,34 +4465,17 @@
|
||||||
"react-dom": "^17.0.0"
|
"react-dom": "^17.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@terra-dev/web-connector-controller": {
|
"node_modules/@terra-dev/web-extension": {
|
||||||
"version": "0.8.1",
|
"version": "0.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/@terra-dev/web-connector-controller/-/web-connector-controller-0.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/@terra-dev/web-extension/-/web-extension-0.6.0.tgz",
|
||||||
"integrity": "sha512-TIwFtta7vN2GdDUy8SbIIsfTd9XWiU+U6yjizd82yUAhlOJNAGHshG0r1j0irkA5MycYG1duAlr7foeKRu4PGA==",
|
"integrity": "sha512-IyIWHLfweZCb5nHuMyzavnMYposnZMvpsA/89zZPIgIooxhxE//uZD+Ty+ptt4nvkbOgEFKdKIKe5rIHqgVLpA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@terra-dev/web-connector-interface": "^0.8.1",
|
"@terra-money/terra.js": "^1.8.0 || ^2.0.0",
|
||||||
"bowser": "^2.11.0",
|
"bowser": "^2.11.0",
|
||||||
"rxjs": "^7.4.0"
|
"rxjs": "^7.3.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@terra-money/terra.js": "^2.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@terra-dev/web-connector-interface": {
|
|
||||||
"version": "0.8.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@terra-dev/web-connector-interface/-/web-connector-interface-0.8.1.tgz",
|
|
||||||
"integrity": "sha512-ryA3xtTFJ7OkAF6pTlrsuqxtSUp0DxHhyxvzwRPbT3h8VqlkFStknvYjRwNRspN2LOpi4/F1TNFzcUBNHPCo2g==",
|
|
||||||
"dependencies": {
|
|
||||||
"rxjs": "^7.4.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@terra-money/terra.js": "^2.0.0"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@terra-money/terra.js": {
|
"node_modules/@terra-money/terra.js": {
|
||||||
|
@ -4536,27 +4520,26 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@terra-money/wallet-provider": {
|
"node_modules/@terra-money/wallet-provider": {
|
||||||
"version": "2.5.3",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@terra-money/wallet-provider/-/wallet-provider-2.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/@terra-money/wallet-provider/-/wallet-provider-2.2.0.tgz",
|
||||||
"integrity": "sha512-v/5Z35gCo4nZyZCu3nYDFvhwuvlyDeNSSYmN9KUc9ewoIO9K/2fi3vxcOLcvqq5PYowwwod21vgaQ9QHFV+8eA==",
|
"integrity": "sha512-K8NLpJ/yak8Pq6jQpjVr7yWDIbxjTp42OXaAS+xlTufqQwWbCR7coAGbm2FpYX43j4uymuSAICZvsOS1qrFeYA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@terra-dev/browser-check": "^2.5.3",
|
"@terra-dev/browser-check": "^2.2.0",
|
||||||
"@terra-dev/chrome-extension": "^2.5.3",
|
"@terra-dev/chrome-extension": "^2.2.0",
|
||||||
"@terra-dev/readonly-wallet": "^2.5.3",
|
"@terra-dev/readonly-wallet": "^2.2.0",
|
||||||
"@terra-dev/readonly-wallet-modal": "^2.5.3",
|
"@terra-dev/readonly-wallet-modal": "^2.2.0",
|
||||||
"@terra-dev/use-wallet": "^2.5.3",
|
"@terra-dev/use-wallet": "^2.2.0",
|
||||||
"@terra-dev/wallet-types": "^2.5.3",
|
"@terra-dev/wallet-types": "^2.2.0",
|
||||||
"@terra-dev/walletconnect": "^2.5.3",
|
"@terra-dev/walletconnect": "^2.2.0",
|
||||||
"@terra-dev/web-connector-controller": "^0.8.1",
|
"@terra-dev/web-extension": "^0.6.0",
|
||||||
"@terra-dev/web-connector-interface": "^0.8.1",
|
"@terra-money/terra.js": "^2.0.0",
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"rxjs": "^7.4.0"
|
"rxjs": "^7.3.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@terra-money/terra.js": "^2.0.0",
|
|
||||||
"react": "^17.0.0"
|
"react": "^17.0.0"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
|
@ -29130,22 +29113,14 @@
|
||||||
"styled-components": "^5.0.0"
|
"styled-components": "^5.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@terra-dev/web-connector-controller": {
|
"@terra-dev/web-extension": {
|
||||||
"version": "0.8.1",
|
"version": "0.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/@terra-dev/web-connector-controller/-/web-connector-controller-0.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/@terra-dev/web-extension/-/web-extension-0.6.0.tgz",
|
||||||
"integrity": "sha512-TIwFtta7vN2GdDUy8SbIIsfTd9XWiU+U6yjizd82yUAhlOJNAGHshG0r1j0irkA5MycYG1duAlr7foeKRu4PGA==",
|
"integrity": "sha512-IyIWHLfweZCb5nHuMyzavnMYposnZMvpsA/89zZPIgIooxhxE//uZD+Ty+ptt4nvkbOgEFKdKIKe5rIHqgVLpA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@terra-dev/web-connector-interface": "^0.8.1",
|
"@terra-money/terra.js": "^1.8.0 || ^2.0.0",
|
||||||
"bowser": "^2.11.0",
|
"bowser": "^2.11.0",
|
||||||
"rxjs": "^7.4.0"
|
"rxjs": "^7.3.0"
|
||||||
}
|
|
||||||
},
|
|
||||||
"@terra-dev/web-connector-interface": {
|
|
||||||
"version": "0.8.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@terra-dev/web-connector-interface/-/web-connector-interface-0.8.1.tgz",
|
|
||||||
"integrity": "sha512-ryA3xtTFJ7OkAF6pTlrsuqxtSUp0DxHhyxvzwRPbT3h8VqlkFStknvYjRwNRspN2LOpi4/F1TNFzcUBNHPCo2g==",
|
|
||||||
"requires": {
|
|
||||||
"rxjs": "^7.4.0"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@terra-money/terra.js": {
|
"@terra-money/terra.js": {
|
||||||
|
@ -29189,21 +29164,21 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@terra-money/wallet-provider": {
|
"@terra-money/wallet-provider": {
|
||||||
"version": "2.5.3",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@terra-money/wallet-provider/-/wallet-provider-2.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/@terra-money/wallet-provider/-/wallet-provider-2.2.0.tgz",
|
||||||
"integrity": "sha512-v/5Z35gCo4nZyZCu3nYDFvhwuvlyDeNSSYmN9KUc9ewoIO9K/2fi3vxcOLcvqq5PYowwwod21vgaQ9QHFV+8eA==",
|
"integrity": "sha512-K8NLpJ/yak8Pq6jQpjVr7yWDIbxjTp42OXaAS+xlTufqQwWbCR7coAGbm2FpYX43j4uymuSAICZvsOS1qrFeYA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@terra-dev/browser-check": "^2.5.3",
|
"@terra-dev/browser-check": "^2.2.0",
|
||||||
"@terra-dev/chrome-extension": "^2.5.3",
|
"@terra-dev/chrome-extension": "^2.2.0",
|
||||||
"@terra-dev/readonly-wallet": "^2.5.3",
|
"@terra-dev/readonly-wallet": "^2.2.0",
|
||||||
"@terra-dev/readonly-wallet-modal": "^2.5.3",
|
"@terra-dev/readonly-wallet-modal": "^2.2.0",
|
||||||
"@terra-dev/use-wallet": "^2.5.3",
|
"@terra-dev/use-wallet": "^2.2.0",
|
||||||
"@terra-dev/wallet-types": "^2.5.3",
|
"@terra-dev/wallet-types": "^2.2.0",
|
||||||
"@terra-dev/walletconnect": "^2.5.3",
|
"@terra-dev/walletconnect": "^2.2.0",
|
||||||
"@terra-dev/web-connector-controller": "^0.8.1",
|
"@terra-dev/web-extension": "^0.6.0",
|
||||||
"@terra-dev/web-connector-interface": "^0.8.1",
|
"@terra-money/terra.js": "^2.0.0",
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"rxjs": "^7.4.0"
|
"rxjs": "^7.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@tootallnate/once": {
|
"@tootallnate/once": {
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
"@material-ui/icons": "^4.11.2",
|
"@material-ui/icons": "^4.11.2",
|
||||||
"@material-ui/lab": "^4.0.0-alpha.60",
|
"@material-ui/lab": "^4.0.0-alpha.60",
|
||||||
"@metamask/detect-provider": "^1.2.0",
|
"@metamask/detect-provider": "^1.2.0",
|
||||||
|
"@terra-money/wallet-provider": "^2.2.0",
|
||||||
"@types/node": "^16.11.19",
|
"@types/node": "^16.11.19",
|
||||||
"@types/react": "^17.0.38",
|
"@types/react": "^17.0.38",
|
||||||
"@types/react-dom": "^17.0.11",
|
"@types/react-dom": "^17.0.11",
|
||||||
|
|
|
@ -16,17 +16,21 @@ const useStyles = makeStyles((theme) => ({
|
||||||
export default function TransactionProgress({
|
export default function TransactionProgress({
|
||||||
chainId,
|
chainId,
|
||||||
txBlockNumber,
|
txBlockNumber,
|
||||||
step,
|
isSourceSwapComplete,
|
||||||
|
hasSignedVAA,
|
||||||
|
isTargetSwapComplete,
|
||||||
}: {
|
}: {
|
||||||
chainId: ChainId;
|
chainId: ChainId;
|
||||||
txBlockNumber: number | undefined;
|
txBlockNumber: number | undefined;
|
||||||
step: number;
|
isSourceSwapComplete: boolean;
|
||||||
|
hasSignedVAA: boolean;
|
||||||
|
isTargetSwapComplete: boolean;
|
||||||
}) {
|
}) {
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const { provider } = useEthereumProvider();
|
const { provider } = useEthereumProvider();
|
||||||
const [currentBlock, setCurrentBlock] = useState(0);
|
const [currentBlock, setCurrentBlock] = useState(0);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (step !== 1 || !txBlockNumber) return;
|
if (hasSignedVAA || !txBlockNumber) return;
|
||||||
if (isEVMChain(chainId) && provider) {
|
if (isEVMChain(chainId) && provider) {
|
||||||
let cancelled = false;
|
let cancelled = false;
|
||||||
(async () => {
|
(async () => {
|
||||||
|
@ -46,7 +50,7 @@ export default function TransactionProgress({
|
||||||
cancelled = true;
|
cancelled = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}, [step, chainId, provider, txBlockNumber]);
|
}, [hasSignedVAA, chainId, provider, txBlockNumber]);
|
||||||
const blockDiff =
|
const blockDiff =
|
||||||
txBlockNumber !== undefined && txBlockNumber && currentBlock
|
txBlockNumber !== undefined && txBlockNumber && currentBlock
|
||||||
? currentBlock - txBlockNumber
|
? currentBlock - txBlockNumber
|
||||||
|
@ -55,24 +59,20 @@ export default function TransactionProgress({
|
||||||
let value;
|
let value;
|
||||||
let valueBuffer;
|
let valueBuffer;
|
||||||
let message;
|
let message;
|
||||||
switch (step) {
|
if (!hasSignedVAA) {
|
||||||
case 1:
|
value = (blockDiff / expectedBlocks) * 50;
|
||||||
value = (blockDiff / expectedBlocks) * 50;
|
valueBuffer = 50;
|
||||||
valueBuffer = 50;
|
message = `Waiting for ${blockDiff} / ${expectedBlocks} confirmations on ${
|
||||||
message = `Waiting for ${blockDiff} / ${expectedBlocks} confirmations on ${
|
chainId === CHAIN_ID_POLYGON ? "Polygon" : "Ethereum"
|
||||||
chainId === CHAIN_ID_POLYGON ? "Polygon" : "Ethereum"
|
}...`;
|
||||||
}...`;
|
} else if (!isTargetSwapComplete) {
|
||||||
break;
|
value = 50;
|
||||||
case 2:
|
valueBuffer = 100;
|
||||||
value = 50;
|
message = "Waiting for relayer to complete swap...";
|
||||||
valueBuffer = 100;
|
} else {
|
||||||
message = "Waiting for relayer to complete swap...";
|
value = 100;
|
||||||
break;
|
valueBuffer = 100;
|
||||||
case 3:
|
message = "Success!";
|
||||||
value = 100;
|
|
||||||
valueBuffer = 100;
|
|
||||||
message = "";
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div className={classes.root}>
|
<div className={classes.root}>
|
||||||
|
|
|
@ -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;
|
|
@ -0,0 +1,97 @@
|
||||||
|
import {
|
||||||
|
NetworkInfo,
|
||||||
|
Wallet,
|
||||||
|
WalletProvider,
|
||||||
|
useWallet,
|
||||||
|
} from "@terra-money/wallet-provider";
|
||||||
|
import React, {
|
||||||
|
ReactChildren,
|
||||||
|
useCallback,
|
||||||
|
useContext,
|
||||||
|
useMemo,
|
||||||
|
useState,
|
||||||
|
} from "react";
|
||||||
|
|
||||||
|
const testnet: NetworkInfo = {
|
||||||
|
name: "testnet",
|
||||||
|
chainID: "bombay-12",
|
||||||
|
lcd: "https://bombay-lcd.terra.dev",
|
||||||
|
};
|
||||||
|
|
||||||
|
const walletConnectChainIds: Record<number, NetworkInfo> = {
|
||||||
|
0: testnet,
|
||||||
|
};
|
||||||
|
|
||||||
|
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 [, 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={testnet}
|
||||||
|
walletConnectChainIds={walletConnectChainIds}
|
||||||
|
>
|
||||||
|
<TerraWalletWrapper>{children}</TerraWalletWrapper>
|
||||||
|
</WalletProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useTerraWallet = () => {
|
||||||
|
return useContext(TerraWalletContext);
|
||||||
|
};
|
|
@ -1,5 +1,11 @@
|
||||||
import { ChainId, CHAIN_ID_SOLANA, isEVMChain } from "@certusone/wormhole-sdk";
|
import {
|
||||||
|
ChainId,
|
||||||
|
CHAIN_ID_SOLANA,
|
||||||
|
CHAIN_ID_TERRA,
|
||||||
|
isEVMChain,
|
||||||
|
} from "@certusone/wormhole-sdk";
|
||||||
import { hexlify, hexStripZeros } from "@ethersproject/bytes";
|
import { hexlify, hexStripZeros } from "@ethersproject/bytes";
|
||||||
|
import { useConnectedWallet } from "@terra-money/wallet-provider";
|
||||||
import { useCallback, useMemo } from "react";
|
import { useCallback, useMemo } from "react";
|
||||||
import { useEthereumProvider } from "../contexts/EthereumProviderContext";
|
import { useEthereumProvider } from "../contexts/EthereumProviderContext";
|
||||||
// import { useSolanaWallet } from "../contexts/SolanaWalletContext";
|
// import { useSolanaWallet } from "../contexts/SolanaWalletContext";
|
||||||
|
@ -31,6 +37,8 @@ function useIsWalletReady(
|
||||||
const autoSwitch = enableNetworkAutoswitch;
|
const autoSwitch = enableNetworkAutoswitch;
|
||||||
// const solanaWallet = useSolanaWallet();
|
// const solanaWallet = useSolanaWallet();
|
||||||
// const solPK = solanaWallet?.publicKey;
|
// const solPK = solanaWallet?.publicKey;
|
||||||
|
const terraWallet = useConnectedWallet();
|
||||||
|
const hasTerraWallet = !!terraWallet;
|
||||||
const {
|
const {
|
||||||
provider,
|
provider,
|
||||||
signerAddress,
|
signerAddress,
|
||||||
|
@ -54,15 +62,28 @@ function useIsWalletReady(
|
||||||
}, [provider, correctEvmNetwork, chainId]);
|
}, [provider, correctEvmNetwork, chainId]);
|
||||||
|
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
//if (chainId === CHAIN_ID_SOLANA && solPK) {
|
if (
|
||||||
// return createWalletStatus(
|
chainId === CHAIN_ID_TERRA &&
|
||||||
// true,
|
hasTerraWallet &&
|
||||||
// undefined,
|
terraWallet?.walletAddress
|
||||||
// forceNetworkSwitch,
|
) {
|
||||||
// solPK.toString()
|
// TODO: terraWallet does not update on wallet changes
|
||||||
// );
|
return createWalletStatus(
|
||||||
//}
|
true,
|
||||||
|
undefined,
|
||||||
|
forceNetworkSwitch,
|
||||||
|
terraWallet.walletAddress
|
||||||
|
);
|
||||||
|
}
|
||||||
if (isEVMChain(chainId) && hasEthInfo && signerAddress) {
|
if (isEVMChain(chainId) && hasEthInfo && signerAddress) {
|
||||||
|
//if (chainId === CHAIN_ID_SOLANA && solPK) {
|
||||||
|
// return createWalletStatus(
|
||||||
|
// true,
|
||||||
|
// undefined,
|
||||||
|
// forceNetworkSwitch,
|
||||||
|
// solPK.toString()
|
||||||
|
// );
|
||||||
|
//}
|
||||||
if (hasCorrectEvmNetwork) {
|
if (hasCorrectEvmNetwork) {
|
||||||
return createWalletStatus(
|
return createWalletStatus(
|
||||||
true,
|
true,
|
||||||
|
@ -93,12 +114,14 @@ function useIsWalletReady(
|
||||||
chainId,
|
chainId,
|
||||||
autoSwitch,
|
autoSwitch,
|
||||||
forceNetworkSwitch,
|
forceNetworkSwitch,
|
||||||
|
hasTerraWallet,
|
||||||
// solPK,
|
// solPK,
|
||||||
hasEthInfo,
|
hasEthInfo,
|
||||||
correctEvmNetwork,
|
correctEvmNetwork,
|
||||||
hasCorrectEvmNetwork,
|
hasCorrectEvmNetwork,
|
||||||
provider,
|
provider,
|
||||||
signerAddress,
|
signerAddress,
|
||||||
|
terraWallet,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 25.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 288.9 274" style="enable-background:new 0 0 288.9 274;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill-rule:evenodd;clip-rule:evenodd;fill:#2849A9;}
|
||||||
|
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:#5795ED;}
|
||||||
|
</style>
|
||||||
|
<path class="st0" d="M151.1,0.3c33.7,0,64.9,12.1,88.7,32.9c31.8,24.5,22.6,113.9-9.6,90.3c-70.8-0.3-202.4-38.2-163.2-90.3
|
||||||
|
c4-5.3,9-9.6,14.5-13.7h-0.3c0.9-0.5,1.9-1,2.8-1.6c0.9-0.5,1.9-1.1,2.8-1.6h0c2.8-1.6,5.6-3.1,8.7-4.3
|
||||||
|
C112.5,4.6,131.3,0.3,151.1,0.3z M174.9,272.8c-14.2,0.9-42.6-21.4-50.7-50.9c-15.1-55.9,107.2-84.4,118.7-85.4
|
||||||
|
c31.2,0.9,38.9,38.2,16.1,76.7C229.3,262.6,175.5,272.8,174.9,272.8z"/>
|
||||||
|
<path class="st1" d="M14.8,77.9c9.9,2.8,70.5-16.5,88.4-43.8c0.3-0.3,14.2-21.7-12.7-22c-3.1,0-11.7,0.3-20.1,5.3
|
||||||
|
c-4,2.5-7.7,5-11.4,7.8c-5.8,4.3-11.3,9.5-16.5,14.4h0l-0.2,0.2c-5.3,5-10.2,10.9-14.5,16.8c-4.3,5.9-8.3,12.4-11.7,18.9
|
||||||
|
c-0.2,0.5-0.4,0.9-0.6,1.2C15.2,77,15,77.4,14.8,77.9z M86.5,272.8c1.9-2.8,3.1-36.6,1.9-45.3c-1.2-8.7-4-26.4-20.7-55.6
|
||||||
|
c-2.8-4.7-16.1-26.4-26-39.7c-5.6-7.8-11.7-15-17.8-22.3h0c-5.1-6-10.2-12.1-15-18.4c-0.3,0.8-0.5,1.5-0.8,2.2s-0.5,1.4-0.8,2.2
|
||||||
|
c-2.5,7.1-4.3,14.6-5.6,22.4S0,133.8,0,141.8c0,8.1,0.6,15.8,1.9,23.6s3.4,15.2,5.6,22.4c2.2,7.1,5.3,14.3,8.7,20.8
|
||||||
|
s7.4,13,11.7,18.9c4.3,5.9,9.3,11.5,14.5,16.8c4.9,5.3,10.8,10.2,16.7,14.6h0h0c4.6,3.1,9.3,6.2,13.9,9c8.5,5,11.7,5,13.4,5
|
||||||
|
C86.4,272.8,86.4,272.8,86.5,272.8z M288.9,141.8c0,18.9-3.7,36.9-10.2,53.4c-15.7,17-115.3-20.7-130.8-26.6c-1.2-0.5-2-0.7-2-0.8
|
||||||
|
c-15.8-6.8-63.3-27.9-67.7-60.8c-6.2-47.5,89.6-80.7,131.9-82c4.9,0,20.4,0.3,29.4,7.5C269.8,59.2,288.9,98.4,288.9,141.8z
|
||||||
|
M188.8,260.1c-3.7,12.1,10.2,16.5,22.6,10.6c24.7-13,45.1-33.2,59-57.1c0.9-1.2,0-2.5-1.5-2.2C255.6,212.6,195.6,236.5,188.8,260.1
|
||||||
|
z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.0 KiB |
|
@ -5,6 +5,7 @@ import ReactDOM from "react-dom";
|
||||||
import App from "./App";
|
import App from "./App";
|
||||||
import ErrorBoundary from "./components/ErrorBoundary";
|
import ErrorBoundary from "./components/ErrorBoundary";
|
||||||
import { EthereumProviderProvider } from "./contexts/EthereumProviderContext";
|
import { EthereumProviderProvider } from "./contexts/EthereumProviderContext";
|
||||||
|
import { TerraWalletProvider } from "./contexts/TerraWalletContext";
|
||||||
import { theme } from "./muiTheme";
|
import { theme } from "./muiTheme";
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
|
@ -12,9 +13,11 @@ ReactDOM.render(
|
||||||
<ThemeProvider theme={theme}>
|
<ThemeProvider theme={theme}>
|
||||||
<CssBaseline>
|
<CssBaseline>
|
||||||
<EthereumProviderProvider>
|
<EthereumProviderProvider>
|
||||||
<SnackbarProvider maxSnack={3}>
|
<TerraWalletProvider>
|
||||||
<App />
|
<SnackbarProvider maxSnack={3}>
|
||||||
</SnackbarProvider>
|
<App />
|
||||||
|
</SnackbarProvider>
|
||||||
|
</TerraWalletProvider>
|
||||||
</EthereumProviderProvider>
|
</EthereumProviderProvider>
|
||||||
</CssBaseline>
|
</CssBaseline>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
|
|
|
@ -7,9 +7,6 @@ import {
|
||||||
WETH_TOKEN_INFO,
|
WETH_TOKEN_INFO,
|
||||||
WMATIC_TOKEN_INFO,
|
WMATIC_TOKEN_INFO,
|
||||||
UST_TOKEN_INFO,
|
UST_TOKEN_INFO,
|
||||||
WORMHOLE_CHAIN_ID_ETHEREUM,
|
|
||||||
WORMHOLE_CHAIN_ID_POLYGON,
|
|
||||||
WORMHOLE_CHAIN_ID_TERRA,
|
|
||||||
} from "../utils/consts";
|
} from "../utils/consts";
|
||||||
import { addFixedAmounts, subtractFixedAmounts } from "../utils/math";
|
import { addFixedAmounts, subtractFixedAmounts } from "../utils/math";
|
||||||
import { UstLocation } from "./generic";
|
import { UstLocation } from "./generic";
|
||||||
|
@ -19,7 +16,12 @@ import {
|
||||||
makeExactInParameters,
|
makeExactInParameters,
|
||||||
makeExactOutParameters,
|
makeExactOutParameters,
|
||||||
} from "./uniswap-core";
|
} from "./uniswap-core";
|
||||||
import { ChainId } from "@certusone/wormhole-sdk";
|
import {
|
||||||
|
ChainId,
|
||||||
|
CHAIN_ID_ETH,
|
||||||
|
CHAIN_ID_POLYGON,
|
||||||
|
CHAIN_ID_TERRA,
|
||||||
|
} from "@certusone/wormhole-sdk";
|
||||||
|
|
||||||
export { PROTOCOL as PROTOCOL_UNISWAP_V2 } from "./uniswap-v2";
|
export { PROTOCOL as PROTOCOL_UNISWAP_V2 } from "./uniswap-v2";
|
||||||
export { PROTOCOL as PROTOCOL_UNISWAP_V3 } from "./uniswap-v3";
|
export { PROTOCOL as PROTOCOL_UNISWAP_V3 } from "./uniswap-v3";
|
||||||
|
@ -57,13 +59,13 @@ export function makeEvmProviderFromAddress(tokenAddress: string) {
|
||||||
export function getChainIdFromAddress(tokenAddress: string) {
|
export function getChainIdFromAddress(tokenAddress: string) {
|
||||||
switch (tokenAddress) {
|
switch (tokenAddress) {
|
||||||
case WETH_TOKEN_INFO.address: {
|
case WETH_TOKEN_INFO.address: {
|
||||||
return WORMHOLE_CHAIN_ID_ETHEREUM;
|
return CHAIN_ID_ETH;
|
||||||
}
|
}
|
||||||
case WMATIC_TOKEN_INFO.address: {
|
case WMATIC_TOKEN_INFO.address: {
|
||||||
return WORMHOLE_CHAIN_ID_POLYGON;
|
return CHAIN_ID_POLYGON;
|
||||||
}
|
}
|
||||||
case UST_TOKEN_INFO.address: {
|
case UST_TOKEN_INFO.address: {
|
||||||
return WORMHOLE_CHAIN_ID_TERRA;
|
return CHAIN_ID_TERRA;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
throw Error("unrecognized evm token address");
|
throw Error("unrecognized evm token address");
|
||||||
|
@ -110,16 +112,16 @@ export interface RelayerFee {
|
||||||
export interface ExactInCrossParameters {
|
export interface ExactInCrossParameters {
|
||||||
amountIn: string;
|
amountIn: string;
|
||||||
minAmountOut: string;
|
minAmountOut: string;
|
||||||
src: ExactInParameters;
|
src: ExactInParameters | undefined;
|
||||||
dst: ExactInParameters;
|
dst: ExactInParameters | undefined;
|
||||||
relayerFee: RelayerFee;
|
relayerFee: RelayerFee;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ExactOutCrossParameters {
|
export interface ExactOutCrossParameters {
|
||||||
amountOut: string;
|
amountOut: string;
|
||||||
maxAmountIn: string;
|
maxAmountIn: string;
|
||||||
src: ExactOutParameters;
|
src: ExactOutParameters | undefined;
|
||||||
dst: ExactOutParameters;
|
dst: ExactOutParameters | undefined;
|
||||||
relayerFee: RelayerFee;
|
relayerFee: RelayerFee;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,22 +134,16 @@ export class UniswapToUniswapQuoter {
|
||||||
srcRouter: UstRouter | EthRouter | MaticRouter;
|
srcRouter: UstRouter | EthRouter | MaticRouter;
|
||||||
dstRouter: UstRouter | EthRouter | MaticRouter;
|
dstRouter: UstRouter | EthRouter | MaticRouter;
|
||||||
|
|
||||||
constructor() {}
|
async initialize(tokenInAddress: string, tokenOutAddress: string) {
|
||||||
|
|
||||||
async initialize(
|
|
||||||
tokenInAddress: string,
|
|
||||||
tokenOutAddress: string
|
|
||||||
): Promise<void> {
|
|
||||||
if (tokenInAddress !== this.tokenInAddress) {
|
if (tokenInAddress !== this.tokenInAddress) {
|
||||||
this.tokenInAddress = tokenInAddress;
|
this.tokenInAddress = tokenInAddress;
|
||||||
this.srcRouter = await makeRouter(tokenInAddress, UstLocation.Out);
|
this.srcRouter = await makeRouter(tokenInAddress, UstLocation.Out);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tokenOutAddress != this.tokenOutAddress) {
|
if (tokenOutAddress !== this.tokenOutAddress) {
|
||||||
this.tokenOutAddress = tokenOutAddress;
|
this.tokenOutAddress = tokenOutAddress;
|
||||||
this.dstRouter = await makeRouter(tokenOutAddress, UstLocation.In);
|
this.dstRouter = await makeRouter(tokenOutAddress, UstLocation.In);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async computeAndVerifySrcPoolAddress(): Promise<string> {
|
async computeAndVerifySrcPoolAddress(): Promise<string> {
|
||||||
|
@ -158,7 +154,7 @@ export class UniswapToUniswapQuoter {
|
||||||
return this.dstRouter.computeAndVerifyPoolAddress();
|
return this.dstRouter.computeAndVerifyPoolAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
computeSwapSlippage(slippage): string {
|
computeSwapSlippage(slippage: string): string {
|
||||||
if (this.isSrcUst() || this.isDstUst()) {
|
if (this.isSrcUst() || this.isDstUst()) {
|
||||||
return slippage;
|
return slippage;
|
||||||
}
|
}
|
||||||
|
@ -184,7 +180,7 @@ export class UniswapToUniswapQuoter {
|
||||||
makeSrcExactInParameters(
|
makeSrcExactInParameters(
|
||||||
amountIn: string,
|
amountIn: string,
|
||||||
minAmountOut: string
|
minAmountOut: string
|
||||||
): ExactInParameters {
|
): ExactInParameters | undefined {
|
||||||
if (this.isSrcUst()) {
|
if (this.isSrcUst()) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -195,7 +191,7 @@ export class UniswapToUniswapQuoter {
|
||||||
makeDstExactInParameters(
|
makeDstExactInParameters(
|
||||||
amountIn: string,
|
amountIn: string,
|
||||||
minAmountOut: string
|
minAmountOut: string
|
||||||
): ExactInParameters {
|
): ExactInParameters | undefined {
|
||||||
if (this.isDstUst()) {
|
if (this.isDstUst()) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -251,9 +247,9 @@ export class UniswapToUniswapQuoter {
|
||||||
makeSrcExactOutParameters(
|
makeSrcExactOutParameters(
|
||||||
amountOut: string,
|
amountOut: string,
|
||||||
maxAmountIn: string
|
maxAmountIn: string
|
||||||
): ExactOutParameters {
|
): ExactOutParameters | undefined {
|
||||||
if (this.isSrcUst()) {
|
if (this.isSrcUst()) {
|
||||||
return null;
|
return undefined;
|
||||||
}
|
}
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return makeExactOutParameters(this.srcRouter, amountOut, maxAmountIn);
|
return makeExactOutParameters(this.srcRouter, amountOut, maxAmountIn);
|
||||||
|
@ -262,9 +258,9 @@ export class UniswapToUniswapQuoter {
|
||||||
makeDstExactOutParameters(
|
makeDstExactOutParameters(
|
||||||
amountOut: string,
|
amountOut: string,
|
||||||
maxAmountIn: string
|
maxAmountIn: string
|
||||||
): ExactOutParameters {
|
): ExactOutParameters | undefined {
|
||||||
if (this.isDstUst()) {
|
if (this.isDstUst()) {
|
||||||
return null;
|
return undefined;
|
||||||
}
|
}
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return makeExactOutParameters(this.dstRouter, amountOut, maxAmountIn);
|
return makeExactOutParameters(this.dstRouter, amountOut, maxAmountIn);
|
||||||
|
@ -337,7 +333,7 @@ export class UniswapToUniswapQuoter {
|
||||||
return this.tokenOutAddress === TERRA_UST;
|
return this.tokenOutAddress === TERRA_UST;
|
||||||
}
|
}
|
||||||
|
|
||||||
getSrcEvmProvider(): ethers.providers.Provider {
|
getSrcEvmProvider(): ethers.providers.Provider | undefined {
|
||||||
if (this.isSrcUst()) {
|
if (this.isSrcUst()) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -345,7 +341,7 @@ export class UniswapToUniswapQuoter {
|
||||||
return this.srcRouter.getProvider();
|
return this.srcRouter.getProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
getDstEvmProvider(): ethers.providers.Provider {
|
getDstEvmProvider(): ethers.providers.Provider | undefined {
|
||||||
if (this.isDstUst()) {
|
if (this.isDstUst()) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { ethers } from "ethers";
|
||||||
import { GenericToken } from "./generic";
|
import { GenericToken } from "./generic";
|
||||||
|
|
||||||
// erc20 spec
|
// erc20 spec
|
||||||
import { abi as Erc20Abi } from "../../abi/erc20.json";
|
import { abi as Erc20Abi } from "../abi/erc20.json";
|
||||||
import {
|
import {
|
||||||
TransactionReceipt,
|
TransactionReceipt,
|
||||||
TransactionRequest,
|
TransactionRequest,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
//@ts-nocheck
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
import { CurrencyAmount, Token } from "@uniswap/sdk-core";
|
import { CurrencyAmount, Token } from "@uniswap/sdk-core";
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
|
//@ts-nocheck
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
import { TransactionReceipt } from "@ethersproject/abstract-provider";
|
import { TransactionReceipt } from "@ethersproject/abstract-provider";
|
||||||
import {
|
import {
|
||||||
ChainId,
|
ChainId,
|
||||||
|
CHAIN_ID_ETH,
|
||||||
|
CHAIN_ID_POLYGON,
|
||||||
|
CHAIN_ID_TERRA,
|
||||||
getEmitterAddressEth,
|
getEmitterAddressEth,
|
||||||
hexToUint8Array,
|
hexToUint8Array,
|
||||||
nativeToHexString,
|
nativeToHexString,
|
||||||
parseSequenceFromLogEth,
|
parseSequenceFromLogEth,
|
||||||
//getSignedVAAWithRetry,
|
getSignedVAAWithRetry,
|
||||||
} from "@certusone/wormhole-sdk";
|
} from "@certusone/wormhole-sdk";
|
||||||
import getSignedVAAWithRetry from "@certusone/wormhole-sdk/lib/cjs/rpc/getSignedVAAWithRetry";
|
|
||||||
import { grpc } from "@improbable-eng/grpc-web";
|
import { grpc } from "@improbable-eng/grpc-web";
|
||||||
import { UniEvmToken } from "../route/uniswap-core";
|
import { UniEvmToken } from "../route/uniswap-core";
|
||||||
import {
|
import {
|
||||||
|
@ -26,9 +29,6 @@ import {
|
||||||
CORE_BRIDGE_ADDRESS_ETHEREUM,
|
CORE_BRIDGE_ADDRESS_ETHEREUM,
|
||||||
CORE_BRIDGE_ADDRESS_POLYGON,
|
CORE_BRIDGE_ADDRESS_POLYGON,
|
||||||
CORE_BRIDGE_ADDRESS_TERRA,
|
CORE_BRIDGE_ADDRESS_TERRA,
|
||||||
WORMHOLE_CHAIN_ID_ETHEREUM,
|
|
||||||
WORMHOLE_CHAIN_ID_POLYGON,
|
|
||||||
WORMHOLE_CHAIN_ID_TERRA,
|
|
||||||
WORMHOLE_RPC_HOSTS,
|
WORMHOLE_RPC_HOSTS,
|
||||||
//ETH_NETWORK_CHAIN_ID,
|
//ETH_NETWORK_CHAIN_ID,
|
||||||
//POLYGON_NETWORK_CHAIN_ID,
|
//POLYGON_NETWORK_CHAIN_ID,
|
||||||
|
@ -44,10 +44,10 @@ import {
|
||||||
swapExactOutFromVaaNative,
|
swapExactOutFromVaaNative,
|
||||||
swapExactOutFromVaaToken,
|
swapExactOutFromVaaToken,
|
||||||
} from "./util";
|
} from "./util";
|
||||||
import { abi as SWAP_CONTRACT_V2_ABI } from "../../abi/contracts/CrossChainSwapV2.json";
|
import { abi as SWAP_CONTRACT_V2_ABI } from "../abi/contracts/CrossChainSwapV2.json";
|
||||||
import { abi as SWAP_CONTRACT_V3_ABI } from "../../abi/contracts/CrossChainSwapV3.json";
|
import { abi as SWAP_CONTRACT_V3_ABI } from "../abi/contracts/CrossChainSwapV3.json";
|
||||||
import { SWAP_CONTRACT_ADDRESS as CROSSCHAINSWAP_CONTRACT_ADDRESS_ETHEREUM } from "../../scripts/contract-addresses/goerli";
|
import { SWAP_CONTRACT_ADDRESS as CROSSCHAINSWAP_CONTRACT_ADDRESS_ETHEREUM } from "../addresses/goerli";
|
||||||
import { SWAP_CONTRACT_ADDRESS as CROSSCHAINSWAP_CONTRACT_ADDRESS_POLYGON } from "../../scripts/contract-addresses/mumbai";
|
import { SWAP_CONTRACT_ADDRESS as CROSSCHAINSWAP_CONTRACT_ADDRESS_POLYGON } from "../addresses/mumbai";
|
||||||
|
|
||||||
// placeholders
|
// placeholders
|
||||||
const CROSSCHAINSWAP_CONTRACT_ADDRESS_TERRA = "";
|
const CROSSCHAINSWAP_CONTRACT_ADDRESS_TERRA = "";
|
||||||
|
@ -72,7 +72,7 @@ const EXECUTION_PARAMETERS_ETHEREUM: ExecutionParameters = {
|
||||||
address: CROSSCHAINSWAP_CONTRACT_ADDRESS_ETHEREUM,
|
address: CROSSCHAINSWAP_CONTRACT_ADDRESS_ETHEREUM,
|
||||||
},
|
},
|
||||||
wormhole: {
|
wormhole: {
|
||||||
chainId: WORMHOLE_CHAIN_ID_ETHEREUM,
|
chainId: CHAIN_ID_ETH,
|
||||||
coreBridgeAddress: CORE_BRIDGE_ADDRESS_ETHEREUM,
|
coreBridgeAddress: CORE_BRIDGE_ADDRESS_ETHEREUM,
|
||||||
tokenBridgeAddress: TOKEN_BRIDGE_ADDRESS_ETHEREUM,
|
tokenBridgeAddress: TOKEN_BRIDGE_ADDRESS_ETHEREUM,
|
||||||
},
|
},
|
||||||
|
@ -83,7 +83,7 @@ const EXECUTION_PARAMETERS_POLYGON: ExecutionParameters = {
|
||||||
address: CROSSCHAINSWAP_CONTRACT_ADDRESS_POLYGON,
|
address: CROSSCHAINSWAP_CONTRACT_ADDRESS_POLYGON,
|
||||||
},
|
},
|
||||||
wormhole: {
|
wormhole: {
|
||||||
chainId: WORMHOLE_CHAIN_ID_POLYGON,
|
chainId: CHAIN_ID_POLYGON,
|
||||||
coreBridgeAddress: CORE_BRIDGE_ADDRESS_POLYGON,
|
coreBridgeAddress: CORE_BRIDGE_ADDRESS_POLYGON,
|
||||||
tokenBridgeAddress: TOKEN_BRIDGE_ADDRESS_POLYGON,
|
tokenBridgeAddress: TOKEN_BRIDGE_ADDRESS_POLYGON,
|
||||||
},
|
},
|
||||||
|
@ -94,7 +94,7 @@ const EXECUTION_PARAMETERS_TERRA: ExecutionParameters = {
|
||||||
address: CROSSCHAINSWAP_CONTRACT_ADDRESS_TERRA,
|
address: CROSSCHAINSWAP_CONTRACT_ADDRESS_TERRA,
|
||||||
},
|
},
|
||||||
wormhole: {
|
wormhole: {
|
||||||
chainId: WORMHOLE_CHAIN_ID_TERRA,
|
chainId: CHAIN_ID_TERRA,
|
||||||
coreBridgeAddress: CORE_BRIDGE_ADDRESS_TERRA,
|
coreBridgeAddress: CORE_BRIDGE_ADDRESS_TERRA,
|
||||||
tokenBridgeAddress: TOKEN_BRIDGE_ADDRESS_TERRA,
|
tokenBridgeAddress: TOKEN_BRIDGE_ADDRESS_TERRA,
|
||||||
},
|
},
|
||||||
|
@ -102,13 +102,13 @@ const EXECUTION_PARAMETERS_TERRA: ExecutionParameters = {
|
||||||
|
|
||||||
function makeExecutionParameters(chainId: ChainId): ExecutionParameters {
|
function makeExecutionParameters(chainId: ChainId): ExecutionParameters {
|
||||||
switch (chainId) {
|
switch (chainId) {
|
||||||
case WORMHOLE_CHAIN_ID_ETHEREUM: {
|
case CHAIN_ID_ETH: {
|
||||||
return EXECUTION_PARAMETERS_ETHEREUM;
|
return EXECUTION_PARAMETERS_ETHEREUM;
|
||||||
}
|
}
|
||||||
case WORMHOLE_CHAIN_ID_POLYGON: {
|
case CHAIN_ID_POLYGON: {
|
||||||
return EXECUTION_PARAMETERS_POLYGON;
|
return EXECUTION_PARAMETERS_POLYGON;
|
||||||
}
|
}
|
||||||
case WORMHOLE_CHAIN_ID_TERRA: {
|
case CHAIN_ID_TERRA: {
|
||||||
return EXECUTION_PARAMETERS_TERRA;
|
return EXECUTION_PARAMETERS_TERRA;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
|
|
@ -1,21 +1,12 @@
|
||||||
import {
|
import {
|
||||||
ChainId,
|
ChainId,
|
||||||
CHAIN_ID_ETH as WORMHOLE_CHAIN_ID_ETHEREUM,
|
CHAIN_ID_ETH,
|
||||||
CHAIN_ID_POLYGON as WORMHOLE_CHAIN_ID_POLYGON,
|
CHAIN_ID_POLYGON,
|
||||||
CHAIN_ID_TERRA as WORMHOLE_CHAIN_ID_TERRA,
|
CHAIN_ID_TERRA,
|
||||||
} from "@certusone/wormhole-sdk";
|
} from "@certusone/wormhole-sdk";
|
||||||
//import ethIcon from "../icons/eth.svg";
|
import ethIcon from "../icons/eth.svg";
|
||||||
//import polygonIcon from "../icons/polygon.svg";
|
import polygonIcon from "../icons/polygon.svg";
|
||||||
|
import terraIcon from "../icons/terra.svg";
|
||||||
const ethIcon = undefined;
|
|
||||||
const polygonIcon = undefined;
|
|
||||||
const ustIcon = undefined;
|
|
||||||
|
|
||||||
export {
|
|
||||||
WORMHOLE_CHAIN_ID_ETHEREUM,
|
|
||||||
WORMHOLE_CHAIN_ID_POLYGON,
|
|
||||||
WORMHOLE_CHAIN_ID_TERRA,
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface TokenInfo {
|
export interface TokenInfo {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -24,13 +15,13 @@ export interface TokenInfo {
|
||||||
logo: string;
|
logo: string;
|
||||||
isNative: boolean;
|
isNative: boolean;
|
||||||
maxAmount: number;
|
maxAmount: number;
|
||||||
ustPairedAddress: string;
|
ustPairedAddress: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MATIC_TOKEN_INFO: TokenInfo = {
|
export const MATIC_TOKEN_INFO: TokenInfo = {
|
||||||
name: "MATIC",
|
name: "MATIC",
|
||||||
address: "0x9c3c9283d3e44854697cd22d3faa240cfb032889", // used to compute quote
|
address: "0x9c3c9283d3e44854697cd22d3faa240cfb032889", // used to compute quote
|
||||||
chainId: WORMHOLE_CHAIN_ID_POLYGON,
|
chainId: CHAIN_ID_POLYGON,
|
||||||
logo: polygonIcon,
|
logo: polygonIcon,
|
||||||
isNative: true,
|
isNative: true,
|
||||||
maxAmount: 0.1,
|
maxAmount: 0.1,
|
||||||
|
@ -40,7 +31,7 @@ export const MATIC_TOKEN_INFO: TokenInfo = {
|
||||||
export const WMATIC_TOKEN_INFO: TokenInfo = {
|
export const WMATIC_TOKEN_INFO: TokenInfo = {
|
||||||
name: "WMATIC",
|
name: "WMATIC",
|
||||||
address: "0x9c3c9283d3e44854697cd22d3faa240cfb032889",
|
address: "0x9c3c9283d3e44854697cd22d3faa240cfb032889",
|
||||||
chainId: WORMHOLE_CHAIN_ID_POLYGON,
|
chainId: CHAIN_ID_POLYGON,
|
||||||
logo: polygonIcon,
|
logo: polygonIcon,
|
||||||
isNative: false,
|
isNative: false,
|
||||||
maxAmount: 0.1,
|
maxAmount: 0.1,
|
||||||
|
@ -50,7 +41,7 @@ export const WMATIC_TOKEN_INFO: TokenInfo = {
|
||||||
export const ETH_TOKEN_INFO: TokenInfo = {
|
export const ETH_TOKEN_INFO: TokenInfo = {
|
||||||
name: "ETH",
|
name: "ETH",
|
||||||
address: "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6", // used to compute quote
|
address: "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6", // used to compute quote
|
||||||
chainId: WORMHOLE_CHAIN_ID_ETHEREUM,
|
chainId: CHAIN_ID_ETH,
|
||||||
logo: ethIcon,
|
logo: ethIcon,
|
||||||
isNative: true,
|
isNative: true,
|
||||||
maxAmount: 0.01,
|
maxAmount: 0.01,
|
||||||
|
@ -60,7 +51,7 @@ export const ETH_TOKEN_INFO: TokenInfo = {
|
||||||
export const WETH_TOKEN_INFO: TokenInfo = {
|
export const WETH_TOKEN_INFO: TokenInfo = {
|
||||||
name: "WETH",
|
name: "WETH",
|
||||||
address: "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6",
|
address: "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6",
|
||||||
chainId: WORMHOLE_CHAIN_ID_ETHEREUM,
|
chainId: CHAIN_ID_ETH,
|
||||||
logo: ethIcon,
|
logo: ethIcon,
|
||||||
isNative: false,
|
isNative: false,
|
||||||
maxAmount: 0.01,
|
maxAmount: 0.01,
|
||||||
|
@ -70,9 +61,9 @@ export const WETH_TOKEN_INFO: TokenInfo = {
|
||||||
export const UST_TOKEN_INFO: TokenInfo = {
|
export const UST_TOKEN_INFO: TokenInfo = {
|
||||||
name: "UST",
|
name: "UST",
|
||||||
address: "uusd",
|
address: "uusd",
|
||||||
chainId: WORMHOLE_CHAIN_ID_TERRA,
|
chainId: CHAIN_ID_TERRA,
|
||||||
logo: ustIcon,
|
logo: terraIcon,
|
||||||
isNative: false,
|
isNative: true, // TODO: change?
|
||||||
maxAmount: 10.0,
|
maxAmount: 10.0,
|
||||||
ustPairedAddress: undefined,
|
ustPairedAddress: undefined,
|
||||||
};
|
};
|
||||||
|
@ -85,18 +76,33 @@ export const TOKEN_INFOS = [
|
||||||
UST_TOKEN_INFO,
|
UST_TOKEN_INFO,
|
||||||
];
|
];
|
||||||
|
|
||||||
// evm handling
|
export const getSupportedSwaps = (tokenInfo: TokenInfo) => {
|
||||||
export const EVM_ETH_NETWORK_CHAIN_ID = 5;
|
switch (tokenInfo) {
|
||||||
export const EVM_POLYGON_NETWORK_CHAIN_ID = 80001;
|
case MATIC_TOKEN_INFO:
|
||||||
|
return [ETH_TOKEN_INFO, UST_TOKEN_INFO];
|
||||||
|
case WMATIC_TOKEN_INFO:
|
||||||
|
return [WETH_TOKEN_INFO];
|
||||||
|
case ETH_TOKEN_INFO:
|
||||||
|
return [MATIC_TOKEN_INFO, UST_TOKEN_INFO];
|
||||||
|
case WETH_TOKEN_INFO:
|
||||||
|
return [WMATIC_TOKEN_INFO];
|
||||||
|
case UST_TOKEN_INFO:
|
||||||
|
return [ETH_TOKEN_INFO, MATIC_TOKEN_INFO];
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ETH_NETWORK_CHAIN_ID = 5;
|
||||||
|
|
||||||
|
export const POLYGON_NETWORK_CHAIN_ID = 80001;
|
||||||
|
|
||||||
export const getEvmChainId = (chainId: ChainId) =>
|
export const getEvmChainId = (chainId: ChainId) =>
|
||||||
chainId === WORMHOLE_CHAIN_ID_ETHEREUM
|
chainId === CHAIN_ID_ETH
|
||||||
? EVM_ETH_NETWORK_CHAIN_ID
|
? ETH_NETWORK_CHAIN_ID
|
||||||
: chainId === WORMHOLE_CHAIN_ID_POLYGON
|
: chainId === CHAIN_ID_POLYGON
|
||||||
? EVM_POLYGON_NETWORK_CHAIN_ID
|
? POLYGON_NETWORK_CHAIN_ID
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
// misc
|
|
||||||
export const RELAYER_FEE_UST = "0.25";
|
export const RELAYER_FEE_UST = "0.25";
|
||||||
|
|
||||||
export const WORMHOLE_RPC_HOSTS = [
|
export const WORMHOLE_RPC_HOSTS = [
|
||||||
|
|
|
@ -6,7 +6,7 @@ export function addFixedAmounts(
|
||||||
decimals: number
|
decimals: number
|
||||||
): string {
|
): string {
|
||||||
const sum = FixedNumber.from(left).addUnsafe(FixedNumber.from(right));
|
const sum = FixedNumber.from(left).addUnsafe(FixedNumber.from(right));
|
||||||
return sum.round(this.getDecimals()).toString();
|
return sum.round(decimals).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function subtractFixedAmounts(
|
export function subtractFixedAmounts(
|
||||||
|
|
|
@ -7,7 +7,12 @@ import {
|
||||||
TextField,
|
TextField,
|
||||||
Typography,
|
Typography,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import { ChainId, getSignedVAAWithRetry } from "@certusone/wormhole-sdk";
|
import {
|
||||||
|
ChainId,
|
||||||
|
CHAIN_ID_TERRA,
|
||||||
|
getSignedVAAWithRetry,
|
||||||
|
isEVMChain,
|
||||||
|
} from "@certusone/wormhole-sdk";
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import ButtonWithLoader from "../components/ButtonWithLoader";
|
import ButtonWithLoader from "../components/ButtonWithLoader";
|
||||||
import EthereumSignerKey from "../components/EthereumSignerKey";
|
import EthereumSignerKey from "../components/EthereumSignerKey";
|
||||||
|
@ -16,11 +21,11 @@ import { useEthereumProvider } from "../contexts/EthereumProviderContext";
|
||||||
import {
|
import {
|
||||||
ETH_TOKEN_INFO,
|
ETH_TOKEN_INFO,
|
||||||
getEvmChainId,
|
getEvmChainId,
|
||||||
|
getSupportedSwaps,
|
||||||
MATIC_TOKEN_INFO,
|
MATIC_TOKEN_INFO,
|
||||||
RELAYER_FEE_UST,
|
RELAYER_FEE_UST,
|
||||||
|
TokenInfo,
|
||||||
TOKEN_INFOS,
|
TOKEN_INFOS,
|
||||||
WETH_TOKEN_INFO,
|
|
||||||
WMATIC_TOKEN_INFO,
|
|
||||||
WORMHOLE_RPC_HOSTS,
|
WORMHOLE_RPC_HOSTS,
|
||||||
} from "../utils/consts";
|
} from "../utils/consts";
|
||||||
import { COLORS } from "../muiTheme";
|
import { COLORS } from "../muiTheme";
|
||||||
|
@ -34,9 +39,15 @@ import parseError from "../utils/parseError";
|
||||||
import Settings from "../components/Settings";
|
import Settings from "../components/Settings";
|
||||||
import getIsTransferCompletedEvmWithRetry from "../utils/getIsTransferCompletedWithRetry";
|
import getIsTransferCompletedEvmWithRetry from "../utils/getIsTransferCompletedWithRetry";
|
||||||
import CircleLoader from "../components/CircleLoader";
|
import CircleLoader from "../components/CircleLoader";
|
||||||
import { ArrowForward, CheckCircleOutlineRounded } from "@material-ui/icons";
|
import {
|
||||||
|
ArrowForward,
|
||||||
|
CheckCircleOutlineRounded,
|
||||||
|
QueueTwoTone,
|
||||||
|
} from "@material-ui/icons";
|
||||||
import SwapProgress from "../components/SwapProgress";
|
import SwapProgress from "../components/SwapProgress";
|
||||||
import Footer from "../components/Footer";
|
import Footer from "../components/Footer";
|
||||||
|
import TerraWalletKey from "../components/TerraWalletKey";
|
||||||
|
import useIsWalletReady from "../hooks/useIsWalletReady";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
bg: {
|
bg: {
|
||||||
|
@ -135,7 +146,7 @@ const useStyles = makeStyles((theme) => ({
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const switchProviderNetwork = async (
|
const switchEvmProviderNetwork = async (
|
||||||
provider: Web3Provider,
|
provider: Web3Provider,
|
||||||
chainId: ChainId
|
chainId: ChainId
|
||||||
) => {
|
) => {
|
||||||
|
@ -152,6 +163,74 @@ const switchProviderNetwork = async (
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ConnectedWalletAddress = ({ chainId }: { chainId: ChainId }) => {
|
||||||
|
const { walletAddress } = useIsWalletReady(chainId, false);
|
||||||
|
if (walletAddress) {
|
||||||
|
const is0x = walletAddress.startsWith("0x");
|
||||||
|
return (
|
||||||
|
<Typography variant="subtitle2">
|
||||||
|
{walletAddress?.substring(0, is0x ? 6 : 3)}...
|
||||||
|
{walletAddress?.substring(walletAddress.length - (is0x ? 4 : 3))}
|
||||||
|
</Typography>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const SwapButton = ({
|
||||||
|
source,
|
||||||
|
target,
|
||||||
|
disabled,
|
||||||
|
showLoader,
|
||||||
|
onClick,
|
||||||
|
}: {
|
||||||
|
source: TokenInfo;
|
||||||
|
target: TokenInfo;
|
||||||
|
disabled: boolean;
|
||||||
|
showLoader: boolean;
|
||||||
|
onClick: () => void;
|
||||||
|
}) => {
|
||||||
|
const { isReady: isSourceWalletReady, walletAddress: sourceWalletAddress } =
|
||||||
|
useIsWalletReady(source.chainId, false);
|
||||||
|
const { isReady: isTargetWalletReady, walletAddress: targetWalletAddress } =
|
||||||
|
useIsWalletReady(target.chainId, false);
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
"sourceWalletAddress",
|
||||||
|
sourceWalletAddress,
|
||||||
|
"targetWalletAddress",
|
||||||
|
targetWalletAddress
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isSourceWalletReady) {
|
||||||
|
return isEVMChain(source.chainId) ? (
|
||||||
|
<EthereumSignerKey />
|
||||||
|
) : source.chainId === CHAIN_ID_TERRA ? (
|
||||||
|
<TerraWalletKey />
|
||||||
|
) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!isTargetWalletReady &&
|
||||||
|
(!isEVMChain(source.chainId) || !isEVMChain(target.chainId))
|
||||||
|
) {
|
||||||
|
return isEVMChain(target.chainId) ? (
|
||||||
|
<EthereumSignerKey />
|
||||||
|
) : source.chainId === CHAIN_ID_TERRA ? (
|
||||||
|
<TerraWalletKey />
|
||||||
|
) : null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<ButtonWithLoader
|
||||||
|
disabled={disabled}
|
||||||
|
showLoader={showLoader}
|
||||||
|
onClick={onClick}
|
||||||
|
>
|
||||||
|
Swap
|
||||||
|
</ButtonWithLoader>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const [sourceTokenInfo, setSourceTokenInfo] = useState(MATIC_TOKEN_INFO);
|
const [sourceTokenInfo, setSourceTokenInfo] = useState(MATIC_TOKEN_INFO);
|
||||||
|
@ -169,14 +248,16 @@ export default function Home() {
|
||||||
const [hasQuote, setHasQuote] = useState(false);
|
const [hasQuote, setHasQuote] = useState(false);
|
||||||
const { provider, signer } = useEthereumProvider();
|
const { provider, signer } = useEthereumProvider();
|
||||||
const { enqueueSnackbar } = useSnackbar();
|
const { enqueueSnackbar } = useSnackbar();
|
||||||
const [isFirstSwapComplete, setIsFirstSwapComplete] = useState(false);
|
const [isSourceSwapComplete, setIsSourceSwapComplete] = useState(false);
|
||||||
const [isSecondSwapComplete, setIsSecondSwapComplete] = useState(false);
|
const [isTargetSwapComplete, setIsTargetSwapComplete] = useState(false);
|
||||||
const [sourceTxBlockNumber, setSourceTxBlockNumber] = useState<
|
const [sourceTxBlockNumber, setSourceTxBlockNumber] = useState<
|
||||||
number | undefined
|
number | undefined
|
||||||
>(undefined);
|
>(undefined);
|
||||||
const [hasSignedVAA, setHasSignedVAA] = useState(false);
|
const [hasSignedVAA, setHasSignedVAA] = useState(false);
|
||||||
const [relayerTimeoutString, setRelayerTimeoutString] = useState("");
|
const [relayerTimeoutString, setRelayerTimeoutString] = useState("");
|
||||||
|
|
||||||
|
const foo = useIsWalletReady(sourceTokenInfo.chainId);
|
||||||
|
|
||||||
const computeQuote = useCallback(() => {
|
const computeQuote = useCallback(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
setHasQuote(false);
|
setHasQuote(false);
|
||||||
|
@ -205,10 +286,15 @@ export default function Home() {
|
||||||
executor.setSlippage((parseFloat(slippage) / 100).toString());
|
executor.setSlippage((parseFloat(slippage) / 100).toString());
|
||||||
executor.setRelayerFee(RELAYER_FEE_UST);
|
executor.setRelayerFee(RELAYER_FEE_UST);
|
||||||
const quote = await executor.computeQuoteExactIn(amountIn);
|
const quote = await executor.computeQuoteExactIn(amountIn);
|
||||||
|
// TODO: FIX
|
||||||
|
if (!quote || !quote.dst) {
|
||||||
|
throw new Error("failed to compute quote");
|
||||||
|
}
|
||||||
setExecutor(executor);
|
setExecutor(executor);
|
||||||
setAmountOut(
|
setAmountOut(
|
||||||
parseFloat(
|
parseFloat(
|
||||||
executor.tokens.dstOut.formatAmount(quote.dst.minAmountOut)
|
// executor.tokens.dstOut.formatAmount(quote.dst.minAmountOut)
|
||||||
|
quote.minAmountOut
|
||||||
).toFixed(8)
|
).toFixed(8)
|
||||||
);
|
);
|
||||||
setAmountInUST(
|
setAmountInUST(
|
||||||
|
@ -260,30 +346,38 @@ export default function Home() {
|
||||||
setDeadline(deadline);
|
setDeadline(deadline);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleSourceChange = useCallback((event) => {
|
const handleSourceChange = useCallback(
|
||||||
// NOTE: only native-to-native or wrapped-to-wrapped swaps are currently supported
|
(event) => {
|
||||||
if (event.target.value === WMATIC_TOKEN_INFO.name) {
|
const tokenInfo = TOKEN_INFOS.find((x) => x.name === event.target.value);
|
||||||
setSourceTokenInfo(WMATIC_TOKEN_INFO);
|
if (tokenInfo) {
|
||||||
setTargetTokenInfo(WETH_TOKEN_INFO);
|
const supportedSwaps = getSupportedSwaps(tokenInfo);
|
||||||
} else if (event.target.value === WETH_TOKEN_INFO.name) {
|
console.log(supportedSwaps);
|
||||||
setSourceTokenInfo(WETH_TOKEN_INFO);
|
if (supportedSwaps) {
|
||||||
setTargetTokenInfo(WMATIC_TOKEN_INFO);
|
setSourceTokenInfo(tokenInfo);
|
||||||
} else if (event.target.value === ETH_TOKEN_INFO.name) {
|
if (!supportedSwaps.find((x) => x.name === targetTokenInfo.name)) {
|
||||||
setSourceTokenInfo(ETH_TOKEN_INFO);
|
setTargetTokenInfo(supportedSwaps[0]);
|
||||||
setTargetTokenInfo(MATIC_TOKEN_INFO);
|
}
|
||||||
} else {
|
setAmountIn("");
|
||||||
setSourceTokenInfo(MATIC_TOKEN_INFO);
|
setAmountOut("");
|
||||||
setTargetTokenInfo(ETH_TOKEN_INFO);
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[targetTokenInfo]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleTargetChange = useCallback((event) => {
|
||||||
|
const tokenInfo = TOKEN_INFOS.find((x) => x.name === event.target.value);
|
||||||
|
if (tokenInfo) {
|
||||||
|
setTargetTokenInfo(tokenInfo);
|
||||||
|
setAmountOut("");
|
||||||
}
|
}
|
||||||
setAmountIn("");
|
|
||||||
setAmountOut("");
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const reset = useCallback(() => {
|
const reset = useCallback(() => {
|
||||||
setIsSwapping(false);
|
setIsSwapping(false);
|
||||||
setHasQuote(false);
|
setHasQuote(false);
|
||||||
setIsFirstSwapComplete(false);
|
setIsSourceSwapComplete(false);
|
||||||
setIsSecondSwapComplete(false);
|
setIsTargetSwapComplete(false);
|
||||||
setAmountIn("");
|
setAmountIn("");
|
||||||
setAmountOut("");
|
setAmountOut("");
|
||||||
setSourceTxBlockNumber(undefined);
|
setSourceTxBlockNumber(undefined);
|
||||||
|
@ -294,18 +388,19 @@ export default function Home() {
|
||||||
if (provider && signer && executor) {
|
if (provider && signer && executor) {
|
||||||
try {
|
try {
|
||||||
setIsSwapping(true);
|
setIsSwapping(true);
|
||||||
setIsFirstSwapComplete(false);
|
setIsSourceSwapComplete(false);
|
||||||
setHasSignedVAA(false);
|
setHasSignedVAA(false);
|
||||||
setIsSecondSwapComplete(false);
|
setIsTargetSwapComplete(false);
|
||||||
setRelayerTimeoutString("");
|
setRelayerTimeoutString("");
|
||||||
await switchProviderNetwork(provider, sourceTokenInfo.chainId);
|
await switchEvmProviderNetwork(provider, sourceTokenInfo.chainId);
|
||||||
|
|
||||||
const sourceReceipt = await executor.approveAndSwap(signer);
|
// TODO: fix
|
||||||
|
const sourceReceipt = await executor.evmApproveAndSwap(signer);
|
||||||
console.info(
|
console.info(
|
||||||
"firstSwapTransactionHash:",
|
"firstSwapTransactionHash:",
|
||||||
sourceReceipt.transactionHash
|
sourceReceipt.transactionHash
|
||||||
);
|
);
|
||||||
setIsFirstSwapComplete(true);
|
setIsSourceSwapComplete(true);
|
||||||
setSourceTxBlockNumber(sourceReceipt.blockNumber);
|
setSourceTxBlockNumber(sourceReceipt.blockNumber);
|
||||||
|
|
||||||
// Wait for the guardian network to reach consensus and emit the signedVAA
|
// Wait for the guardian network to reach consensus and emit the signedVAA
|
||||||
|
@ -319,7 +414,9 @@ export default function Home() {
|
||||||
// Check if the signedVAA has redeemed by the relayer
|
// Check if the signedVAA has redeemed by the relayer
|
||||||
const isCompleted = await getIsTransferCompletedEvmWithRetry(
|
const isCompleted = await getIsTransferCompletedEvmWithRetry(
|
||||||
executor.dstExecutionParams.wormhole.tokenBridgeAddress,
|
executor.dstExecutionParams.wormhole.tokenBridgeAddress,
|
||||||
executor.quoter.dstProvider,
|
// TODO: fix
|
||||||
|
//@ts-ignore
|
||||||
|
executor.quoter.getDstEvmProvider(),
|
||||||
vaaBytes,
|
vaaBytes,
|
||||||
// retry for two minutes
|
// retry for two minutes
|
||||||
3000,
|
3000,
|
||||||
|
@ -330,14 +427,14 @@ export default function Home() {
|
||||||
setRelayerTimeoutString(
|
setRelayerTimeoutString(
|
||||||
"Timed out waiting for relayer to complete swap. You'll need to complete it yourself."
|
"Timed out waiting for relayer to complete swap. You'll need to complete it yourself."
|
||||||
);
|
);
|
||||||
await switchProviderNetwork(provider, targetTokenInfo.chainId);
|
await switchEvmProviderNetwork(provider, targetTokenInfo.chainId);
|
||||||
const targetReceipt = await executor.fetchVaaAndSwap(signer);
|
const targetReceipt = await executor.fetchVaaAndSwap(signer);
|
||||||
console.info(
|
console.info(
|
||||||
"secondSwapTransactionHash:",
|
"secondSwapTransactionHash:",
|
||||||
targetReceipt.transactionHash
|
targetReceipt.transactionHash
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
setIsSecondSwapComplete(true);
|
setIsTargetSwapComplete(true);
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
reset();
|
reset();
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
@ -357,6 +454,7 @@ export default function Home() {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const readyToSwap = provider && signer && hasQuote;
|
const readyToSwap = provider && signer && hasQuote;
|
||||||
|
const disableSelect = isSwapping || isComputingQuote;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes.bg}>
|
<div className={classes.bg}>
|
||||||
|
@ -367,9 +465,9 @@ export default function Home() {
|
||||||
</Typography>
|
</Typography>
|
||||||
<div className={classes.spacer} />
|
<div className={classes.spacer} />
|
||||||
<Paper className={classes.mainPaper}>
|
<Paper className={classes.mainPaper}>
|
||||||
<Collapse in={!isFirstSwapComplete}>
|
<Collapse in={!isSourceSwapComplete}>
|
||||||
<Settings
|
<Settings
|
||||||
disabled={isSwapping || isComputingQuote}
|
disabled={disableSelect}
|
||||||
slippage={slippage}
|
slippage={slippage}
|
||||||
deadline={deadline}
|
deadline={deadline}
|
||||||
onSlippageChange={handleSlippageChange}
|
onSlippageChange={handleSlippageChange}
|
||||||
|
@ -379,13 +477,13 @@ export default function Home() {
|
||||||
tokens={TOKEN_INFOS}
|
tokens={TOKEN_INFOS}
|
||||||
value={sourceTokenInfo.name}
|
value={sourceTokenInfo.name}
|
||||||
onChange={handleSourceChange}
|
onChange={handleSourceChange}
|
||||||
disabled={isSwapping || isComputingQuote}
|
disabled={disableSelect}
|
||||||
></TokenSelect>
|
></TokenSelect>
|
||||||
<Typography variant="subtitle1">Send</Typography>
|
<Typography variant="subtitle1">Send</Typography>
|
||||||
<TextField
|
<TextField
|
||||||
type="number"
|
type="number"
|
||||||
value={amountIn}
|
value={amountIn}
|
||||||
disabled={isSwapping || isComputingQuote}
|
disabled={disableSelect}
|
||||||
InputProps={{ disableUnderline: true }}
|
InputProps={{ disableUnderline: true }}
|
||||||
className={classes.numberField}
|
className={classes.numberField}
|
||||||
onChange={handleAmountChange}
|
onChange={handleAmountChange}
|
||||||
|
@ -397,12 +495,13 @@ export default function Home() {
|
||||||
color="error"
|
color="error"
|
||||||
>{`The max input amount is ${sourceTokenInfo.maxAmount} ${sourceTokenInfo.name}`}</Typography>
|
>{`The max input amount is ${sourceTokenInfo.maxAmount} ${sourceTokenInfo.name}`}</Typography>
|
||||||
) : null}
|
) : null}
|
||||||
|
<ConnectedWalletAddress chainId={sourceTokenInfo.chainId} />
|
||||||
<div className={classes.spacer} />
|
<div className={classes.spacer} />
|
||||||
<TokenSelect
|
<TokenSelect
|
||||||
tokens={TOKEN_INFOS}
|
tokens={getSupportedSwaps(sourceTokenInfo)}
|
||||||
value={targetTokenInfo.name}
|
value={targetTokenInfo.name}
|
||||||
onChange={() => {}}
|
onChange={handleTargetChange}
|
||||||
disabled={true}
|
disabled={disableSelect}
|
||||||
></TokenSelect>
|
></TokenSelect>
|
||||||
<Typography variant="subtitle1">Receive (estimated)</Typography>
|
<Typography variant="subtitle1">Receive (estimated)</Typography>
|
||||||
<TextField
|
<TextField
|
||||||
|
@ -414,10 +513,20 @@ export default function Home() {
|
||||||
inputProps={{ readOnly: true }}
|
inputProps={{ readOnly: true }}
|
||||||
placeholder="0.0"
|
placeholder="0.0"
|
||||||
></TextField>
|
></TextField>
|
||||||
|
<ConnectedWalletAddress
|
||||||
|
chainId={
|
||||||
|
isEVMChain(sourceTokenInfo.chainId) &&
|
||||||
|
isEVMChain(targetTokenInfo.chainId)
|
||||||
|
? sourceTokenInfo.chainId
|
||||||
|
: targetTokenInfo.chainId
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<div className={classes.spacer} />
|
||||||
<Typography variant="subtitle2">{`Slippage tolerance: ${slippage}%`}</Typography>
|
<Typography variant="subtitle2">{`Slippage tolerance: ${slippage}%`}</Typography>
|
||||||
<Typography variant="subtitle2">{`Relayer fee: ${RELAYER_FEE_UST} UST`}</Typography>
|
<Typography variant="subtitle2">{`Relayer fee: ${RELAYER_FEE_UST} UST`}</Typography>
|
||||||
{!isSwapping && <EthereumSignerKey />}
|
<SwapButton
|
||||||
<ButtonWithLoader
|
source={sourceTokenInfo}
|
||||||
|
target={targetTokenInfo}
|
||||||
disabled={
|
disabled={
|
||||||
!readyToSwap ||
|
!readyToSwap ||
|
||||||
isSwapping ||
|
isSwapping ||
|
||||||
|
@ -425,11 +534,9 @@ export default function Home() {
|
||||||
}
|
}
|
||||||
showLoader={isSwapping}
|
showLoader={isSwapping}
|
||||||
onClick={handleSwapClick}
|
onClick={handleSwapClick}
|
||||||
>
|
/>
|
||||||
Swap
|
|
||||||
</ButtonWithLoader>
|
|
||||||
</Collapse>
|
</Collapse>
|
||||||
<Collapse in={isFirstSwapComplete && !isSecondSwapComplete}>
|
<Collapse in={isSourceSwapComplete && !isTargetSwapComplete}>
|
||||||
<div className={classes.loaderHolder}>
|
<div className={classes.loaderHolder}>
|
||||||
<CircleLoader />
|
<CircleLoader />
|
||||||
<div className={classes.spacer} />
|
<div className={classes.spacer} />
|
||||||
|
@ -438,14 +545,14 @@ export default function Home() {
|
||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
<Collapse in={isSecondSwapComplete}>
|
<Collapse in={isTargetSwapComplete}>
|
||||||
<div className={classes.loaderHolder}>
|
<div className={classes.loaderHolder}>
|
||||||
<CheckCircleOutlineRounded
|
<CheckCircleOutlineRounded
|
||||||
className={classes.successIcon}
|
className={classes.successIcon}
|
||||||
fontSize={"inherit"}
|
fontSize={"inherit"}
|
||||||
/>
|
/>
|
||||||
<Typography>Swap completed!</Typography>
|
<Typography>Swap completed!</Typography>
|
||||||
<ButtonWithLoader onClick={() => reset()}>
|
<ButtonWithLoader onClick={reset}>
|
||||||
Swap more tokens!
|
Swap more tokens!
|
||||||
</ButtonWithLoader>
|
</ButtonWithLoader>
|
||||||
</div>
|
</div>
|
||||||
|
@ -460,19 +567,23 @@ export default function Home() {
|
||||||
{`${amountOut} ${targetTokenInfo.name}`}
|
{`${amountOut} ${targetTokenInfo.name}`}
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
{isFirstSwapComplete &&
|
{isSourceSwapComplete &&
|
||||||
!isSecondSwapComplete &&
|
!isTargetSwapComplete &&
|
||||||
!relayerTimeoutString && (
|
!relayerTimeoutString && (
|
||||||
<SwapProgress
|
<>
|
||||||
chainId={sourceTokenInfo.chainId}
|
<SwapProgress
|
||||||
txBlockNumber={sourceTxBlockNumber}
|
chainId={sourceTokenInfo.chainId}
|
||||||
step={!hasSignedVAA ? 1 : !isSecondSwapComplete ? 2 : 3}
|
txBlockNumber={sourceTxBlockNumber}
|
||||||
/>
|
isSourceSwapComplete={isSourceSwapComplete}
|
||||||
|
hasSignedVAA={hasSignedVAA}
|
||||||
|
isTargetSwapComplete={isTargetSwapComplete}
|
||||||
|
/>
|
||||||
|
<div className={classes.spacer} />
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
{relayerTimeoutString && (
|
{relayerTimeoutString && (
|
||||||
<Typography variant="subtitle1">{relayerTimeoutString}</Typography>
|
<Typography variant="subtitle1">{relayerTimeoutString}</Typography>
|
||||||
)}
|
)}
|
||||||
<div className={classes.spacer} />
|
|
||||||
<Typography variant="subtitle2" color="error">
|
<Typography variant="subtitle2" color="error">
|
||||||
WARNING: this is a Testnet release only
|
WARNING: this is a Testnet release only
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
Loading…
Reference in New Issue